Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions apiClient/policy_pack.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package apiClient

func (client *Client) CreatePolicyPack(input map[string]interface{}) (*PolicyPack, error) {
query := createPolicyPackMutation()
responseData := &PolicyPackResponse{}
variables := map[string]interface{}{
"input": input,
}

// execute api call
if err := client.doRequest(query, variables, responseData); err != nil {
return nil, client.handleCreateError(err, input, "policy pack")
}
return &responseData.PolicyPack, nil
}

func (client *Client) ReadPolicyPack(id string) (*PolicyPack, error) {
query := readPolicyPackQuery(id)
responseData := &PolicyPackResponse{}

// execute api call
if err := client.doRequest(query, nil, responseData); err != nil {
return nil, client.handleReadError(err, id, "smart folder")
}
return &responseData.PolicyPack, nil
}

func (client *Client) UpdatePolicyPack(input map[string]interface{}) (*PolicyPack, error) {
query := updatePolicyPackMutation()
responseData := &PolicyPackResponse{}
variables := map[string]interface{}{
"input": input,
}
// execute api call
if err := client.doRequest(query, variables, responseData); err != nil {
return nil, client.handleUpdateError(err, input, "smart folder")
}
return &responseData.PolicyPack, nil
}
34 changes: 34 additions & 0 deletions apiClient/policy_pack_attachment.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
package apiClient

import (
"fmt"
)

func (client *Client) CreatePolicyPackAttachment(input map[string]interface{}) (*TurbotResourceMetadata, error) {
query := createPolicyPackAttachmentMutation()
responseData := &CreatePolicyPackAttachResponse{}

variables := map[string]interface{}{
"input": input,
}

// execute api call
if err := client.doRequest(query, variables, responseData); err != nil {
return nil, client.handleCreateError(err, input, "policy pack attachment")
}
return &responseData.PolicyPackAttach.Turbot, nil
}

func (client *Client) DeletePolicyPackAttachment(input map[string]interface{}) error {
query := detachPolicyPackAttachmentMutation()
var responseData interface{}

variables := map[string]interface{}{
"input": input,
}
// execute api call
if err := client.doRequest(query, variables, responseData); err != nil {
return fmt.Errorf("error deleting policy pack attachment: %s", err.Error())
}
return nil
}
64 changes: 64 additions & 0 deletions apiClient/queries.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,70 @@ func detachSmartFolderAttachment() string {
}`)
}

// policy pack
func createPolicyPackMutation() string {
return fmt.Sprintf(`mutation CreatePolicyPack($input: CreatePolicyPackInput!) {
policyPack: createPolicyPack(input: $input) {
turbot {
id
parentId
akas
title
}
}
}`)
}

func readPolicyPackQuery(id string) string {
return fmt.Sprintf(`{
policyPack: resource(id:"%s") {
title: get(path:"turbot.title")
description: get(path:"description")
targets: get(path: "targets")
filters: get(path:"filters")
parent: get(path:"turbot.parentId")
turbot: get(path:"turbot")
attachedResources{
items{
turbot: get(path:"turbot")
}
}
}
}`, id)
}

func updatePolicyPackMutation() string {
return fmt.Sprintf(`mutation UpdatePolicyPack($input: UpdatePolicyPackInput!) {
policyPack: updatePolicyPack(input: $input) {
turbot {
id
parentId
akas
}
}
}`)
}

func createPolicyPackAttachmentMutation() string {
return `mutation AttachPolicyPack($input: AttachPolicyPackInput!) {
attachPolicyPacks(input: $input) {
turbot {
id
}
}
}`
}

func detachPolicyPackAttachmentMutation() string {
return `mutation DetachPolicyPack($input: DetachPolicyPackInput!) {
detachPolicyPack: detachPolicyPacks(input: $input) {
turbot {
id
}
}
}`
}

// mod
func installModMutation() string {
return `mutation InstallMod($input: InstallModInput!) {
Expand Down
39 changes: 39 additions & 0 deletions apiClient/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,45 @@ type CreateSmartFolderAttachResponse struct {
}
}

// Policy Pack
type PolicyPackResponse struct {
PolicyPack PolicyPack
}

type PolicyPack struct {
Turbot TurbotResourceMetadata
Title string
Description string
Filters []string
Targets []string
Parent string
AttachedResources struct {
Items []struct {
Turbot TurbotResourceMetadata
}
}
}

// Policy pack attachment
type PolicyPackAttachment struct {
Turbot TurbotResourceMetadata
Title string
Description string
Filters map[string]interface{}
Parent string
}

type PolicyPackByPhase struct {
Phase string `json:"phase"`
Id string `json:"id"`
}

type CreatePolicyPackAttachResponse struct {
PolicyPackAttach struct {
Turbot TurbotResourceMetadata
}
}

// Local directory
type LocalDirectoryResponse struct {
Resource LocalDirectory
Expand Down
1 change: 1 addition & 0 deletions turbot/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ func Provider() terraform.ResourceProvider {
"turbot_google_directory": resourceGoogleDirectory(),
"turbot_grant": resourceTurbotGrant(),
"turbot_grant_activation": resourceTurbotGrantActivation(),
"turbot_guardrail": resourceTurbotGuardrail(),
"turbot_ldap_directory": resourceTurbotLdapDirectory(),
"turbot_local_directory": resourceTurbotLocalDirectory(),
"turbot_local_directory_user": resourceTurbotLocalDirectoryUser(),
Expand Down
177 changes: 177 additions & 0 deletions turbot/resource_turbot_guardrail.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
package turbot

import (
"github.com/hashicorp/terraform/helper/schema"
"github.com/turbot/terraform-provider-turbot/apiClient"
"github.com/turbot/terraform-provider-turbot/errors"
"github.com/turbot/terraform-provider-turbot/helpers"
)

// properties which must be passed to a create/update call
var guardrailProperties = []interface{}{"title", "description", "parent", "filter", "targets", "akas"}

func getGuardrailUpdateProperties() []interface{} {
excludedProperties := []string{"parent"}
return helpers.RemoveProperties(guardrailProperties, excludedProperties)
}

func resourceTurbotGuardrail() *schema.Resource {
return &schema.Resource{
Create: resourceTurbotGuardrailCreate,
Read: resourceTurbotGuardrailRead,
Update: resourceTurbotGuardrailUpdate,
Delete: resourceTurbotGuardrailDelete,
Exists: resourceTurbotGuardrailExists,
Importer: &schema.ResourceImporter{
State: resourceTurbotGuardrailImport,
},
Schema: map[string]*schema.Schema{
//aka of the parent resource
"parent": {
Type: schema.TypeString,
// when doing a diff, the state file will contain the id of the parent but the config contains the aka,
// so we need custom diff code
DiffSuppressFunc: suppressIfAkaMatches("parent_akas"),
Optional: true,
Default: "tmod:@turbot/turbot#/",
},
//when doing a read, fetch the parent akas to use in suppressIfAkaMatches
"parent_akas": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"title": {
Type: schema.TypeString,
Required: true,
},
"description": {
Type: schema.TypeString,
Optional: true,
},
"filter": {
Type: schema.TypeString,
Optional: true,
},
"targets": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"akas": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
DiffSuppressFunc: suppressIfAkaRemoved(),
},
},
}
}

func resourceTurbotGuardrailExists(d *schema.ResourceData, meta interface{}) (b bool, e error) {
client := meta.(*apiClient.Client)
id := d.Id()
return client.ResourceExists(id)
}

func resourceTurbotGuardrailCreate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*apiClient.Client)
// build map of folder properties
input := mapFromResourceData(d, guardrailProperties)

policyPack, err := client.CreatePolicyPack(input)
if err != nil {
return err
}

// assign the id
d.SetId(policyPack.Turbot.Id)
// TODO Remove Read call once schema changes are In.
return resourceTurbotGuardrailRead(d, meta)
}

func resourceTurbotGuardrailUpdate(d *schema.ResourceData, meta interface{}) error {
client := meta.(*apiClient.Client)
id := d.Id()

// build map of folder properties
input := mapFromResourceData(d, getGuardrailUpdateProperties())
input["id"] = id

_, err := client.UpdatePolicyPack(input)
if err != nil {
return err
}
// set 'Read' Properties
// TODO Remove Read call once schema changes are In.
return resourceTurbotGuardrailRead(d, meta)
}

func resourceTurbotGuardrailRead(d *schema.ResourceData, meta interface{}) error {
client := meta.(*apiClient.Client)
id := d.Id()

policyPack, err := client.ReadPolicyPack(id)
if err != nil {
if errors.NotFoundError(err) {
// folder was not found - clear id
d.SetId("")
}
return err
}

// assign results back into ResourceData
// set parent_akas property by loading resource and fetching the akas
if err := storeAkas(policyPack.Turbot.ParentId, "parent_akas", d, meta); err != nil {
return err
}
// NOTE currently turbot accepts array of filters but only uses the first
if len(policyPack.Filters) > 0 {
d.Set("filter", policyPack.Filters[0])
}
d.Set("parent", policyPack.Parent)
d.Set("title", policyPack.Title)
d.Set("description", policyPack.Description)
d.Set("akas", policyPack.Turbot.Akas)

// The "targets" parameter can be provided as either an ID or the URI of the resource.
// However, the query response always returns IDs, which can cause a mismatch between
// the input and the state file. To maintain consistency, the input values are directly
// saved to the state file as-is.
if value, ok := d.GetOk("targets"); ok {
targets := make([]string, len(value.([]interface{})))
for i, target := range value.([]interface{}) {
targets[i] = target.(string)
}
d.Set("targets", targets)
}

return nil
}

func resourceTurbotGuardrailDelete(d *schema.ResourceData, meta interface{}) error {
client := meta.(*apiClient.Client)
id := d.Id()
err := client.DeleteResource(id)
if err != nil {
return err
}

// clear the id to show we have deleted
d.SetId("")

return nil
}

func resourceTurbotGuardrailImport(d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) {
if err := resourceTurbotGuardrailRead(d, meta); err != nil {
return nil, err
}
return []*schema.ResourceData{d}, nil
}
Loading
Loading