Skip to content

Commit

Permalink
mock access policy
Browse files Browse the repository at this point in the history
  • Loading branch information
gemmahou committed Mar 27, 2024
1 parent 0962188 commit 0d1724a
Show file tree
Hide file tree
Showing 7 changed files with 147 additions and 13 deletions.
2 changes: 1 addition & 1 deletion config/tests/samples/create/harness.go
Original file line number Diff line number Diff line change
Expand Up @@ -437,9 +437,9 @@ func MaybeSkip(t *testing.T, name string, resources []*unstructured.Unstructured
}

switch gvk.GroupKind() {
case schema.GroupKind{Group: "accesscontextmanager.cnrm.cloud.google.com", Kind: "AccessContextManagerAccessPolicy"}:
case schema.GroupKind{Group: "accesscontextmanager.cnrm.cloud.google.com", Kind: "AccessContextManagerAccessLevel"}:
case schema.GroupKind{Group: "accesscontextmanager.cnrm.cloud.google.com", Kind: "AccessContextManagerServicePerimeter"}:
//case schema.GroupKind{Group: "accesscontextmanager.cnrm.cloud.google.com", Kind: "AccessContextManagerServicePerimeterResource"}:

case schema.GroupKind{Group: "apikeys.cnrm.cloud.google.com", Kind: "APIKeysKey"}:

Expand Down
1 change: 1 addition & 0 deletions mockgcp/mockaccesscontextmanager/accesslevel.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mockaccesscontextmanager

import (
Expand Down
113 changes: 113 additions & 0 deletions mockgcp/mockaccesscontextmanager/accesspolicy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
// Copyright 2024 Google LLC
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mockaccesscontextmanager

import (
"context"
"crypto/md5"
"fmt"
"time"

pb "github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp/generated/mockgcp/identity/accesscontextmanager/v1"
"google.golang.org/genproto/googleapis/longrunning"
"google.golang.org/protobuf/proto"
"k8s.io/klog/v2"
)

func (s *AccessContextManagerV1) GetAccessPolicy(ctx context.Context, req *pb.GetAccessPolicyRequest) (*pb.AccessPolicy, error) {
name, err := s.parseAccessPolicyName(req.Name)
if err != nil {
return nil, err
}

fqn := name.String()

obj := &pb.AccessPolicy{}
if err := s.storage.Get(ctx, fqn, obj); err != nil {
return nil, err
}

return obj, nil
}

func (s *AccessContextManagerV1) CreateAccessPolicy(ctx context.Context, req *pb.AccessPolicy) (*longrunning.Operation, error) {
accessPolicy := req.Name
if accessPolicy == "" {
accessPolicy = fmt.Sprintf("%d", time.Now().UnixNano())
}
reqName := "accessPolicies/" + accessPolicy
name, err := s.parseAccessPolicyName(reqName)
if err != nil {
return nil, err
}

fqn := name.String()

obj := proto.Clone(req).(*pb.AccessPolicy)
obj.Name = fqn

if err := s.storage.Create(ctx, fqn, obj); err != nil {
return nil, err
}

return s.operations.NewLRO(ctx)
}

func (s *AccessContextManagerV1) UpdateAccessPolicy(ctx context.Context, req *pb.UpdateAccessPolicyRequest) (*longrunning.Operation, error) {
reqName := req.GetPolicy().GetName()

name, err := s.parseAccessPolicyName(reqName)
if err != nil {
return nil, err
}

fqn := name.String()
obj := &pb.AccessPolicy{}
if err := s.storage.Get(ctx, fqn, obj); err != nil {
return nil, err
}

if err := s.storage.Update(ctx, fqn, obj); err != nil {
return nil, err
}

return s.operations.NewLRO(ctx)
}

func (s *AccessContextManagerV1) DeleteAccessPolicy(ctx context.Context, req *pb.DeleteAccessPolicyRequest) (*longrunning.Operation, error) {
name, err := s.parseAccessPolicyName(req.Name)
if err != nil {
return nil, err
}

fqn := name.String()

oldObj := &pb.AccessPolicy{}
if err := s.storage.Delete(ctx, fqn, oldObj); err != nil {
return nil, err
}

return s.operations.NewLRO(ctx)
}

func computeEtag(obj proto.Message) []byte {
// TODO: Do we risk exposing internal fields? Doesn't matter on a mock, I guess
b, err := proto.Marshal(obj)
if err != nil {
klog.Fatalf("failed to marshal proto object: %v", err)
}
hash := md5.Sum(b)
return hash[:]
}
30 changes: 25 additions & 5 deletions mockgcp/mockaccesscontextmanager/names.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,23 +17,28 @@ package mockaccesscontextmanager
import (
"strings"

"github.com/GoogleCloudPlatform/k8s-config-connector/mockgcp/common/projects"

"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)

type accessPolicyName struct {
AccessPolicyName string
}

type accessLevelName struct {
AccessPolicyName string
AccessLevelName string
}

type servicePerimeterName struct {
Project *projects.ProjectData
AccessPolicyName string
ServicePerimeterName string
}

func (n *accessPolicyName) String() string {
return "accessPolicies/" + n.AccessPolicyName
}

func (n *accessLevelName) String() string {
return "accessPolicies/" + n.AccessPolicyName + "/accessLevels/" + n.AccessLevelName
}
Expand All @@ -42,6 +47,21 @@ func (n *servicePerimeterName) String() string {
return "accessPolicies/" + n.AccessPolicyName + "/servicePerimeters/" + n.ServicePerimeterName
}

// parseAccessLevelName parses a string into a accessLevelName.
// The expected form is accessPolicies/<accessPolicyName>/accessLevels/<accessLevelName>
func (s *MockService) parseAccessPolicyName(name string) (*accessPolicyName, error) {
tokens := strings.Split(name, "/")

if len(tokens) == 2 && tokens[0] == "accessPolicies" {
name := &accessPolicyName{
AccessPolicyName: tokens[1],
}
return name, nil
} else {
return nil, status.Errorf(codes.InvalidArgument, "name %q is not valid", name)
}
}

// parseAccessLevelName parses a string into a accessLevelName.
// The expected form is accessPolicies/<accessPolicyName>/accessLevels/<accessLevelName>
func (s *MockService) parseAccessLevelName(name string) (*accessLevelName, error) {
Expand All @@ -58,8 +78,8 @@ func (s *MockService) parseAccessLevelName(name string) (*accessLevelName, error
}
}

// parseAccessLevelName parses a string into a accessLevelName.
// The expected form is accessPolicies/<accessPolicyName>/accessLevels/<accessLevelName>
// parseServicePerimeterName parses a string into a ServicePerimeterName.
// The expected form is accessPolicies/<accessPolicyName>/servicePerimeters/<servicePerimeterName>
func (s *MockService) parseServicePerimeterName(name string) (*servicePerimeterName, error) {
tokens := strings.Split(name, "/")

Expand Down
8 changes: 5 additions & 3 deletions mockgcp/mockaccesscontextmanager/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mockaccesscontextmanager

import (
Expand All @@ -29,6 +30,7 @@ import (

// MockService represents a mocked privateca service.
type MockService struct {
*common.MockEnvironment
kube client.Client
storage storage.Storage

Expand All @@ -40,9 +42,9 @@ type MockService struct {
// New creates a MockService.
func New(env *common.MockEnvironment, storage storage.Storage) *MockService {
s := &MockService{
kube: env.GetKubeClient(),
storage: storage,
operations: operations.NewOperationsService(storage),
MockEnvironment: env,
storage: storage,
operations: operations.NewOperationsService(storage),
}
s.v1 = &AccessContextManagerV1{MockService: s}
return s
Expand Down
3 changes: 2 additions & 1 deletion mockgcp/mockaccesscontextmanager/serviceperimeter.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package mockaccesscontextmanager

import (
Expand Down Expand Up @@ -39,7 +40,7 @@ func (s *AccessContextManagerV1) GetServicePerimeter(ctx context.Context, req *p
}

func (s *AccessContextManagerV1) CreateServicePerimeter(ctx context.Context, req *pb.CreateServicePerimeterRequest) (*longrunning.Operation, error) {
reqName := req.GetServicePerimeter().Name
reqName := req.GetServicePerimeter().GetName()
name, err := s.parseServicePerimeterName(reqName)
if err != nil {
return nil, err
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,4 @@ spec:
#TODO: support recursive reference https://github.com/GoogleCloudPlatform/k8s-config-connector/issues/1309
external: "accessPolicies/578359180191/servicePerimeters/restrict_all_test"
resourceRef:
# Referencing a resource name leads to recursive reference and KCC does not support the feature for now.
# Please use external reference instead.
external: "accessPolicies/578359180191/servicePerimeters/restrict_all_test"
name: project-${uniqueId}

0 comments on commit 0d1724a

Please sign in to comment.