Skip to content

Commit e54ec1e

Browse files
authored
Some Cleanups (#43)
We're passing around two types when handling identities and it gets a bit messy with multiple copies, which leads to bugs due to missed fields and the like. Also steath in the server groups provisioning which has been missing for some time.
1 parent efe2a38 commit e54ec1e

File tree

12 files changed

+226
-228
lines changed

12 files changed

+226
-228
lines changed

charts/region/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ description: A Helm chart for deploying Unikorn's Region Controller
44

55
type: application
66

7-
version: v0.1.28
8-
appVersion: v0.1.28
7+
version: v0.1.29
8+
appVersion: v0.1.29
99

1010
icon: https://raw.githubusercontent.com/unikorn-cloud/assets/main/images/logos/dark-on-light/icon.png
1111

charts/region/crds/region.unikorn-cloud.org_identities.yaml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,27 @@ spec:
6161
description: OpenStack is populated when the provider type is set
6262
to "openstack".
6363
properties:
64+
cloud:
65+
description: Cloud is the cloud name in the cloud config to use.
66+
type: string
67+
cloudConfig:
68+
description: CloudConfig is a client compatible cloud configuration.
69+
format: byte
70+
type: string
6471
projectID:
6572
description: ProjectID is the ID of the project created for the
6673
identity.
6774
type: string
75+
serverGroupID:
76+
description: ServerGroupID is the ID of the server group created
77+
for the identity.
78+
type: string
6879
userID:
6980
description: UserID is the ID of the user created for the identity.
7081
type: string
7182
required:
83+
- cloud
84+
- cloudConfig
7285
- projectID
7386
- userID
7487
type: object

pkg/apis/unikorn/v1alpha1/types.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,16 @@ type IdentitySpec struct {
301301
}
302302

303303
type IdentitySpecOpenStack struct {
304+
// CloudConfig is a client compatible cloud configuration.
305+
CloudConfig []byte `json:"cloudConfig"`
306+
// Cloud is the cloud name in the cloud config to use.
307+
Cloud string `json:"cloud"`
304308
// UserID is the ID of the user created for the identity.
305309
UserID string `json:"userID"`
306310
// ProjectID is the ID of the project created for the identity.
307311
ProjectID string `json:"projectID"`
312+
// ServerGroupID is the ID of the server group created for the identity.
313+
ServerGroupID *string `json:"serverGroupID,omitempty"`
308314
}
309315

310316
type IdentityStatus struct {

pkg/apis/unikorn/v1alpha1/zz_generated.deepcopy.go

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pkg/handler/handler.go

Lines changed: 45 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ package handler
2020

2121
import (
2222
"cmp"
23+
"context"
2324
"encoding/base64"
2425
"fmt"
2526
"net/http"
@@ -42,7 +43,6 @@ import (
4243
"github.com/unikorn-cloud/region/pkg/server/util"
4344

4445
kerrors "k8s.io/apimachinery/pkg/api/errors"
45-
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
4646
"k8s.io/apimachinery/pkg/labels"
4747

4848
"sigs.k8s.io/controller-runtime/pkg/client"
@@ -82,6 +82,20 @@ func (h *Handler) setUncacheable(w http.ResponseWriter) {
8282
w.Header().Add("Cache-Control", "no-cache")
8383
}
8484

85+
func (h *Handler) getIdentity(ctx context.Context, id string) (*unikornv1.Identity, error) {
86+
identity := &unikornv1.Identity{}
87+
88+
if err := h.client.Get(ctx, client.ObjectKey{Namespace: h.namespace, Name: id}, identity); err != nil {
89+
if kerrors.IsNotFound(err) {
90+
return nil, errors.HTTPNotFound().WithError(err)
91+
}
92+
93+
return nil, errors.OAuth2ServerError("unable to lookup identity").WithError(err)
94+
}
95+
96+
return identity, nil
97+
}
98+
8599
func (h *Handler) GetApiV1OrganizationsOrganizationIDRegions(w http.ResponseWriter, r *http.Request, organizationID openapi.OrganizationIDParameter) {
86100
if err := rbac.AllowOrganizationScope(r.Context(), "regions", identityapi.Read, organizationID); err != nil {
87101
errors.HandleError(w, r, err)
@@ -283,32 +297,33 @@ func convertTags(in unikornv1.TagList) openapi.TagList {
283297
return out
284298
}
285299

286-
func convertIdentity(identity *unikornv1.Identity, in *providers.CloudConfig) *openapi.IdentityRead {
300+
func convertIdentity(in *unikornv1.Identity) *openapi.IdentityRead {
287301
out := &openapi.IdentityRead{
288-
Metadata: conversion.ProjectScopedResourceReadMetadata(identity, coreapi.ResourceProvisioningStatusProvisioned),
302+
Metadata: conversion.ProjectScopedResourceReadMetadata(in, coreapi.ResourceProvisioningStatusProvisioned),
289303
Spec: openapi.IdentitySpec{
290-
RegionId: identity.Labels[constants.RegionLabel],
304+
RegionId: in.Labels[constants.RegionLabel],
291305
},
292306
}
293307

294-
if tags := convertTags(identity.Spec.Tags); tags != nil {
308+
if tags := convertTags(in.Spec.Tags); tags != nil {
295309
out.Spec.Tags = &tags
296310
}
297311

298-
switch identity.Spec.Provider {
312+
switch in.Spec.Provider {
299313
case unikornv1.ProviderOpenstack:
300314
out.Spec.Type = openapi.Openstack
301315

316+
cloudConfig := base64.URLEncoding.EncodeToString(in.Spec.OpenStack.CloudConfig)
317+
302318
out.Spec.Openstack = &openapi.IdentitySpecOpenStack{
303-
UserId: identity.Spec.OpenStack.UserID,
304-
ProjectId: identity.Spec.OpenStack.ProjectID,
319+
CloudConfig: cloudConfig,
320+
Cloud: in.Spec.OpenStack.Cloud,
321+
UserId: in.Spec.OpenStack.UserID,
322+
ProjectId: in.Spec.OpenStack.ProjectID,
305323
}
306324

307-
if in != nil {
308-
cloudConfig := base64.URLEncoding.EncodeToString(in.OpenStack.Credentials.CloudConfig)
309-
310-
out.Spec.Openstack.Cloud = &in.OpenStack.Credentials.Cloud
311-
out.Spec.Openstack.CloudConfig = &cloudConfig
325+
if in.Spec.OpenStack.ServerGroupID != nil {
326+
out.Spec.Openstack.ServerGroupId = in.Spec.OpenStack.ServerGroupID
312327
}
313328
}
314329

@@ -319,7 +334,7 @@ func convertIdentityList(in unikornv1.IdentityList) openapi.IdentitiesRead {
319334
out := make(openapi.IdentitiesRead, len(in.Items))
320335

321336
for i := range in.Items {
322-
out[i] = *convertIdentity(&in.Items[i], nil)
337+
out[i] = *convertIdentity(&in.Items[i])
323338
}
324339

325340
return out
@@ -370,14 +385,14 @@ func (h *Handler) PostApiV1OrganizationsOrganizationIDProjectsProjectIDIdentitie
370385
return
371386
}
372387

373-
identity, cloudconfig, err := provider.CreateIdentity(r.Context(), organizationID, projectID, request)
388+
identity, err := provider.CreateIdentity(r.Context(), organizationID, projectID, request)
374389
if err != nil {
375390
errors.HandleError(w, r, err)
376391
return
377392
}
378393

379394
h.setCacheable(w)
380-
util.WriteJSONResponse(w, r, http.StatusCreated, convertIdentity(identity, cloudconfig))
395+
util.WriteJSONResponse(w, r, http.StatusCreated, convertIdentity(identity))
381396
}
382397

383398
func (h *Handler) DeleteApiV1OrganizationsOrganizationIDProjectsProjectIDIdentitiesIdentityID(w http.ResponseWriter, r *http.Request, organizationID openapi.OrganizationIDParameter, projectID openapi.ProjectIDParameter, identityID openapi.IdentityIDParameter) {
@@ -386,22 +401,24 @@ func (h *Handler) DeleteApiV1OrganizationsOrganizationIDProjectsProjectIDIdentit
386401
return
387402
}
388403

389-
resource := &unikornv1.Identity{
390-
ObjectMeta: metav1.ObjectMeta{
391-
Name: identityID,
392-
Namespace: h.namespace,
393-
},
404+
identity, err := h.getIdentity(r.Context(), identityID)
405+
if err != nil {
406+
errors.HandleError(w, r, err)
407+
return
394408
}
395409

396-
if err := h.client.Delete(r.Context(), resource); err != nil {
397-
if kerrors.IsNotFound(err) {
398-
errors.HandleError(w, r, errors.HTTPNotFound().WithError(err))
399-
return
400-
}
410+
provider, err := region.NewClient(h.client, h.namespace).Provider(r.Context(), identity.Labels[constants.RegionLabel])
411+
if err != nil {
412+
errors.HandleError(w, r, err)
413+
return
414+
}
401415

416+
if err := provider.DeleteIdentity(r.Context(), identity); err != nil {
402417
errors.HandleError(w, r, errors.OAuth2ServerError("failed to delete identity").WithError(err))
403418
return
404419
}
420+
421+
w.WriteHeader(http.StatusAccepted)
405422
}
406423

407424
func convertPhysicalNetwork(in *unikornv1.PhysicalNetwork) *openapi.PhysicalNetworkRead {
@@ -429,14 +446,8 @@ func (h *Handler) PostApiV1OrganizationsOrganizationIDProjectsProjectIDIdentitie
429446
return
430447
}
431448

432-
identity := &unikornv1.Identity{}
433-
434-
if err := h.client.Get(r.Context(), client.ObjectKey{Namespace: h.namespace, Name: identityID}, identity); err != nil {
435-
if kerrors.IsNotFound(err) {
436-
errors.HandleError(w, r, errors.HTTPNotFound().WithError(err))
437-
return
438-
}
439-
449+
identity, err := h.getIdentity(r.Context(), identityID)
450+
if err != nil {
440451
errors.HandleError(w, r, err)
441452
return
442453
}

0 commit comments

Comments
 (0)