Skip to content

Commit

Permalink
Split organization.go into multiple files
Browse files Browse the repository at this point in the history
  • Loading branch information
glrf committed Jan 12, 2022
1 parent 218eef3 commit 241b261
Show file tree
Hide file tree
Showing 10 changed files with 677 additions and 564 deletions.
111 changes: 0 additions & 111 deletions apiserver/organization/organization.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,11 @@
package organization

import (
"context"
"errors"
"fmt"

orgv1 "github.com/appuio/control-api/apis/organization/v1"

apierrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
genericregistry "k8s.io/apiserver/pkg/registry/generic"
Expand Down Expand Up @@ -55,114 +52,6 @@ func (s *organizationStorage) NamespaceScoped() bool {
return false
}

var _ rest.Getter = &organizationStorage{}

func (s *organizationStorage) Get(ctx context.Context, name string, options *metav1.GetOptions) (runtime.Object, error) {
err := s.authorizer.AuthorizeGet(ctx, name)
if err != nil {
return nil, err
}

org := &orgv1.Organization{}
ns, err := s.namepaces.GetNamespace(ctx, name, options)
if err != nil {
return nil, convertNamespaceError(err)
}
org = orgv1.NewOrganizationFromNS(ns)
if org == nil {
// This namespace is not an organization
return nil, apierrors.NewNotFound(org.GetGroupVersionResource().GroupResource(), name)
}
return org, nil
}

var _ rest.Creater = &organizationStorage{}

func (s *organizationStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
org, ok := obj.(*orgv1.Organization)
if !ok {
return nil, fmt.Errorf("not an organization: %#v", obj)
}
err := s.authorizer.AuthorizeContext(ctx)
if err != nil {
return nil, err
}

// Validate Org
if err := createValidation(ctx, obj); err != nil {
return nil, err
}

if err := s.namepaces.CreateNamespace(ctx, org.ToNamespace(), options); err != nil {
return nil, convertNamespaceError(err)
}
return org, nil
}

var _ rest.Updater = &organizationStorage{}
var _ rest.CreaterUpdater = &organizationStorage{}

func (s *organizationStorage) Update(ctx context.Context, name string, objInfo rest.UpdatedObjectInfo,
createValidation rest.ValidateObjectFunc, updateValidation rest.ValidateObjectUpdateFunc,
forceAllowCreate bool, options *metav1.UpdateOptions) (runtime.Object, bool, error) {

err := s.authorizer.AuthorizeContext(ctx)
if err != nil {
return nil, false, err
}

newOrg := &orgv1.Organization{}

oldOrg, err := s.Get(ctx, name, nil)
if err != nil {

return nil, false, err
}

newObj, err := objInfo.UpdatedObject(ctx, oldOrg)
if err != nil {
return nil, false, err
}

newOrg, ok := newObj.(*orgv1.Organization)
if !ok {
return nil, false, fmt.Errorf("new object is not an organization")
}

if updateValidation != nil {
err = updateValidation(ctx, newOrg, oldOrg)
if err != nil {
return nil, false, err
}
}

return newOrg, false, convertNamespaceError(s.namepaces.UpdateNamespace(ctx, newOrg.ToNamespace(), options))
}

var _ rest.GracefulDeleter = &organizationStorage{}

func (s *organizationStorage) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
err := s.authorizer.AuthorizeContext(ctx)
if err != nil {
return nil, false, err
}

org, err := s.Get(ctx, name, nil)
if err != nil {
return nil, false, err
}

if deleteValidation != nil {
err := deleteValidation(ctx, org)
if err != nil {
return nil, false, err
}
}

ns, err := s.namepaces.DeleteNamespace(ctx, name, options)
return orgv1.NewOrganizationFromNS(ns), false, convertNamespaceError(err)
}

func convertNamespaceError(err error) error {
groupResource := schema.GroupResource{
Group: orgv1.GroupVersion.Group,
Expand Down
35 changes: 35 additions & 0 deletions apiserver/organization/organization_create.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package organization

import (
"context"
"fmt"

orgv1 "github.com/appuio/control-api/apis/organization/v1"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
)

var _ rest.Creater = &organizationStorage{}

func (s *organizationStorage) Create(ctx context.Context, obj runtime.Object, createValidation rest.ValidateObjectFunc, options *metav1.CreateOptions) (runtime.Object, error) {
org, ok := obj.(*orgv1.Organization)
if !ok {
return nil, fmt.Errorf("not an organization: %#v", obj)
}
err := s.authorizer.AuthorizeContext(ctx)
if err != nil {
return nil, err
}

// Validate Org
if err := createValidation(ctx, obj); err != nil {
return nil, err
}

if err := s.namepaces.CreateNamespace(ctx, org.ToNamespace(), options); err != nil {
return nil, convertNamespaceError(err)
}
return org, nil
}
106 changes: 106 additions & 0 deletions apiserver/organization/organization_create_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
package organization

import (
"context"
"errors"
"testing"

"github.com/golang/mock/gomock"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"

orgv1 "github.com/appuio/control-api/apis/organization/v1"

apierrors "k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
"k8s.io/apiserver/pkg/authorization/authorizer"
"k8s.io/apiserver/pkg/endpoints/request"
)

func TestOrganizationStorage_Create(t *testing.T) {
tests := map[string]struct {
organizationIn *orgv1.Organization

namespaceErr error

authDecision authResponse

organizationOut *orgv1.Organization
err error
}{
"GivenCreateOrg_ThenSuccess": {
organizationIn: fooOrg,
authDecision: authResponse{
decision: authorizer.DecisionAllow,
},
organizationOut: fooOrg,
},
"GivenNsExists_ThenFail": {
organizationIn: fooOrg,
authDecision: authResponse{
decision: authorizer.DecisionAllow,
},
namespaceErr: apierrors.NewAlreadyExists(schema.GroupResource{
Resource: "namepaces",
}, "foo"),
err: apierrors.NewAlreadyExists(schema.GroupResource{
Group: orgv1.GroupVersion.Group,
Resource: "organizations",
}, "foo"),
},
"GivenAuthFails_ThenFail": {
organizationIn: fooOrg,
authDecision: authResponse{
err: errors.New("failed"),
},
err: errors.New("failed"),
},
"GivenForbidden_ThenForbidden": {
organizationIn: fooOrg,
authDecision: authResponse{
decision: authorizer.DecisionDeny,
reason: "confidential",
},
err: apierrors.NewForbidden(schema.GroupResource{
Group: orgv1.GroupVersion.Group,
Resource: "organizations",
}, fooOrg.Name, errors.New("confidential")),
},
}

for n, tc := range tests {
t.Run(n, func(t *testing.T) {
ctrl := gomock.NewController(t)
defer ctrl.Finish()
os, mnp, mauth := newMockedOrganizationStorage(ctrl)
mauth.EXPECT().
Authorize(gomock.Any(), isAuthRequest("create")).
Return(tc.authDecision.decision, tc.authDecision.reason, tc.authDecision.err).
Times(1)
mnp.EXPECT().
CreateNamespace(gomock.Any(), gomock.Any(), gomock.Any()).
Return(tc.namespaceErr).
AnyTimes()

nopValidate := func(ctx context.Context, obj runtime.Object) error {
return nil
}
org, err := os.Create(request.WithRequestInfo(request.NewContext(),
&request.RequestInfo{
Verb: "create",
APIGroup: orgv1.GroupVersion.Group,
Resource: "organizations",
Name: tc.organizationIn.Name,
}),
tc.organizationIn, nopValidate, nil)

if tc.err != nil {
assert.EqualError(t, err, tc.err.Error())
return
}
require.NoError(t, err)
assert.Equal(t, tc.organizationOut, org)
})
}
}
35 changes: 35 additions & 0 deletions apiserver/organization/organization_delete.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package organization

import (
"context"

orgv1 "github.com/appuio/control-api/apis/organization/v1"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apiserver/pkg/registry/rest"
)

var _ rest.GracefulDeleter = &organizationStorage{}

func (s *organizationStorage) Delete(ctx context.Context, name string, deleteValidation rest.ValidateObjectFunc, options *metav1.DeleteOptions) (runtime.Object, bool, error) {
err := s.authorizer.AuthorizeContext(ctx)
if err != nil {
return nil, false, err
}

org, err := s.Get(ctx, name, nil)
if err != nil {
return nil, false, err
}

if deleteValidation != nil {
err := deleteValidation(ctx, org)
if err != nil {
return nil, false, err
}
}

ns, err := s.namepaces.DeleteNamespace(ctx, name, options)
return orgv1.NewOrganizationFromNS(ns), false, convertNamespaceError(err)
}
Loading

0 comments on commit 241b261

Please sign in to comment.