Skip to content

Commit

Permalink
Merge branch 'develop' into fix/SCALRCORE-21894
Browse files Browse the repository at this point in the history
  • Loading branch information
RomanMytsko committed May 23, 2022
2 parents ef0e8bc + c4f4a1a commit b14d711
Show file tree
Hide file tree
Showing 4 changed files with 259 additions and 22 deletions.
30 changes: 30 additions & 0 deletions helper_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,36 @@ func createPolicyGroup(t *testing.T, client *Client, vcsProvider *VcsProvider) (
}
}

func linkPolicyGroupToEnvironment(t *testing.T, client *Client, policyGroup *PolicyGroup, environment *Environment) func() {
ctx := context.Background()
options := PolicyGroupEnvironmentsCreateOptions{
PolicyGroupID: policyGroup.ID,
PolicyGroupEnvironments: []*PolicyGroupEnvironment{{ID: environment.ID}},
}

err := client.PolicyGroupEnvironments.Create(ctx, options)

if err != nil {
t.Fatal(err)
}

return func() {
err := client.PolicyGroupEnvironments.Delete(
ctx,
PolicyGroupEnvironmentDeleteOptions{
PolicyGroupID: policyGroup.ID,
EnvironmentID: environment.ID,
},
)

if err != nil {
t.Errorf("Error destroying policy group environment linkage! WARNING: Dangling resources\n"+
"may exist! The full error is shown below.\n\n"+
"Policy group: %s\nError: %s", policyGroup.ID, err)
}
}
}

func randomString(t *testing.T) string {
v, err := uuid.GenerateUUID()
if err != nil {
Expand Down
100 changes: 100 additions & 0 deletions policy_group_environments.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
package scalr

import (
"context"
"errors"
"fmt"
"net/url"

"github.com/svanharmelen/jsonapi"
)

// Compile-time proof of interface implementation.
var _ PolicyGroupEnvironments = (*policyGroupEnvironment)(nil)

// PolicyGroupEnvironments describes all the policy group environments related methods that the
// Scalr API supports.
type PolicyGroupEnvironments interface {
Create(ctx context.Context, options PolicyGroupEnvironmentsCreateOptions) error
Delete(ctx context.Context, options PolicyGroupEnvironmentDeleteOptions) error
}

// policyGroupEnvironments implements PolicyGroupEnvironments.
type policyGroupEnvironment struct {
client *Client
}

// PolicyGroupEnvironment represents a single policy group environment relation.
type PolicyGroupEnvironment struct {
ID string `jsonapi:"primary,environments"`
}

// PolicyGroupEnvironmentsCreateOptions represents options for creating new policy group environment linkage
type PolicyGroupEnvironmentsCreateOptions struct {
PolicyGroupID string
PolicyGroupEnvironments []*PolicyGroupEnvironment
}

type PolicyGroupEnvironmentDeleteOptions struct {
PolicyGroupID string
EnvironmentID string
}

func (o PolicyGroupEnvironmentsCreateOptions) valid() error {
if !validStringID(&o.PolicyGroupID) {
return errors.New("invalid value for policy group ID")
}
if o.PolicyGroupEnvironments == nil || len(o.PolicyGroupEnvironments) < 1 {
return errors.New("list of environments is required")
}
return nil
}

func (o PolicyGroupEnvironmentDeleteOptions) valid() error {
if !validStringID(&o.PolicyGroupID) {
return errors.New("invalid value for policy group ID")
}

if !validStringID(&o.EnvironmentID) {
return errors.New("invalid value for environment ID")
}

return nil
}

// Create a new policy group.
func (s *policyGroupEnvironment) Create(ctx context.Context, options PolicyGroupEnvironmentsCreateOptions) error {
if err := options.valid(); err != nil {
return err
}
u := fmt.Sprintf("policy-groups/%s/relationships/environments", url.QueryEscape(options.PolicyGroupID))
payload, err := jsonapi.Marshal(options.PolicyGroupEnvironments)
if err != nil {
return err
}
req, err := s.client.newJsonRequest("POST", u, payload)
if err != nil {
return err
}

return s.client.do(ctx, req, nil)
}

// Delete policy group by its ID.
func (s *policyGroupEnvironment) Delete(ctx context.Context, options PolicyGroupEnvironmentDeleteOptions) error {
if err := options.valid(); err != nil {
return err
}

u := fmt.Sprintf(
"policy-groups/%s/relationships/environments/%s",
url.QueryEscape(options.PolicyGroupID),
url.QueryEscape(options.EnvironmentID),
)
req, err := s.client.newRequest("DELETE", u, nil)
if err != nil {
return err
}

return s.client.do(ctx, req, nil)
}
105 changes: 105 additions & 0 deletions policy_group_environments_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package scalr

import (
"context"
"testing"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)

func TestPolicyGroupEnvironmentsCreate(t *testing.T) {
// TODO: delete skip after SCALRCORE-19891
t.Skip("Works with personal token but does not work with github action token.")

client := testClient(t)
ctx := context.Background()

envTest, envTestCleanup := createEnvironment(t, client)
defer envTestCleanup()

policyGroup, policyGroupCleanup := createPolicyGroup(t, client, nil)
defer policyGroupCleanup()

t.Run("with valid options", func(t *testing.T) {
options := PolicyGroupEnvironmentsCreateOptions{
PolicyGroupID: policyGroup.ID,
PolicyGroupEnvironments: []*PolicyGroupEnvironment{{ID: envTest.ID}},
}

err := client.PolicyGroupEnvironments.Create(ctx, options)

require.NoError(t, err)

// Get a refreshed view from the API.
refreshed, err := client.PolicyGroups.Read(ctx, policyGroup.ID)
require.NoError(t, err)

for _, item := range refreshed.Environments {
assert.Equal(t, envTest.ID, item.ID)
}

func() {
client.PolicyGroupEnvironments.Delete(
ctx,
PolicyGroupEnvironmentDeleteOptions{
PolicyGroupID: policyGroup.ID,
EnvironmentID: envTest.ID,
},
)
}()
})

t.Run("with empty options", func(t *testing.T) {
err := client.PolicyGroupEnvironments.Create(ctx, PolicyGroupEnvironmentsCreateOptions{})
assert.EqualError(t, err, "invalid value for policy group ID")
})

t.Run("when options has an invalid environment", func(t *testing.T) {
var envID = "env-123"
options := PolicyGroupEnvironmentsCreateOptions{
PolicyGroupID: policyGroup.ID,
PolicyGroupEnvironments: []*PolicyGroupEnvironment{{ID: envID}},
}

err := client.PolicyGroupEnvironments.Create(ctx, options)
assert.NotEmpty(t, err)
})

}

func TestPolicyGroupEnvironmentDelete(t *testing.T) {
// TODO: delete skip after SCALRCORE-19891
t.Skip("Works with personal token but does not work with github action token.")

client := testClient(t)
ctx := context.Background()

envTest, envTestCleanup := createEnvironment(t, client)
policyGroup, policyGroupCleanup := createPolicyGroup(t, client, nil)
policyGroupEnvironmentLinkCleanup := linkPolicyGroupToEnvironment(t, client, policyGroup, envTest)
defer policyGroupEnvironmentLinkCleanup()
defer policyGroupCleanup()
defer envTestCleanup()

t.Run("with valid options", func(t *testing.T) {
err := client.PolicyGroupEnvironments.Delete(ctx, PolicyGroupEnvironmentDeleteOptions{
PolicyGroupID: policyGroup.ID,
EnvironmentID: envTest.ID,
})
require.NoError(t, err)

// Get a refreshed view from the API.
refreshed, err := client.PolicyGroups.Read(ctx, policyGroup.ID)
require.NoError(t, err)
assert.Empty(t, refreshed.Environments)
})

t.Run("without a valid policy group ID", func(t *testing.T) {
err := client.PolicyGroupEnvironments.Delete(ctx, PolicyGroupEnvironmentDeleteOptions{
PolicyGroupID: badIdentifier,
EnvironmentID: envTest.ID,
})
assert.EqualError(t, err, "invalid value for policy group ID")
})
}
46 changes: 24 additions & 22 deletions scalr.go
Original file line number Diff line number Diff line change
Expand Up @@ -116,28 +116,29 @@ type Client struct {
retryLogHook RetryLogHook
retryServerErrors bool

Accounts Accounts
AccessPolicies AccessPolicies
AccessTokens AccessTokens
AccountUsers AccountUsers
AgentPoolTokens AgentPoolTokens
AgentPools AgentPools
ConfigurationVersions ConfigurationVersions
Endpoints Endpoints
Environments Environments
ModuleVersions ModuleVersions
Modules Modules
PolicyGroups PolicyGroups
Roles Roles
Runs Runs
Teams Teams
Users Users
Variables Variables
VcsProviders VcsProviders
VcsRevisions VcsRevisions
Webhooks Webhooks
Workspaces Workspaces
RunTriggers RunTriggers
Accounts Accounts
AccessPolicies AccessPolicies
AccessTokens AccessTokens
AccountUsers AccountUsers
AgentPoolTokens AgentPoolTokens
AgentPools AgentPools
ConfigurationVersions ConfigurationVersions
Endpoints Endpoints
Environments Environments
ModuleVersions ModuleVersions
Modules Modules
PolicyGroups PolicyGroups
PolicyGroupEnvironments PolicyGroupEnvironments
Roles Roles
Runs Runs
Teams Teams
Users Users
Variables Variables
VcsProviders VcsProviders
VcsRevisions VcsRevisions
Webhooks Webhooks
Workspaces Workspaces
RunTriggers RunTriggers
}

// NewClient creates a new Scalr API client.
Expand Down Expand Up @@ -216,6 +217,7 @@ func NewClient(cfg *Config) (*Client, error) {
client.ModuleVersions = &moduleVersions{client: client}
client.Modules = &modules{client: client}
client.PolicyGroups = &policyGroups{client: client}
client.PolicyGroupEnvironments = &policyGroupEnvironment{client: client}
client.Roles = &roles{client: client}
client.Runs = &runs{client: client}
client.Teams = &teams{client: client}
Expand Down

0 comments on commit b14d711

Please sign in to comment.