Skip to content

Commit

Permalink
Merge pull request #1 from awakesecurity/baloo/initial.commit
Browse files Browse the repository at this point in the history
Release terraform-provider-dhall
  • Loading branch information
baloo authored Nov 29, 2021
2 parents 2267f75 + ff59d61 commit 28dddda
Show file tree
Hide file tree
Showing 11 changed files with 866 additions and 1 deletion.
2 changes: 1 addition & 1 deletion .github/workflows/golang.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ jobs:
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.26.0
golangci-lint run
test:
test:
runs-on: ubuntu-20.04
steps:
- uses: actions/checkout@v2
Expand Down
1 change: 1 addition & 0 deletions .go-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.16.0
67 changes: 67 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
# terraform-provider-dhall

This providers brings the ability for terraform to use dhall as an external datasource.

Result from the dhall evaluation is provided as a JSON-encoded string.

## Usage

```terraform
# resources.tf
resource "aws_iam_policy" "assets-access" {
name = "assets-access"
description = "A policy allowing access to assets."
policy = data.dhall.iam_policy_assets_access.result
}
data "dhall" "iam_policy_assets_access" {
entrypoint = "(./assets_access.dhall) { region = \"${var.region}\", accountId = \"${var.account-id}\" }"
}
# terraform.tf
terraform {
required_providers {
dhall = {
source = "awakesecurity/dhall"
version = "0.0.1"
}
}
}
```

```dhall
# assets_access.dhall
let predicate =
https://raw.githubusercontent.com/mjgpy3/iam-dhall/20bcc9c507d353fb3736a633280239a922b91aa6/policy.dhall

let policy =
https://raw.githubusercontent.com/mjgpy3/iam-dhall/20bcc9c507d353fb3736a633280239a922b91aa6/output.dhall

let Aws : Type = { accountId : Text, region : Text }

{- Grant access to list the objects on a store, and get any object -}
let listGetBucketAccess = \(bucket: Text) ->
[ predicate.serviceAllow
predicate.Service.S3
[ "ListBucket" ]
[ bucket ]
// { sid = "ListObjects" }
, predicate.serviceAllow
predicate.Service.S3
[ "GetObject" ]
[ "${bucket}/*" ]
// { sid = "GetObject" }
]

let assetsAccess = \(aws: Aws) ->
policy
aws
(
{- merge access to public-assets and static-assets -}
( listGetBucketAccess "public-assets" )
# ( listGetBucketAccess "static-assets" )
)

in assetsAccess
```
12 changes: 12 additions & 0 deletions default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
{ lib, buildGoModule, nix-gitignore }:

buildGoModule rec {
pname = "terraform-provider-dhall";
version = "0.0.1";

src = nix-gitignore.gitignoreSource [] ./.;

vendorSha256 = "0m11cpis171j9aicw0c66y4m1ckg41gjknj86qvblh57ai96gc1n";

postInstall = "mv $out/bin/terraform-provider-dhall{,_v${version}}";
}
8 changes: 8 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
module github.com/awakesecurity/terraform-provider-dhall

go 1.15

require (
github.com/hashicorp/terraform-plugin-sdk/v2 v2.8.0
github.com/philandstuff/dhall-golang/v6 v6.0.2
)
577 changes: 577 additions & 0 deletions go.sum

Large diffs are not rendered by default.

88 changes: 88 additions & 0 deletions internal/provider/data_source.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
package provider

import (
"encoding/json"
"fmt"
"log"
"os"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"github.com/philandstuff/dhall-golang/v6"
)

func dataSource() *schema.Resource {
return &schema.Resource{
Description: "The `dhall` data source allows to provide data from a dhall-lang file",

Read: dataSourceRead,

Schema: map[string]*schema.Schema{
"entrypoint": {
Description: "The dhall expression to be used as entrypoint",
Type: schema.TypeString,
Required: true,
},

"working_dir": {
Description: "Working directory of the dhall evaluation. If not supplied, the dhall expression will run " +
"in the current directory.",
Type: schema.TypeString,
Optional: true,
Default: "",
},

"result": {
Description: "The return of the dhall evaluation encoded as json.",
Type: schema.TypeString,
Computed: true,
},
},
}
}

func dataSourceRead(d *schema.ResourceData, meta interface{}) error {
entryP := d.Get("entrypoint").(string)
workingDir := d.Get("working_dir").(string)

entryPoint := []byte(entryP)

oldDir, err := os.Getwd()
log.Println("[DEBUG] olddir: ", oldDir)
if err != nil {
return fmt.Errorf("failed to get current directory: %s", err)
}
if workingDir != "" {
defer func() {
err := os.Chdir(oldDir)
_ = err
}()

err = os.Chdir(workingDir)
if err != nil {
return fmt.Errorf("failed to change current directory: %s", err)
}
}

log.Println("[DEBUG] newdir: ", workingDir)

var data interface{}
log.Println("[DEBUG] input: ", entryP)
err = dhall.Unmarshal(entryPoint, &data)
if err != nil {
return fmt.Errorf("failed to evaluate dhall: %s", err)
}

log.Println("[DEBUG] data: ", data)

outJSON, err := json.Marshal(data)
if err != nil {
return err
}
err = d.Set("result", string(outJSON))
if err != nil {
return fmt.Errorf("failed to export result: %s", err)
}

d.SetId("terraform-provider-dhall")
return nil
}
51 changes: 51 additions & 0 deletions internal/provider/data_source_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
package provider

import (
"fmt"
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
)

const testDataSourceConfigBasic = `
data "dhall" "test" {
entrypoint = "\"Hello world\""
}
output "simple" {
value = "${data.dhall.test.result}"
}
`

func TestDataSourceDhall(t *testing.T) {
resource.UnitTest(t, resource.TestCase{
Providers: testProviders,
Steps: []resource.TestStep{
{
Config: testDataSourceConfigBasic,
Check: func(s *terraform.State) error {
_, ok := s.RootModule().Resources["data.dhall.test"]
if !ok {
return fmt.Errorf("missing data resource")
}

outputs := s.RootModule().Outputs

if outputs["simple"] == nil {
return fmt.Errorf("missing 'simple' output")
}

if outputs["simple"].Value != "\"Hello world\"" {
return fmt.Errorf(
"'simple' output is %q; want '\"Hello World\"'",
outputs["simple"].Value,
)
}

return nil
},
},
},
})
}
15 changes: 15 additions & 0 deletions internal/provider/provider.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package provider

import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

// New creates a new instance of the dhall data provider
func New() *schema.Provider {
return &schema.Provider{
DataSourcesMap: map[string]*schema.Resource{
"dhall": dataSource(),
},
ResourcesMap: map[string]*schema.Resource{},
}
}
17 changes: 17 additions & 0 deletions internal/provider/provider_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package provider

import (
"testing"

"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)

func TestProvider(t *testing.T) {
if err := New().InternalValidate(); err != nil {
t.Fatalf("err: %s", err)
}
}

var testProviders = map[string]*schema.Provider{
"dhall": New(),
}
29 changes: 29 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package main

import (
"context"
"flag"
"log"

"github.com/awakesecurity/terraform-provider-dhall/internal/provider"
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
)

func main() {
var debugMode bool

flag.BoolVar(&debugMode, "debug", false, "set to true to run the provider with support for debuggers like delve")
flag.Parse()

opts := &plugin.ServeOpts{ProviderFunc: provider.New}

if debugMode {
err := plugin.Debug(context.Background(), "registry.terraform.io/awakesecurity/dhall", opts)
if err != nil {
log.Fatal(err.Error())
}
return
}

plugin.Serve(opts)
}

0 comments on commit 28dddda

Please sign in to comment.