Skip to content

Commit bec4811

Browse files
Merge pull request #105 from vmware/vasundharas/acceptance-test-image-policy
Acceptance Tests for Image Policy Resource
2 parents bf484a3 + 6469ba5 commit bec4811

File tree

4 files changed

+422
-1
lines changed

4 files changed

+422
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
Copyright © 2022 VMware, Inc. All Rights Reserved.
3+
SPDX-License-Identifier: MPL-2.0
4+
*/
5+
6+
package imagepolicyresource
7+
8+
import (
9+
"testing"
10+
11+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
12+
"github.com/stretchr/testify/require"
13+
14+
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/authctx"
15+
policykindimage "github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/policy/kind/image"
16+
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/workspace"
17+
)
18+
19+
func initTestProvider(t *testing.T) *schema.Provider {
20+
testAccProvider := &schema.Provider{
21+
Schema: authctx.ProviderAuthSchema(),
22+
ResourcesMap: map[string]*schema.Resource{
23+
policykindimage.ResourceName: ResourceImagePolicy(),
24+
workspace.ResourceName: workspace.ResourceWorkspace(),
25+
},
26+
ConfigureContextFunc: authctx.ProviderConfigureContext,
27+
}
28+
if err := testAccProvider.InternalValidate(); err != nil {
29+
require.NoError(t, err)
30+
}
31+
32+
return testAccProvider
33+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,349 @@
1+
/*
2+
Copyright © 2022 VMware, Inc. All Rights Reserved.
3+
SPDX-License-Identifier: MPL-2.0
4+
*/
5+
6+
package imagepolicyresource
7+
8+
import (
9+
"fmt"
10+
"log"
11+
"os"
12+
"strings"
13+
"testing"
14+
"time"
15+
16+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
17+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
18+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
19+
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
20+
"github.com/pkg/errors"
21+
22+
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/authctx"
23+
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/client/proxy"
24+
policyorganizationmodel "github.com/vmware/terraform-provider-tanzu-mission-control/internal/models/policy/organization"
25+
policyworkspacemodel "github.com/vmware/terraform-provider-tanzu-mission-control/internal/models/policy/workspace"
26+
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/policy"
27+
policykindImage "github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/policy/kind/image"
28+
policyoperations "github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/policy/operations"
29+
"github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/policy/scope"
30+
testhelper "github.com/vmware/terraform-provider-tanzu-mission-control/internal/resources/testing"
31+
)
32+
33+
const (
34+
imagePolicyResource = policykindImage.ResourceName
35+
imagePolicyResourceVar = "test_image_policy"
36+
imagePolicyNamePrefix = "tf-ip-test"
37+
)
38+
39+
type testAcceptanceConfig struct {
40+
Provider *schema.Provider
41+
ImagePolicyResource string
42+
ImagePolicyResourceVar string
43+
ImagePolicyResourceName string
44+
ImagePolicyName string
45+
ScopeHelperResources *policy.ScopeHelperResources
46+
}
47+
48+
func testGetDefaultAcceptanceConfig(t *testing.T) *testAcceptanceConfig {
49+
return &testAcceptanceConfig{
50+
Provider: initTestProvider(t),
51+
ImagePolicyResource: imagePolicyResource,
52+
ImagePolicyResourceVar: imagePolicyResourceVar,
53+
ImagePolicyResourceName: fmt.Sprintf("%s.%s", imagePolicyResource, imagePolicyResourceVar),
54+
ImagePolicyName: acctest.RandomWithPrefix(imagePolicyNamePrefix),
55+
ScopeHelperResources: policy.NewScopeHelperResources(),
56+
}
57+
}
58+
59+
func TestAcceptanceForImagePolicyResource(t *testing.T) {
60+
testConfig := testGetDefaultAcceptanceConfig(t)
61+
62+
t.Log("start image policy resource acceptance tests!")
63+
64+
// Test case for image policy resource with allowed-name-tag recipe.
65+
resource.Test(t, resource.TestCase{
66+
PreCheck: testhelper.TestPreCheck(t),
67+
ProviderFactories: testhelper.GetTestProviderFactories(testConfig.Provider),
68+
CheckDestroy: nil,
69+
Steps: []resource.TestStep{
70+
{
71+
Config: testConfig.getTestImagePolicyResourceBasicConfigValue(scope.WorkspaceScope, policykindImage.AllowedNameTagRecipe),
72+
Check: testConfig.checkImagePolicyResourceAttributes(scope.WorkspaceScope),
73+
},
74+
{
75+
PreConfig: func() {
76+
if testConfig.ScopeHelperResources.OrgID == "" {
77+
t.Skip("ORG_ID env var is not set for organization scoped image policy acceptance test")
78+
}
79+
},
80+
Config: testConfig.getTestImagePolicyResourceBasicConfigValue(scope.OrganizationScope, policykindImage.AllowedNameTagRecipe),
81+
Check: testConfig.checkImagePolicyResourceAttributes(scope.OrganizationScope),
82+
},
83+
},
84+
},
85+
)
86+
87+
t.Log("Image policy resource acceptance test complete for allowed-name-tag recipe!")
88+
time.Sleep(2 * time.Minute)
89+
90+
// Test case for image policy resource with block-latest-tag recipe.
91+
resource.Test(t, resource.TestCase{
92+
PreCheck: testhelper.TestPreCheck(t),
93+
ProviderFactories: testhelper.GetTestProviderFactories(testConfig.Provider),
94+
CheckDestroy: nil,
95+
Steps: []resource.TestStep{
96+
{
97+
Config: testConfig.getTestImagePolicyResourceBasicConfigValue(scope.WorkspaceScope, policykindImage.BlockLatestTagRecipe),
98+
Check: testConfig.checkImagePolicyResourceAttributes(scope.WorkspaceScope),
99+
},
100+
{
101+
PreConfig: func() {
102+
if testConfig.ScopeHelperResources.OrgID == "" {
103+
t.Skip("ORG_ID env var is not set for organization scoped image policy acceptance test")
104+
}
105+
},
106+
Config: testConfig.getTestImagePolicyResourceBasicConfigValue(scope.OrganizationScope, policykindImage.BlockLatestTagRecipe),
107+
Check: testConfig.checkImagePolicyResourceAttributes(scope.OrganizationScope),
108+
},
109+
},
110+
},
111+
)
112+
113+
t.Log("Image policy resource acceptance test complete for block-latest-tag recipe!")
114+
time.Sleep(2 * time.Minute)
115+
116+
// Test case for image policy resource with require-digest recipe.
117+
resource.Test(t, resource.TestCase{
118+
PreCheck: testhelper.TestPreCheck(t),
119+
ProviderFactories: testhelper.GetTestProviderFactories(testConfig.Provider),
120+
CheckDestroy: nil,
121+
Steps: []resource.TestStep{
122+
{
123+
Config: testConfig.getTestImagePolicyResourceBasicConfigValue(scope.WorkspaceScope, policykindImage.RequireDigestRecipe),
124+
Check: testConfig.checkImagePolicyResourceAttributes(scope.WorkspaceScope),
125+
},
126+
{
127+
PreConfig: func() {
128+
if testConfig.ScopeHelperResources.OrgID == "" {
129+
t.Skip("ORG_ID env var is not set for organization scoped image policy acceptance test")
130+
}
131+
},
132+
Config: testConfig.getTestImagePolicyResourceBasicConfigValue(scope.OrganizationScope, policykindImage.RequireDigestRecipe),
133+
Check: testConfig.checkImagePolicyResourceAttributes(scope.OrganizationScope),
134+
},
135+
},
136+
},
137+
)
138+
139+
t.Log("Image policy resource acceptance test complete for require-digest recipe!")
140+
time.Sleep(2 * time.Minute)
141+
142+
// Test case for image policy resource with custom recipe.
143+
resource.Test(t, resource.TestCase{
144+
PreCheck: testhelper.TestPreCheck(t),
145+
ProviderFactories: testhelper.GetTestProviderFactories(testConfig.Provider),
146+
CheckDestroy: nil,
147+
Steps: []resource.TestStep{
148+
149+
{
150+
Config: testConfig.getTestImagePolicyResourceBasicConfigValue(scope.WorkspaceScope, policykindImage.CustomRecipe),
151+
Check: testConfig.checkImagePolicyResourceAttributes(scope.WorkspaceScope),
152+
},
153+
{
154+
PreConfig: func() {
155+
if testConfig.ScopeHelperResources.OrgID == "" {
156+
t.Skip("ORG_ID env var is not set for organization scoped image policy acceptance test")
157+
}
158+
},
159+
Config: testConfig.getTestImagePolicyResourceBasicConfigValue(scope.OrganizationScope, policykindImage.CustomRecipe),
160+
Check: testConfig.checkImagePolicyResourceAttributes(scope.OrganizationScope),
161+
},
162+
},
163+
},
164+
)
165+
166+
t.Log("Image policy resource acceptance test complete for custom recipe!")
167+
t.Log("all image policy resource acceptance tests complete!")
168+
}
169+
170+
func (testConfig *testAcceptanceConfig) getTestImagePolicyResourceBasicConfigValue(scope scope.Scope, recipe policykindImage.Recipe) string {
171+
helperBlock, scopeBlock := testConfig.ScopeHelperResources.GetTestPolicyResourceHelperAndScope(scope, policyoperations.ScopeMap[testConfig.ImagePolicyResource])
172+
inputBlock := testConfig.getTestImagePolicyResourceInput(recipe)
173+
174+
return fmt.Sprintf(`
175+
%s
176+
177+
resource "%s" "%s" {
178+
name = "%s"
179+
180+
%s
181+
182+
spec {
183+
%s
184+
185+
namespace_selector {
186+
match_expressions {
187+
key = "component"
188+
operator = "NotIn"
189+
values = [
190+
"api-server",
191+
"agent-gateway"
192+
]
193+
}
194+
match_expressions {
195+
key = "not-a-component"
196+
operator = "DoesNotExist"
197+
values = []
198+
}
199+
}
200+
}
201+
}
202+
`, helperBlock, testConfig.ImagePolicyResource, testConfig.ImagePolicyResourceVar, testConfig.ImagePolicyName, scopeBlock, inputBlock)
203+
}
204+
205+
// getTestImagePolicyResourceInput builds the input block for image policy resource based a recipe.
206+
func (testConfig *testAcceptanceConfig) getTestImagePolicyResourceInput(recipe policykindImage.Recipe) string {
207+
var inputBlock string
208+
209+
switch recipe {
210+
case policykindImage.AllowedNameTagRecipe:
211+
inputBlock = `
212+
input {
213+
allowed_name_tag {
214+
audit = true
215+
rules {
216+
imagename = "bar"
217+
tag {
218+
negate = true
219+
value = "test"
220+
}
221+
}
222+
}
223+
}
224+
`
225+
case policykindImage.BlockLatestTagRecipe:
226+
inputBlock = `
227+
input {
228+
block_latest_tag {
229+
audit = false
230+
}
231+
}
232+
`
233+
case policykindImage.RequireDigestRecipe:
234+
inputBlock = `
235+
input {
236+
require_digest {
237+
audit = false
238+
}
239+
}
240+
`
241+
case policykindImage.CustomRecipe:
242+
inputBlock = `
243+
input {
244+
custom {
245+
audit = true
246+
rules {
247+
hostname = "foo"
248+
imagename = "bar"
249+
port = "80"
250+
requiredigest = false
251+
tag {
252+
negate = false
253+
value = "test"
254+
}
255+
}
256+
}
257+
}
258+
`
259+
case policykindImage.UnknownRecipe:
260+
log.Printf("[ERROR]: No valid input recipe block found: minimum one valid input recipe block is required among: %v. Please check the schema.", strings.Join(policykindImage.RecipesAllowed[:], `, `))
261+
}
262+
263+
return inputBlock
264+
}
265+
266+
// checkImagePolicyResourceAttributes checks for image policy creation along with meta attributes.
267+
func (testConfig *testAcceptanceConfig) checkImagePolicyResourceAttributes(scopeType scope.Scope) resource.TestCheckFunc {
268+
var check = []resource.TestCheckFunc{
269+
testConfig.verifyImagePolicyResourceCreation(scopeType),
270+
resource.TestCheckResourceAttr(testConfig.ImagePolicyResourceName, "name", testConfig.ImagePolicyName),
271+
}
272+
273+
switch scopeType {
274+
case scope.WorkspaceScope:
275+
check = append(check, resource.TestCheckResourceAttr(testConfig.ImagePolicyResourceName, "scope.0.workspace.0.workspace", testConfig.ScopeHelperResources.Workspace.Name))
276+
case scope.OrganizationScope:
277+
check = append(check, resource.TestCheckResourceAttr(testConfig.ImagePolicyResourceName, "scope.0.organization.0.organization", testConfig.ScopeHelperResources.OrgID))
278+
case scope.UnknownScope:
279+
log.Printf("[ERROR]: No valid scope type block found: minimum one valid scope type block is required among: %v. Please check the schema.", strings.Join(policyoperations.ScopeMap[testConfig.ImagePolicyResource], `, `))
280+
}
281+
282+
check = append(check, policy.MetaResourceAttributeCheck(testConfig.ImagePolicyResourceName)...)
283+
284+
return resource.ComposeTestCheckFunc(check...)
285+
}
286+
287+
func (testConfig *testAcceptanceConfig) verifyImagePolicyResourceCreation(scopeType scope.Scope) resource.TestCheckFunc {
288+
return func(s *terraform.State) error {
289+
if testConfig.Provider == nil {
290+
return fmt.Errorf("provider not initialised")
291+
}
292+
293+
rs, ok := s.RootModule().Resources[testConfig.ImagePolicyResourceName]
294+
if !ok {
295+
return fmt.Errorf("not found resource: %s", testConfig.ImagePolicyResourceName)
296+
}
297+
298+
if rs.Primary.ID == "" {
299+
return fmt.Errorf("ID not set, resource: %s", testConfig.ImagePolicyResourceName)
300+
}
301+
302+
config := authctx.TanzuContext{
303+
ServerEndpoint: os.Getenv(authctx.ServerEndpointEnvVar),
304+
Token: os.Getenv(authctx.VMWCloudAPITokenEnvVar),
305+
VMWCloudEndPoint: os.Getenv(authctx.VMWCloudEndpointEnvVar),
306+
TLSConfig: &proxy.TLSConfig{},
307+
}
308+
309+
err := config.Setup()
310+
if err != nil {
311+
return errors.Wrap(err, "unable to set the context")
312+
}
313+
314+
switch scopeType {
315+
case scope.WorkspaceScope:
316+
fn := &policyworkspacemodel.VmwareTanzuManageV1alpha1WorkspacePolicyFullName{
317+
WorkspaceName: testConfig.ScopeHelperResources.Workspace.Name,
318+
Name: testConfig.ImagePolicyName,
319+
}
320+
321+
resp, err := config.TMCConnection.WorkspacePolicyResourceService.ManageV1alpha1WorkspacePolicyResourceServiceGet(fn)
322+
if err != nil {
323+
return errors.Wrap(err, "workspace scoped image policy resource not found")
324+
}
325+
326+
if resp == nil {
327+
return errors.Wrapf(err, "workspace scoped image policy resource is empty, resource: %s", testConfig.ImagePolicyResourceName)
328+
}
329+
case scope.OrganizationScope:
330+
fn := &policyorganizationmodel.VmwareTanzuManageV1alpha1OrganizationPolicyFullName{
331+
OrgID: testConfig.ScopeHelperResources.OrgID,
332+
Name: testConfig.ImagePolicyName,
333+
}
334+
335+
resp, err := config.TMCConnection.OrganizationPolicyResourceService.ManageV1alpha1OrganizationPolicyResourceServiceGet(fn)
336+
if err != nil {
337+
return errors.Wrap(err, "organization scoped image policy resource not found")
338+
}
339+
340+
if resp == nil {
341+
return errors.Wrapf(err, "organization scoped image policy resource is empty, resource: %s", testConfig.ImagePolicyResourceName)
342+
}
343+
case scope.UnknownScope:
344+
return errors.Errorf("[ERROR]: No valid scope type block found: minimum one valid scope type block is required among: %v. Please check the schema.", strings.Join(policyoperations.ScopeMap[testConfig.ImagePolicyResource], `, `))
345+
}
346+
347+
return nil
348+
}
349+
}

internal/resources/policy/kind/image/resource/resource_image_registry_policy.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ Copyright © 2022 VMware, Inc. All Rights Reserved.
33
SPDX-License-Identifier: MPL-2.0
44
*/
55

6-
package imageregistrypolicyresource
6+
package imagepolicyresource
77

88
import (
99
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/customdiff"

0 commit comments

Comments
 (0)