@@ -26,11 +26,13 @@ import (
2626
2727 "github.com/digitalocean/godo"
2828 v1 "k8s.io/api/core/v1"
29+ "k8s.io/apimachinery/pkg/types"
2930 cloudprovider "k8s.io/cloud-provider"
3031)
3132
3233const (
3334 dropletShutdownStatus = "off"
35+ providerIDPrefix = "digitalocean://"
3436)
3537
3638// instances implements the InstancesV2() interface
@@ -92,25 +94,66 @@ func (i *instances) InstanceShutdown(ctx context.Context, node *v1.Node) (bool,
9294 return droplet .Status == dropletShutdownStatus , nil
9395}
9496
95- func (i * instances ) InstanceMetadata (ctx context.Context , node * v1.Node ) (* cloudprovider.InstanceMetadata , error ) {
96- dropletID , err := dropletIDFromProviderID (node .Spec .ProviderID )
97+ // dropletByName returns a *godo.Droplet for the droplet identified by nodeName.
98+ //
99+ // When nodeName identifies more than one droplet, only the first will be
100+ // considered.
101+ func dropletByName (ctx context.Context , client * godo.Client , nodeName types.NodeName ) (* godo.Droplet , error ) {
102+ droplets , err := allDropletList (ctx , func (ctx context.Context , opt * godo.ListOptions ) ([]godo.Droplet , * godo.Response , error ) {
103+ return client .Droplets .ListByName (ctx , string (nodeName ), opt )
104+ })
97105 if err != nil {
98- return nil , fmt . Errorf ( "determining droplet ID from providerID: %s" , err . Error ())
106+ return nil , err
99107 }
100108
101- droplet , err := dropletByID (ctx , i .resources .gclient , dropletID )
102- if err != nil {
103- return nil , fmt .Errorf ("getting droplet by ID: %s: " , err .Error ())
109+ for _ , droplet := range droplets {
110+ if droplet .Name == string (nodeName ) {
111+ return & droplet , nil
112+ }
113+ addresses , _ := nodeAddresses (& droplet )
114+ for _ , address := range addresses {
115+ if address .Address == string (nodeName ) {
116+ return & droplet , nil
117+ }
118+ }
104119 }
105- if droplet == nil {
106- return nil , fmt .Errorf ("droplet %d for node %s does not exist" , dropletID , node .Name )
120+
121+ return nil , cloudprovider .InstanceNotFound
122+ }
123+
124+ func (i * instances ) InstanceMetadata (ctx context.Context , node * v1.Node ) (* cloudprovider.InstanceMetadata , error ) {
125+ var (
126+ dropletID int
127+ err error
128+ droplet * godo.Droplet
129+ )
130+
131+ if node .Spec .ProviderID == "" {
132+ droplet , err = dropletByName (ctx , i .resources .gclient , types .NodeName (node .GetName ()))
133+ if err != nil {
134+ return nil , fmt .Errorf ("getting droplet by name: %s" , err .Error ())
135+ }
136+ dropletID = droplet .ID
137+ } else {
138+ dropletID , err = dropletIDFromProviderID (node .Spec .ProviderID )
139+ if err != nil {
140+ return nil , fmt .Errorf ("determining droplet ID from providerID: %s" , err .Error ())
141+ }
142+ droplet , err = dropletByID (ctx , i .resources .gclient , dropletID )
143+ if err != nil {
144+ return nil , fmt .Errorf ("getting droplet by ID: %s: " , err .Error ())
145+ }
146+ if droplet == nil {
147+ return nil , fmt .Errorf ("droplet %d for node %s does not exist" , dropletID , node .Name )
148+ }
107149 }
150+
108151 nodeAddrs , err := nodeAddresses (droplet )
109152 if err != nil {
110153 return nil , fmt .Errorf ("getting node addresses of droplet %d for node %s: %s" , dropletID , node .Name , err .Error ())
111154 }
112155 return & cloudprovider.InstanceMetadata {
113- ProviderID : node . Spec . ProviderID , // the providerID may or may not be present according to the interface doc. However, we set this from kubelet.
156+ ProviderID : fmt . Sprintf ( "%s%d" , providerIDPrefix , dropletID ),
114157 InstanceType : droplet .SizeSlug ,
115158 Region : droplet .Region .Slug ,
116159 NodeAddresses : nodeAddrs ,
@@ -132,13 +175,11 @@ func dropletIDFromProviderID(providerID string) (int, error) {
132175 return 0 , errors .New ("provider ID cannot be empty" )
133176 }
134177
135- const prefix = "digitalocean://"
136-
137- if ! strings .HasPrefix (providerID , prefix ) {
138- return 0 , fmt .Errorf ("provider ID %q is missing prefix %q" , providerID , prefix )
178+ if ! strings .HasPrefix (providerID , providerIDPrefix ) {
179+ return 0 , fmt .Errorf ("provider ID %q is missing prefix %q" , providerID , providerIDPrefix )
139180 }
140181
141- provIDNum := strings .TrimPrefix (providerID , prefix )
182+ provIDNum := strings .TrimPrefix (providerID , providerIDPrefix )
142183 if provIDNum == "" {
143184 return 0 , errors .New ("provider ID number cannot be empty" )
144185 }
0 commit comments