From 1453b36577075a1fdee720588b8808ee5d7a1275 Mon Sep 17 00:00:00 2001 From: mrinalirao Date: Wed, 16 Nov 2022 17:35:27 +1100 Subject: [PATCH] code tidy up + add validations --- tfe/resource_tfe_policy.go | 92 ++++++++++++++++++++--------- tfe/resource_tfe_sentinel_policy.go | 2 +- 2 files changed, 64 insertions(+), 30 deletions(-) diff --git a/tfe/resource_tfe_policy.go b/tfe/resource_tfe_policy.go index 06e87abe5..498185325 100644 --- a/tfe/resource_tfe_policy.go +++ b/tfe/resource_tfe_policy.go @@ -25,26 +25,30 @@ func resourceTFEPolicy() *schema.Resource { Schema: map[string]*schema.Schema{ "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Description: "The name of the policy", + Type: schema.TypeString, + Required: true, + ForceNew: true, }, "description": { - Type: schema.TypeString, - Optional: true, + Description: "Text describing the policy's purpose", + Type: schema.TypeString, + Optional: true, }, "organization": { - Type: schema.TypeString, - Required: true, - ForceNew: true, + Description: "Name of the organization that this policy belongs to", + Type: schema.TypeString, + Required: true, + ForceNew: true, }, "kind": { - Type: schema.TypeString, - Optional: true, - Default: string(tfe.Sentinel), + Description: "The policy-as-code framework for the policy. Valid values are sentinel and opa", + Type: schema.TypeString, + Optional: true, + Default: string(tfe.Sentinel), ValidateFunc: validation.StringInSlice( []string{ string(tfe.OPA), @@ -53,21 +57,30 @@ func resourceTFEPolicy() *schema.Resource { }, "query": { - Type: schema.TypeString, - Optional: true, + Description: "The OPA query to run. Required for OPA policies", + Type: schema.TypeString, + Optional: true, }, "policy": { - Type: schema.TypeString, - Required: true, + Description: "Text of a valid Sentinel or OPA policy", + Type: schema.TypeString, + Required: true, }, "enforce_mode": { Type: schema.TypeString, Description: fmt.Sprintf( - "The enforce_mode of the policy. For Sentinel, valid values are `%s`, `%s`, and `%s`. For OPA, Valid values are `%s`and `%s`", - tfe.EnforcementHard, tfe.EnforcementSoft, tfe.EnforcementAdvisory, - tfe.EnforcementMandatory, tfe.EnforcementAdvisory), + "The enforce_mode of the policy. For Sentinel, valid values are %s. For OPA, Valid values are `%s`", sentenceList( + sentinelPolicyEnforcementLevels(), + "`", + "`", + "and"), + sentenceList( + opaPolicyEnforcementLevels(), + "`", + "`", + "and")), Optional: true, ValidateFunc: validation.StringInSlice( []string{ @@ -83,6 +96,21 @@ func resourceTFEPolicy() *schema.Resource { } } +func sentinelPolicyEnforcementLevels() []string { + return []string{ + string(tfe.EnforcementHard), + string(tfe.EnforcementSoft), + string(tfe.EnforcementAdvisory), + } +} + +func opaPolicyEnforcementLevels() []string { + return []string{ + string(tfe.EnforcementMandatory), + string(tfe.EnforcementAdvisory), + } +} + func resourceTFEPolicyCreate(d *schema.ResourceData, meta interface{}) error { tfeClient := meta.(*tfe.Client) @@ -105,17 +133,20 @@ func resourceTFEPolicyCreate(d *schema.ResourceData, meta interface{}) error { options.Description = tfe.String(desc.(string)) } + var err error // Setup per-kind policy options switch tfe.PolicyKind(kind) { case tfe.Sentinel: - options = createSentinelPolicyOptions(options, d) + options, err = createSentinelPolicyOptions(options, d) case tfe.OPA: - options = createOPAPolicyOptions(options, d) + options, err = createOPAPolicyOptions(options, d) default: - return fmt.Errorf( + err = fmt.Errorf( "Unsupported policy kind %s: has to be one of [%s, %s]", kind, string(tfe.Sentinel), string(tfe.OPA)) } - + if err != nil { + return err + } log.Printf("[DEBUG] Create %s policy %s for organization: %s", kind, name, organization) policy, err := tfeClient.Policies.Create(ctx, organization, *options) if err != nil { @@ -135,7 +166,7 @@ func resourceTFEPolicyCreate(d *schema.ResourceData, meta interface{}) error { return resourceTFEPolicyRead(d, meta) } -func createOPAPolicyOptions(options *tfe.PolicyCreateOptions, d *schema.ResourceData) *tfe.PolicyCreateOptions { +func createOPAPolicyOptions(options *tfe.PolicyCreateOptions, d *schema.ResourceData) (*tfe.PolicyCreateOptions, error) { name := d.Get("name").(string) path := name + ".rego" options.Enforce = []*tfe.EnforcementOptions{ @@ -144,22 +175,25 @@ func createOPAPolicyOptions(options *tfe.PolicyCreateOptions, d *schema.Resource Mode: tfe.EnforcementMode(tfe.EnforcementLevel(d.Get("enforce_mode").(string))), }, } - if vQuery, ok := d.GetOk("query"); ok { - options.Query = tfe.String(vQuery.(string)) + vQuery, ok := d.GetOk("query") + if !ok { + return options, fmt.Errorf("Missing query for OPA policy.") } - return options + options.Query = tfe.String(vQuery.(string)) + + return options, nil } -func createSentinelPolicyOptions(options *tfe.PolicyCreateOptions, d *schema.ResourceData) *tfe.PolicyCreateOptions { +func createSentinelPolicyOptions(options *tfe.PolicyCreateOptions, d *schema.ResourceData) (*tfe.PolicyCreateOptions, error) { name := d.Get("name").(string) - path := name + ".rego" + path := name + ".sentinel" options.Enforce = []*tfe.EnforcementOptions{ { Path: tfe.String(path), Mode: tfe.EnforcementMode(tfe.EnforcementLevel(d.Get("enforce_mode").(string))), }, } - return options + return options, nil } func resourceTFEPolicyRead(d *schema.ResourceData, meta interface{}) error { diff --git a/tfe/resource_tfe_sentinel_policy.go b/tfe/resource_tfe_sentinel_policy.go index 9c75b295c..64b9da68c 100644 --- a/tfe/resource_tfe_sentinel_policy.go +++ b/tfe/resource_tfe_sentinel_policy.go @@ -13,7 +13,7 @@ import ( func resourceTFESentinelPolicy() *schema.Resource { return &schema.Resource{ - DeprecationMessage: "tfe_sentinel_policy is being deprecated, please use tfe_policy instead", + DeprecationMessage: "tfe_sentinel_policy is deprecated, please use tfe_policy instead", Create: resourceTFESentinelPolicyCreate, Read: resourceTFESentinelPolicyRead, Update: resourceTFESentinelPolicyUpdate,