Skip to content

Commit

Permalink
Add permission resources (#91)
Browse files Browse the repository at this point in the history
  • Loading branch information
JakeNeyer authored Mar 9, 2023
1 parent 7de1ac1 commit 4a6b400
Show file tree
Hide file tree
Showing 21 changed files with 1,040 additions and 76 deletions.
3 changes: 1 addition & 2 deletions GNUmakefile
Original file line number Diff line number Diff line change
@@ -1,12 +1,11 @@
POLYTOMIC_DEPLOYMENT_URL ?= app.polytomic-local.com:8443
POLYTOMIC_DEPLOYMENT_KEY ?= secret-key

default: testacc

# Run acceptance tests
.PHONY: testacc
testacc:
POLYTOMIC_DEPLOYMENT_URL=$(POLYTOMIC_DEPLOYMENT_URL) POLYTOMIC_DEPLOYMENT_KEY=$(POLYTOMIC_DEPLOYMENT_KEY) TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m
POLYTOMIC_DEPLOYMENT_URL=$(POLYTOMIC_DEPLOYMENT_URL) TF_ACC=1 go test ./... -v $(TESTARGS) -timeout 120m


.PHONY: dev
Expand Down
2 changes: 2 additions & 0 deletions cli/cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,10 @@ func newRootCmd(version string) *cobra.Command {
var output string
runCmd.PersistentFlags().StringVar(&output, "output", ".", "Output directory for generated files (defaults to current directory)")
runCmd.PersistentFlags().Bool("replace", false, "Replace existing files")
runCmd.PersistentFlags().Bool("include-permissions", false, "Include permission resources")
viper.BindPFlag("output", runCmd.PersistentFlags().Lookup("output"))
viper.BindPFlag("replace", runCmd.PersistentFlags().Lookup("replace"))
viper.BindPFlag("include-permissions", runCmd.PersistentFlags().Lookup("include-permissions"))

// Register commands
rootCmd.AddCommand(runCmd)
Expand Down
3 changes: 2 additions & 1 deletion cli/cmd/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ var runCmd = &cobra.Command{
apiKey := viper.GetString("api-key")
path := viper.GetString("output")
replace := viper.GetBool("replace")
includePermissions := viper.GetBool("include-permissions")

importer.Init(url, apiKey, path, replace)
importer.Init(url, apiKey, path, replace, includePermissions)
},
}
62 changes: 62 additions & 0 deletions docs/resources/policy.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
---
# generated by https://github.com/fbreckle/terraform-plugin-docs
page_title: "polytomic_policy Resource - terraform-provider-polytomic"
subcategory: "Organizations"
description: |-
A policy in a Polytomic organization
---

# polytomic_policy (Resource)

A policy in a Polytomic organization

## Example Usage

```terraform
resource "polytomic_policy" "example" {
name = "Terraform role"
policy_actions = [
{
action = "create"
role_ids = [
polytomic_role.example.id
]
},
{
action = "delete"
role_ids = [
polytomic_role.example.id
]
},
]
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String)

### Optional

- `organization` (String) Organization ID
- `policy_actions` (Attributes Set) Policy actions (see [below for nested schema](#nestedatt--policy_actions))

### Read-Only

- `id` (String) The ID of this resource.

<a id="nestedatt--policy_actions"></a>
### Nested Schema for `policy_actions`

Required:

- `action` (String) Action

Optional:

- `role_ids` (Set of String) Role IDs


36 changes: 36 additions & 0 deletions docs/resources/role.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
---
# generated by https://github.com/fbreckle/terraform-plugin-docs
page_title: "polytomic_role Resource - terraform-provider-polytomic"
subcategory: "Organizations"
description: |-
A role in a Polytomic organization
---

# polytomic_role (Resource)

A role in a Polytomic organization

## Example Usage

```terraform
resource "polytomic_role" "example" {
name = "Terraform role"
}
```

<!-- schema generated by tfplugindocs -->
## Schema

### Required

- `name` (String)

### Optional

- `organization` (String) Organization ID

### Read-Only

- `id` (String) The ID of this resource.


17 changes: 17 additions & 0 deletions examples/resources/polytomic_policy/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
resource "polytomic_policy" "example" {
name = "Terraform role"
policy_actions = [
{
action = "create"
role_ids = [
polytomic_role.example.id
]
},
{
action = "delete"
role_ids = [
polytomic_role.example.id
]
},
]
}
3 changes: 3 additions & 0 deletions examples/resources/polytomic_role/resource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
resource "polytomic_role" "example" {
name = "Terraform role"
}
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ require (
github.com/hashicorp/terraform-plugin-log v0.8.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.25.0
github.com/mitchellh/mapstructure v1.5.0
github.com/polytomic/polytomic-go v0.0.0-20230224215215-d1563076f476
github.com/polytomic/polytomic-go v0.0.0-20230308205457-3e0a5ade2f59
github.com/rs/zerolog v1.29.0
github.com/spf13/cobra v1.6.1
github.com/spf13/viper v1.15.0
Expand Down Expand Up @@ -74,7 +74,7 @@ require (
github.com/subosito/gotenv v1.4.2 // indirect
github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.1 // indirect
github.com/vmihailenco/tagparser v0.1.2 // indirect
golang.org/x/crypto v0.6.0 // indirect
golang.org/x/mod v0.7.0 // indirect
golang.org/x/net v0.6.0 // indirect
Expand Down
7 changes: 4 additions & 3 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -299,8 +299,8 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qRg=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/polytomic/polytomic-go v0.0.0-20230224215215-d1563076f476 h1:11enc89C8zq4mYoeDxUxoVY1jrhGcIrvbFYQhiUAwy0=
github.com/polytomic/polytomic-go v0.0.0-20230224215215-d1563076f476/go.mod h1:OYSOoZCtLFAW6hCf5YGWGXuoX6RgYAd49QEV7v7QLvo=
github.com/polytomic/polytomic-go v0.0.0-20230308205457-3e0a5ade2f59 h1:XJUlgDX6IN5eKYnDmd503lw+8tqYnbJMtqy4kMjJdw0=
github.com/polytomic/polytomic-go v0.0.0-20230308205457-3e0a5ade2f59/go.mod h1:OYSOoZCtLFAW6hCf5YGWGXuoX6RgYAd49QEV7v7QLvo=
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
Expand Down Expand Up @@ -355,8 +355,9 @@ github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaU
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/vmihailenco/tagparser v0.1.2 h1:gnjoVuB/kljJ5wICEEOpx98oXMWPLj22G67Vbd1qPqc=
github.com/vmihailenco/tagparser v0.1.2/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
14 changes: 12 additions & 2 deletions importer/formatter.go
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,18 @@ func typeConverter(value any) cty.Value {
config[k] = typeConverter(v)
case map[string]string:
config[k] = typeConverter(v)
case []string:
if len(v) == 0 {
continue
}
vals := make([]cty.Value, 0)
for _, v := range v {
vals = append(vals, cty.StringVal(v))
}
if len(vals) == 0 {
continue
}
config[k] = cty.ListVal(vals)
case []any:
if len(v) == 0 {
continue
Expand All @@ -49,7 +61,6 @@ func typeConverter(value any) cty.Value {
switch v := v.(type) {
case map[string]any:
vals = append(vals, typeConverter(v))

case string:
vals = append(vals, cty.StringVal(v))
case int:
Expand Down Expand Up @@ -100,7 +111,6 @@ func typeConverter(value any) cty.Value {
switch v := v.(type) {
case map[string]any:
vals = append(vals, typeConverter(v))

case string:
vals = append(vals, cty.StringVal(v))
case int:
Expand Down
7 changes: 6 additions & 1 deletion importer/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ type Importable interface {
Filename() string
}

func Init(url, key, path string, recreate bool) {
func Init(url, key, path string, recreate bool, includePermissions bool) {
err := createDirectory(path)
if err != nil {
log.Fatal().AnErr("error", err).Msg("failed to create directory")
Expand All @@ -36,6 +36,11 @@ func Init(url, key, path string, recreate bool) {
NewSyncs(c),
}

if includePermissions {
importables = append(importables, NewPolicies(c))
importables = append(importables, NewRoles(c))
}

// Create import.sh
importFile, err := createFile(recreate, 0755, path, ImportFileName)
if err != nil {
Expand Down
99 changes: 99 additions & 0 deletions importer/policy.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
package importer

import (
"context"
"fmt"
"io"

"github.com/hashicorp/hcl/v2/hclwrite"
"github.com/polytomic/polytomic-go"
"github.com/polytomic/terraform-provider-polytomic/provider"
"github.com/zclconf/go-cty/cty"
)

const (
PoliciesResourceFileName = "policies.tf"
PolicyResource = "polytomic_policy"
)

var (
_ Importable = &Policies{}
)

type Policies struct {
c *polytomic.Client

Resources []*polytomic.Policy
}

func NewPolicies(c *polytomic.Client) *Policies {
return &Policies{
c: c,
}
}

func (p *Policies) Init(ctx context.Context) error {
policies, err := p.c.Permissions().ListPolicies(ctx)
if err != nil {
return err
}

for _, policy := range policies {
// Skip system policies, they are not editable
if policy.System {
continue
}

hyrdatedPolicy, err := p.c.Permissions().GetPolicy(ctx, policy.ID)
if err != nil {
return err
}

p.Resources = append(p.Resources, hyrdatedPolicy)
}

return nil

}

func (p *Policies) GenerateTerraformFiles(ctx context.Context, writer io.Writer) error {
for _, policy := range p.Resources {
hclFile := hclwrite.NewEmptyFile()
body := hclFile.Body()
name := provider.ToSnakeCase(policy.Name)

resourceBlock := body.AppendNewBlock("resource", []string{PolicyResource, name})

resourceBlock.Body().SetAttributeValue("name", cty.StringVal(policy.Name))
if policy.OrganizationID != "" {
resourceBlock.Body().SetAttributeValue("organization", cty.StringVal(policy.OrganizationID))
}

var policyActions []map[string]interface{}
for _, action := range policy.PolicyActions {
policyActions = append(policyActions, map[string]interface{}{
"action": action.Action,
"role_ids": action.RoleIDs,
})
}
resourceBlock.Body().SetAttributeValue("policy_actions", typeConverter(policyActions))

writer.Write(hclFile.Bytes())
}
return nil
}

func (p *Policies) GenerateImports(ctx context.Context, writer io.Writer) error {
for _, policy := range p.Resources {
writer.Write([]byte(fmt.Sprintf("terraform import %s.%s %s",
PolicyResource,
provider.ToSnakeCase(policy.Name),
policy.ID)))
writer.Write([]byte(fmt.Sprintf(" # %s\n", policy.Name)))
}
return nil
}

func (p *Policies) Filename() string {
return PoliciesResourceFileName
}
Loading

0 comments on commit 4a6b400

Please sign in to comment.