-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'develop' into fix/SCALRCORE-21894
- Loading branch information
Showing
4 changed files
with
259 additions
and
22 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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") | ||
}) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters