From 6d57fd868e096caf7fe07bc90fa701a72c4a5291 Mon Sep 17 00:00:00 2001 From: Gabriel Pereira Date: Thu, 26 Jan 2023 22:22:13 -0300 Subject: [PATCH 1/3] commiting WIP - it will not work yet --- cyral/model_regopolicy_instance.go | 102 +++++ cyral/resource_cyral_regopolicy_instance.go | 413 ++++++++++++++++++++ 2 files changed, 515 insertions(+) create mode 100644 cyral/model_regopolicy_instance.go create mode 100644 cyral/resource_cyral_regopolicy_instance.go diff --git a/cyral/model_regopolicy_instance.go b/cyral/model_regopolicy_instance.go new file mode 100644 index 00000000..376c3916 --- /dev/null +++ b/cyral/model_regopolicy_instance.go @@ -0,0 +1,102 @@ +package cyral + +import ( + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" +) + +type Scope struct { + RepoIds []string `json:"repoIds,omitempty"` +} + +type ChangeInfo_ActorType int32 + +const ( + ChangeInfo_USER ChangeInfo_ActorType = 0 + ChangeInfo_API_CLIENT ChangeInfo_ActorType = 1 +) + +type Category int32 + +const ( + Category_UNKNOWN Category = 0 + Category_SECURITY Category = 1 + Category_GRANT Category = 2 + Category_USER_DEFINED Category = 3 +) + +type ChangeInfo struct { + Actor string `json:"actor,omitempty"` + ActorType ChangeInfo_ActorType `json:"actorType,omitempty"` + Timestamp *timestamppb.Timestamp `json:"timestamp,omitempty"` +} + +type Key struct { + Id string `json:"id,omitempty"` + Category Category `json:"category,omitempty"` +} + +type PolicyInstance struct { + Name string `json:"name,omitempty"` + Description string `json:"description,omitempty"` + TemplateId string `json:"templateId,omitempty"` + Parameters string `json:"parameters,omitempty"` + Enabled bool `json:"enabled,omitempty"` + Scope *Scope `json:"scope,omitempty"` + Tags []string `json:"tags,omitempty"` + LastUpdated *ChangeInfo `json:"lastUpdated,omitempty"` + Created *ChangeInfo `json:"created,omitempty"` +} + +// used for 'data' in requests +type PolicyInstanceDataRequest struct { + Instance *PolicyInstance `json:"policyInstance,omitempty"` + Duration *durationpb.Duration `json:"duration,omitempty"` +} + +type ListPolicyInstancePartial struct { + Key Key `json:"key,omitempty"` + Name string `json:"name,omitempty"` + TemplateId string `json:"templateId,omitempty"` +} + +type InsertPolicyInstanceRequest struct { + Category Category `json:"category,omitempty"` + Data PolicyInstanceDataRequest `json:"data,omitempty"` +} + +type UpdatePolicyInstanceRequest struct { + Key Key `json:"key,omitempty"` + Data PolicyInstanceDataRequest `json:"data,omitempty"` +} + +type DeletePolicyInstanceRequest struct { + Key Key `json:"key,omitempty"` +} + +type ReadPolicyInstanceRequest struct { + Key Key `json:"key,omitempty"` +} + +type ReadPolicyInstancesRequest struct { + Category Category `json:"category,omitempty"` +} + +type InsertPolicyInstanceResponse struct { + Key Key `json:"key,omitempty"` +} + +type UpdatePolicyInstanceResponse struct { +} + +type DeletePolicyInstanceResponse struct { + instance PolicyInstance `json:"instance,omitempty"` +} + +type ReadPolicyInstanceResponse struct { + instance PolicyInstance `json:"instance,omitempty"` +} + +type ReadPolicyInstancesResponse struct { + instances []ListPolicyInstancePartial `json:"instances,omitempty"` +} diff --git a/cyral/resource_cyral_regopolicy_instance.go b/cyral/resource_cyral_regopolicy_instance.go new file mode 100644 index 00000000..291d37d0 --- /dev/null +++ b/cyral/resource_cyral_regopolicy_instance.go @@ -0,0 +1,413 @@ +package cyral + +import ( + "context" + "fmt" + "net/http" + + "github.com/cyralinc/terraform-provider-cyral/client" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "google.golang.org/protobuf/types/known/durationpb" + "google.golang.org/protobuf/types/known/timestamppb" +) + +func (r *InsertPolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { + scope := &Scope{} + for _, scopeObj := range d.Get("scope").([]interface{}) { + scopeMap := scopeObj.(map[string]interface{}) + repoIds := scopeMap["repo_ids"] + for _, repoId := range repoIds.([]interface{}) { + scope.RepoIds = append(scope.RepoIds, repoId.(string)) + } + } + + lastUpdated := &ChangeInfo{} + for _, lastUpdatedObj := range d.Get("last_updated").([]interface{}) { + lastUpdatedMap := lastUpdatedObj.(map[string]interface{}) + actor := lastUpdatedMap["actor"].(string) + actorType := lastUpdatedMap["actor_type"].(int32) + timestamp := lastUpdatedMap["timestamp"].(int64) + lastUpdated.Actor = actor + lastUpdated.ActorType = ChangeInfo_ActorType(actorType) + lastUpdated.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} + } + + created := &ChangeInfo{} + for _, createdObj := range d.Get("created").([]interface{}) { + createdMap := createdObj.(map[string]interface{}) + actor := createdMap["actor"].(string) + actorType := createdMap["actor_type"].(int32) + timestamp := createdMap["timestamp"].(int64) + created.Actor = actor + created.ActorType = ChangeInfo_ActorType(actorType) + created.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} + } + + duration := d.Get("duration").(int64) + + r.Category = d.Get("category").(Category) + r.Data = PolicyInstanceDataRequest{ + Instance: &PolicyInstance{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + TemplateId: d.Get("template_id").(string), + Parameters: d.Get("parameters").(string), + Enabled: d.Get("enabled").(bool), + Scope: scope, + LastUpdated: lastUpdated, + Created: created, + }, + Duration: &durationpb.Duration{Seconds: duration}, + } + return nil +} + +func (r *UpdatePolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { + r.AccessGateway = &AccessGateway{ + BindingId: d.Get(BindingIDKey).(string), + SidecarId: d.Get(SidecarIDKey).(string), + } + return nil +} + +func (r *DeletePolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { + r.AccessGateway = &AccessGateway{ + BindingId: d.Get(BindingIDKey).(string), + SidecarId: d.Get(SidecarIDKey).(string), + } + return nil +} + +func (r *ReadPolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { + r.AccessGateway = &AccessGateway{ + BindingId: d.Get(BindingIDKey).(string), + SidecarId: d.Get(SidecarIDKey).(string), + } + return nil +} + +func (r *InsertPolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { + d.SetId(d.Get(RepositoryIDKey).(string)) + d.Set("name", r.instance.Name) + d.Set("description", r.instance.Description) + d.Set("template_id", r.instance.TemplateId) + d.Set("parameters", r.instance.Parameters) + d.Set("enabled", r.instance.Enabled) + repoIds := r.instance.Scope.RepoIds + scope := map[string]interface{}{ + "repo_ids": repoIds, + } + d.Set("scope", scope) + d.Set("tags", r.instance.Tags) + lastUpdated := map[string]interface{}{ + "actor": r.instance.LastUpdated.Actor, + "actor_type": r.instance.LastUpdated.ActorType, + "timestamp": r.instance.LastUpdated.Timestamp, + } + d.Set("last_updated", lastUpdated) + created := map[string]interface{}{ + "actor": r.instance.Created.Actor, + "actor_type": r.instance.Created.ActorType, + "timestamp": r.instance.Created.Timestamp, + } + d.Set("created", created) + return nil +} + +func (r *UpdatePolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { + d.SetId(d.Get(RepositoryIDKey).(string)) + d.Set("name", r.instance.Name) + d.Set("description", r.instance.Description) + d.Set("template_id", r.instance.TemplateId) + d.Set("parameters", r.instance.Parameters) + d.Set("enabled", r.instance.Enabled) + repoIds := r.instance.Scope.RepoIds + scope := map[string]interface{}{ + "repo_ids": repoIds, + } + d.Set("scope", scope) + d.Set("tags", r.instance.Tags) + lastUpdated := map[string]interface{}{ + "actor": r.instance.LastUpdated.Actor, + "actor_type": r.instance.LastUpdated.ActorType, + "timestamp": r.instance.LastUpdated.Timestamp, + } + d.Set("last_updated", lastUpdated) + created := map[string]interface{}{ + "actor": r.instance.Created.Actor, + "actor_type": r.instance.Created.ActorType, + "timestamp": r.instance.Created.Timestamp, + } + d.Set("created", created) + return nil +} + +func (r *DeletePolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { + d.SetId(d.Get(RepositoryIDKey).(string)) + d.Set("name", r.instance.Name) + d.Set("description", r.instance.Description) + d.Set("template_id", r.instance.TemplateId) + d.Set("parameters", r.instance.Parameters) + d.Set("enabled", r.instance.Enabled) + repoIds := r.instance.Scope.RepoIds + scope := map[string]interface{}{ + "repo_ids": repoIds, + } + d.Set("scope", scope) + d.Set("tags", r.instance.Tags) + lastUpdated := map[string]interface{}{ + "actor": r.instance.LastUpdated.Actor, + "actor_type": r.instance.LastUpdated.ActorType, + "timestamp": r.instance.LastUpdated.Timestamp, + } + d.Set("last_updated", lastUpdated) + created := map[string]interface{}{ + "actor": r.instance.Created.Actor, + "actor_type": r.instance.Created.ActorType, + "timestamp": r.instance.Created.Timestamp, + } + d.Set("created", created) + return nil +} + +func (r *ReadPolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { + d.SetId(d.Get(RepositoryIDKey).(string)) + d.Set("name", r.instance.Name) + d.Set("description", r.instance.Description) + d.Set("template_id", r.instance.TemplateId) + d.Set("parameters", r.instance.Parameters) + d.Set("enabled", r.instance.Enabled) + repoIds := r.instance.Scope.RepoIds + scope := map[string]interface{}{ + "repo_ids": repoIds, + } + d.Set("scope", scope) + d.Set("tags", r.instance.Tags) + lastUpdated := map[string]interface{}{ + "actor": r.instance.LastUpdated.Actor, + "actor_type": r.instance.LastUpdated.ActorType, + "timestamp": r.instance.LastUpdated.Timestamp, + } + d.Set("last_updated", lastUpdated) + created := map[string]interface{}{ + "actor": r.instance.Created.Actor, + "actor_type": r.instance.Created.ActorType, + "timestamp": r.instance.Created.Timestamp, + } + d.Set("created", created) + return nil +} + +// Reading the instance +var ReadRegopolicyInstanceConfig = ResourceOperationConfig{ + Name: "RegopolicyInstanceRead", + HttpMethod: http.MethodGet, + CreateURL: func(d *schema.ResourceData, c *client.Client) string { + category := d.Get("category").(string) + id := d.Get("regopolicy_id").(string) + return fmt.Sprintf("https://%s/v1/regopolicies/instances/%s/%s", c.ControlPlane, category, id) + }, + NewResponseData: func(d *schema.ResourceData) ResponseData { + return &ReadPolicyInstanceResponse{} + }, +} + +func resourceRegopolicyInstance() *schema.Resource { + return &schema.Resource{ + Description: "Manages the regopolicy instances.", + // Creating the instance + CreateContext: CreateResource( + ResourceOperationConfig{ + Name: "RegopolicyInstanceCreate", + HttpMethod: http.MethodPost, + CreateURL: func(d *schema.ResourceData, c *client.Client) string { + category := d.Get("category").(string) + return fmt.Sprintf("https://%s/v1/regopolicies/instances/%s/", c.ControlPlane, category) + }, + // payload to pass + NewResourceData: func() ResourceData { + return &InsertPolicyInstanceRequest{} + }, + // return from API + NewResponseData: func(d *schema.ResourceData) ResponseData { + nameFilter := d.Get("name").(string) + if nameFilter == "" { + return &GetDataLabelsResponse{} + } else { + return &GetDataLabelResponse{} + } + }, + }, + // reading to update terraform values + ReadRegopolicyInstanceConfig, + ), + // Read + ReadContext: ReadResource(ReadRegopolicyInstanceConfig), + UpdateContext: UpdateResource( + ResourceOperationConfig{ + Name: "RegopolicyInstanceUpdate", + HttpMethod: http.MethodPut, + CreateURL: func(d *schema.ResourceData, c *client.Client) string { + category := d.Get("category").(string) + return fmt.Sprintf("https://%s/v1/regopolicies/instances/%s/", c.ControlPlane, category) + }, + // payload to pass + NewResourceData: func() ResourceData { + + }, + // return from API + NewResponseData: func(d *schema.ResourceData) ResponseData { + nameFilter := d.Get("name").(string) + if nameFilter == "" { + return &GetDataLabelsResponse{} + } else { + return &GetDataLabelResponse{} + } + }, + }, + // reading to update terraform values + ReadRegopolicyInstanceConfig, + ), + DeleteContext: DeleteResource( + ResourceOperationConfig{ + Name: "RegopolicyInstanceDelete", + HttpMethod: http.MethodDelete, + CreateURL: func(d *schema.ResourceData, c *client.Client) string { + category := d.Get("category").(string) + id := d.Get("id").(string) + return fmt.Sprintf("https://%s/v1/regopolicies/instances/%s/%s", c.ControlPlane, category, id) + }, + }, + ), + Schema: map[string]*schema.Schema{ + "regopolicy_id": { + Description: "ID of the repository the access gateway is associated with. This is also the " + + "import ID for this resource.", + Type: schema.TypeString, + ForceNew: true, + Required: true, + }, + "category": { + Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Type: schema.TypeString, + Required: true, + }, + "name": { + Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Type: schema.TypeString, + Required: true, + }, + "description": { + Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Type: schema.TypeString, + Required: true, + }, + "template_id": { + Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Type: schema.TypeString, + Required: true, + }, + "parameters": { + Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Type: schema.TypeString, + Required: true, + }, + "enabled": { + Description: "Whether the policy is enabled or not", + Type: schema.TypeBool, + Required: true, + }, + "scope": { + Description: "Object that defines the scope of the policy, i.e. where it is applicable", + Type: schema.TypeSet, + Computed: true, + MaxItems: 1, + Required: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "repo_ids": { + Description: "List of repo ids where the policy is applicable", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + "tags": { + Description: "Tags used to categorize policy instance.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + "last_updated": { + Description: "Classification rules are used by the [Automatic Data Map](https://cyral.com/docs/policy/automatic-datamap) feature to automatically map data locations to labels. Currently, only `PREDEFINED` labels have classification rules.", + Type: schema.TypeSet, + Computed: true, + MaxItems: 1, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actor": { + Description: "Actor identification (e.g. email)", + Type: schema.TypeString, + Computed: true, + }, + "actor_type": { + Description: "Type of actor, if it is user or api", + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Description: "Timestamp for action of updating", + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "created": { + Description: "Classification rules are used by the [Automatic Data Map](https://cyral.com/docs/policy/automatic-datamap) feature to automatically map data locations to labels. Currently, only `PREDEFINED` labels have classification rules.", + Type: schema.TypeSet, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "actor": { + Description: "Actor identification (e.g. email)", + Type: schema.TypeString, + Computed: true, + }, + "actor_type": { + Description: "Type of actor, if it is user or api", + Type: schema.TypeString, + Computed: true, + }, + "timestamp": { + Description: "Timestamp for the action of creating", + Type: schema.TypeString, + Computed: true, + }, + }, + }, + }, + "duration": { + Description: "Duration of the policy instance.", + Type: schema.TypeString, + Required: true, + }, + }, + Importer: &schema.ResourceImporter{ + StateContext: func( + ctx context.Context, + d *schema.ResourceData, + m interface{}, + ) ([]*schema.ResourceData, error) { + d.Set(RepositoryIDKey, d.Id()) + return []*schema.ResourceData{d}, nil + }, + }, + } +} From bdc40581533974101c1b1a5cf78e76de350a4fdb Mon Sep 17 00:00:00 2001 From: Gabriel Pereira Date: Mon, 30 Jan 2023 22:23:00 -0300 Subject: [PATCH 2/3] Add more changes - still need to test --- .../data_source_cyral_regopolicy_instance.go | 109 +++++++++++ cyral/model_regopolicy_instance.go | 13 +- cyral/resource_cyral_regopolicy_instance.go | 174 ++++++++---------- 3 files changed, 192 insertions(+), 104 deletions(-) create mode 100644 cyral/data_source_cyral_regopolicy_instance.go diff --git a/cyral/data_source_cyral_regopolicy_instance.go b/cyral/data_source_cyral_regopolicy_instance.go new file mode 100644 index 00000000..f2516fed --- /dev/null +++ b/cyral/data_source_cyral_regopolicy_instance.go @@ -0,0 +1,109 @@ +package cyral + +import ( + "fmt" + "net/http" + + "github.com/google/uuid" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + + "github.com/cyralinc/terraform-provider-cyral/client" +) + +type GetRegopolicyInstancesResponse struct { + Instances []*PolicyInstance `json:"instances"` +} + +func (resp *GetRegopolicyInstancesResponse) WriteToSchema(d *schema.ResourceData) error { + if err := writeRegopolicyInstancesToDataSourceSchema(resp.Instances, d); err != nil { + return err + } + // creating a new id for data source + d.SetId(uuid.New().String()) + return nil +} + +func writeRegopolicyInstancesToDataSourceSchema(instances []*PolicyInstance, d *schema.ResourceData) error { + var instancesList []interface{} + for _, instance := range instances { + instancesList = append(instancesList, map[string]interface{}{ + "name": instance.Name, + "description": instance.Description, + "template_id": instance.TemplateId, + "tags": instance.TagsAsInterface(), + }) + } + if err := d.Set("regopolicy_instance_list", instancesList); err != nil { + return err + } + return nil +} + +func dataSourceRegopolicyInstanceReadConfig() ResourceOperationConfig { + return ResourceOperationConfig{ + Name: "DatalabelDataSourceRead", + HttpMethod: http.MethodGet, + CreateURL: func(d *schema.ResourceData, c *client.Client) string { + nameFilter := d.Get("name").(string) + typeFilter := d.Get("type").(string) + var pathParams string + if nameFilter != "" { + pathParams = fmt.Sprintf("/%s", nameFilter) + } + queryParams := urlQuery(map[string]string{ + "type": typeFilter, + }) + + return fmt.Sprintf("https://%s/v1/datalabels%s%s", c.ControlPlane, pathParams, queryParams) + }, + NewResponseData: func(d *schema.ResourceData) ResponseData { + nameFilter := d.Get("name").(string) + if nameFilter == "" { + return &GetDataLabelsResponse{} + } else { + return &GetDataLabelResponse{} + } + }, + } +} + +func dataSourceRegopolicyInstance() *schema.Resource { + return &schema.Resource{ + Description: "Retrieve and filter policy instances. See also resource [`cyral_regopolicy`](../resources/regopolicy_instance.md).", + ReadContext: ReadResource(dataSourceDatalabelReadConfig()), + Schema: map[string]*schema.Schema{ + "regopolicy_instance_list": { + Description: "List of existing regopolicy instances satisfying given filter criteria.", + Type: schema.TypeList, + Computed: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + + "name": { + Description: "Name of the policy instance.", + Type: schema.TypeString, + Required: true, + }, + "description": { + Description: "Description for the policy instance.", + Type: schema.TypeString, + Required: true, + }, + "template_id": { + Description: "Template Id on which the instance was based", + Type: schema.TypeString, + Required: true, + }, + "tags": { + Description: "Tags used to categorize policy instance.", + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + }, + }, + }, + }, + }, + } +} diff --git a/cyral/model_regopolicy_instance.go b/cyral/model_regopolicy_instance.go index 376c3916..845f36fe 100644 --- a/cyral/model_regopolicy_instance.go +++ b/cyral/model_regopolicy_instance.go @@ -1,7 +1,6 @@ package cyral import ( - "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -36,6 +35,14 @@ type Key struct { Category Category `json:"category,omitempty"` } +func (pi *PolicyInstance) TagsAsInterface() []interface{} { + var tagIfaces []interface{} + for _, tag := range pi.Tags { + tagIfaces = append(tagIfaces, tag) + } + return tagIfaces +} + type PolicyInstance struct { Name string `json:"name,omitempty"` Description string `json:"description,omitempty"` @@ -50,8 +57,8 @@ type PolicyInstance struct { // used for 'data' in requests type PolicyInstanceDataRequest struct { - Instance *PolicyInstance `json:"policyInstance,omitempty"` - Duration *durationpb.Duration `json:"duration,omitempty"` + Instance *PolicyInstance `json:"policyInstance,omitempty"` + Duration string `json:"duration,omitempty"` } type ListPolicyInstancePartial struct { diff --git a/cyral/resource_cyral_regopolicy_instance.go b/cyral/resource_cyral_regopolicy_instance.go index 291d37d0..80862042 100644 --- a/cyral/resource_cyral_regopolicy_instance.go +++ b/cyral/resource_cyral_regopolicy_instance.go @@ -7,7 +7,6 @@ import ( "github.com/cyralinc/terraform-provider-cyral/client" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "google.golang.org/protobuf/types/known/durationpb" "google.golang.org/protobuf/types/known/timestamppb" ) @@ -43,7 +42,7 @@ func (r *InsertPolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) err created.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} } - duration := d.Get("duration").(int64) + duration := d.Get("duration").(string) r.Category = d.Get("category").(Category) r.Data = PolicyInstanceDataRequest{ @@ -57,93 +56,83 @@ func (r *InsertPolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) err LastUpdated: lastUpdated, Created: created, }, - Duration: &durationpb.Duration{Seconds: duration}, + Duration: duration, } return nil } func (r *UpdatePolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { - r.AccessGateway = &AccessGateway{ - BindingId: d.Get(BindingIDKey).(string), - SidecarId: d.Get(SidecarIDKey).(string), + scope := &Scope{} + for _, scopeObj := range d.Get("scope").([]interface{}) { + scopeMap := scopeObj.(map[string]interface{}) + repoIds := scopeMap["repo_ids"] + for _, repoId := range repoIds.([]interface{}) { + scope.RepoIds = append(scope.RepoIds, repoId.(string)) + } + } + + lastUpdated := &ChangeInfo{} + for _, lastUpdatedObj := range d.Get("last_updated").([]interface{}) { + lastUpdatedMap := lastUpdatedObj.(map[string]interface{}) + actor := lastUpdatedMap["actor"].(string) + actorType := lastUpdatedMap["actor_type"].(int32) + timestamp := lastUpdatedMap["timestamp"].(int64) + lastUpdated.Actor = actor + lastUpdated.ActorType = ChangeInfo_ActorType(actorType) + lastUpdated.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} + } + + created := &ChangeInfo{} + for _, createdObj := range d.Get("created").([]interface{}) { + createdMap := createdObj.(map[string]interface{}) + actor := createdMap["actor"].(string) + actorType := createdMap["actor_type"].(int32) + timestamp := createdMap["timestamp"].(int64) + created.Actor = actor + created.ActorType = ChangeInfo_ActorType(actorType) + created.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} + } + + duration := d.Get("duration").(string) + + r.Data = PolicyInstanceDataRequest{ + Instance: &PolicyInstance{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + TemplateId: d.Get("template_id").(string), + Parameters: d.Get("parameters").(string), + Enabled: d.Get("enabled").(bool), + Scope: scope, + LastUpdated: lastUpdated, + Created: created, + }, + Duration: duration, } return nil } func (r *DeletePolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { - r.AccessGateway = &AccessGateway{ - BindingId: d.Get(BindingIDKey).(string), - SidecarId: d.Get(SidecarIDKey).(string), - } + r.Key.Id = d.Get("regopolicy_id").(string) + r.Key.Category = d.Get("category").(Category) return nil } func (r *ReadPolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { - r.AccessGateway = &AccessGateway{ - BindingId: d.Get(BindingIDKey).(string), - SidecarId: d.Get(SidecarIDKey).(string), - } + r.Key.Id = d.Get("regopolicy_id").(string) + r.Key.Category = d.Get("category").(Category) return nil } func (r *InsertPolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { - d.SetId(d.Get(RepositoryIDKey).(string)) - d.Set("name", r.instance.Name) - d.Set("description", r.instance.Description) - d.Set("template_id", r.instance.TemplateId) - d.Set("parameters", r.instance.Parameters) - d.Set("enabled", r.instance.Enabled) - repoIds := r.instance.Scope.RepoIds - scope := map[string]interface{}{ - "repo_ids": repoIds, - } - d.Set("scope", scope) - d.Set("tags", r.instance.Tags) - lastUpdated := map[string]interface{}{ - "actor": r.instance.LastUpdated.Actor, - "actor_type": r.instance.LastUpdated.ActorType, - "timestamp": r.instance.LastUpdated.Timestamp, - } - d.Set("last_updated", lastUpdated) - created := map[string]interface{}{ - "actor": r.instance.Created.Actor, - "actor_type": r.instance.Created.ActorType, - "timestamp": r.instance.Created.Timestamp, - } - d.Set("created", created) - return nil -} - -func (r *UpdatePolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { - d.SetId(d.Get(RepositoryIDKey).(string)) - d.Set("name", r.instance.Name) - d.Set("description", r.instance.Description) - d.Set("template_id", r.instance.TemplateId) - d.Set("parameters", r.instance.Parameters) - d.Set("enabled", r.instance.Enabled) - repoIds := r.instance.Scope.RepoIds - scope := map[string]interface{}{ - "repo_ids": repoIds, - } - d.Set("scope", scope) - d.Set("tags", r.instance.Tags) - lastUpdated := map[string]interface{}{ - "actor": r.instance.LastUpdated.Actor, - "actor_type": r.instance.LastUpdated.ActorType, - "timestamp": r.instance.LastUpdated.Timestamp, - } - d.Set("last_updated", lastUpdated) - created := map[string]interface{}{ - "actor": r.instance.Created.Actor, - "actor_type": r.instance.Created.ActorType, - "timestamp": r.instance.Created.Timestamp, - } - d.Set("created", created) + regoPolicyId := r.Key.Id + regoPolicyCategory := r.Key.Category + d.SetId(regoPolicyId + "/" + string(regoPolicyCategory)) + d.Set("regopolicy_id", regoPolicyId) + d.Set("category", regoPolicyCategory) return nil } func (r *DeletePolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { - d.SetId(d.Get(RepositoryIDKey).(string)) d.Set("name", r.instance.Name) d.Set("description", r.instance.Description) d.Set("template_id", r.instance.TemplateId) @@ -171,7 +160,6 @@ func (r *DeletePolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) err } func (r *ReadPolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { - d.SetId(d.Get(RepositoryIDKey).(string)) d.Set("name", r.instance.Name) d.Set("description", r.instance.Description) d.Set("template_id", r.instance.TemplateId) @@ -222,7 +210,7 @@ func resourceRegopolicyInstance() *schema.Resource { HttpMethod: http.MethodPost, CreateURL: func(d *schema.ResourceData, c *client.Client) string { category := d.Get("category").(string) - return fmt.Sprintf("https://%s/v1/regopolicies/instances/%s/", c.ControlPlane, category) + return fmt.Sprintf("https://%s/v1/regopolicies/instances/%s", c.ControlPlane, category) }, // payload to pass NewResourceData: func() ResourceData { @@ -230,12 +218,7 @@ func resourceRegopolicyInstance() *schema.Resource { }, // return from API NewResponseData: func(d *schema.ResourceData) ResponseData { - nameFilter := d.Get("name").(string) - if nameFilter == "" { - return &GetDataLabelsResponse{} - } else { - return &GetDataLabelResponse{} - } + return &InsertPolicyInstanceResponse{} }, }, // reading to update terraform values @@ -249,20 +232,12 @@ func resourceRegopolicyInstance() *schema.Resource { HttpMethod: http.MethodPut, CreateURL: func(d *schema.ResourceData, c *client.Client) string { category := d.Get("category").(string) - return fmt.Sprintf("https://%s/v1/regopolicies/instances/%s/", c.ControlPlane, category) + id := d.Get("regopolicy_id").(string) + return fmt.Sprintf("https://%s/v1/regopolicies/instances/%s/%s", c.ControlPlane, category, id) }, // payload to pass NewResourceData: func() ResourceData { - - }, - // return from API - NewResponseData: func(d *schema.ResourceData) ResponseData { - nameFilter := d.Get("name").(string) - if nameFilter == "" { - return &GetDataLabelsResponse{} - } else { - return &GetDataLabelResponse{} - } + return &UpdatePolicyInstanceRequest{} }, }, // reading to update terraform values @@ -281,34 +256,34 @@ func resourceRegopolicyInstance() *schema.Resource { ), Schema: map[string]*schema.Schema{ "regopolicy_id": { - Description: "ID of the repository the access gateway is associated with. This is also the " + - "import ID for this resource.", - Type: schema.TypeString, - ForceNew: true, - Required: true, + Description: "ID for the policy instance.", + Type: schema.TypeString, + ForceNew: true, + Required: true, }, "category": { - Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Description: "Category of the policy instance.", Type: schema.TypeString, + ForceNew: true, Required: true, }, "name": { - Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Description: "Name of the policy instance.", Type: schema.TypeString, Required: true, }, "description": { - Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Description: "Description for the policy instance.", Type: schema.TypeString, Required: true, }, "template_id": { - Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Description: "Template Id on which the instance was based", Type: schema.TypeString, Required: true, }, "parameters": { - Description: "ID of the sidecar that will be set as the access gateway for the given repository.", + Description: "Parameters for the policy instance (matches the template parameter schema)", Type: schema.TypeString, Required: true, }, @@ -320,7 +295,6 @@ func resourceRegopolicyInstance() *schema.Resource { "scope": { Description: "Object that defines the scope of the policy, i.e. where it is applicable", Type: schema.TypeSet, - Computed: true, MaxItems: 1, Required: true, Elem: &schema.Resource{ @@ -328,7 +302,6 @@ func resourceRegopolicyInstance() *schema.Resource { "repo_ids": { Description: "List of repo ids where the policy is applicable", Type: schema.TypeList, - Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, @@ -339,13 +312,12 @@ func resourceRegopolicyInstance() *schema.Resource { "tags": { Description: "Tags used to categorize policy instance.", Type: schema.TypeList, - Computed: true, Elem: &schema.Schema{ Type: schema.TypeString, }, }, "last_updated": { - Description: "Classification rules are used by the [Automatic Data Map](https://cyral.com/docs/policy/automatic-datamap) feature to automatically map data locations to labels. Currently, only `PREDEFINED` labels have classification rules.", + Description: "Object that defines the actor and the time when the instance last update happened.", Type: schema.TypeSet, Computed: true, MaxItems: 1, @@ -370,7 +342,7 @@ func resourceRegopolicyInstance() *schema.Resource { }, }, "created": { - Description: "Classification rules are used by the [Automatic Data Map](https://cyral.com/docs/policy/automatic-datamap) feature to automatically map data locations to labels. Currently, only `PREDEFINED` labels have classification rules.", + Description: "Object that defines the actor and the time when the instance creation happened.", Type: schema.TypeSet, Computed: true, Elem: &schema.Resource{ From 6e79ba9b665db755953d51e3690557dd7f0f94df Mon Sep 17 00:00:00 2001 From: Gabriel Pereira Date: Fri, 17 Feb 2023 20:27:57 -0300 Subject: [PATCH 3/3] WIP - changing computers --- .../data_source_cyral_regopolicy_instance.go | 1 + cyral/model_regopolicy_instance.go | 67 ++++--- cyral/provider.go | 2 + cyral/resource_cyral_regopolicy_instance.go | 188 ++++++++---------- docs/resources/regopolicy_instance.md | 38 ++++ 5 files changed, 156 insertions(+), 140 deletions(-) create mode 100644 docs/resources/regopolicy_instance.md diff --git a/cyral/data_source_cyral_regopolicy_instance.go b/cyral/data_source_cyral_regopolicy_instance.go index f2516fed..df9f013e 100644 --- a/cyral/data_source_cyral_regopolicy_instance.go +++ b/cyral/data_source_cyral_regopolicy_instance.go @@ -100,6 +100,7 @@ func dataSourceRegopolicyInstance() *schema.Resource { Elem: &schema.Schema{ Type: schema.TypeString, }, + Optional: true, }, }, }, diff --git a/cyral/model_regopolicy_instance.go b/cyral/model_regopolicy_instance.go index 845f36fe..d7b23310 100644 --- a/cyral/model_regopolicy_instance.go +++ b/cyral/model_regopolicy_instance.go @@ -8,31 +8,43 @@ type Scope struct { RepoIds []string `json:"repoIds,omitempty"` } -type ChangeInfo_ActorType int32 - const ( - ChangeInfo_USER ChangeInfo_ActorType = 0 - ChangeInfo_API_CLIENT ChangeInfo_ActorType = 1 + actorUser = "USER" + actorApiClient = "API_CLIENT" ) -type Category int32 +func actorTypes() []string { + return []string{ + actorUser, + actorApiClient, + } +} const ( - Category_UNKNOWN Category = 0 - Category_SECURITY Category = 1 - Category_GRANT Category = 2 - Category_USER_DEFINED Category = 3 + categoryTypeUnknown = "UNKNOWN" + categoryTypePredefined = "SECURITY" + categoryTypeCustom = "GRANT" + categoryUserDefined = "USER_DEFINED" ) +func categoryTypes() []string { + return []string{ + categoryTypeUnknown, + categoryTypePredefined, + categoryTypeCustom, + categoryUserDefined, + } +} + type ChangeInfo struct { Actor string `json:"actor,omitempty"` - ActorType ChangeInfo_ActorType `json:"actorType,omitempty"` + ActorType string `json:"actorType,omitempty"` Timestamp *timestamppb.Timestamp `json:"timestamp,omitempty"` } type Key struct { - Id string `json:"id,omitempty"` - Category Category `json:"category,omitempty"` + Id string `json:"id,omitempty"` + Category string `json:"category,omitempty"` } func (pi *PolicyInstance) TagsAsInterface() []interface{} { @@ -57,7 +69,7 @@ type PolicyInstance struct { // used for 'data' in requests type PolicyInstanceDataRequest struct { - Instance *PolicyInstance `json:"policyInstance,omitempty"` + Instance *PolicyInstance `json:"instance,omitempty"` Duration string `json:"duration,omitempty"` } @@ -67,43 +79,38 @@ type ListPolicyInstancePartial struct { TemplateId string `json:"templateId,omitempty"` } -type InsertPolicyInstanceRequest struct { - Category Category `json:"category,omitempty"` - Data PolicyInstanceDataRequest `json:"data,omitempty"` -} +type InsertPolicyInstanceRequest PolicyInstanceDataRequest -type UpdatePolicyInstanceRequest struct { - Key Key `json:"key,omitempty"` - Data PolicyInstanceDataRequest `json:"data,omitempty"` -} +type UpdatePolicyInstanceRequest PolicyInstanceDataRequest type DeletePolicyInstanceRequest struct { - Key Key `json:"key,omitempty"` + Id string `json:"id,omitempty"` + Category string `json:"category,omitempty"` } type ReadPolicyInstanceRequest struct { - Key Key `json:"key,omitempty"` + Id string `json:"id,omitempty"` + Category string `json:"category,omitempty"` } type ReadPolicyInstancesRequest struct { - Category Category `json:"category,omitempty"` + Category string `json:"category,omitempty"` } type InsertPolicyInstanceResponse struct { - Key Key `json:"key,omitempty"` + Id string `json:"id,omitempty"` + Category string `json:"category,omitempty"` } type UpdatePolicyInstanceResponse struct { } type DeletePolicyInstanceResponse struct { - instance PolicyInstance `json:"instance,omitempty"` + Instance PolicyInstance `json:"instance,omitempty"` } -type ReadPolicyInstanceResponse struct { - instance PolicyInstance `json:"instance,omitempty"` -} +type ReadPolicyInstanceResponse PolicyInstance type ReadPolicyInstancesResponse struct { - instances []ListPolicyInstancePartial `json:"instances,omitempty"` + Instances []ListPolicyInstancePartial `json:"instances,omitempty"` } diff --git a/cyral/provider.go b/cyral/provider.go index 8590a676..9f956302 100644 --- a/cyral/provider.go +++ b/cyral/provider.go @@ -81,6 +81,7 @@ func Provider() *schema.Provider { "cyral_sidecar_cft_template": dataSourceSidecarCftTemplate(), "cyral_sidecar_id": dataSourceSidecarID(), "cyral_sidecar_instance_ids": dataSourceSidecarInstanceIDs(), + "cyral_regopolicy_instance": dataSourceRegopolicyInstance(), }, ResourcesMap: map[string]*schema.Resource{ @@ -106,6 +107,7 @@ func Provider() *schema.Provider { "cyral_integration_sumo_logic": resourceIntegrationSumoLogic(), "cyral_policy": resourcePolicy(), "cyral_policy_rule": resourcePolicyRule(), + "cyral_regopolicy_instance": resourceRegopolicyInstance(), "cyral_repository": resourceRepository(), "cyral_repository_binding": resourceRepositoryBinding(), "cyral_repository_conf_analysis": resourceRepositoryConfAnalysis(), diff --git a/cyral/resource_cyral_regopolicy_instance.go b/cyral/resource_cyral_regopolicy_instance.go index 80862042..125c6dd9 100644 --- a/cyral/resource_cyral_regopolicy_instance.go +++ b/cyral/resource_cyral_regopolicy_instance.go @@ -7,12 +7,14 @@ import ( "github.com/cyralinc/terraform-provider-cyral/client" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" "google.golang.org/protobuf/types/known/timestamppb" ) +// mand func (r *InsertPolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { scope := &Scope{} - for _, scopeObj := range d.Get("scope").([]interface{}) { + for _, scopeObj := range d.Get("scope").(*schema.Set).List() { scopeMap := scopeObj.(map[string]interface{}) repoIds := scopeMap["repo_ids"] for _, repoId := range repoIds.([]interface{}) { @@ -21,46 +23,44 @@ func (r *InsertPolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) err } lastUpdated := &ChangeInfo{} - for _, lastUpdatedObj := range d.Get("last_updated").([]interface{}) { + for _, lastUpdatedObj := range d.Get("last_updated").(*schema.Set).List() { lastUpdatedMap := lastUpdatedObj.(map[string]interface{}) actor := lastUpdatedMap["actor"].(string) - actorType := lastUpdatedMap["actor_type"].(int32) + actorType := lastUpdatedMap["actor_type"].(string) timestamp := lastUpdatedMap["timestamp"].(int64) lastUpdated.Actor = actor - lastUpdated.ActorType = ChangeInfo_ActorType(actorType) + lastUpdated.ActorType = actorType lastUpdated.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} } created := &ChangeInfo{} - for _, createdObj := range d.Get("created").([]interface{}) { + for _, createdObj := range d.Get("created").(*schema.Set).List() { createdMap := createdObj.(map[string]interface{}) actor := createdMap["actor"].(string) - actorType := createdMap["actor_type"].(int32) + actorType := createdMap["actor_type"].(string) timestamp := createdMap["timestamp"].(int64) created.Actor = actor - created.ActorType = ChangeInfo_ActorType(actorType) + created.ActorType = actorType created.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} } duration := d.Get("duration").(string) - r.Category = d.Get("category").(Category) - r.Data = PolicyInstanceDataRequest{ - Instance: &PolicyInstance{ - Name: d.Get("name").(string), - Description: d.Get("description").(string), - TemplateId: d.Get("template_id").(string), - Parameters: d.Get("parameters").(string), - Enabled: d.Get("enabled").(bool), - Scope: scope, - LastUpdated: lastUpdated, - Created: created, - }, - Duration: duration, + r.Instance = &PolicyInstance{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + TemplateId: d.Get("template_id").(string), + Parameters: d.Get("parameters").(string), + Enabled: d.Get("enabled").(bool), + Scope: scope, + LastUpdated: lastUpdated, + Created: created, } + r.Duration = duration return nil } +// mand func (r *UpdatePolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { scope := &Scope{} for _, scopeObj := range d.Get("scope").([]interface{}) { @@ -75,10 +75,10 @@ func (r *UpdatePolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) err for _, lastUpdatedObj := range d.Get("last_updated").([]interface{}) { lastUpdatedMap := lastUpdatedObj.(map[string]interface{}) actor := lastUpdatedMap["actor"].(string) - actorType := lastUpdatedMap["actor_type"].(int32) + actorType := lastUpdatedMap["actor_type"].(string) timestamp := lastUpdatedMap["timestamp"].(int64) lastUpdated.Actor = actor - lastUpdated.ActorType = ChangeInfo_ActorType(actorType) + lastUpdated.ActorType = actorType lastUpdated.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} } @@ -86,101 +86,65 @@ func (r *UpdatePolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) err for _, createdObj := range d.Get("created").([]interface{}) { createdMap := createdObj.(map[string]interface{}) actor := createdMap["actor"].(string) - actorType := createdMap["actor_type"].(int32) + actorType := createdMap["actor_type"].(string) timestamp := createdMap["timestamp"].(int64) created.Actor = actor - created.ActorType = ChangeInfo_ActorType(actorType) + created.ActorType = actorType created.Timestamp = ×tamppb.Timestamp{Seconds: timestamp} } duration := d.Get("duration").(string) - r.Data = PolicyInstanceDataRequest{ - Instance: &PolicyInstance{ - Name: d.Get("name").(string), - Description: d.Get("description").(string), - TemplateId: d.Get("template_id").(string), - Parameters: d.Get("parameters").(string), - Enabled: d.Get("enabled").(bool), - Scope: scope, - LastUpdated: lastUpdated, - Created: created, - }, - Duration: duration, + r.Instance = &PolicyInstance{ + Name: d.Get("name").(string), + Description: d.Get("description").(string), + TemplateId: d.Get("template_id").(string), + Parameters: d.Get("parameters").(string), + Enabled: d.Get("enabled").(bool), + Scope: scope, + LastUpdated: lastUpdated, + Created: created, } - return nil -} - -func (r *DeletePolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { - r.Key.Id = d.Get("regopolicy_id").(string) - r.Key.Category = d.Get("category").(Category) - return nil -} + r.Duration = duration -func (r *ReadPolicyInstanceRequest) ReadFromSchema(d *schema.ResourceData) error { - r.Key.Id = d.Get("regopolicy_id").(string) - r.Key.Category = d.Get("category").(Category) return nil } +// mand func (r *InsertPolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { - regoPolicyId := r.Key.Id - regoPolicyCategory := r.Key.Category - d.SetId(regoPolicyId + "/" + string(regoPolicyCategory)) + regoPolicyId := r.Id + regoPolicyCategory := r.Category + d.SetId(marshalComposedID([]string{regoPolicyId, regoPolicyCategory}, "/")) d.Set("regopolicy_id", regoPolicyId) d.Set("category", regoPolicyCategory) return nil } -func (r *DeletePolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { - d.Set("name", r.instance.Name) - d.Set("description", r.instance.Description) - d.Set("template_id", r.instance.TemplateId) - d.Set("parameters", r.instance.Parameters) - d.Set("enabled", r.instance.Enabled) - repoIds := r.instance.Scope.RepoIds - scope := map[string]interface{}{ - "repo_ids": repoIds, - } - d.Set("scope", scope) - d.Set("tags", r.instance.Tags) - lastUpdated := map[string]interface{}{ - "actor": r.instance.LastUpdated.Actor, - "actor_type": r.instance.LastUpdated.ActorType, - "timestamp": r.instance.LastUpdated.Timestamp, - } - d.Set("last_updated", lastUpdated) - created := map[string]interface{}{ - "actor": r.instance.Created.Actor, - "actor_type": r.instance.Created.ActorType, - "timestamp": r.instance.Created.Timestamp, - } - d.Set("created", created) - return nil -} - +// mand func (r *ReadPolicyInstanceResponse) WriteToSchema(d *schema.ResourceData) error { - d.Set("name", r.instance.Name) - d.Set("description", r.instance.Description) - d.Set("template_id", r.instance.TemplateId) - d.Set("parameters", r.instance.Parameters) - d.Set("enabled", r.instance.Enabled) - repoIds := r.instance.Scope.RepoIds - scope := map[string]interface{}{ - "repo_ids": repoIds, + d.Set("name", r.Name) + d.Set("description", r.Description) + d.Set("template_id", r.TemplateId) + d.Set("parameters", r.Parameters) + d.Set("enabled", r.Enabled) + if r.Scope != nil { + repoIds := r.Scope.RepoIds + scope := map[string]interface{}{ + "repo_ids": repoIds, + } + d.Set("scope", scope) } - d.Set("scope", scope) - d.Set("tags", r.instance.Tags) + d.Set("tags", r.Tags) lastUpdated := map[string]interface{}{ - "actor": r.instance.LastUpdated.Actor, - "actor_type": r.instance.LastUpdated.ActorType, - "timestamp": r.instance.LastUpdated.Timestamp, + "actor": r.LastUpdated.Actor, + "actor_type": r.LastUpdated.ActorType, + "timestamp": r.LastUpdated.Timestamp, } d.Set("last_updated", lastUpdated) created := map[string]interface{}{ - "actor": r.instance.Created.Actor, - "actor_type": r.instance.Created.ActorType, - "timestamp": r.instance.Created.Timestamp, + "actor": r.Created.Actor, + "actor_type": r.Created.ActorType, + "timestamp": r.Created.Timestamp, } d.Set("created", created) return nil @@ -259,13 +223,14 @@ func resourceRegopolicyInstance() *schema.Resource { Description: "ID for the policy instance.", Type: schema.TypeString, ForceNew: true, - Required: true, + Computed: true, }, "category": { - Description: "Category of the policy instance.", - Type: schema.TypeString, - ForceNew: true, - Required: true, + Description: "Category of the policy instance.", + Type: schema.TypeString, + ForceNew: true, + Required: true, + ValidateFunc: validation.StringInSlice(append(categoryTypes(), ""), false), }, "name": { Description: "Name of the policy instance.", @@ -275,7 +240,7 @@ func resourceRegopolicyInstance() *schema.Resource { "description": { Description: "Description for the policy instance.", Type: schema.TypeString, - Required: true, + Optional: true, }, "template_id": { Description: "Template Id on which the instance was based", @@ -285,18 +250,18 @@ func resourceRegopolicyInstance() *schema.Resource { "parameters": { Description: "Parameters for the policy instance (matches the template parameter schema)", Type: schema.TypeString, - Required: true, + Optional: true, }, "enabled": { Description: "Whether the policy is enabled or not", Type: schema.TypeBool, - Required: true, + Optional: true, }, "scope": { Description: "Object that defines the scope of the policy, i.e. where it is applicable", Type: schema.TypeSet, MaxItems: 1, - Required: true, + Optional: true, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "repo_ids": { @@ -305,6 +270,7 @@ func resourceRegopolicyInstance() *schema.Resource { Elem: &schema.Schema{ Type: schema.TypeString, }, + Optional: true, }, }, }, @@ -315,12 +281,12 @@ func resourceRegopolicyInstance() *schema.Resource { Elem: &schema.Schema{ Type: schema.TypeString, }, + Optional: true, }, "last_updated": { Description: "Object that defines the actor and the time when the instance last update happened.", Type: schema.TypeSet, Computed: true, - MaxItems: 1, Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "actor": { @@ -329,9 +295,10 @@ func resourceRegopolicyInstance() *schema.Resource { Computed: true, }, "actor_type": { - Description: "Type of actor, if it is user or api", - Type: schema.TypeString, - Computed: true, + Description: "Type of actor, if it is user or api", + Type: schema.TypeString, + Computed: true, + ValidateFunc: validation.StringInSlice(append(actorTypes(), ""), false), }, "timestamp": { Description: "Timestamp for action of updating", @@ -353,9 +320,10 @@ func resourceRegopolicyInstance() *schema.Resource { Computed: true, }, "actor_type": { - Description: "Type of actor, if it is user or api", - Type: schema.TypeString, - Computed: true, + Description: "Type of actor, if it is user or api", + Type: schema.TypeString, + Computed: true, + ValidateFunc: validation.StringInSlice(append(actorTypes(), ""), false), }, "timestamp": { Description: "Timestamp for the action of creating", @@ -368,7 +336,7 @@ func resourceRegopolicyInstance() *schema.Resource { "duration": { Description: "Duration of the policy instance.", Type: schema.TypeString, - Required: true, + Optional: true, }, }, Importer: &schema.ResourceImporter{ diff --git a/docs/resources/regopolicy_instance.md b/docs/resources/regopolicy_instance.md new file mode 100644 index 00000000..478bc1ee --- /dev/null +++ b/docs/resources/regopolicy_instance.md @@ -0,0 +1,38 @@ +--- +# generated by https://github.com/hashicorp/terraform-plugin-docs +page_title: "cyral_datalabel Resource - cyral" +subcategory: "" +description: |- + Manages data labels. Data labels are part of the Cyral Data Map https://cyral.com/docs/policy/datamap. +--- + +# cyral_datalabel (Resource) + +Manages data labels. Data labels are part of the Cyral [Data Map](https://cyral.com/docs/policy/datamap). + +## Example Usage + +```terraform +resource "cyral_datalabel" "NAME" { + name = "NAME" + description = "Customer name" + tags = ["PII", "SENSITIVE"] +} +``` + + + +## Schema + +### Required + +- `name` (String) Name of the data label. + +### Optional + +- `description` (String) Description of the data label. +- `tags` (List of String) Tags that can be used to categorize data labels. + +### Read-Only + +- `id` (String) The ID of this resource.