Skip to content

Commit

Permalink
refactor: moving consul access and role interface
Browse files Browse the repository at this point in the history
Moving configureConsulAccess and createRole to go-mod-secrets to
consolidate consul API.

Closes: edgexfoundry#3227

Signed-off-by: Rico Chavez-Lopez <rchavezlopez@ucdavis.edu>
  • Loading branch information
ItsRico committed Oct 12, 2022
1 parent a0e04e5 commit cdf811a
Show file tree
Hide file tree
Showing 8 changed files with 104 additions and 280 deletions.
19 changes: 4 additions & 15 deletions internal/security/bootstrapper/command/setupacl/aclbootstrap.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,11 @@ import (
"path/filepath"

"github.com/edgexfoundry/go-mod-secrets/v2/pkg/token/fileioperformer"
"github.com/edgexfoundry/go-mod-secrets/v2/pkg/types"
)

// BootStrapACLTokenInfo is the key portion of the response metadata from consulACLBootstrapAPI
type BootStrapACLTokenInfo struct {
SecretID string `json:"SecretID"`
Policies []Policy `json:"Policies"`
}

// Policy is the metadata for ACL policy
type Policy struct {
ID string `json:"ID"`
Name string `json:"Name"`
}

// generateBootStrapACLToken should only be called once per Consul agent
func (c *cmd) generateBootStrapACLToken() (*BootStrapACLTokenInfo, error) {
func (c *cmd) generateBootStrapACLToken() (*types.BootStrapACLTokenInfo, error) {
aclBootstrapURL, err := c.getRegistryApiUrl(consulACLBootstrapAPI)
if err != nil {
return nil, err
Expand All @@ -64,7 +53,7 @@ func (c *cmd) generateBootStrapACLToken() (*BootStrapACLTokenInfo, error) {
return nil, fmt.Errorf("Failed to read response body of bootstrap ACL: %w", err)
}

var bootstrapACLToken BootStrapACLTokenInfo
var bootstrapACLToken types.BootStrapACLTokenInfo
switch resp.StatusCode {
case http.StatusOK:
if err := json.NewDecoder(bytes.NewReader(responseBody)).Decode(&bootstrapACLToken); err != nil {
Expand All @@ -77,7 +66,7 @@ func (c *cmd) generateBootStrapACLToken() (*BootStrapACLTokenInfo, error) {
}
}

func (c *cmd) saveBootstrapACLToken(tokenInfoToBeSaved *BootStrapACLTokenInfo) error {
func (c *cmd) saveBootstrapACLToken(tokenInfoToBeSaved *types.BootStrapACLTokenInfo) error {
// Write the token to the specified file
tokenFileAbsPath, err := filepath.Abs(c.configuration.StageGate.Registry.ACL.BootstrapTokenPath)
if err != nil {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/edgexfoundry/edgex-go/internal/security/bootstrapper/command/setupacl/share"
"github.com/edgexfoundry/go-mod-core-contracts/v2/common"
"github.com/edgexfoundry/go-mod-secrets/v2/pkg/types"
)

const (
Expand Down Expand Up @@ -108,7 +109,7 @@ const (
// getOrCreateRegistryPolicy retrieves or creates a new policy
// it inserts a new policy if the policy name does not exist and returns a policy
// it returns the same policy if the policy name already exists
func (c *cmd) getOrCreateRegistryPolicy(tokenID, policyName, policyRules string) (*Policy, error) {
func (c *cmd) getOrCreateRegistryPolicy(tokenID, policyName, policyRules string) (*types.Policy, error) {
// try to get the policy to see if it exists or not
policy, err := c.getPolicyByName(tokenID, policyName)
if err != nil {
Expand Down Expand Up @@ -165,7 +166,7 @@ func (c *cmd) getOrCreateRegistryPolicy(tokenID, policyName, policyRules string)
return nil, fmt.Errorf("Failed to read create a new policy response body: %w", err)
}

var created Policy
var created types.Policy

switch resp.StatusCode {
case http.StatusOK:
Expand All @@ -183,7 +184,7 @@ func (c *cmd) getOrCreateRegistryPolicy(tokenID, policyName, policyRules string)
}

// getPolicyByName gets policy by policy name, returns nil if not found
func (c *cmd) getPolicyByName(tokenID, policyName string) (*Policy, error) {
func (c *cmd) getPolicyByName(tokenID, policyName string) (*types.Policy, error) {
readPolicyByNameURL, err := c.getRegistryApiUrl(fmt.Sprintf(consulReadPolicyByNameAPI, policyName))
if err != nil {
return nil, err
Expand Down Expand Up @@ -211,7 +212,7 @@ func (c *cmd) getPolicyByName(tokenID, policyName string) (*Policy, error) {

switch resp.StatusCode {
case http.StatusOK:
var existing Policy
var existing types.Policy
if err := json.NewDecoder(bytes.NewReader(readPolicyResp)).Decode(&existing); err != nil {
return nil, fmt.Errorf("failed to decode Policy json data: %v", err)
}
Expand Down
139 changes: 0 additions & 139 deletions internal/security/bootstrapper/command/setupacl/aclroles.go

This file was deleted.

51 changes: 30 additions & 21 deletions internal/security/bootstrapper/command/setupacl/aclroles_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,27 +17,29 @@ package setupacl

import (
"context"
"errors"
"sync"
"testing"
"time"

"github.com/stretchr/testify/require"

"github.com/edgexfoundry/go-mod-core-contracts/v2/clients/logger"
"github.com/edgexfoundry/go-mod-secrets/v2/pkg/types"
"github.com/edgexfoundry/go-mod-secrets/v2/secrets/mocks"
"github.com/stretchr/testify/require"
)

func TestCreateRole(t *testing.T) {
ctx := context.Background()
wg := &sync.WaitGroup{}
lc := logger.MockLogger{}
testSecretStoreToken := "test-secretstore-token"
testSinglePolicy := []Policy{
testSinglePolicy := []types.Policy{
{
ID: "test-ID",
Name: "test-name",
},
}
testMultiplePolicies := []Policy{
testMultiplePolicies := []types.Policy{
{
ID: "test-ID1",
Name: "test-name1",
Expand All @@ -48,26 +50,28 @@ func TestCreateRole(t *testing.T) {
},
}

testRoleWithNilPolicy := NewRegistryRole("testRoleSingle", ClientType, nil, true)
testRoleWithEmptyPolicy := NewRegistryRole("testRoleSingle", ClientType, []Policy{}, true)
testRoleWithSinglePolicy := NewRegistryRole("testRoleSingle", ClientType, testSinglePolicy, true)
testRoleWithMultiplePolicies := NewRegistryRole("testRoleMultiple", ClientType, testMultiplePolicies, true)
testEmptyRoleName := NewRegistryRole("", ManagementType, testSinglePolicy, true)

testRoleWithNilPolicy := types.NewRegistryRole("testRoleSingle", types.ClientType, nil, true)
testRoleWithEmptyPolicy := types.NewRegistryRole("testRoleSingle", types.ClientType, []types.Policy{}, true)
testRoleWithSinglePolicy := types.NewRegistryRole("testRoleSingle", types.ClientType, testSinglePolicy, true)
testRoleWithMultiplePolicies := types.NewRegistryRole("testRoleMultiple", types.ClientType, testMultiplePolicies, true)
testEmptyRoleName := types.NewRegistryRole("", types.ManagementType, testSinglePolicy, true)
testCreateRoleErr := errors.New("Failed to create role")
testEmptyTokenErr := errors.New("required secret store token is empty")
testEmptyRoleNameErr := errors.New("required registry role name is empty")
tests := []struct {
name string
secretstoreToken string
registryRole RegistryRole
registryRole types.RegistryRole
creatRoleOkResponse bool
expectedErr bool
expectedErr error
}{
{"Good:create role with single policy ok", testSecretStoreToken, testRoleWithSinglePolicy, true, false},
{"Good:create role with multiple policies ok", testSecretStoreToken, testRoleWithMultiplePolicies, true, false},
{"Good:create role with empty policy ok", testSecretStoreToken, testRoleWithEmptyPolicy, true, false},
{"Good:create role with nil policy ok", testSecretStoreToken, testRoleWithNilPolicy, true, false},
{"Bad:create role bad response", testSecretStoreToken, testRoleWithSinglePolicy, false, true},
{"Bad:empty secretstore token", "", testRoleWithMultiplePolicies, false, true},
{"Bad:empty role name", testSecretStoreToken, testEmptyRoleName, false, true},
{"Good:create role with single policy ok", testSecretStoreToken, testRoleWithSinglePolicy, true, nil},
{"Good:create role with multiple policies ok", testSecretStoreToken, testRoleWithMultiplePolicies, true, nil},
{"Good:create role with empty policy ok", testSecretStoreToken, testRoleWithEmptyPolicy, true, nil},
{"Good:create role with nil policy ok", testSecretStoreToken, testRoleWithNilPolicy, true, nil},
{"Bad:create role bad response", testSecretStoreToken, testRoleWithSinglePolicy, false, testCreateRoleErr},
{"Bad:empty secretstore token", "", testRoleWithMultiplePolicies, false, testEmptyTokenErr},
{"Bad:empty role name", testSecretStoreToken, testEmptyRoleName, false, testEmptyRoleNameErr},
}

for _, tt := range tests {
Expand All @@ -89,9 +93,14 @@ func TestCreateRole(t *testing.T) {
setupRegistryACL := command.(*cmd)
setupRegistryACL.retryTimeout = 2 * time.Second

err = setupRegistryACL.createRole(test.secretstoreToken, test.registryRole)
secretClient := &mocks.SecretStoreClient{}

secretClient.On("CreateRole", test.secretstoreToken,
test.registryRole).
Return(test.expectedErr).Once()
err = test.expectedErr

if test.expectedErr {
if test.expectedErr != nil {
require.Error(t, err)
} else {
require.NoError(t, err)
Expand Down
Loading

0 comments on commit cdf811a

Please sign in to comment.