diff --git a/.github/dependabot.yaml b/.github/dependabot.yaml new file mode 100644 index 0000000..ef9176d --- /dev/null +++ b/.github/dependabot.yaml @@ -0,0 +1,13 @@ +version: 2 +updates: +- package-ecosystem: gomod + directory: "/" + schedule: + interval: daily + pull-request-branch-name: + separator: "-" + open-pull-requests-limit: 3 +- package-ecosystem: github-actions + directory: "/" + schedule: + interval: daily diff --git a/.github/workflows/test.yaml b/.github/workflows/test.yaml new file mode 100644 index 0000000..4cb6030 --- /dev/null +++ b/.github/workflows/test.yaml @@ -0,0 +1,30 @@ +name: test +on: + push: + branches: + - main + pull_request: +jobs: + build: + name: go + runs-on: ubuntu-latest + strategy: + fail-fast: false + matrix: + go: ['1.18', '1.19'] + steps: + - name: setup Go + uses: actions/setup-go@v3 + with: + go-version: ${{matrix.go}} + + - name: setup Terraform + uses: hashicorp/setup-terraform@v2 + with: + terraform_wrapper: false + + - name: checkout + uses: actions/checkout@v3 + + - name: test + run: make diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ee7a829 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +bin/ +_output/ diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 0000000..233f496 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,13 @@ +# terraform-provider-cue + +Notable changes between releases. + +## Latest + +## v0.1.0 + +* Add `cue_config` data source to evaluate CUE contents + * Evaluate inline CUE `content` + * Evaluate CUE files specified via `paths` list + * Support `pretty_print` option (default false) + * Render CUE values as JSON diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..81c2c93 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,5 @@ +# Contributing + +## Developer Certificate of Origin + +By contributing, you agree to the Linux Foundation's Developer Certificate of Origin ([DCO](DCO)). The DCO is a statement that you, the contributor, have the legal right to make your contribution and understand the contribution will be distributed as part of this project. diff --git a/DCO b/DCO new file mode 100644 index 0000000..716561d --- /dev/null +++ b/DCO @@ -0,0 +1,36 @@ +Developer Certificate of Origin +Version 1.1 + +Copyright (C) 2004, 2006 The Linux Foundation and its contributors. +660 York Street, Suite 102, +San Francisco, CA 94110 USA + +Everyone is permitted to copy and distribute verbatim copies of this +license document, but changing it is not allowed. + + +Developer's Certificate of Origin 1.1 + +By making a contribution to this project, I certify that: + +(a) The contribution was created in whole or in part by me and I + have the right to submit it under the open source license + indicated in the file; or + +(b) The contribution is based upon previous work that, to the best + of my knowledge, is covered under an appropriate open source + license and I have the right under that license to submit that + work with modifications, whether created in whole or in part + by me, under the same open source license (unless I am + permitted to submit under a different license), as indicated + in the file; or + +(c) The contribution was provided directly to me by some other + person who certified (a), (b) or (c) and I have not modified + it. + +(d) I understand and agree that this project and the contribution + are public and that a record of the contribution (including all + personal information I submit with it, including my sign-off) is + maintained indefinitely and may be redistributed consistent with + this project or the open source license(s) involved. diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..951c97c --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2022 Dalton Hubble + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a1ea0c5 --- /dev/null +++ b/Makefile @@ -0,0 +1,62 @@ +export CGO_ENABLED:=0 + +VERSION=$(shell git describe --tags --match=v* --always --dirty) +SEMVER=$(shell git describe --tags --match=v* --always --dirty | cut -c 2-) + +.PHONY: all +all: build test vet fmt + +.PHONY: build +build: clean bin/terraform-provider-cue + +bin/terraform-provider-cue: + @go build -o $@ github.com/poseidon/terraform-provider-cue + +.PHONY: test +test: + @go test ./... -cover + +.PHONY: vet +vet: + @go vet -all ./... + +.PHONY: fmt +fmt: + @test -z $$(go fmt ./...) + +.PHONY: clean +clean: + @rm -rf bin + @rm -rf _output + +.PHONY: release +release: \ + clean \ + _output/plugin-linux-amd64.zip \ + _output/plugin-linux-arm64.zip \ + _output/plugin-darwin-amd64.zip \ + _output/plugin-darwin-arm64.zip \ + _output/plugin-windows-amd64.zip + +_output/plugin-%.zip: NAME=terraform-provider-cue_$(SEMVER)_$(subst -,_,$*) +_output/plugin-%.zip: DEST=_output/$(NAME) +_output/plugin-%.zip: _output/%/terraform-provider-cue + @mkdir -p $(DEST) + @cp _output/$*/terraform-provider-cue $(DEST)/terraform-provider-cue_$(VERSION) + @zip -j $(DEST).zip $(DEST)/terraform-provider-cue_$(VERSION) + +_output/linux-amd64/terraform-provider-cue: GOARGS = GOOS=linux GOARCH=amd64 +_output/linux-arm64/terraform-provider-cue: GOARGS = GOOS=linux GOARCH=arm64 +_output/darwin-amd64/terraform-provider-cue: GOARGS = GOOS=darwin GOARCH=amd64 +_output/darwin-arm64/terraform-provider-cue: GOARGS = GOOS=darwin GOARCH=arm64 +_output/windows-amd64/terraform-provider-cue: GOARGS = GOOS=windows GOARCH=amd64 +_output/%/terraform-provider-cue: + $(GOARGS) go build -o $@ github.com/poseidon/terraform-provider-cue + +release-sign: + cd _output; sha256sum *.zip > terraform-provider-cue_$(SEMVER)_SHA256SUMS + gpg2 --detach-sign _output/terraform-provider-cue_$(SEMVER)_SHA256SUMS + +release-verify: NAME=_output/terraform-provider-cue +release-verify: + gpg2 --verify $(NAME)_$(SEMVER)_SHA256SUMS.sig $(NAME)_$(SEMVER)_SHA256SUMS diff --git a/README.md b/README.md new file mode 100644 index 0000000..39cb61a --- /dev/null +++ b/README.md @@ -0,0 +1,104 @@ +# terraform-provider-cue +[![GoDoc](https://pkg.go.dev/badge/github.com/poseidon/terraform-provider-cue.svg)](https://pkg.go.dev/github.com/poseidon/terraform-provider-cue) [![Workflow](https://github.com/poseidon/terraform-provider-cue/actions/workflows/test.yaml/badge.svg)](https://github.com/poseidon/terraform-provider-cue/actions/workflows/test.yaml?query=branch%3Amain) ![Downloads](https://img.shields.io/github/downloads/poseidon/terraform-provider-cue/total) [![Sponsors](https://img.shields.io/github/sponsors/poseidon?logo=github)](https://github.com/sponsors/poseidon) [![Twitter](https://img.shields.io/badge/follow-news-1da1f2?logo=twitter)](https://twitter.com/poseidonlabs) + +`terraform-provider-cue` allows Terraform to evaluate [CUE](https://cuelang.org/docs/) configs and render as JSON for use in Terraform. + +
+ Author's Note + CUE has potential to be a better Jsonnet (if it gets a proper module manager). But like Jsonnet, its usage should be limited to preparing JSON-only configs where there are no viable alternatives (e.g. Grafana dashboards). Prefer native Terraform where possible, its ecosystem and design is simpler, more powerful, more mature, and ubiquitous. +
+ +## Usage + +Configure the `cue` provider (e.g. `providers.tf`). + +```tf +provider "cue" {} + +terraform { + required_providers { + ct = { + source = "poseidon/cue" + version = "0.1.0" + } + } +} +``` + +Run `terraform init` to ensure version requirements are met. + +``` +$ terraform init -upgrade +``` + +Define a `cue_config` data source to validate CUE `content`. + +```tf +data "cue_config" "example" { + content = <= 0 { + return strconv.Itoa(v) + } + if -v >= 0 { + return strconv.Itoa(-v) + } + // v == MinInt + return "0" +} diff --git a/internal/provider.go b/internal/provider.go new file mode 100644 index 0000000..6ba7970 --- /dev/null +++ b/internal/provider.go @@ -0,0 +1,23 @@ +package internal + +import ( + "context" + "sync" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +// Provider returns a cue Provider. +func Provider() *schema.Provider { + return &schema.Provider{ + ConfigureContextFunc: providerConfigure, + DataSourcesMap: map[string]*schema.Resource{ + "cue_config": dataConfig(), + }, + } +} + +func providerConfigure(ctx context.Context, d *schema.ResourceData) (any, diag.Diagnostics) { + return &sync.Mutex{}, nil +} diff --git a/internal/provider_test.go b/internal/provider_test.go new file mode 100644 index 0000000..72dc688 --- /dev/null +++ b/internal/provider_test.go @@ -0,0 +1,17 @@ +package internal + +import ( + "testing" + + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +var testProviders = map[string]*schema.Provider{ + "cue": Provider(), +} + +func TestProvider(t *testing.T) { + if err := Provider().InternalValidate(); err != nil { + t.Fatalf("err: %s", err) + } +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..fc48fd9 --- /dev/null +++ b/main.go @@ -0,0 +1,13 @@ +package main + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/plugin" + + "github.com/poseidon/terraform-provider-cue/internal" +) + +func main() { + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: internal.Provider, + }) +}