Skip to content

Commit

Permalink
feat: added Validate func responsible for validating references of lo…
Browse files Browse the repository at this point in the history
…aded AM resources

Signed-off-by: Bernd Warmuth <[email protected]>
  • Loading branch information
warber committed Oct 13, 2023
1 parent 96be314 commit d325641
Show file tree
Hide file tree
Showing 9 changed files with 281 additions and 18 deletions.
23 changes: 23 additions & 0 deletions pkg/persistence/account/errors.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* @license
* Copyright 2023 Dynatrace 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 account

import "errors"

var ErrRefMissing = errors.New("no referenced target found")
var ErrIdFieldMissing = errors.New("no ref id field found")
var ErrIdFieldNoString = errors.New("ref id field is not a string")
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
users:
- email: [email protected]
groups:
- type: reference
- Log viewer
17 changes: 17 additions & 0 deletions pkg/persistence/account/test-resources/no-ref-group.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
users:
- email: [email protected]
groups:
- type: reference
id: non-existing-group-ref
- Default Group

# GROUPS
groups:
- name: Another Group
id: another-group
description: This is a group
account:
permissions:
- Default permissions
policies:
- Default policies
14 changes: 14 additions & 0 deletions pkg/persistence/account/test-resources/no-ref-policy-account.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
users:
- email: [email protected]
groups:
- type: reference
id: my-group
# GROUPS
groups:
- name: My Group
id: my-group
description: This is my group
account:
policies:
- type: reference
id: non-existing-policy-ref
18 changes: 18 additions & 0 deletions pkg/persistence/account/test-resources/no-ref-policy-env.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
users:
- email: [email protected]
groups:
- type: reference
id: my-group
# GROUPS
groups:
- name: My Group
id: my-group
description: This is my group
account:
environment:
- name: myenv
permissions:
- View environment
policies:
- type: reference
id: non-existing-policy-ref
42 changes: 42 additions & 0 deletions pkg/persistence/account/test-resources/valid.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
users:
- email: [email protected]
groups:
- type: reference
id: my-group
- Log viewer


groups:
- name: My Group
id: my-group
description: This is my group
account:
permissions:
- View my Group Stuff
policies:
- Request My Group Stuff

environment:
- name: myenv123
permissions:
- View environment
policies:
- View environment
- type: reference
id: my-policy

managementZone:
- environment: env12345
managementZone: Mzone
permissions:
- View environment

policies:
- name: My Policy
id: my-policy
level:
type: account
description: abcde
policy: |-
ALLOW a:b:c;
18 changes: 0 additions & 18 deletions pkg/persistence/account/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,3 @@ type (
Groups []any `mapstructure:"groups"`
}
)

func (a *AMResources) GroupExists(id string) bool {
for _, g := range a.Groups {
if g.ID == id {
return true
}
}
return false
}

func (a *AMResources) PolicyExists(id string) bool {
for _, p := range a.Policies {
if p.ID == id {
return true
}
}
return false
}
86 changes: 86 additions & 0 deletions pkg/persistence/account/validate.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
/*
* @license
* Copyright 2023 Dynatrace 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 account

import "fmt"

// Validate checks the references in the provided AMResources instance to ensure
// that all referenced groups and policies exist. It iterates through the users,
// environment policies, and account policies, validating their references.
func Validate(res *AMResources) error {
for _, user := range res.Users {
for _, groupRef := range user.Groups {
if err := refCheck(groupRef, res.GroupExists); err != nil {
return err
}
}
}

for _, group := range res.Groups {
// check references in environment policies
for _, env := range group.Environment {
for _, policyRef := range env.Policies {
if err := refCheck(policyRef, res.PolicyExists); err != nil {
return err
}
}
}
// check references in account policies
for _, policyRef := range group.Account.Policies {
if err := refCheck(policyRef, res.PolicyExists); err != nil {
return err
}
}
}
return nil
}

func refCheck(elem any, refCheckFn func(string) bool) error {
if reference, isCustomRef := elem.(anyMap); isCustomRef {
idField, hasIdField := reference["id"]
if !hasIdField {
return fmt.Errorf("error validating account resources: %w", ErrIdFieldMissing)
}
idFieldStr, isIdFieldStr := idField.(string)
if !isIdFieldStr {
return fmt.Errorf("error validating account resources: %w", ErrIdFieldNoString)
}
policyRefExists := refCheckFn(idFieldStr)
if !policyRefExists {
return fmt.Errorf("error validating account resources with id %q: %w", idFieldStr, ErrRefMissing)
}
}
return nil
}

func (a *AMResources) GroupExists(id string) bool {
for _, g := range a.Groups {
if g.ID == id {
return true
}
}
return false
}

func (a *AMResources) PolicyExists(id string) bool {
for _, p := range a.Policies {
if p.ID == id {
return true
}
}
return false
}
76 changes: 76 additions & 0 deletions pkg/persistence/account/validate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
/*
* @license
* Copyright 2023 Dynatrace 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 account

import (
"github.com/spf13/afero"
"github.com/stretchr/testify/assert"
"testing"
)

func TestValidateT(t *testing.T) {
testCases := []struct {
name string
path string
expected error
expectedErrMsg string
}{
{

name: "group reference not found",
path: "test-resources/no-ref-group.yaml",
expected: ErrRefMissing,
expectedErrMsg: `error validating account resources with id "non-existing-group-ref": no referenced target found`,
},
{
name: "environment level policy reference not found",
path: "test-resources/no-ref-policy-env.yaml",
expected: ErrRefMissing,
expectedErrMsg: `error validating account resources with id "non-existing-policy-ref": no referenced target found`,
},
{
name: "account level policy reference not found",
path: "test-resources/no-ref-policy-account.yaml",
expected: ErrRefMissing,
expectedErrMsg: `error validating account resources with id "non-existing-policy-ref": no referenced target found`,
},
{
name: "group reference with missing id field",
path: "test-resources/no-id-field-group-ref.yaml",
expected: ErrIdFieldMissing,
expectedErrMsg: `error validating account resources: no ref id field found`,
},
{
name: "valid",
path: "test-resources/valid.yaml",
expected: nil,
},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
resources, _ := Load(afero.NewOsFs(), tc.path)
err := Validate(resources)
if tc.expected != nil {
assert.ErrorIs(t, err, tc.expected)
assert.ErrorContains(t, err, tc.expectedErrMsg)
} else {
assert.NoError(t, err)
}
})
}
}

0 comments on commit d325641

Please sign in to comment.