-
Notifications
You must be signed in to change notification settings - Fork 27
/
cloud.go
161 lines (136 loc) · 5.86 KB
/
cloud.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
package metal
import (
"fmt"
"io"
"os"
metal "github.com/equinix/equinix-sdk-go/services/metalv1"
cloudprovider "k8s.io/cloud-provider"
"k8s.io/component-base/version"
"k8s.io/klog/v2"
)
const (
ProviderName string = "equinixmetal"
// deprecatedProviderName is used to provide backward compatibility support
// with previous versions
deprecatedProviderName string = "packet"
// ConsumerToken token for metal consumer
ConsumerToken string = "cloud-provider-equinix-metal"
// checkLoopTimerSeconds how often to resync the kubernetes informers, in seconds
checkLoopTimerSeconds = 60
)
// cloud implements cloudprovider.Interface
type cloud struct {
client *metal.APIClient
config Config
instances *instances
loadBalancer *loadBalancers
controlPlaneEndpointManager *controlPlaneEndpointManager
controlPlaneLoadBalancerManager *controlPlaneLoadBalancerManager
// holds our bgp service handler
bgp *bgp
}
var _ cloudprovider.Interface = (*cloud)(nil)
func newCloud(metalConfig Config, client *metal.APIClient) (cloudprovider.Interface, error) {
return &cloud{
client: client,
config: metalConfig,
}, nil
}
func init() {
cloudprovider.RegisterCloudProvider(ProviderName, func(config io.Reader) (cloudprovider.Interface, error) {
// by the time we get here, there is no error, as it would have been handled earlier
metalConfig, err := getMetalConfig(config)
// register the provider
if err != nil {
return nil, fmt.Errorf("provider config error: %w", err)
}
// report the config to startup logs
printMetalConfig(metalConfig)
// set up our client and create the cloud interface
configuration := metal.NewConfiguration()
configuration.AddDefaultHeader("X-Auth-Token", metalConfig.AuthToken)
configuration.UserAgent = fmt.Sprintf("cloud-provider-equinix-metal/%s %s", version.Get(), configuration.UserAgent)
configuration.Debug = checkDebugEnabled()
client := metal.NewAPIClient(configuration)
cloud, err := newCloud(metalConfig, client)
if err != nil {
return nil, fmt.Errorf("failed to create new cloud handler: %w", err)
}
// note that this is not fully initialized until it calls cloud.Initialize()
return cloud, nil
})
}
// Initialize provides the cloud with a kubernetes client builder and may spawn goroutines
// to perform housekeeping activities within the cloud provider.
func (c *cloud) Initialize(clientBuilder cloudprovider.ControllerClientBuilder, stop <-chan struct{}) {
klog.V(5).Info("called Initialize")
clientset := clientBuilder.ClientOrDie("cloud-provider-equinix-metal-shared-informers")
// initialize the individual services
epm, err := newControlPlaneEndpointManager(clientset, stop, c.config.EIPTag, c.config.ProjectID, c.client, c.config.APIServerPort, c.config.EIPHealthCheckUseHostIP)
if err != nil {
klog.Fatalf("could not initialize ControlPlaneEndpointManager: %v", err)
}
lbm, err := newControlPlaneLoadBalancerManager(clientset, stop, c.config.ProjectID, c.config.LoadBalancerID, c.config.APIServerPort, c.config.EIPHealthCheckUseHostIP)
if err != nil {
klog.Fatalf("could not initialize ControlPlaneEndpointManager: %v", err)
}
bgp, err := newBGP(c.client.BGPApi, clientset, c.config)
if err != nil {
klog.Fatalf("could not initialize BGP: %v", err)
}
lb, err := newLoadBalancers(c.client, clientset, c.config.AuthToken, c.config.ProjectID, c.config.Metro, c.config.Facility, c.config.LoadBalancerSetting, bgp.localASN, bgp.bgpPass, c.config.AnnotationNetworkIPv4Private, c.config.AnnotationLocalASN, c.config.AnnotationPeerASN, c.config.AnnotationPeerIP, c.config.AnnotationSrcIP, c.config.AnnotationBGPPass, c.config.AnnotationEIPMetro, c.config.AnnotationEIPFacility, c.config.BGPNodeSelector, c.config.EIPTag)
if err != nil {
klog.Fatalf("could not initialize LoadBalancers: %v", err)
}
c.loadBalancer = lb
c.bgp = bgp
c.instances = newInstances(c.client.DevicesApi, c.config.ProjectID)
c.controlPlaneEndpointManager = epm
c.controlPlaneLoadBalancerManager = lbm
klog.Info("Initialize of cloud provider complete")
}
// LoadBalancer returns a balancer interface. Also returns true if the interface is supported, false otherwise.
func (c *cloud) LoadBalancer() (cloudprovider.LoadBalancer, bool) {
klog.V(5).Info("called LoadBalancer")
return c.loadBalancer, c.loadBalancer != nil
}
// Instances returns an instances interface. Also returns true if the interface is supported, false otherwise.
func (c *cloud) Instances() (cloudprovider.Instances, bool) {
klog.V(5).Info("called Instances")
return nil, false
}
// InstancesV2 returns an implementation of cloudprovider.InstancesV2.
func (c *cloud) InstancesV2() (cloudprovider.InstancesV2, bool) {
klog.V(5).Info("called InstancesV2")
return c.instances, true
}
// Zones returns a zones interface. Also returns true if the interface is supported, false otherwise.
// DEPRECATED. Will not be called if InstancesV2 is implemented
func (c *cloud) Zones() (cloudprovider.Zones, bool) {
klog.V(5).Info("called Zones")
return nil, false
}
// Clusters returns a clusters interface. Also returns true if the interface is supported, false otherwise.
func (c *cloud) Clusters() (cloudprovider.Clusters, bool) {
klog.V(5).Info("called Clusters")
return nil, false
}
// Routes returns a routes interface along with whether the interface is supported.
func (c *cloud) Routes() (cloudprovider.Routes, bool) {
klog.V(5).Info("called Routes")
return nil, false
}
// ProviderName returns the cloud provider ID.
func (c *cloud) ProviderName() string {
klog.V(2).Infof("called ProviderName, returning %s", ProviderName)
return ProviderName
}
// HasClusterID returns true if a ClusterID is required and set
func (c *cloud) HasClusterID() bool {
klog.V(5).Info("called HasClusterID")
return true
}
func checkDebugEnabled() bool {
_, legacyVarIsSet := os.LookupEnv("PACKNGO_DEBUG")
return legacyVarIsSet
}