Skip to content

Commit

Permalink
groups provider
Browse files Browse the repository at this point in the history
  • Loading branch information
bvanderveen committed Sep 29, 2020
1 parent 36a7ab8 commit c715e18
Show file tree
Hide file tree
Showing 6 changed files with 229 additions and 0 deletions.
2 changes: 2 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ all: lint install
lint:
go vet ./...
go mod tidy
go fmt ./...

build:
go build -o ${BINARY}
Expand Down Expand Up @@ -38,3 +39,4 @@ release:

test:
./examples/realms/applications/roles/test.sh
./examples/realms/applications/groups/test.sh
67 changes: 67 additions & 0 deletions examples/realms/applications/groups/main.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# Configure the Terraform runtime
terraform {
required_version = ">= 0.13"
required_providers {
tozny = {
# Pull signed provider binaries from
# the Terraform hosted registry namespace
# for Tozny registry.terraform.io/tozny
source = "tozny/tozny"
# Pin Tozny provider version
version = ">=0.0.6"
}
}
}

# Include the Tozny Terraform provider
provider "tozny" {
api_endpoint = "http://platform.local.tozny.com:8000"
account_username = "test+${random_string.account_username_salt.result}@tozny.com"
}

# Generate a random string for use in creating
# accounts across environments or executions conflict free
resource "random_string" "account_username_salt" {
length = 8
special = false
}

# Generate a random string for use in creating
# realms across environments or executions conflict free
resource "random_string" "random_realm_name" {
length = 8
special = false
}

# Local variables for defining where to store and find local Tozny client credentials
locals {
tozny_client_credentials_filepath = "./tozny_client_credentials.json"
}

# A resource for provisioning a Tozny account using Terraform generated
# credentials that are saved to user specified filepath for reuse upon success.
resource "tozny_account" "autogenerated_tozny_account" {
autogenerate_account_credentials = true
client_credentials_save_filepath = local.tozny_client_credentials_filepath
}

# A resource for provisioning a TozID Realm
# using local filebased credentials for a Tozny Client with permissions to manage Realms.
resource "tozny_realm" "my_organizations_realm" {
# Block on and use client credentials generated from the provisioned account
depends_on = [
tozny_account.autogenerated_tozny_account,
]
client_credentials_filepath = local.tozny_client_credentials_filepath
realm_name = random_string.random_realm_name.result
sovereign_name = "Administrator"
}

resource "tozny_realm_group" "my_first_group" {
depends_on = [
tozny_realm.my_organizations_realm
]
client_credentials_filepath = local.tozny_client_credentials_filepath
name = "My First Group"
realm_name = tozny_realm.my_organizations_realm.realm_name
}
32 changes: 32 additions & 0 deletions examples/realms/applications/groups/test.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#!/bin/bash

cd "$(dirname "$0")"

terraform init
terraform plan
yes yes | terraform apply

test_result=$(cat terraform.tfstate | jq \
'def resource(resource_name): .resources | map(select(.name == resource_name)) | first | .instances | first | .attributes;
def assert(exp; msg): exp as $e | if $e then . else . as $in | "assertion failed: \(msg) => \($e)" | debug | $in end;
def assertEquals(x;y): if x == y then . else . as $in | "assertion failed: \(x) != \(y)" | debug | $in end;
resource("my_organizations_realm") as $realm |
resource("my_first_group") as $group |
assert($realm.id != null and $realm.id != ""; "expected realm to have id") |
assertEquals($realm.sovereign_name; "Administrator") |
assert($group.id != null and $group.id != ""; "expected application role to have id") |
assertEquals($group.name; "My First Group")
' 2>&1 > /dev/null)

yes yes | terraform destroy

if [ ! -z "$test_result" ]; then
echo "Terraform emitted unexpected state."
echo "$test_result"
exit 1
else
echo "Terraform state test passed."
fi
2 changes: 2 additions & 0 deletions examples/realms/applications/roles/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -28,4 +28,6 @@ if [ ! -z "$test_result" ]; then
echo "Terraform emitted unexpected state."
echo "$test_result"
exit 1
else
echo "Terraform state test passed."
fi
1 change: 1 addition & 0 deletions tozny/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ func Provider() *schema.Provider {
"tozny_realm_broker_delegation": resourceRealmBrokerDelegation(),
"tozny_realm_application": resourceRealmApplication(),
"tozny_realm_application_role": resourceRealmApplicationRole(),
"tozny_realm_group": resourceRealmGroup(),
"tozny_realm_provider": resourceRealmProvider(),
"tozny_realm_provider_mapper": resourceRealmProviderMapper(),
},
Expand Down
125 changes: 125 additions & 0 deletions tozny/resource_realm_group.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package tozny

import (
"context"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/tozny/e3db-clients-go/identityClient"
)

// resourceRealmGroup returns the schema and methods for provisioning a Tozny Realm Group
func resourceRealmGroup() *schema.Resource {
return &schema.Resource{
CreateContext: resourceRealmGroupCreate,
ReadContext: resourceRealmGroupRead,
DeleteContext: resourceRealmGroupDelete,
Schema: map[string]*schema.Schema{
"client_credentials_filepath": {
Description: "The filepath to Tozny client credentials for the Terraform provider to use when provisioning this realm provider.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"realm_name": {
Description: "The name of the Realm to provision the Application Role for.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"name": {
Description: "Human readable/reference-able name for the application role.",
Type: schema.TypeString,
Required: true,
ForceNew: true,
},
"group_id": {
Description: "Server defined unique identifier for the Application role.",
Type: schema.TypeString,
Computed: true,
ForceNew: true,
},
},
}
}

func resourceRealmGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics

toznyClientCredentialsFilePath := d.Get("client_credentials_filepath").(string)

toznySDK, err := MakeToznySDK(toznyClientCredentialsFilePath, m)

if err != nil {
return diag.FromErr(err)
}

createGroupParams := identityClient.CreateRealmGroupRequest{
RealmName: d.Get("realm_name").(string),
Group: identityClient.Group{
Name: d.Get("name").(string),
},
}

group, err := toznySDK.CreateRealmGroup(ctx, createGroupParams)

if err != nil {
return diag.FromErr(err)
}

groupId := group.ID

d.Set("group_id", groupId)
d.SetId(groupId)

return diags
}

func resourceRealmGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics

toznyClientCredentialsFilePath := d.Get("client_credentials_filepath").(string)

toznySDK, err := MakeToznySDK(toznyClientCredentialsFilePath, m)

if err != nil {
return diag.FromErr(err)
}

group, err := toznySDK.DescribeRealmGroup(ctx, identityClient.DescribeRealmGroupRequest{
RealmName: d.Get("realm_name").(string),
GroupID: d.Get("group_id").(string),
})

if err != nil {
return diag.FromErr(err)
}

d.Set("name", group.Name)

return diags
}

func resourceRealmGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
var diags diag.Diagnostics

toznyClientCredentialsFilePath := d.Get("client_credentials_filepath").(string)

toznySDK, err := MakeToznySDK(toznyClientCredentialsFilePath, m)

if err != nil {
return diag.FromErr(err)
}

err = toznySDK.DeleteRealmGroup(ctx, identityClient.DeleteRealmGroupRequest{
RealmName: d.Get("realm_name").(string),
GroupID: d.Get("group_id").(string),
})

if err != nil {
return diag.FromErr(err)
}

d.SetId("")

return diags
}

0 comments on commit c715e18

Please sign in to comment.