Skip to content

Commit 85305c0

Browse files
committed
Look up instance by providerID and node name consistently.
Currently, some instance operations look up instances by providerID and then fall back to node name, and other operations just use providerID. This causes problems using the cluster api, since nodes aren't provisioned with a providerID initially. This patch looks up instances by both providerID and node name consistently, and lightly refactors lookups to avoid repeat queries.
1 parent 53e7b3a commit 85305c0

1 file changed

Lines changed: 27 additions & 26 deletions

File tree

internal/provider/instances_v2.go

Lines changed: 27 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ package provider
66

77
import (
88
"context"
9+
"errors"
910
"fmt"
10-
"strings"
1111
"time"
1212

1313
"github.com/oxidecomputer/oxide.go/oxide"
@@ -36,6 +36,8 @@ func (i *InstancesV2) InstanceExists(ctx context.Context, node *v1.Node) (bool,
3636
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
3737
defer cancel()
3838

39+
// Look up instance by the node's providerID. By this point, the providerID will have been set
40+
// via InstanceMetadata.
3941
instanceID, err := InstanceIDFromProviderID(node.Spec.ProviderID)
4042
if err != nil {
4143
return false, fmt.Errorf("failed retrieving instance id from provider id: %w", err)
@@ -44,7 +46,8 @@ func (i *InstancesV2) InstanceExists(ctx context.Context, node *v1.Node) (bool,
4446
if _, err := i.client.InstanceView(ctx, oxide.InstanceViewParams{
4547
Instance: oxide.NameOrId(instanceID),
4648
}); err != nil {
47-
if strings.Contains(err.Error(), "NotFound") {
49+
var httpErr *oxide.HTTPError
50+
if errors.As(err, &httpErr) && httpErr.ErrorResponse.ErrorCode == "ObjectNotFound" {
4851
return false, nil
4952
}
5053

@@ -63,32 +66,23 @@ func (i *InstancesV2) InstanceMetadata(
6366
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
6467
defer cancel()
6568

66-
// Get the instance ID, either from the provider ID or by looking up by name.
67-
instanceID, err := i.getInstanceID(ctx, node)
69+
instance, err := i.getInstance(ctx, node)
6870
if err != nil {
69-
return nil, err
70-
}
71-
72-
// Retrieve the instance details.
73-
instance, err := i.client.InstanceView(ctx, oxide.InstanceViewParams{
74-
Instance: oxide.NameOrId(instanceID),
75-
})
76-
if err != nil {
77-
return nil, fmt.Errorf("failed viewing oxide instance: %v", err)
71+
return nil, fmt.Errorf("failed retrieving instance: %w", err)
7872
}
7973

8074
nics, err := i.client.InstanceNetworkInterfaceList(
8175
ctx,
8276
oxide.InstanceNetworkInterfaceListParams{
83-
Instance: oxide.NameOrId(instanceID),
77+
Instance: oxide.NameOrId(instance.Id),
8478
},
8579
)
8680
if err != nil {
8781
return nil, fmt.Errorf("failed listing instance network interfaces: %v", err)
8882
}
8983

9084
externalIPs, err := i.client.InstanceExternalIpList(ctx, oxide.InstanceExternalIpListParams{
91-
Instance: oxide.NameOrId(instanceID),
85+
Instance: oxide.NameOrId(instance.Id),
9286
})
9387
if err != nil {
9488
return nil, fmt.Errorf("failed listing instance external ips: %v", err)
@@ -148,36 +142,43 @@ func (i *InstancesV2) InstanceMetadata(
148142
}
149143

150144
return &cloudprovider.InstanceMetadata{
151-
ProviderID: NewProviderID(instanceID),
145+
ProviderID: NewProviderID(instance.Id),
152146
InstanceType: fmt.Sprintf("%d-%d", instance.Ncpus, instance.Memory/gibibyte),
153147
NodeAddresses: nodeAddresses,
154148
}, nil
155149
}
156150

157-
// getInstanceID retrieves the instance ID either from the node's provider ID
151+
// getInstance retrieves the instance, either from the node's provider ID
158152
// or by looking up the instance by name.
159-
func (i *InstancesV2) getInstanceID(ctx context.Context, node *v1.Node) (string, error) {
153+
func (i *InstancesV2) getInstance(ctx context.Context, node *v1.Node) (*oxide.Instance, error) {
154+
var params oxide.InstanceViewParams
155+
160156
if node.Spec.ProviderID != "" {
161-
return InstanceIDFromProviderID(node.Spec.ProviderID)
157+
instanceID, err := InstanceIDFromProviderID(node.Spec.ProviderID)
158+
if err != nil {
159+
return nil, fmt.Errorf("failed parsing provider id: %w", err)
160+
}
161+
params.Instance = oxide.NameOrId(instanceID)
162+
} else {
163+
params.Project = oxide.NameOrId(i.project)
164+
params.Instance = oxide.NameOrId(node.GetName())
162165
}
163166

164-
// If no provider ID is set, look up the instance by name.
165-
instance, err := i.client.InstanceView(ctx, oxide.InstanceViewParams{
166-
Project: oxide.NameOrId(i.project),
167-
Instance: oxide.NameOrId(node.GetName()),
168-
})
167+
instance, err := i.client.InstanceView(ctx, params)
169168
if err != nil {
170-
return "", fmt.Errorf("failed viewing oxide instance by name: %v", err)
169+
return nil, fmt.Errorf("failed looking up oxide instance: %w", err)
171170
}
172171

173-
return instance.Id, nil
172+
return instance, nil
174173
}
175174

176175
// InstanceShutdown checks whether the provided node is shut down in Oxide.
177176
func (i *InstancesV2) InstanceShutdown(ctx context.Context, node *v1.Node) (bool, error) {
178177
ctx, cancel := context.WithTimeout(ctx, 30*time.Second)
179178
defer cancel()
180179

180+
// Look up instance by the node's providerID. By this point, the providerID will have been set
181+
// via InstanceMetadata.
181182
instanceID, err := InstanceIDFromProviderID(node.Spec.ProviderID)
182183
if err != nil {
183184
return false, fmt.Errorf("failed retrieving instance id from provider id: %w", err)

0 commit comments

Comments
 (0)