Skip to content

Commit

Permalink
Merge branch 'main' into quotas
Browse files Browse the repository at this point in the history
  • Loading branch information
mariatsji authored Jan 20, 2025
2 parents 924d8c4 + ca33d5a commit 8033e1b
Show file tree
Hide file tree
Showing 6 changed files with 74 additions and 26 deletions.
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
k8s.io/apimachinery v0.32.1
k8s.io/client-go v0.32.1
k8s.io/utils v0.0.0-20241210054802-24370beab758
sigs.k8s.io/controller-runtime v0.19.4
sigs.k8s.io/controller-runtime v0.20.0
sigs.k8s.io/controller-tools v0.17.1
)

Expand All @@ -38,6 +38,7 @@ require (
github.com/gobuffalo/flect v1.0.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.4 // indirect
github.com/google/btree v1.1.3 // indirect
github.com/google/gnostic-models v0.6.9 // indirect
github.com/google/gofuzz v1.2.0 // indirect
github.com/google/uuid v1.6.0 // indirect
Expand All @@ -64,7 +65,6 @@ require (
go.opentelemetry.io/otel/trace v1.33.0 // indirect
go.uber.org/multierr v1.11.0 // indirect
go.uber.org/zap v1.27.0 // indirect
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 // indirect
golang.org/x/mod v0.22.0 // indirect
golang.org/x/net v0.34.0 // indirect
golang.org/x/oauth2 v0.24.0 // indirect
Expand Down
8 changes: 4 additions & 4 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,8 @@ github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek=
github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps=
github.com/google/btree v1.1.3 h1:CVpQJjYgC4VbzxeGVHfvZrv1ctoYCAI8vbl07Fcxlyg=
github.com/google/btree v1.1.3/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4=
github.com/google/gnostic-models v0.6.9 h1:MU/8wDLif2qCXZmzncUQ/BOfxWfthHi63KqpoNbWqVw=
github.com/google/gnostic-models v0.6.9/go.mod h1:CiWsm0s6BSQd1hRn8/QmxqB6BesYcbSZxsz9b0KuDBw=
github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
Expand Down Expand Up @@ -166,8 +168,6 @@ go.uber.org/zap v1.27.0/go.mod h1:GB2qFLM7cTU87MWRP2mPIjqfIDnGu+VIO4V/SdhGo2E=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67 h1:1UoZQm6f0P/ZO0w1Ri+f+ifG/gXhegadRdwBIXEFWDo=
golang.org/x/exp v0.0.0-20241217172543-b2144cdd0a67/go.mod h1:qj5a5QZpwLU2NLQudwIN5koi3beDhSAlJwa67PuM98c=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.22.0 h1:D4nJWe9zXqHOmWqj4VMOJhvzj7bEZg4wEYa759z1pH4=
Expand Down Expand Up @@ -248,8 +248,8 @@ k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7 h1:hcha5B1kVACrLujCKLbr8X
k8s.io/kube-openapi v0.0.0-20241212222426-2c72e554b1e7/go.mod h1:GewRfANuJ70iYzvn+i4lezLDAFzvjxZYK1gn1lWcfas=
k8s.io/utils v0.0.0-20241210054802-24370beab758 h1:sdbE21q2nlQtFh65saZY+rRM6x6aJJI8IUa1AmH/qa0=
k8s.io/utils v0.0.0-20241210054802-24370beab758/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0=
sigs.k8s.io/controller-runtime v0.19.4 h1:SUmheabttt0nx8uJtoII4oIP27BVVvAKFvdvGFwV/Qo=
sigs.k8s.io/controller-runtime v0.19.4/go.mod h1:iRmWllt8IlaLjvTTDLhRBXIEtkCK6hwVBJJsYS9Ajf4=
sigs.k8s.io/controller-runtime v0.20.0 h1:jjkMo29xEXH+02Md9qaVXfEIaMESSpy3TBWPrsfQkQs=
sigs.k8s.io/controller-runtime v0.20.0/go.mod h1:BrP3w158MwvB3ZbNpaAcIKkHQ7YGpYnzpoSTZ8E14WU=
sigs.k8s.io/controller-tools v0.17.1 h1:bQ+dKCS7jY9AgpefenBDtm6geJZCHVKbegpLynxgyus=
sigs.k8s.io/controller-tools v0.17.1/go.mod h1:3QXAdrmdxYuQ4MifvbCAFD9wLXn7jylnfBPYS4yVDdc=
sigs.k8s.io/json v0.0.0-20241014173422-cfa47c3a1cc8 h1:gBQPwqORJ8d8/YNZWEjoZs7npUVDpVXUUOFfW6CgAqE=
Expand Down
6 changes: 3 additions & 3 deletions internal/controller/group/group.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,10 +154,10 @@ func (c *external) Observe(ctx context.Context, mg resource.Managed) (managed.Ex
}

observedGroup, err := c.cloudianService.GetGroup(ctx, externalName)
if errors.Is(err, cloudian.ErrNotFound) {
return managed.ExternalObservation{ResourceExists: false}, nil
}
if err != nil {
if errors.Is(err, cloudian.ErrNotFound) {
return managed.ExternalObservation{ResourceExists: false}, nil
}
return managed.ExternalObservation{}, errors.Wrap(err, errGetGroup)
}

Expand Down
27 changes: 11 additions & 16 deletions internal/controller/user/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"

xpv1 "github.com/crossplane/crossplane-runtime/apis/common/v1"
"github.com/crossplane/crossplane-runtime/pkg/connection"
"github.com/crossplane/crossplane-runtime/pkg/controller"
"github.com/crossplane/crossplane-runtime/pkg/event"
Expand All @@ -48,7 +49,6 @@ const (
errNewClient = "cannot create new Service"
errCreateUser = "cannot create User"
errDeleteUser = "cannot delete User"
errListUsers = "cannot list Users"
errGetUser = "cannot get User"
)

Expand Down Expand Up @@ -157,40 +157,35 @@ func (c *external) Observe(ctx context.Context, mg resource.Managed) (managed.Ex
return managed.ExternalObservation{}, nil
}

// TODO: GET User instead of listing users for group
users, err := c.cloudianService.ListUsers(ctx, group, nil)
_, err := c.cloudianService.GetUser(ctx, cloudian.User{
GroupID: group,
UserID: externalName})
if errors.Is(err, cloudian.ErrNotFound) {
return managed.ExternalObservation{ResourceExists: false}, nil
}
if err != nil {
return managed.ExternalObservation{}, errors.Wrap(err, errListUsers)
return managed.ExternalObservation{}, errors.Wrap(err, errGetUser)
}

upToDate := isUpToDate(meta.GetExternalName(mg), users)
cr.SetConditions(xpv1.Available())

return managed.ExternalObservation{
// Return false when the external resource does not exist. This lets
// the managed resource reconciler know that it needs to call Create to
// (re)create the resource, or that it has successfully been deleted.
ResourceExists: upToDate,
ResourceExists: true,

// Return false when the external resource exists, but it not up to date
// with the desired managed resource state. This lets the managed
// resource reconciler know that it needs to call Update.
ResourceUpToDate: upToDate,
ResourceUpToDate: true,

// Return any details that may be required to connect to the external
// resource. These will be stored as the connection secret.
ConnectionDetails: managed.ConnectionDetails{},
}, nil
}

func isUpToDate(userId string, users []cloudian.User) bool {
for _, user := range users {
if user.UserID == userId {
return true
}
}
return false
}

func (c *external) Create(ctx context.Context, mg resource.Managed) (managed.ExternalCreation, error) {
cr, ok := mg.(*v1alpha1.User)
if !ok {
Expand Down
27 changes: 26 additions & 1 deletion internal/sdk/cloudian/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -230,6 +230,31 @@ func (client Client) CreateUser(ctx context.Context, user User) error {
}
}

// GetUser gets a user. Returns an error even in the case of a user not found.
// This error can then be checked against ErrNotFound: errors.Is(err, ErrNotFound)
func (client Client) GetUser(ctx context.Context, user User) (*User, error) {
// FIXME: Introduce UserId struct and enrich User
resp, err := client.newRequest(ctx).
SetQueryParams(map[string]string{
"groupId": user.GroupID,
"userId": user.UserID,
}).
Get("/user")
if err != nil {
return nil, err
}

switch resp.StatusCode() {
case 200:
return &user, nil
case 204:
// Cloudian-API returns 204 if the user does not exist
return nil, ErrNotFound
default:
return nil, fmt.Errorf("error: GET user unexpected status code: %d", resp.StatusCode())
}
}

// CreateUserCredentials creates a new set of credentials for a user.
func (client Client) CreateUserCredentials(ctx context.Context, user User) (*SecurityInfo, error) {
var securityInfo SecurityInfo
Expand Down Expand Up @@ -400,7 +425,7 @@ func (client Client) GetGroup(ctx context.Context, groupID string) (*Group, erro
// Cloudian-API returns 204 if the group does not exist
return nil, ErrNotFound
default:
return nil, fmt.Errorf("GET unexpected status. Failure: %w", err)
return nil, fmt.Errorf("error: GET group unexpected status code: %d", resp.StatusCode())
}
}

Expand Down
28 changes: 28 additions & 0 deletions internal/sdk/cloudian/sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,3 +191,31 @@ func mockBy(handler http.HandlerFunc) (*Client, *httptest.Server) {
mockServer := httptest.NewServer(handler)
return NewClient(mockServer.URL, ""), mockServer
}

func TestClient_GetUser(t *testing.T) {
tests := []struct {
name string
user User
status int
wantErr error
}{
{name: "Exists", user: User{UserID: strconv.Itoa(http.StatusOK)}},
{name: "Not found", user: User{UserID: strconv.Itoa(http.StatusNoContent)}, wantErr: ErrNotFound},
}

client, testServer := mockBy(func(w http.ResponseWriter, r *http.Request) {
userId := r.URL.Query().Get("userId")
statusCode, _ := strconv.Atoi(userId)
w.WriteHeader(statusCode)
})
defer testServer.Close()

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := client.GetUser(context.Background(), tt.user)
if !errors.Is(err, tt.wantErr) {
t.Errorf("GetUser() error = %v, wantErr %v", err, tt.wantErr)
}
})
}
}

0 comments on commit 8033e1b

Please sign in to comment.