-
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.
Consolidated changes for policy engine providers
- Loading branch information
1 parent
ea947b4
commit b2ad3ba
Showing
13 changed files
with
904 additions
and
30 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
package policyv2 | ||
|
||
const ( | ||
resourceName = "cyral_policy_v2" | ||
dataSourceName = resourceName | ||
apiPathLocal = "v2/policies/local" | ||
apiPathGlobal = "v2/policies/global" | ||
apiPathApproval = "v2/policies/approval" | ||
) | ||
|
||
func getAPIPath(policyType string) string { | ||
switch policyType { | ||
case "POLICY_TYPE_LOCAL", "local": | ||
return apiPathLocal | ||
case "POLICY_TYPE_GLOBAL", "global": | ||
return apiPathGlobal | ||
case "POLICY_TYPE_APPROVAL", "approval": | ||
return apiPathApproval | ||
default: | ||
return "" | ||
} | ||
} |
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,109 @@ | ||
package policyv2 | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
|
||
"github.com/cyralinc/terraform-provider-cyral/cyral/client" | ||
"github.com/cyralinc/terraform-provider-cyral/cyral/core" | ||
"github.com/cyralinc/terraform-provider-cyral/cyral/core/types/resourcetype" | ||
) | ||
|
||
var dsContextHandler = core.DefaultContextHandler{ | ||
ResourceName: dataSourceName, | ||
ResourceType: resourcetype.DataSource, | ||
SchemaWriterFactoryGetMethod: func(_ *schema.ResourceData) core.SchemaWriter { return &PolicyV2{} }, | ||
ReadUpdateDeleteURLFactory: func(d *schema.ResourceData, c *client.Client) string { | ||
return fmt.Sprintf("https://%s/%s/%s", c.ControlPlane, getAPIPath(d.Get("type").(string)), d.Get("id").(string)) | ||
}, | ||
} | ||
|
||
func dataSourceSchema() *schema.Resource { | ||
return &schema.Resource{ | ||
Description: "This data source provides information about a policy.", | ||
ReadContext: dsContextHandler.ReadContext(), | ||
Schema: map[string]*schema.Schema{ | ||
"id": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The unique ID for the policy. This field is automatically set.", | ||
}, | ||
"type": { | ||
Type: schema.TypeString, | ||
Required: true, | ||
Description: "The type of the policy.", | ||
}, | ||
"name": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: "A human-friendly name for the policy.", | ||
}, | ||
"description": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: "A description for the policy.", | ||
}, | ||
"enabled": { | ||
Type: schema.TypeBool, | ||
Computed: true, | ||
Description: "Indicates if the policy is enabled.", | ||
}, | ||
"tags": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Description: "Tags associated with the policy for categorization.", | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
}, | ||
"scope": { | ||
Type: schema.TypeList, | ||
Computed: true, | ||
Elem: &schema.Resource{ | ||
Schema: map[string]*schema.Schema{ | ||
"repo_ids": { | ||
Type: schema.TypeList, | ||
Elem: &schema.Schema{Type: schema.TypeString}, | ||
Computed: true, | ||
}, | ||
}, | ||
}, | ||
}, | ||
"valid_from": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: "The time when the policy comes into effect. An unspecified value implies the policy has no start time.", | ||
}, | ||
"valid_until": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: "The time after which the policy is no longer in effect. An unspecified value implies the policy will always apply once it comes into effect.", | ||
}, | ||
"document": { | ||
Type: schema.TypeString, | ||
Computed: true, | ||
Description: "The actual policy document in JSON format. It must conform to the schema for the policy type.", | ||
}, | ||
"last_updated": { | ||
Description: "Information about when and by whom the policy was last updated.", | ||
Type: schema.TypeMap, | ||
Optional: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
"created": { | ||
Description: "Information about when and by whom the policy was created.", | ||
Type: schema.TypeMap, | ||
Optional: true, | ||
Elem: &schema.Schema{ | ||
Type: schema.TypeString, | ||
}, | ||
}, | ||
"enforced": { | ||
Type: schema.TypeBool, | ||
Computed: true, | ||
Description: "Indicates if the policy is enforced.", | ||
}, | ||
}, | ||
} | ||
} |
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,170 @@ | ||
package policyv2 | ||
|
||
import ( | ||
"fmt" | ||
|
||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" | ||
) | ||
|
||
// ChangeInfo represents information about changes to the policy | ||
type ChangeInfo struct { | ||
Actor string `json:"actor,omitempty"` | ||
ActorType string `json:"actorType,omitempty"` | ||
Timestamp string `json:"timestamp,omitempty"` | ||
} | ||
|
||
// PolicyV2 represents the top-level policy structure | ||
type PolicyV2 struct { | ||
Policy Policy `json:"policy,omitempty"` | ||
} | ||
|
||
type Scope struct { | ||
RepoIds []string `json:"repoIds,omitempty"` | ||
} | ||
|
||
// Policy represents the policy details | ||
type Policy struct { | ||
ID string `json:"id,omitempty"` | ||
Name string `json:"name,omitempty"` | ||
Description string `json:"description,omitempty"` | ||
Enabled bool `json:"enabled,omitempty"` | ||
Scope *Scope `json:"scope,omitempty"` | ||
Tags []string `json:"tags,omitempty"` | ||
ValidFrom string `json:"validFrom,omitempty"` | ||
ValidUntil string `json:"validUntil,omitempty"` | ||
Document string `json:"document,omitempty"` | ||
LastUpdated ChangeInfo `json:"lastUpdated,omitempty"` | ||
Created ChangeInfo `json:"created,omitempty"` | ||
Enforced bool `json:"enforced,omitempty"` | ||
Type string `json:"type,omitempty"` | ||
} | ||
|
||
// WriteToSchema writes the policy data to the schema | ||
func (r PolicyV2) WriteToSchema(d *schema.ResourceData) error { | ||
if err := d.Set("id", r.Policy.ID); err != nil { | ||
return fmt.Errorf("error setting 'id' field: %w", err) | ||
} | ||
if err := d.Set("name", r.Policy.Name); err != nil { | ||
return fmt.Errorf("error setting 'name' field: %w", err) | ||
} | ||
if err := d.Set("description", r.Policy.Description); err != nil { | ||
return fmt.Errorf("error setting 'description' field: %w", err) | ||
} | ||
if err := d.Set("enabled", r.Policy.Enabled); err != nil { | ||
return fmt.Errorf("error setting 'enabled' field: %w", err) | ||
} | ||
if err := d.Set("tags", r.Policy.Tags); err != nil { | ||
return fmt.Errorf("error setting 'tags' field: %w", err) | ||
} | ||
if err := d.Set("valid_from", r.Policy.ValidFrom); err != nil { | ||
return fmt.Errorf("error setting 'valid_from' field: %w", err) | ||
} | ||
if err := d.Set("valid_until", r.Policy.ValidUntil); err != nil { | ||
return fmt.Errorf("error setting 'valid_until' field: %w", err) | ||
} | ||
|
||
if err := d.Set("document", r.Policy.Document); err != nil { | ||
return fmt.Errorf("error setting 'document' field: %w", err) | ||
} | ||
|
||
if err := d.Set("last_updated", map[string]interface{}{ | ||
"actor": r.Policy.LastUpdated.Actor, | ||
"actor_type": r.Policy.LastUpdated.ActorType, | ||
"timestamp": r.Policy.LastUpdated.Timestamp, | ||
}); err != nil { | ||
return fmt.Errorf("error setting 'last_updated' field: %w", err) | ||
} | ||
if err := d.Set("created", map[string]interface{}{ | ||
"actor": r.Policy.Created.Actor, | ||
"actor_type": r.Policy.Created.ActorType, | ||
"timestamp": r.Policy.Created.Timestamp, | ||
}); err != nil { | ||
return fmt.Errorf("error setting 'created' field: %w", err) | ||
} | ||
if err := d.Set("enforced", r.Policy.Enforced); err != nil { | ||
return fmt.Errorf("error setting 'enforced' field: %w", err) | ||
} | ||
if r.Policy.Type != "" { | ||
if err := d.Set("type", r.Policy.Type); err != nil { | ||
return fmt.Errorf("error setting 'type' field: %w", err) | ||
} | ||
} | ||
if err := d.Set("scope", flattenScope(r.Policy.Scope)); err != nil { | ||
return fmt.Errorf("error setting 'scope' field: %w", err) | ||
} | ||
d.SetId(r.Policy.ID) | ||
return nil | ||
} | ||
|
||
// ReadFromSchema reads the policy data from the schema | ||
func (r *PolicyV2) ReadFromSchema(d *schema.ResourceData) error { | ||
r.Policy.ID = d.Get("id").(string) | ||
r.Policy.Name = d.Get("name").(string) | ||
r.Policy.Description = d.Get("description").(string) | ||
r.Policy.Enabled = d.Get("enabled").(bool) | ||
r.Policy.Tags = expandStringList(d.Get("tags").([]interface{})) | ||
r.Policy.ValidFrom = d.Get("valid_from").(string) | ||
r.Policy.ValidUntil = d.Get("valid_until").(string) | ||
|
||
r.Policy.Document = d.Get("document").(string) | ||
|
||
r.Policy.LastUpdated = expandChangeInfo(d.Get("last_updated").(map[string]interface{})) | ||
r.Policy.Created = expandChangeInfo(d.Get("created").(map[string]interface{})) | ||
r.Policy.Enforced = d.Get("enforced").(bool) | ||
r.Policy.Type = d.Get("type").(string) | ||
if v, ok := d.GetOk("scope"); ok { | ||
r.Policy.Scope = expandScope(v.([]interface{})) | ||
} | ||
return nil | ||
} | ||
|
||
// expandStringList converts a list of interface{} to a list of strings | ||
func expandStringList(list []interface{}) []string { | ||
result := make([]string, len(list)) | ||
for i, v := range list { | ||
result[i] = v.(string) | ||
} | ||
return result | ||
} | ||
|
||
// expandChangeInfo converts a map to a ChangeInfo struct | ||
func expandChangeInfo(m map[string]interface{}) ChangeInfo { | ||
return ChangeInfo{ | ||
Actor: getStringOrDefault(m["actor"]), | ||
ActorType: getStringOrDefault(m["actor_type"]), | ||
Timestamp: getStringOrDefault(m["timestamp"]), | ||
} | ||
} | ||
|
||
// getStringOrDefault returns the string value or an empty string if nil | ||
func getStringOrDefault(v interface{}) string { | ||
if v == nil { | ||
return "" | ||
} | ||
return v.(string) | ||
} | ||
|
||
// flattenScope converts the Scope struct to a list of maps | ||
func flattenScope(scope *Scope) []map[string]interface{} { | ||
if scope == nil { | ||
return nil | ||
} | ||
scopeMap := []map[string]interface{}{ | ||
{ | ||
"repo_ids": scope.RepoIds, | ||
}, | ||
} | ||
return scopeMap | ||
} | ||
|
||
// expandScope converts the map to a Scope struct | ||
func expandScope(s []interface{}) *Scope { | ||
if len(s) == 0 || s[0] == nil { | ||
return nil | ||
} | ||
m := s[0].(map[string]interface{}) | ||
scope := Scope{ | ||
RepoIds: expandStringList(m["repo_ids"].([]interface{})), | ||
} | ||
return &scope | ||
} |
Oops, something went wrong.