diff --git a/pkg/provider/core.go b/pkg/provider/core.go index d1b70bf6..55218407 100644 --- a/pkg/provider/core.go +++ b/pkg/provider/core.go @@ -173,7 +173,7 @@ func (p *Provider) CreateMachine(ctx context.Context, req *driver.CreateMachineR server, err := p.client.CreateServer(ctx, projectID, providerSpec.Region, createReq) if err != nil { klog.Errorf("Failed to create server for machine %q: %v", req.Machine.Name, err) - return nil, status.Error(codes.Internal, fmt.Sprintf("failed to create server: %v", err)) + return nil, status.Error(codes.Internal, fmt.Sprintf("failed to create server: secgroups: %v err: %v", createReq.SecurityGroups, err)) } // Generate ProviderID in format: stackit:/// @@ -205,7 +205,16 @@ func (p *Provider) DeleteMachine(ctx context.Context, req *driver.DeleteMachineR // Validate ProviderID exists if req.Machine.Spec.ProviderID == "" { - return nil, status.Error(codes.InvalidArgument, "ProviderID is required") + // the server is already deleted, return success so the CRD can be cleaned up + // TODO: verify this + return nil, nil + // return nil, status.Error(codes.InvalidArgument, "ProviderID is required") + } + + // Decode ProviderSpec from MachineClass + providerSpec, err := decodeProviderSpec(req.MachineClass) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) } // Extract credentials from Secret @@ -225,11 +234,6 @@ func (p *Provider) DeleteMachine(ctx context.Context, req *driver.DeleteMachineR return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid ProviderID format: %v", err)) } - providerSpec, err := decodeProviderSpec(req.MachineClass) - if err != nil { - return nil, status.Error(codes.Internal, err.Error()) - } - // Call STACKIT API to delete server err = p.client.DeleteServer(ctx, projectID, providerSpec.Region, serverID) if err != nil { @@ -274,6 +278,12 @@ func (p *Provider) GetMachineStatus(ctx context.Context, req *driver.GetMachineS return nil, status.Error(codes.NotFound, "machine does not have a ProviderID yet") } + // Decode ProviderSpec from MachineClass + providerSpec, err := decodeProviderSpec(req.MachineClass) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + // Extract credentials from Secret serviceAccountKey := string(req.Secret.Data["serviceaccount.json"]) @@ -292,12 +302,6 @@ func (p *Provider) GetMachineStatus(ctx context.Context, req *driver.GetMachineS return nil, status.Error(codes.InvalidArgument, fmt.Sprintf("invalid ProviderID format: %v", err)) } - // Decode ProviderSpec from MachineClass - providerSpec, err := decodeProviderSpec(req.MachineClass) - if err != nil { - return nil, status.Error(codes.Internal, err.Error()) - } - // Call STACKIT API to get server status server, err := p.client.GetServer(ctx, projectID, providerSpec.Region, serverID) if err != nil { @@ -335,6 +339,12 @@ func (p *Provider) ListMachines(ctx context.Context, req *driver.ListMachinesReq klog.V(2).Infof("List machines request has been received for %q", req.MachineClass.Name) defer klog.V(2).Infof("List machines request has been processed for %q", req.MachineClass.Name) + // Decode ProviderSpec from MachineClass + providerSpec, err := decodeProviderSpec(req.MachineClass) + if err != nil { + return nil, status.Error(codes.Internal, err.Error()) + } + // Extract credentials from Secret projectID := string(req.Secret.Data["project-id"]) serviceAccountKey := string(req.Secret.Data["serviceaccount.json"]) @@ -344,12 +354,6 @@ func (p *Provider) ListMachines(ctx context.Context, req *driver.ListMachinesReq return nil, status.Error(codes.Internal, fmt.Sprintf("failed to initialize STACKIT client: %v", err)) } - // Decode ProviderSpec from MachineClass - providerSpec, err := decodeProviderSpec(req.MachineClass) - if err != nil { - return nil, status.Error(codes.Internal, err.Error()) - } - // Call STACKIT API to list all servers servers, err := p.client.ListServers(ctx, projectID, providerSpec.Region) if err != nil { diff --git a/pkg/provider/helpers.go b/pkg/provider/helpers.go index da6eb7a2..f7d91fbf 100644 --- a/pkg/provider/helpers.go +++ b/pkg/provider/helpers.go @@ -37,14 +37,18 @@ func encodeProviderSpecForResponse(spec *api.ProviderSpec) ([]byte, error) { func parseProviderID(providerID string) (projectID, serverID string, err error) { const prefix = "stackit://" - if !strings.HasPrefix(providerID, prefix) { - return "", "", fmt.Errorf("ProviderID must start with 'stackit://'") - } + // if !strings.HasPrefix(providerID, prefix) { + // return "", "", fmt.Errorf("ProviderID must start with 'stackit://'") + // } // Remove prefix and split by '/' remainder := strings.TrimPrefix(providerID, prefix) parts := strings.Split(remainder, "/") + if len(parts) == 3 { + return "", parts[3], nil + } + if len(parts) != 2 { return "", "", fmt.Errorf("ProviderID must have format 'stackit:///'") } diff --git a/pkg/provider/sdk_client.go b/pkg/provider/sdk_client.go index 167cb05c..9bdca334 100644 --- a/pkg/provider/sdk_client.go +++ b/pkg/provider/sdk_client.go @@ -50,7 +50,11 @@ var ( // - More secure than static tokens (short-lived, rotating) func createIAASClient(serviceAccountKey string) (*iaas.APIClient, error) { // Configure SDK with custom base URL if provided (for testing with mock server) - baseURL := os.Getenv("STACKIT_API_ENDPOINT") + // baseURL := os.Getenv("STACKIT_API_ENDPOINT") + // TODO: this should be configureable via ske-stages or ske-base + // TODO: the STACKIT_TOKEN_BASEURL env + baseURL := "https://iaas.api.eu01.qa.stackit.cloud" + tokenEndpoint := "https://service-account.api.qa.stackit.cloud/token" noAuth := os.Getenv("STACKIT_NO_AUTH") == "true" var opts []config.ConfigurationOption @@ -72,6 +76,10 @@ func createIAASClient(serviceAccountKey string) (*iaas.APIClient, error) { opts = append(opts, config.WithEndpoint(baseURL)) } + if tokenEndpoint != "" { + opts = append(opts, config.WithTokenEndpoint(tokenEndpoint)) + } + iaasClient, err := iaas.NewAPIClient(opts...) if err != nil { return nil, fmt.Errorf("failed to create STACKIT SDK API client: %w", err)