diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f507bfe --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +release +build +vendor +reports +.idea diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 0000000..dbc4c74 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,46 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +In the interest of fostering an open and welcoming environment, we as contributors and maintainers pledge to making participation in our project and our community a harassment-free experience for everyone, regardless of age, body size, disability, ethnicity, gender identity and expression, level of experience, nationality, personal appearance, race, religion, or sexual identity and orientation. + +## Our Standards + +Examples of behavior that contributes to creating a positive environment include: + +* Using welcoming and inclusive language +* Being respectful of differing viewpoints and experiences +* Gracefully accepting constructive criticism +* Focusing on what is best for the community +* Showing empathy towards other community members + +Examples of unacceptable behavior by participants include: + +* The use of sexualized language or imagery and unwelcome sexual attention or advances +* Trolling, insulting/derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or electronic address, without explicit permission +* Other conduct which could reasonably be considered inappropriate in a professional setting + +## Our Responsibilities + +Project maintainers are responsible for clarifying the standards of acceptable behavior and are expected to take appropriate and fair corrective action in response to any instances of unacceptable behavior. + +Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct, or to ban temporarily or permanently any contributor for other behaviors that they deem inappropriate, threatening, offensive, or harmful. + +## Scope + +This Code of Conduct applies both within project spaces and in public spaces when an individual is representing the project or its community. Examples of representing a project or community include using an official project e-mail address, posting via an official social media account, or acting as an appointed representative at an online or offline event. Representation of a project may be further defined and clarified by project maintainers. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting the project team by reporting an issue here in Github. All complaints will be reviewed and investigated and will result in a response that is deemed necessary and appropriate to the circumstances. The project team is obligated to maintain confidentiality with regard to the reporter of an incident. Further details of specific enforcement policies may be posted separately. + +Project maintainers who do not follow or enforce the Code of Conduct in good faith may face temporary or permanent repercussions as determined by other members of the project's leadership. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, available at [https://contributor-covenant.org/version/1/4][version] + +[homepage]: https://contributor-covenant.org +[version]: https://contributor-covenant.org/version/1/4/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000..2d40e5a --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,44 @@ +# Contributing to terraform-provider-vinyldns + +The following is a set of guidelines for contributing. These are mostly guidelines, not rules. Use your best judgment and feel free to propose changes to this document in a pull request. + +## Code of Conduct + +This project and everyone participating in it is governed by the [Code of Conduct](CODE_OF_CONDUCT.md). By participating, you are expected to uphold this code. Please report unacceptable behavior by submitting an issue under the github repo. + +## Reporting Bugs + +Bugs are tracked as [GitHub issues](https://guides.github.com/features/issues/). Please complete [the template](ISSUE_TEMPLATE.md) when creating an issue. This helps resolve issues faster. + +> **Note:** If you find a **Closed** issue that seems like it is the same thing that you're experiencing, open a new issue and include a link to the original issue in the body of your new one. + +Please also consider the following when creating reporting a bug: + +* **Use a clear and descriptive title** for the issue to identify the problem. +* **Describe the exact steps which reproduce the problem** in as many details as possible. When listing steps, **don't just say what you did, but explain how you did it**. For example, if you moved the cursor to the end of a line, explain if you used the mouse, or a keyboard shortcut. +* **Provide specific examples to demonstrate the steps**. Include details such as a strack trace, links to files or GitHub projects, or copy/pasteable snippets that illustrate the problem. If you're providing snippets in the issue, use [Markdown code blocks](https://help.github.com/articles/markdown-basics/#multiple-lines). +* **Describe the behavior you observed after following the steps** and point out what exactly is the problem with that behavior. +* **Explain the behavior you expected to see instead and why.** + +Provide more context by answering these questions: + +* **Did the problem start happening recently** (e.g. after updating to a new version) or was this always a problem? +* If the problem started happening recently, **can you reproduce the problem in an older version?** What's the most recent version in which the problem doesn't happen? +* **Can you reliably reproduce the issue?** If not, provide details about how often the problem happens and under which conditions it normally happens. + +## Pull Requests + +* Complete the [the required template](PULL_REQUEST_TEMPLATE.md) +* Do not include issue numbers in the PR title + +### Contributor License Agreement + +Before Comcast merges your code into the project you must sign the [Comcast Contributor License Agreement (CLA)](https://gist.github.com/ComcastOSS/a7b8933dd8e368535378cda25c92d19a). + +If you haven't previously signed a Comcast CLA, you'll automatically be asked to when you open a pull request. Alternatively, we can send you a PDF that you can sign and scan back to us. Please create a new GitHub issue to request a PDF version of the CLA. + +### Git Commit Messages + +* Use the present tense ("Add feature" not "Added feature") +* Limit the first line to 72 characters or less +* Reference issues and pull requests liberally after the first line diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..d493615 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,4 @@ +FROM golang:1.10.3 +COPY . /go/src/github.com/vinyldns/terraform-provider-vinyldns +WORKDIR /go/src/github.com/vinyldns/terraform-provider-vinyldns +RUN make build diff --git a/GNUmakefile b/GNUmakefile new file mode 100644 index 0000000..6b41160 --- /dev/null +++ b/GNUmakefile @@ -0,0 +1,73 @@ +PKG_NAME=vinyldns +NAME=terraform-provider-vinyldns +WEBSITE_REPO=github.com/hashicorp/terraform-website +SOURCE=./... +VERSION=0.8.0 + +all: updatedeps test install + +updatedeps: + go get -u github.com/golang/dep/cmd/dep + go get -u golang.org/x/tools/cmd/cover + go get -u github.com/mitchellh/gox + dep ensure + +# NOTE: acceptance tests assume a VinylDNS instance is running on localhost:9000 using the +# technique here: https://github.com/vinyldns/vinyldns/blob/master/bin/docker-up-vinyldns.sh +test: + go vet + go test -cover + VINYLDNS_ACCESS_KEY=okAccessKey VINYLDNS_SECRET_KEY=okSecretKey VINYLDNS_HOST=http://localhost:9000 TF_LOG=DEBUG TF_ACC=1 go test ${SOURCE} -v + +cover: + go test $(TEST) -coverprofile=coverage.out + go tool cover -html=coverage.out + rm coverage.out + +install: + dep ensure + +build: updatedeps + export CGO_ENABLED=0; gox -ldflags "-X main.version=${VERSION}" -os "linux darwin windows" -arch "386 amd64" -output "build/{{.OS}}_{{.Arch}}/terraform-provider-vinyldns" + +version: + echo ${VERSION} + +website: +ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO))) + echo "$(WEBSITE_REPO) not found in your GOPATH (necessary for layouts and assets), get-ting..." + git clone https://$(WEBSITE_REPO) $(GOPATH)/src/$(WEBSITE_REPO) +endif + @$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME) + +website-test: +ifeq (,$(wildcard $(GOPATH)/src/$(WEBSITE_REPO))) + echo "$(WEBSITE_REPO) not found in your GOPATH (necessary for layouts and assets), get-ting..." + git clone https://$(WEBSITE_REPO) $(GOPATH)/src/$(WEBSITE_REPO) +endif + @$(MAKE) -C $(GOPATH)/src/$(WEBSITE_REPO) website-provider-test PROVIDER_PATH=$(shell pwd) PROVIDER_NAME=$(PKG_NAME) + +.PHONY: updatedeps test cover install build version website website-test + +package: build + rm -rf release + mkdir release + for f in build/*; do \ + g=`basename $$f`; \ + tar -zcf release/$(NAME)-$${g}-$(VERSION).tgz -C build/$${g} .; \ + done + +release: package + go get github.com/aktau/github-release + github-release release \ + --user vinyldns \ + --repo ${NAME} \ + --target $(shell git rev-parse --abbrev-ref HEAD) \ + --tag ${VERSION} \ + --name "${VERSION}" + ls release/*.tgz | xargs -I FILE github-release upload \ + --user vinyldns \ + --repo ${NAME} \ + --tag ${VERSION} \ + --name FILE \ + --file FILE diff --git a/Gopkg.lock b/Gopkg.lock new file mode 100644 index 0000000..d687c0a --- /dev/null +++ b/Gopkg.lock @@ -0,0 +1,479 @@ +# This file is autogenerated, do not edit; changes may be undone by the next 'dep ensure'. + + +[[projects]] + name = "github.com/agext/levenshtein" + packages = ["."] + revision = "5f10fee965225ac1eecdc234c09daf5cd9e7f7b6" + version = "v1.2.1" + +[[projects]] + name = "github.com/apparentlymart/go-cidr" + packages = ["cidr"] + revision = "b1115bf8e14a60131a196f908223e4506b0ddc35" + version = "v1.0.0" + +[[projects]] + name = "github.com/apparentlymart/go-textseg" + packages = ["textseg"] + revision = "fb01f485ebef760e5ee06d55e1b07534dda2d295" + version = "v1.0.0" + +[[projects]] + name = "github.com/armon/go-radix" + packages = ["."] + revision = "1a2de0c21c94309923825da3df33a4381872c795" + version = "v1.0.0" + +[[projects]] + name = "github.com/aws/aws-sdk-go" + packages = [ + "aws", + "aws/awserr", + "aws/awsutil", + "aws/client", + "aws/client/metadata", + "aws/corehandlers", + "aws/credentials", + "aws/credentials/ec2rolecreds", + "aws/credentials/endpointcreds", + "aws/credentials/stscreds", + "aws/csm", + "aws/defaults", + "aws/ec2metadata", + "aws/endpoints", + "aws/request", + "aws/session", + "aws/signer/v4", + "internal/sdkio", + "internal/sdkrand", + "internal/sdkuri", + "internal/shareddefaults", + "private/protocol", + "private/protocol/eventstream", + "private/protocol/eventstream/eventstreamapi", + "private/protocol/query", + "private/protocol/query/queryutil", + "private/protocol/rest", + "private/protocol/restxml", + "private/protocol/xml/xmlutil", + "service/s3", + "service/sts" + ] + revision = "7715ed93fca215da2c707088a0cca5646ad91543" + version = "v1.15.24" + +[[projects]] + branch = "master" + name = "github.com/bgentry/go-netrc" + packages = ["netrc"] + revision = "9fd32a8b3d3d3f9d43c341bfe098430e07609480" + +[[projects]] + name = "github.com/bgentry/speakeasy" + packages = ["."] + revision = "4aabc24848ce5fd31929f7d1e4ea74d3709c14cd" + version = "v0.1.0" + +[[projects]] + name = "github.com/blang/semver" + packages = ["."] + revision = "2ee87856327ba09384cabd113bc6b5d174e9ec0f" + version = "v3.5.1" + +[[projects]] + name = "github.com/davecgh/go-spew" + packages = ["spew"] + revision = "8991bc29aa16c548c550c7ff78260e27b9ab7c73" + version = "v1.1.1" + +[[projects]] + name = "github.com/fatih/color" + packages = ["."] + revision = "5b77d2a35fb0ede96d138fc9a99f5c9b6aef11b4" + version = "v1.7.0" + +[[projects]] + name = "github.com/go-ini/ini" + packages = ["."] + revision = "5cf292cae48347c2490ac1a58fe36735fb78df7e" + version = "v1.38.2" + +[[projects]] + name = "github.com/golang/protobuf" + packages = [ + "proto", + "ptypes", + "ptypes/any", + "ptypes/duration", + "ptypes/timestamp" + ] + revision = "aa810b61a9c79d51363740d207bb46cf8e620ed5" + version = "v1.2.0" + +[[projects]] + name = "github.com/hashicorp/errwrap" + packages = ["."] + revision = "8a6fb523712970c966eefc6b39ed2c5e74880354" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-cleanhttp" + packages = ["."] + revision = "d5fe4b57a186c716b0e00b8c301cbd9b4182694d" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-getter" + packages = [ + ".", + "helper/url" + ] + revision = "4bda8fa99001c61db3cad96b421d4c12a81f256d" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-hclog" + packages = ["."] + revision = "75ecd6e6d64509d675da33386b15e1174566177b" + +[[projects]] + name = "github.com/hashicorp/go-multierror" + packages = ["."] + revision = "886a7fbe3eb1c874d46f623bfa70af45f425b3d1" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-plugin" + packages = ["."] + revision = "a4620f9913d19f03a6bf19b2f304daaaf83ea130" + +[[projects]] + name = "github.com/hashicorp/go-safetemp" + packages = ["."] + revision = "c9a55de4fe06c920a71964b53cfe3dd293a3c743" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/go-uuid" + packages = ["."] + revision = "27454136f0364f2d44b1276c552d69105cf8c498" + +[[projects]] + name = "github.com/hashicorp/go-version" + packages = ["."] + revision = "b5a281d3160aa11950a6182bd9a9dc2cb1e02d50" + version = "v1.0.0" + +[[projects]] + name = "github.com/hashicorp/hcl" + packages = [ + ".", + "hcl/ast", + "hcl/parser", + "hcl/scanner", + "hcl/strconv", + "hcl/token", + "json/parser", + "json/scanner", + "json/token" + ] + revision = "8cb6e5b959231cc1119e43259c4a608f9c51a241" + version = "v1.0.0" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/hcl2" + packages = [ + "gohcl", + "hcl", + "hcl/hclsyntax", + "hcl/json", + "hcldec", + "hclparse" + ] + revision = "ed8144cda141c1f06f8ab122baff783b645cfe52" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/hil" + packages = [ + ".", + "ast", + "parser", + "scanner" + ] + revision = "fa9f258a92500514cc8e9c67020487709df92432" + +[[projects]] + name = "github.com/hashicorp/logutils" + packages = ["."] + revision = "a335183dfd075f638afcc820c90591ca3c97eba6" + version = "v1.0.0" + +[[projects]] + name = "github.com/hashicorp/terraform" + packages = [ + "config", + "config/configschema", + "config/hcl2shim", + "config/module", + "dag", + "flatmap", + "helper/config", + "helper/hashcode", + "helper/hilmapstructure", + "helper/logging", + "helper/resource", + "helper/schema", + "httpclient", + "moduledeps", + "plugin", + "plugin/discovery", + "registry", + "registry/regsrc", + "registry/response", + "svchost", + "svchost/auth", + "svchost/disco", + "terraform", + "tfdiags", + "version" + ] + revision = "6dfc4d748de9cda23835bc5704307ed45e839622" + version = "v0.11.8" + +[[projects]] + branch = "master" + name = "github.com/hashicorp/yamux" + packages = ["."] + revision = "cc6d2ea263b2471faabce371255777a365bf8306" + +[[projects]] + name = "github.com/jmespath/go-jmespath" + packages = ["."] + revision = "0b12d6b5" + +[[projects]] + name = "github.com/mattn/go-colorable" + packages = ["."] + revision = "167de6bfdfba052fa6b2d3664c8f5272e23c9072" + version = "v0.0.9" + +[[projects]] + name = "github.com/mattn/go-isatty" + packages = ["."] + revision = "0360b2af4f38e8d38c7fce2a9f4e702702d73a39" + version = "v0.0.3" + +[[projects]] + name = "github.com/mitchellh/cli" + packages = ["."] + revision = "3d22a244be8aa6fb16ac24af0e195c08b7d973aa" + version = "v1.0.0" + +[[projects]] + name = "github.com/mitchellh/copystructure" + packages = ["."] + revision = "9a1b6f44e8da0e0e374624fb0a825a231b00c537" + version = "v1.0.0" + +[[projects]] + name = "github.com/mitchellh/go-homedir" + packages = ["."] + revision = "ae18d6b8b3205b561c79e8e5f69bff09736185f4" + version = "v1.0.0" + +[[projects]] + name = "github.com/mitchellh/go-testing-interface" + packages = ["."] + revision = "6d0b8010fcc857872e42fc6c931227569016843c" + version = "v1.0.0" + +[[projects]] + name = "github.com/mitchellh/go-wordwrap" + packages = ["."] + revision = "9e67c67572bc5dd02aef930e2b0ae3c02a4b5a5c" + version = "v1.0.0" + +[[projects]] + name = "github.com/mitchellh/hashstructure" + packages = ["."] + revision = "a38c50148365edc8df43c1580c48fb2b3a1e9cd7" + version = "v1.0.0" + +[[projects]] + name = "github.com/mitchellh/mapstructure" + packages = ["."] + revision = "fa473d140ef3c6adf42d6b391fe76707f1f243c8" + version = "v1.0.0" + +[[projects]] + name = "github.com/mitchellh/reflectwalk" + packages = ["."] + revision = "eecee6c969c02c8cc2ae48e1e269843ae8590796" + version = "v1.0.0" + +[[projects]] + name = "github.com/oklog/run" + packages = ["."] + revision = "4dadeb3030eda0273a12382bb2348ffc7c9d1a39" + version = "v1.0.0" + +[[projects]] + name = "github.com/posener/complete" + packages = [ + ".", + "cmd", + "cmd/install", + "match" + ] + revision = "dcda3199365ca2a5f24aea4c42aa56f6a197d117" + version = "v1.1.2" + +[[projects]] + name = "github.com/smartystreets/go-aws-auth" + packages = ["."] + revision = "8ef1316913ee4f44bc48c2456e44a5c1c68ea53b" + version = "1.0.0" + +[[projects]] + name = "github.com/ulikunitz/xz" + packages = [ + ".", + "internal/hash", + "internal/xlog", + "lzma" + ] + revision = "0c6b41e72360850ca4f98dc341fd999726ea007f" + version = "v0.5.4" + +[[projects]] + name = "github.com/vinyldns/go-vinyldns" + packages = ["vinyldns"] + revision = "016d69a8d059e8bab174ca58d217f2b0de4331a5" + version = "0.8.0" + +[[projects]] + branch = "master" + name = "github.com/zclconf/go-cty" + packages = [ + "cty", + "cty/convert", + "cty/function", + "cty/function/stdlib", + "cty/gocty", + "cty/json", + "cty/set" + ] + revision = "c2393a5d54f2fe015be2ddb1fc55431f749387de" + +[[projects]] + branch = "master" + name = "golang.org/x/crypto" + packages = [ + "bcrypt", + "blowfish", + "cast5", + "openpgp", + "openpgp/armor", + "openpgp/elgamal", + "openpgp/errors", + "openpgp/packet", + "openpgp/s2k" + ] + revision = "614d502a4dac94afa3a6ce146bd1736da82514c6" + +[[projects]] + branch = "master" + name = "golang.org/x/net" + packages = [ + "context", + "html", + "html/atom", + "http/httpguts", + "http2", + "http2/hpack", + "idna", + "internal/timeseries", + "trace" + ] + revision = "8a410e7b638dca158bf9e766925842f6651ff828" + +[[projects]] + branch = "master" + name = "golang.org/x/sys" + packages = ["unix"] + revision = "d99a578cf41bfccdeaf48b0845c823a4b8b0ad5e" + +[[projects]] + name = "golang.org/x/text" + packages = [ + "collate", + "collate/build", + "internal/colltab", + "internal/gen", + "internal/tag", + "internal/triegen", + "internal/ucd", + "language", + "secure/bidirule", + "transform", + "unicode/bidi", + "unicode/cldr", + "unicode/norm", + "unicode/rangetable" + ] + revision = "f21a4dfb5e38f5895301dc265a8def02365cc3d0" + version = "v0.3.0" + +[[projects]] + branch = "master" + name = "google.golang.org/genproto" + packages = ["googleapis/rpc/status"] + revision = "c66870c02cf823ceb633bcd05be3c7cda29976f4" + +[[projects]] + name = "google.golang.org/grpc" + packages = [ + ".", + "balancer", + "balancer/base", + "balancer/roundrobin", + "codes", + "connectivity", + "credentials", + "encoding", + "encoding/proto", + "grpclog", + "health", + "health/grpc_health_v1", + "internal", + "internal/backoff", + "internal/channelz", + "internal/envconfig", + "internal/grpcrand", + "internal/transport", + "keepalive", + "metadata", + "naming", + "peer", + "resolver", + "resolver/dns", + "resolver/passthrough", + "stats", + "status", + "tap" + ] + revision = "32fb0ac620c32ba40a4626ddf94d90d12cce3455" + version = "v1.14.0" + +[solve-meta] + analyzer-name = "dep" + analyzer-version = 1 + inputs-digest = "9e905932948152cd2fb98b57a83d1502a2cbe6aa286aafa319cbe9bce78d31d2" + solver-name = "gps-cdcl" + solver-version = 1 diff --git a/Gopkg.toml b/Gopkg.toml new file mode 100644 index 0000000..b32c21c --- /dev/null +++ b/Gopkg.toml @@ -0,0 +1,38 @@ +# Gopkg.toml example +# +# Refer to https://github.com/golang/dep/blob/master/docs/Gopkg.toml.md +# for detailed Gopkg.toml documentation. +# +# required = ["github.com/user/thing/cmd/thing"] +# ignored = ["github.com/user/project/pkgX", "bitbucket.org/user/project/pkgA/pkgY"] +# +# [[constraint]] +# name = "github.com/user/project" +# version = "1.0.0" +# +# [[constraint]] +# name = "github.com/user/project2" +# branch = "dev" +# source = "github.com/myfork/project2" +# +# [[override]] +# name = "github.com/x/y" +# version = "2.4.0" +# +# [prune] +# non-go = false +# go-tests = true +# unused-packages = true + + +[[constraint]] + name = "github.com/hashicorp/terraform" + version = "0.11.8" + +[[constraint]] + name = "github.com/vinyldns/go-vinyldns" + version = "0.8.0" + +[prune] + go-tests = true + unused-packages = true diff --git a/NOTICE b/NOTICE new file mode 100644 index 0000000..1b97ce3 --- /dev/null +++ b/NOTICE @@ -0,0 +1,17 @@ +terraform-provider-vinyldns + +Copyright 2018 Comcast Cable Communications Management, LLC + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + +http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. + +This product includes software developed at Comcast (http://www.comcast.com/). diff --git a/PULL_REQUEST_TEMPLATE.md b/PULL_REQUEST_TEMPLATE.md new file mode 100644 index 0000000..0cd1787 --- /dev/null +++ b/PULL_REQUEST_TEMPLATE.md @@ -0,0 +1,42 @@ +### Requirements + +* Filling out the template is required. Any pull request that does not include enough information to be reviewed in a timely manner may be closed at the maintainers' discretion. +* All new code requires tests to ensure against regressions. + +### Description of the Change + + + +### Why Should This Be In The Package? + + + +### Benefits + + + +### Possible Drawbacks + + + +### Verification Process + + + +### Applicable Issues (Optional) + + diff --git a/README.md b/README.md new file mode 100644 index 0000000..4812723 --- /dev/null +++ b/README.md @@ -0,0 +1,99 @@ +# terraform-provider-vinyldns + +A [Terraform](https://terraform.io) provider for the [VinylDNS](https://github.com/vinyldns/vinyldns) DNS as a service API. + +* [Terraform](http://terraform.io) +* [VinylDNS](https://www.vinyldns.io) + +See `example.tf` for an example `.tf` file. See `website/docs` for documentation. + +## Installation + +1. Download the desired release version for your operating system from [GitHub](https://github.com/vinyldns/terraform-provider-vinyldns/releases). +2. Untar the download contents +3. Install the `terraform-provider-vinyldns` anywhere on your system +4. Add `terraform-provider-vinyldns` to your `~/.terraformrc` file: + +``` +providers { + "vinyldns" = "path/to/your/terraform-provider-vinyldns" +} +``` + +### Installing from source + +Alternatively, you can install from source: + +* install Golang (1.10 currently required) +* establish your `$GOPATH` +* clone `vinyldns/terraform-provider-vinyldns` to `/$GOPATH/src/github.com/vinyldns/terraform-provider-vinyldns` +* `cd /$GOPATH/github.com/vinyldns/terraform-provider-vinyldns && make` +* Add the following to your `~/.terraformrc`: + +``` +providers { + "vinyldns" = "path/to/your/terraform-provider-vinyldns" +} +``` + +## Running acceptance tests + +The `terraform-provider-vinyldns` acceptance tests assume a VinylDNS API is running on `localhost:9000`. + +To run a local VinylDNS API, you'll need to: + +``` +git clone git@github.com:vinyldns/vinyldns.git +cd vinyldns +bin/docker-up-api-server.sh +``` + +Then, to run the `terraform-provider-vinyldns` acceptance tests against the local Dockerized VinylDNS API server: + +``` +make test +``` + +## Building + +To build `terraform-provider-vinyldns` binaries for all supported platforms: + +``` +make build +``` + +### Building in Docker + +The project contains a `docker-compose.yml`/`Dockerfile` that will perform a test build in a empty container. To run: + +``` +docker-compose build +``` + +## Upgrading Dependencies + +`dep` is used to manage dependencies. To require a specific version of `github.com/vinyldns/go-vinyldns`: + +To add a dependency: + +``` +dep ensure -add github.com/pkg/errors +``` + +## Credits + +`terraform-provider-vinyldns` would not be possible without the help of many other pieces of open source software. Thank you open source world! + +Given the Apache 2.0 license of `terraform-provider-vinyldns`, we specifically want to call out the following packages and their corresponding licenses: + +* [github.com/hashicorp/errwrap](https://github.com/hashicorp/errwrap) - Mozilla Public License 2.0 +* [github.com/hashicorp/go-getter](https://github.com/hashicorp/go-getter) - Mozilla Public License 2.0 +* [github.com/hashicorp/go-multierror](https://github.com/hashicorp/go-multierror) - Mozilla Public License 2.0 +* [github.com/hashicorp/go-plugin](https://github.com/hashicorp/go-plugin) - Mozilla Public License 2.0 +* [github.com/hashicorp/go-uuid](https://github.com/hashicorp/go-uuid) - Mozilla Public License 2.0 +* [github.com/hashicorp/go-version](https://github.com/hashicorp/go-version) - Mozilla Public License 2.0 +* [github.com/hashicorp/hcl](https://github.com/hashicorp/hcl) - Mozilla Public License 2.0 +* [github.com/hashicorp/hil](https://github.com/hashicorp/hil) - Mozilla Public License 2.0 +* [github.com/hashicorp/logutils](https://github.com/hashicorp/logutils) - Mozilla Public License 2.0 +* [github.com/hashicorp/terraform](github.com/hashicorp/terraform) - Mozilla Public License 2.0 +* [github.com/hashicorp/yamux](https://github.com/hashicorp/yamux) - Mozilla Public License 2.0 diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..3541e28 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,4 @@ +build: + build: . + volumes: + - ./build:/go/src/github.com/vinyldns/terraform-provider-vinyldns/build diff --git a/example.tf b/example.tf new file mode 100644 index 0000000..abf113d --- /dev/null +++ b/example.tf @@ -0,0 +1,31 @@ +resource "vinyldns_group" "test_group" { + name = "terraform-provider-test-group" +} + +resource "vinyldns_zone" "test_zone" { + name = "system-test." + email = "foo@bar.com" + admin_group_id = "${vinyldns_group.test_group.id}" + zone_connection { + name = "vinyldns." + key_name = "vinyldns." + key = "123" + primary_server = "127.0.0.1" + } +} + +resource "vinyldns_record_set" "test_record_set" { + name = "terraformtestrecordset" + zone_id = "${vinyldns_zone.test_zone.id}" + type = "A" + ttl = 6000 + record_addresses = ["127.0.0.1"] +} + +resource "vinyldns_record_set" "another_test_record_set" { + name = "another-terraformtestrecordset" + zone_id = "${vinyldns_zone.test_zone.id}" + type = "CNAME" + ttl = 6000 + record_cname = "foo-bar.com." +} diff --git a/main.go b/main.go new file mode 100644 index 0000000..b0a646e --- /dev/null +++ b/main.go @@ -0,0 +1,24 @@ +/* +Copyright 2018 Comcast Cable Communications Management, LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "github.com/hashicorp/terraform/plugin" + "github.com/vinyldns/terraform-provider-vinyldns/vinyldns" +) + +func main() { + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: vinyldns.Provider, + }) +} diff --git a/vinyldns/provider.go b/vinyldns/provider.go new file mode 100644 index 0000000..0a37579 --- /dev/null +++ b/vinyldns/provider.go @@ -0,0 +1,79 @@ +/* +Copyright 2018 Comcast Cable Communications Management, LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vinyldns + +import ( + "os" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" + "github.com/vinyldns/go-vinyldns/vinyldns" +) + +// Provider returns a schema.Provider for VinylDNS. +func Provider() terraform.ResourceProvider { + return &schema.Provider{ + Schema: map[string]*schema.Schema{ + "access_key": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: envDefaultFunc("VINYLDNS_ACCESS_KEY"), + }, + "secret_key": &schema.Schema{ + Type: schema.TypeString, + Required: true, + DefaultFunc: envDefaultFunc("VINYLDNS_SECRET_KEY"), + }, + "host": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + DefaultFunc: envDefaultFunc("VINYLDNS_HOST"), + }, + }, + + ResourcesMap: map[string]*schema.Resource{ + "vinyldns_group": resourceVinylDNSGroup(), + "vinyldns_zone": resourceVinylDNSZone(), + "vinyldns_record_set": resourceVinylDNSRecordSet(), + }, + + ConfigureFunc: providerConfigure, + } +} + +func envDefaultFunc(k string) schema.SchemaDefaultFunc { + return func() (interface{}, error) { + if v := os.Getenv(k); v != "" { + return v, nil + } + + return nil, nil + } +} + +func envDefaultFuncAllowMissing(k string) schema.SchemaDefaultFunc { + return func() (interface{}, error) { + v := os.Getenv(k) + return v, nil + } +} + +func providerConfigure(d *schema.ResourceData) (interface{}, error) { + config := vinyldns.ClientConfiguration{ + AccessKey: d.Get("access_key").(string), + SecretKey: d.Get("secret_key").(string), + Host: d.Get("host").(string), + } + + return vinyldns.NewClient(config), nil +} diff --git a/vinyldns/provider_test.go b/vinyldns/provider_test.go new file mode 100644 index 0000000..edd933a --- /dev/null +++ b/vinyldns/provider_test.go @@ -0,0 +1,40 @@ +/* +Copyright 2018 Comcast Cable Communications Management, LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vinyldns + +import ( + "testing" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/hashicorp/terraform/terraform" +) + +var testAccProviders map[string]terraform.ResourceProvider +var testAccProvider *schema.Provider + +func init() { + testAccProvider = Provider().(*schema.Provider) + testAccProviders = map[string]terraform.ResourceProvider{ + "vinyldns": testAccProvider, + } +} + +func TestProvider(t *testing.T) { + if err := Provider().(*schema.Provider).InternalValidate(); err != nil { + t.Fatalf("err: %s", err) + } +} + +func testAccPreCheck(t *testing.T) { + +} diff --git a/vinyldns/resource_group.go b/vinyldns/resource_group.go new file mode 100644 index 0000000..dcf3ff4 --- /dev/null +++ b/vinyldns/resource_group.go @@ -0,0 +1,163 @@ +/* +Copyright 2018 Comcast Cable Communications Management, LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vinyldns + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform/helper/schema" + "github.com/vinyldns/go-vinyldns/vinyldns" +) + +func resourceVinylDNSGroup() *schema.Resource { + return &schema.Resource{ + Create: resourceVinylDNSGroupCreate, + Read: resourceVinylDNSGroupRead, + Update: resourceVinylDNSGroupUpdate, + Delete: resourceVinylDNSGroupDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "email": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "description": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "member": userSchema(), + "admin": userSchema(), + }, + } +} + +func resourceVinylDNSGroupCreate(d *schema.ResourceData, meta interface{}) error { + name := d.Get("name").(string) + log.Printf("[INFO] Creating Group: %s", name) + created, err := meta.(*vinyldns.Client).GroupCreate(&vinyldns.Group{ + Name: d.Get("name").(string), + Email: d.Get("email").(string), + Description: d.Get("description").(string), + Members: users("member", d), + Admins: users("admin", d), + }) + if err != nil { + return err + } + + d.SetId(created.ID) + + return resourceVinylDNSGroupRead(d, meta) +} + +func resourceVinylDNSGroupRead(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Reading vinyldns group: %s", d.Id()) + g, err := meta.(*vinyldns.Client).Group(d.Id()) + if err != nil { + return err + } + + d.Set("name", g.Name) + + return nil +} + +func resourceVinylDNSGroupUpdate(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Updating vinyldns group: %s", d.Id()) + _, err := meta.(*vinyldns.Client).GroupUpdate(d.Id(), &vinyldns.Group{ + ID: d.Id(), + Name: d.Get("name").(string), + Email: d.Get("email").(string), + Description: d.Get("description").(string), + Members: users("member", d), + Admins: users("admin", d), + }) + if err != nil { + return err + } + + return resourceVinylDNSGroupRead(d, meta) +} + +func resourceVinylDNSGroupDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Deleting vinyldns group: %s", d.Id()) + + _, err := meta.(*vinyldns.Client).GroupDelete(d.Id()) + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func userSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "user_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "first_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "last_name": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "email": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "created": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + } +} + +func users(userType string, d *schema.ResourceData) []vinyldns.User { + users := []vinyldns.User{} + usersCount := d.Get(fmt.Sprintf("%s.#", userType)).(int) + + for i := 0; i < usersCount; i++ { + prefix := fmt.Sprintf("%s.%d", userType, i) + + users = append(users, vinyldns.User{ + UserName: d.Get(prefix + ".user_name").(string), + FirstName: d.Get(prefix + ".first_name").(string), + LastName: d.Get(prefix + ".last_name").(string), + Email: d.Get(prefix + ".email").(string), + Created: d.Get(prefix + ".created").(string), + ID: d.Get(prefix + ".id").(string), + }) + } + + return users +} diff --git a/vinyldns/resource_group_test.go b/vinyldns/resource_group_test.go new file mode 100644 index 0000000..3f1dd40 --- /dev/null +++ b/vinyldns/resource_group_test.go @@ -0,0 +1,94 @@ +/* +Copyright 2018 Comcast Cable Communications Management, LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vinyldns + +import ( + "fmt" + "testing" + + "github.com/vinyldns/go-vinyldns/vinyldns" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" +) + +func TestAccVinylDNSGroupBasic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccVinylDNSGroupDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccVinylDNSGroupConfigBasic, + Check: resource.ComposeTestCheckFunc( + testAccCheckVinylDNSGroupExists("vinyldns_group.test_group"), + resource.TestCheckResourceAttr("vinyldns_group.test_group", "name", "terraformtestgroup"), + ), + }, + }, + }) +} + +func testAccVinylDNSGroupDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*vinyldns.Client) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "vinyldns_group" { + continue + } + + // Try to find the group + _, err := client.Group(rs.Primary.ID) + if err == nil { + return fmt.Errorf("Group %s still exists", rs.Primary.ID) + } + } + + return nil +} + +func testAccCheckVinylDNSGroupExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found %s", rs) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No Group ID is set") + } + + client := testAccProvider.Meta().(*vinyldns.Client) + + g, err := client.Group(rs.Primary.ID) + if err != nil { + return err + } + + if g.Name != "terraformtestgroup" { + return fmt.Errorf("Group not found") + } + if g.Description != "some description" { + return fmt.Errorf("Group 'description' not set") + } + + return nil + } +} + +const testAccVinylDNSGroupConfigBasic = ` +resource "vinyldns_group" "test_group" { + name = "terraformtestgroup" + description = "some description" + email = "tftest@tf.com" +}` diff --git a/vinyldns/resource_record_set.go b/vinyldns/resource_record_set.go new file mode 100644 index 0000000..4a21cfc --- /dev/null +++ b/vinyldns/resource_record_set.go @@ -0,0 +1,279 @@ +package vinyldns + +import ( + "errors" + "log" + "net/http" + "strings" + "time" + + "github.com/hashicorp/terraform/helper/hashcode" + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/vinyldns/go-vinyldns/vinyldns" +) + +func resourceVinylDNSRecordSet() *schema.Resource { + return &schema.Resource{ + Create: resourceVinylDNSRecordSetCreate, + Read: resourceVinylDNSRecordSetRead, + Update: resourceVinylDNSRecordSetUpdate, + Delete: resourceVinylDNSRecordSetDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "zone_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "type": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "ttl": &schema.Schema{ + Type: schema.TypeInt, + Optional: true, + }, + "account": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "record_addresses": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: func(v interface{}) int { + return hashcode.String(v.(string)) + }, + }, + /* + // NS records are not currently supported by vinyldns + "record_nsdnames": &schema.Schema{ + Type: schema.TypeSet, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + Set: func(v interface{}) int { + return hashcode.String(v.(string)) + }, + }, + */ + "record_cname": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + "record_text": &schema.Schema{ + Type: schema.TypeString, + Optional: true, + }, + }, + } +} + +func resourceVinylDNSRecordSetCreate(d *schema.ResourceData, meta interface{}) error { + name := d.Get("name").(string) + log.Printf("[INFO] Creating vinyldns record set: %s", name) + records, err := records(d) + if err != nil { + return err + } + created, err := meta.(*vinyldns.Client).RecordSetCreate(d.Get("zone_id").(string), &vinyldns.RecordSet{ + Name: d.Get("name").(string), + ZoneID: d.Get("zone_id").(string), + Type: d.Get("type").(string), + TTL: d.Get("ttl").(int), + Records: records, + }) + if err != nil { + return err + } + + d.SetId(created.RecordSet.ID) + + err = waitUntilRecordSetDeployed(d, meta, created.ChangeID) + if err != nil { + return err + } + + return resourceVinylDNSRecordSetRead(d, meta) +} + +func resourceVinylDNSRecordSetRead(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Reading vinyldns record set: %s", d.Id()) + rs, err := meta.(*vinyldns.Client).RecordSet(d.Get("zone_id").(string), d.Id()) + if err != nil { + return err + } + + d.Set("name", rs.Name) + + return nil +} + +func resourceVinylDNSRecordSetUpdate(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Updating vinyldns record set: %s", d.Id()) + records, err := records(d) + if err != nil { + return err + } + updated, err := meta.(*vinyldns.Client).RecordSetUpdate(d.Get("zone_id").(string), d.Id(), &vinyldns.RecordSet{ + Name: d.Get("name").(string), + ID: d.Id(), + ZoneID: d.Get("zone_id").(string), + Type: d.Get("type").(string), + TTL: d.Get("ttl").(int), + Records: records, + }) + if err != nil { + return err + } + + err = waitUntilRecordSetDeployed(d, meta, updated.ChangeID) + if err != nil { + return err + } + + return resourceVinylDNSRecordSetRead(d, meta) +} + +func resourceVinylDNSRecordSetDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Deleting vinyldns record set: %s", d.Id()) + + deleted, err := meta.(*vinyldns.Client).RecordSetDelete(d.Get("zone_id").(string), d.Id()) + if err != nil { + return err + } + + err = waitUntilRecordSetDeployed(d, meta, deleted.ChangeID) + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func records(d *schema.ResourceData) ([]vinyldns.Record, error) { + recordType := d.Get("type").(string) + + if recordType == "CNAME" { + cname := d.Get("record_cname").(string) + + if string(cname[len(cname)-1:]) != "." { + return []vinyldns.Record{}, errors.New("record_cname must end in trailing '.'") + } + + return []vinyldns.Record{ + vinyldns.Record{ + CName: cname, + }, + }, nil + } + + // NS and SOA records are currently read-only and cannot be created, updated or deleted by vinyldns + if recordType == "NS" || recordType == "SOA" { + return []vinyldns.Record{}, errors.New(recordType + " records are not currently supported by vinyldns") + + //return nsRecordSets(stringSetToStringSlice(d.Get("record_nsdnames").(*schema.Set))), nil + } + + if recordType == "TXT" { + //return txtRecordSets(d.Get("record_text").(string)), nil + txt := d.Get("record_text").(string) + return []vinyldns.Record{ + vinyldns.Record{ + Text: txt, + }, + }, nil + } + + return addressRecordSets(stringSetToStringSlice(d.Get("record_addresses").(*schema.Set))), nil +} + +func addressRecordSets(addresses []string) []vinyldns.Record { + records := []vinyldns.Record{} + recordsCount := len(addresses) + + for i := 0; i < recordsCount; i++ { + records = append(records, vinyldns.Record{ + Address: removeBrackets(addresses[i]), + }) + } + + return records +} + +func nsRecordSets(nsdnames []string) []vinyldns.Record { + records := []vinyldns.Record{} + recordsCount := len(nsdnames) + + for i := 0; i < recordsCount; i++ { + records = append(records, vinyldns.Record{ + NSDName: nsdnames[i], + }) + } + + return records +} + +func stringSetToStringSlice(stringSet *schema.Set) []string { + ret := []string{} + if stringSet == nil { + return ret + } + for _, envVal := range stringSet.List() { + ret = append(ret, envVal.(string)) + } + return ret +} + +func waitUntilRecordSetDeployed(d *schema.ResourceData, meta interface{}, status string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"Pending", ""}, + Target: []string{"Complete"}, + Refresh: recordSetStateRefreshFunc(d, meta, status), + Timeout: 30 * time.Minute, + Delay: 500 * time.Millisecond, + MinTimeout: 15 * time.Second, + PollInterval: 500 * time.Millisecond, + } + + _, err := stateConf.WaitForState() + return err +} + +func recordSetStateRefreshFunc(d *schema.ResourceData, meta interface{}, status string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + log.Printf("[INFO] waiting for %v Complete status", d.Id()) + rsc, err := meta.(*vinyldns.Client).RecordSetChange(d.Get("zone_id").(string), d.Id(), status) + if err != nil { + if dErr, ok := err.(*vinyldns.Error); ok { + if dErr.ResponseCode == http.StatusNotFound { + return nil, "Pending", nil + } + + log.Printf("[ERROR] %#v", err) + return nil, "", err + } + + log.Printf("[ERROR] %#v", err) + return nil, "", err + } + + if rsc.Status == "Failed" { + err = errors.New("record set status Failed") + log.Printf("[ERROR] record set status Failed: %#v", err) + return rsc, rsc.Status, err + } + + return rsc, rsc.Status, nil + } +} + +// vinyldns responds 400 to IPv6 addresses represented within `[` `]` +func removeBrackets(str string) string { + return strings.Replace(strings.Replace(str, "[", "", -1), "]", "", -1) +} diff --git a/vinyldns/resource_record_set_test.go b/vinyldns/resource_record_set_test.go new file mode 100644 index 0000000..1cc4da1 --- /dev/null +++ b/vinyldns/resource_record_set_test.go @@ -0,0 +1,165 @@ +/* +Copyright 2018 Comcast Cable Communications Management, LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vinyldns + +import ( + "fmt" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/vinyldns/go-vinyldns/vinyldns" +) + +func TestAccVinylDNSRecordSetBasic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccVinylDNSRecordSetDestroy, + Steps: []resource.TestStep{ + resource.TestStep{ + Config: testAccVinylDNSRecordSetConfigBasic, + Check: resource.ComposeTestCheckFunc( + testAccCheckVinylDNSRecordSetExists("vinyldns_record_set.test_a_record_set"), + testAccCheckVinylDNSRecordSetExists("vinyldns_record_set.test_cname_record_set"), + testAccCheckVinylDNSRecordSetExists("vinyldns_record_set.test_txt_record_set"), + resource.TestCheckResourceAttr("vinyldns_record_set.test_a_record_set", "name", "terraformtestrecordset"), + resource.TestCheckResourceAttr("vinyldns_record_set.test_cname_record_set", "name", "cname-terraformtestrecordset"), + resource.TestCheckResourceAttr("vinyldns_record_set.test_txt_record_set", "name", "txt-terraformtestrecordset"), + ), + }, + }, + }) +} + +func testAccVinylDNSRecordSetDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*vinyldns.Client) + + for _, rs := range s.RootModule().Resources { + if rs.Type != "vinyldns_record_set" { + continue + } + id := rs.Primary.ID + testZId, err := testZoneID() + if err != nil { + return fmt.Errorf("Error fetching system-test. zone ID") + } + + // Try to find the record set + _, err = client.RecordSet(testZId, id) + if err == nil { + return fmt.Errorf("RecordSet %s still exists", id) + } + } + + return nil +} + +func testAccCheckVinylDNSRecordSetExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found %s", rs) + } + + if rs.Primary.ID == "" { + return fmt.Errorf("No RecordSet ID is set") + } + + client := testAccProvider.Meta().(*vinyldns.Client) + testZId, err := testZoneID() + if err != nil { + return fmt.Errorf("Error fetching system-test. zone ID") + } + if testZId == "" { + return fmt.Errorf("Could not find system-test. zone ID") + } + + readRs, err := client.RecordSet(testZId, rs.Primary.ID) + if err != nil { + return err + } + + if readRs.Name != rs.Primary.Attributes["name"] { + return fmt.Errorf("Record not found") + } + + return nil + } +} + +func testZoneID() (string, error) { + client := testAccProvider.Meta().(*vinyldns.Client) + zones, err := client.Zones() + if err != nil { + return "", err + } + + for _, each := range zones { + fmt.Println(each) + if each.Name == "system-test." { + return each.ID, nil + } + } + + return "", nil +} + +const testAccVinylDNSRecordSetConfigBasic = ` +resource "vinyldns_group" "test_group" { + name = "terraformtestgroup" + description = "some description" + email = "tftest@tf.com" +} + +resource "vinyldns_zone" "test_zone" { + name = "system-test." + email = "foo@bar.com" + admin_group_id = "${vinyldns_group.test_group.id}" + depends_on = [ + "vinyldns_group.test_group" + ] +} + +resource "vinyldns_record_set" "test_a_record_set" { + name = "terraformtestrecordset" + zone_id = "${vinyldns_zone.test_zone.id}" + type = "A" + ttl = 6000 + record_addresses = ["127.0.0.1", "127.0.0.1"] + depends_on = [ + "vinyldns_zone.test_zone" + ] +} + +resource "vinyldns_record_set" "test_cname_record_set" { + name = "cname-terraformtestrecordset" + zone_id = "${vinyldns_zone.test_zone.id}" + type = "CNAME" + ttl = 6000 + record_cname = "terraformtestrecordset.system-test." + depends_on = [ + "vinyldns_record_set.test_a_record_set" + ] +} + +resource "vinyldns_record_set" "test_txt_record_set" { + name = "txt-terraformtestrecordset" + zone_id = "${vinyldns_zone.test_zone.id}" + type = "TXT" + ttl = 6000 + record_text = "Lorem ipsum and all that jazz" + depends_on = [ + "vinyldns_zone.test_zone" + ] +}` diff --git a/vinyldns/resource_zone.go b/vinyldns/resource_zone.go new file mode 100644 index 0000000..322d815 --- /dev/null +++ b/vinyldns/resource_zone.go @@ -0,0 +1,306 @@ +/* +Copyright 2018 Comcast Cable Communications Management, LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vinyldns + +import ( + "errors" + "log" + "time" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/helper/schema" + "github.com/vinyldns/go-vinyldns/vinyldns" +) + +func resourceVinylDNSZone() *schema.Resource { + return &schema.Resource{ + Create: resourceVinylDNSZoneCreate, + Read: resourceVinylDNSZoneRead, + Update: resourceVinylDNSZoneUpdate, + Delete: resourceVinylDNSZoneDelete, + + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "email": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "admin_group_id": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "status": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "created": &schema.Schema{ + Type: schema.TypeString, + Computed: true, + }, + "transfer_connection": connectionSchema(), + "zone_connection": connectionSchema(), + }, + } +} + +func resourceVinylDNSZoneCreate(d *schema.ResourceData, meta interface{}) error { + name := d.Get("name").(string) + log.Printf("[INFO] Creating vinyldns zone: %s", name) + change, err := meta.(*vinyldns.Client).ZoneCreate(zone(d)) + if err != nil { + return err + } + + log.Printf("[INFO] Setting *schema.ResourceData zone ID to: %s", change.Zone.ID) + + d.SetId(change.Zone.ID) + + log.Printf("[INFO] *schema.ResourceData ID: %s", d.Id()) + + err = waitUntilZoneCreated(d, meta) + if err != nil { + return err + } + + return resourceVinylDNSZoneRead(d, meta) +} + +func resourceVinylDNSZoneRead(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Reading vinyldns zone: %s", d.Id()) + zone, err := meta.(*vinyldns.Client).Zone(d.Id()) + if err != nil { + return err + } + + d.Set("name", zone.Name) + + return nil +} + +func resourceVinylDNSZoneUpdate(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Updating vinyldns zone: %s", d.Id()) + change, err := meta.(*vinyldns.Client).ZoneUpdate(d.Id(), zone(d)) + if err != nil { + return err + } + + err = waitUntilZoneChangeDeployed(d, meta, change.Zone.ID) + if err != nil { + return err + } + + return resourceVinylDNSZoneRead(d, meta) +} + +func zoneConnection(d *schema.ResourceData) *vinyldns.ZoneConnection { + name := d.Get("zone_connection.0.name").(string) + + if name != "" { + log.Printf("[INFO] setting zone connection: %s", d.Get("zone_connection.0.name")) + return &vinyldns.ZoneConnection{ + Name: name, + Key: d.Get("zone_connection.0.key").(string), + KeyName: d.Get("zone_connection.0.key_name").(string), + PrimaryServer: d.Get("zone_connection.0.primary_server").(string), + } + } + + return &vinyldns.ZoneConnection{} +} + +func transferConnection(d *schema.ResourceData) *vinyldns.ZoneConnection { + name := d.Get("transfer_connection.0.name").(string) + + if name != "" { + log.Printf("[INFO] setting transfer connection: %s", d.Get("transfer_connection.0.name")) + return &vinyldns.ZoneConnection{ + Name: name, + Key: d.Get("transfer_connection.0.key").(string), + KeyName: d.Get("transfer_connection.0.key_name").(string), + PrimaryServer: d.Get("transfer_connection.0.primary_server").(string), + } + } + + return &vinyldns.ZoneConnection{} +} + +func resourceVinylDNSZoneDelete(d *schema.ResourceData, meta interface{}) error { + log.Printf("[INFO] Deleting vinyldns zone: %s", d.Id()) + + _, err := meta.(*vinyldns.Client).ZoneDelete(d.Id()) + if err != nil { + return err + } + + err = waitUntilZoneDeleted(d, meta, d.Id()) + if err != nil { + return err + } + + d.SetId("") + + return nil +} + +func waitUntilZoneChangeDeployed(d *schema.ResourceData, meta interface{}, changeID string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"Pending", ""}, + Target: []string{"Synced"}, + Refresh: zoneStateRefreshFunc(d, meta, changeID), + Timeout: 30 * time.Minute, + Delay: 500 * time.Millisecond, + MinTimeout: 15 * time.Second, + PollInterval: 500 * time.Millisecond, + } + + _, err := stateConf.WaitForState() + return err +} + +func zoneStateRefreshFunc(d *schema.ResourceData, meta interface{}, changeID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + log.Printf("[INFO] waiting for Complete status of %v, %s", d.Get("name"), d.Id()) + zc, err := meta.(*vinyldns.Client).ZoneChange(d.Id(), changeID) + if err != nil { + log.Printf("[ERROR] %#v", err) + return nil, "", err + } + if zc.Status == "Failed" { + err = errors.New("zone status Failed") + log.Printf("[ERROR] zone status Failed: %#v", err) + return zc, zc.Status, err + } + + return zc, zc.Status, nil + } +} + +func waitUntilZoneDeleted(d *schema.ResourceData, meta interface{}, zoneID string) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"Pending"}, + Target: []string{"Deleted"}, + Refresh: zoneDeletedStateRefreshFunc(d, meta, zoneID), + Timeout: 30 * time.Minute, + Delay: 500 * time.Millisecond, + MinTimeout: 15 * time.Second, + PollInterval: 500 * time.Millisecond, + } + + _, err := stateConf.WaitForState() + return err +} + +func zoneDeletedStateRefreshFunc(d *schema.ResourceData, meta interface{}, zoneID string) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + state := "Pending" + + log.Printf("[INFO] waiting for successful deletion of %v, %s", d.Get("name"), d.Id()) + exists, err := meta.(*vinyldns.Client).ZoneExists(d.Id()) + if err != nil { + log.Printf("[ERROR] %#v", err) + return nil, "", err + } + + if !exists { + state = "Deleted" + } + + return &zoneState{State: state}, state, err + } +} + +func waitUntilZoneCreated(d *schema.ResourceData, meta interface{}) error { + stateConf := &resource.StateChangeConf{ + Pending: []string{"Pending"}, + Target: []string{"Created"}, + Refresh: zoneCreatedStateRefreshFunc(d, meta), + Timeout: 30 * time.Minute, + Delay: 500 * time.Millisecond, + MinTimeout: 15 * time.Second, + PollInterval: 500 * time.Millisecond, + } + + _, err := stateConf.WaitForState() + return err +} + +func zoneCreatedStateRefreshFunc(d *schema.ResourceData, meta interface{}) resource.StateRefreshFunc { + return func() (interface{}, string, error) { + state := "Pending" + + log.Printf("[INFO] waiting for successful creation of %v, %s", d.Get("name"), d.Id()) + exists, err := meta.(*vinyldns.Client).ZoneExists(d.Id()) + if err != nil { + log.Printf("[ERROR] %#v", err) + return nil, "", err + } + + if exists { + state = "Created" + } + + return &zoneState{State: state}, state, err + } +} + +type zoneState struct { + State string +} + +func connectionSchema() *schema.Schema { + return &schema.Schema{ + Type: schema.TypeList, + Optional: true, + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "key": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "key_name": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + "primary_server": &schema.Schema{ + Type: schema.TypeString, + Required: true, + }, + }, + }, + } +} + +func zone(d *schema.ResourceData) *vinyldns.Zone { + zone := &vinyldns.Zone{ + Name: d.Get("name").(string), + Email: d.Get("email").(string), + AdminGroupID: d.Get("admin_group_id").(string), + } + + if d.Get("zone_connection.0.name").(string) != "" { + zone.Connection = zoneConnection(d) + } + + if d.Get("transfer_connection.0.name").(string) != "" { + zone.TransferConnection = transferConnection(d) + } + + return zone +} diff --git a/vinyldns/resource_zone_test.go b/vinyldns/resource_zone_test.go new file mode 100644 index 0000000..000679c --- /dev/null +++ b/vinyldns/resource_zone_test.go @@ -0,0 +1,105 @@ +/* +Copyright 2018 Comcast Cable Communications Management, LLC +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package vinyldns + +import ( + "fmt" + "log" + "testing" + + "github.com/hashicorp/terraform/helper/resource" + "github.com/hashicorp/terraform/terraform" + "github.com/vinyldns/go-vinyldns/vinyldns" +) + +func TestAccVinylDNSZoneBasic(t *testing.T) { + resource.Test(t, resource.TestCase{ + PreCheck: func() { testAccPreCheck(t) }, + Providers: testAccProviders, + CheckDestroy: testAccVinylDNSZoneDestroy, + Steps: []resource.TestStep{ + { + Config: testAccVinylDNSZoneConfigBasic, + Check: resource.ComposeTestCheckFunc( + testAccCheckVinylDNSZoneExists("vinyldns_zone.test_zone"), + resource.TestCheckResourceAttr("vinyldns_zone.test_zone", "name", "system-test."), + resource.TestCheckResourceAttr("vinyldns_zone.test_zone", "email", "foo@bar.com"), + ), + }, + }, + }) +} + +func testAccVinylDNSZoneDestroy(s *terraform.State) error { + client := testAccProvider.Meta().(*vinyldns.Client) + + for _, rs := range s.RootModule().Resources { + log.Printf("[INFO] testing zone destruction; rs.Type: %s", rs.Type) + if rs.Type != "vinyldns_zone" { + continue + } + id := rs.Primary.ID + + log.Printf("[INFO] testing zone destruction: %s", id) + + // Try to find the zone + _, err := client.Zone(id) + if err == nil { + return fmt.Errorf("Zone still exists") + } + } + + return nil +} + +func testAccCheckVinylDNSZoneExists(n string) resource.TestCheckFunc { + return func(s *terraform.State) error { + rs, ok := s.RootModule().Resources[n] + if !ok { + return fmt.Errorf("Not found %s", rs) + } + log.Printf("[INFO] testing that zone exists: %s", rs.Primary.ID) + + if rs.Primary.ID == "" { + return fmt.Errorf("No Zone ID is set") + } + + client := testAccProvider.Meta().(*vinyldns.Client) + + readZone, err := client.Zone(rs.Primary.ID) + if err != nil { + return err + } + + if readZone.Name != "system-test." { + return fmt.Errorf("Zone not found") + } + + return nil + } +} + +const testAccVinylDNSZoneConfigBasic = ` +resource "vinyldns_group" "test_group" { + name = "terraformtestgroup" + description = "some description" + email = "tftest@tf.com" +} +resource "vinyldns_zone" "test_zone" { + name = "system-test." + email = "foo@bar.com" + admin_group_id = "${vinyldns_group.test_group.id}" + depends_on = [ + "vinyldns_group.test_group" + ] +}` diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown new file mode 100644 index 0000000..b943f2d --- /dev/null +++ b/website/docs/index.html.markdown @@ -0,0 +1,69 @@ +--- +page_title: "Provider: VinylDNS" +sidebar_current: "docs-vinyldns-index" +description: |- + The VinylDNS provider configures VinylDNS resources. +--- + +# VinylDNS Provider + +The VinylDNS provider configures [VinylDNS](https://www.vinyldns.io/) resources. +VinylDNS is a vendor-agnostic DNS front-end for streamlining DNS operations and +enabling self-service for your DNS infrastructure. + +The provider configuration block accepts the following arguments: + +* ``host`` - (Required) The root URL of a VinylDNS API server. May alternatively be + set via the ``VINYLDNS_HOST`` environment variable. + +* ``access_key`` - (Required) The access key required to authenticate to the + VinylDNS server. May alternatively be set via the ``VINYLDNS_ACCESS_KEY`` + environment variable. + +* ``secret_key`` - (Required) The secret key required to authenticate to the + VinylDNS server. May alternatively be set via the ``VINYLDNS_SECRET_KEY`` + environment variable. + +Use the navigation to the left to read about the available resources. + +## Example Usage + +```hcl +provider "vinyldns" { + host = "http://vinyldns.example.com" + access_key = "123" + secret_key = "123" +} + +resource "vinyldns_group" "test_group" { + name = "terraform-provider-test-group" +} + +resource "vinyldns_zone" "test_zone" { + name = "system-test." + email = "foo@bar.com" + admin_group_id = "${vinyldns_group.test_group.id}" + zone_connection { + name = "vinyldns." + key_name = "vinyldns." + key = "123" + primary_server = "127.0.0.1" + } +} + +resource "vinyldns_record_set" "test_record_set" { + name = "terraformtestrecordset" + zone_id = "${vinyldns_zone.test_zone.id}" + type = "A" + ttl = 6000 + record_addresses = ["127.0.0.1"] +} + +resource "vinyldns_record_set" "another_test_record_set" { + name = "another-terraformtestrecordset" + zone_id = "${vinyldns_zone.test_zone.id}" + type = "CNAME" + ttl = 6000 + record_cname = "foo-bar.com." +} +``` diff --git a/website/docs/r/group.html.md b/website/docs/r/group.html.md new file mode 100644 index 0000000..51f0898 --- /dev/null +++ b/website/docs/r/group.html.md @@ -0,0 +1,59 @@ +--- +page_title: "VinylDNS: vinyldns_group" +sidebar_current: "docs-vinyldns-resource-group" +description: |- + The vinyldns_group resource allows a VinylDNS group to be created and managed. +--- + +# vinyldns\_group + +The group resource allows VinylDNS groups to be created and managed. + +## Example Usage + +```hcl +# Create a VinylDNS group +resource "vinyldns_group" "test_group" { + name = "terraform-provider-test-group" +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name for the group. + +* `email` - (Required) The email address for the group. + +* `description` - (Optional) A description of the group. + +* `member` - (Optional) A member to associate with the group. + See [member](#member) below for details. + +* `admin` - (Optional) An admin to associate with the group. + See [admin](#admin) below for details. + +### Member + +* `username` - (Optional) The member's username. + +* `first_name` - (Optional) The member's first name. + +* `last_name` - (Optional) The member's last name. + +* `email` - (Optional) The member's email address. + +* `id` - (Required) The member's UUID. + +### Admin + +* `username` - (Optional) The member's username. + +* `first_name` - (Optional) The member's first name. + +* `last_name` - (Optional) The member's last name. + +* `email` - (Optional) The member's email address. + +* `id` - (Required) The member's UUID. diff --git a/website/docs/r/record_set.html.md b/website/docs/r/record_set.html.md new file mode 100644 index 0000000..f5f5d48 --- /dev/null +++ b/website/docs/r/record_set.html.md @@ -0,0 +1,56 @@ +--- +layout: "vinyldns" +page_title: "VinylDNS: vinyldns_record_set" +sidebar_current: "docs-vinyldns-resource-record-set" +description: |- + The vinyldns_record_set resource allows a VinylDNS record set to be created and managed. +--- + +# vinyldns\_record_set + +The record set resource allows VinylDNS record sets to be created and managed. + +## Example Usage + +```hcl +resource "vinyldns_record_set" "test_record_set" { + name = "terraformtestrecordset" + zone_id = "123" + type = "A" + ttl = 6000 + record_addresses = ["127.0.0.1"] +} + +resource "vinyldns_record_set" "another_test_record_set" { + name = "another-terraformtestrecordset" + zone_id = "123" + type = "CNAME" + ttl = 6000 + record_cname = "foo-bar.com." +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name for the record set. + +* `zone_id` - (Required) The ID for the record set's zone. + +* `type` - (Required) The type of DNS record. + +* `ttl` - (Optional) The DNS record set's TTL, or time to live. + +* `record_addresses` - (Optional) A list of the record set's addresses. + See [record addresses](#record-addresses) below for details. + +* `record_cname` - (Optional) If the record is a CNAME, the record's value. + +* `record_text` - (Optional) If the record is a text record, the record's value. + +## Attributes Reference + +The following attributes are exported: + +* `account` - The account that created the record set. Note that this is deprecated in VinylDNS and will be removed. diff --git a/website/docs/r/zone.html.md b/website/docs/r/zone.html.md new file mode 100644 index 0000000..59c2b15 --- /dev/null +++ b/website/docs/r/zone.html.md @@ -0,0 +1,76 @@ +--- +page_title: "VinylDNS: vinyldns_zone" +sidebar_current: "docs-vinyldns-resource-zone" +description: |- + The vinyldns_zone resource allows a VinylDNS zone to be created and managed. +--- + +# vinyldns\_zone + +The zone resource allows VinylDNS zones to be created and managed. + +## Example Usage + +```hcl +# Create a VinylDNS group +resource "vinyldns_group" "test_group" { + name = "terraform-provider-test-group" +} + +# Create a VinylDNS zone with a zone connection +resource "vinyldns_zone" "test_zone" { + name = "system-test." + email = "foo@bar.com" + admin_group_id = "${vinyldns_group.test_group.id}" + zone_connection { + name = "vinyldns." + key_name = "vinyldns." + key = "123" + primary_server = "127.0.0.1" + } +} +``` + +## Argument Reference + +The following arguments are supported: + +* `name` - (Required) The name for the zone created. + +* `email` - (Required) The email address to associate with the zone + +* `admin_group_id` - (Required) The group ID of the group to make the zone's admin group + +* `zone_connection` - (Optional) The connection used to issue DDNS updates to the backend zone. + See [zone connection](#zone-connection) below for details. + +* `transfer_connection` - (Optional) The connection that is used to sync the zone with the DNS backend. + See [transfer connection](#transfer-connection) below for details. + +### Zone Connection + +* `name` - (Required) The connection name. + +* `key` - (Required) The TSIG secret key used to sign requests when communicating with the primary server. + +* `key_name` - (Required) The name of the DNS key that has access to the DNS server and zone. + +* `primary_server` - (Required) The IP address or host that is connected to. + +### Transfer Connection + +* `name` - (Required) The connection name. + +* `key` - (Required) The TSIG secret key used to sign requests when communicating with the primary server. + +* `key_name` - (Required) The name of the DNS key that has access to the DNS server and zone. + +* `primary_server` - (Required) The IP address or host that is connected to. + +## Attributes Reference + +The following attributes are exported: + +* `status` - The zone status. + +* `created` - The time when the zone was first created. diff --git a/website/vinyldns.erb b/website/vinyldns.erb new file mode 100644 index 0000000..921391b --- /dev/null +++ b/website/vinyldns.erb @@ -0,0 +1,29 @@ +<% wrap_layout :inner do %> + <% content_for :sidebar do %> + + <% end %> + <%= yield %> +<% end %>