diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 0000000..22c02e4 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,26 @@ +version: 2.1 +jobs: + build: + docker: + - image: circleci/golang:1.13.0 + working_directory: /go/src/github.com/{{ORG_NAME}}/{{REPO_NAME}} + steps: + - checkout + - run: + name: Install golangci-lint + command: curl -sfL https://install.goreleaser.com/github.com/golangci/golangci-lint.sh | sh -s -- -d -b $(go env GOPATH)/bin v1.18.0 + + - run: + name: Run lint + when: always + command: make lint + + - run: + name: Run vet + when: always + command: make vet + + - run: + name: Run tests + when: always + command: make test diff --git a/.gitignore b/.gitignore index 4cbf01e..44b56d5 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,4 @@ website/vendor !command/test-fixtures/**/*.tfstate !command/test-fixtures/**/.terraform/ terraform-provider-appoptics +dist/ diff --git a/.goreleaser.yml b/.goreleaser.yml new file mode 100644 index 0000000..e7469a1 --- /dev/null +++ b/.goreleaser.yml @@ -0,0 +1,29 @@ +before: + hooks: + - go mod tidy +builds: + - + goos: + - darwin + - linux + goarch: + - amd64 + env: + - CGO_ENABLED=0 +archives: + - + replacements: + darwin: Darwin + linux: Linux + 386: i386 + amd64: x86_64 +checksum: + name_template: 'checksums.txt' +snapshot: + name_template: "{{ .Tag }}" +changelog: + sort: asc + filters: + exclude: + - '^docs:' + - '^test:' diff --git a/Makefile b/Makefile index 2122879..147accd 100644 --- a/Makefile +++ b/Makefile @@ -1,52 +1,29 @@ -TEST?=$$(go list ./... |grep -v 'vendor') -WEBSITE_REPO=github.com/hashicorp/terraform-website -PKG_NAME=librato -plugin_name=terraform-provider-appoptics -plugin_path=~/.terraform.d/plugins +.PHONY: build test testacc vet lint release +plugin_name=terraform-provider-appoptics default: build build: go build -o $(plugin_name) -user-install: - mkdir -p $(plugin_path) && go build -o $(plugin_path)/$(plugin_name) +test: + go test ./... -test: fmtcheck - go test -i $(TEST) || exit 1 - echo $(TEST) | \ - xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 - -testacc: fmtcheck - TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m +testacc: + TF_ACC=1 go test -v -timeout 120m vet: - @echo "go vet ." - @go vet $$(go list ./... | grep -v vendor/) ; if [ $$? -eq 1 ]; then \ - echo ""; \ - echo "Vet found suspicious constructs. Please check the reported constructs"; \ - echo "and fix them if necessary before submitting the code for review."; \ - exit 1; \ - fi - -fmtcheck: - @sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'" - -errcheck: - @sh -c "'$(CURDIR)/scripts/errcheck.sh'" - -vendor-status: - @govendor status - -test-compile: - @if [ "$(TEST)" = "./..." ]; then \ - echo "ERROR: Set TEST to a specific package. For example,"; \ - echo " make test-compile TEST=./$(PKG_NAME)"; \ - exit 1; \ - fi - go test -c $(TEST) $(TESTARGS) + go vet ./... +lint: + "$$(go env GOPATH)/bin/golangci-lint" run -.PHONY: build test testacc vet fmt fmtcheck errcheck vendor-status test-compile website website-test +# Produces artifacts in the dist directory +# DOES NOT push release artifacts +test-release: + goreleaser --snapshot --skip-publish --rm-dist +# Requires a GITHUB_TOKEN to be set in the environment +release: + goreleaser --rm-dist diff --git a/appoptics/resource_appoptics_alert.go b/appoptics/resource_appoptics_alert.go index a33929e..9d4a914 100644 --- a/appoptics/resource_appoptics_alert.go +++ b/appoptics/resource_appoptics_alert.go @@ -297,7 +297,7 @@ func resourceAppOpticsAlertRead(d *schema.ResourceData, meta interface{}) error } log.Printf("[INFO] Received AppOptics Alert: %s", alert.Name) - d.Set("name", alert.Name) + d.Set("name", alert.Name) //nolint if err := d.Set("description", alert.Description); err != nil { return err diff --git a/appoptics/resource_appoptics_metric.go b/appoptics/resource_appoptics_metric.go index b689f5c..abdc198 100644 --- a/appoptics/resource_appoptics_metric.go +++ b/appoptics/resource_appoptics_metric.go @@ -193,23 +193,23 @@ func resourceAppOpticsMetricRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf("Error reading AppOptics Metric %s: %s", id, err) } - d.Set("name", metric.Name) - d.Set("type", metric.Type) + d.Set("name", metric.Name) //nolint + d.Set("type", metric.Type) //nolint if metric.Description != "" { - d.Set("description", metric.Description) + d.Set("description", metric.Description) //nolint } if metric.DisplayName != "" { - d.Set("display_name", metric.DisplayName) + d.Set("display_name", metric.DisplayName) //nolint } if metric.Period != 0 { - d.Set("period", metric.Period) + d.Set("period", metric.Period) //nolint } if metric.Composite != "" { - d.Set("composite", metric.Composite) + d.Set("composite", metric.Composite) //nolint } attributes := metricAttributesGather(d, &metric.Attributes) diff --git a/appoptics/resource_appoptics_service.go b/appoptics/resource_appoptics_service.go index 97d724a..0a32707 100644 --- a/appoptics/resource_appoptics_service.go +++ b/appoptics/resource_appoptics_service.go @@ -45,9 +45,7 @@ func resourceAppOpticsService() *schema.Resource { // Takes JSON in a string. Decodes JSON into // settings hash func resourceAppOpticsServicesExpandSettings(rawSettings string) (map[string]string, error) { - var settings map[string]string - - settings = make(map[string]string) + settings := make(map[string]string) err := json.Unmarshal([]byte(rawSettings), &settings) if err != nil { return nil, fmt.Errorf("Error decoding JSON: %s", err) @@ -103,7 +101,7 @@ func resourceAppOpticsServiceCreate(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("Error creating AppOptics service: %s", err) } - resource.Retry(1*time.Minute, func() *resource.RetryError { + retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := client.ServicesService().Retrieve(serviceResult.ID) if err != nil { if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { @@ -114,6 +112,10 @@ func resourceAppOpticsServiceCreate(d *schema.ResourceData, meta interface{}) er return nil }) + if retryErr != nil { + return retryErr + } + d.SetId(strconv.Itoa(serviceResult.ID)) return resourceAppOpticsServiceReadResult(d, *serviceResult) } @@ -141,10 +143,10 @@ func resourceAppOpticsServiceRead(d *schema.ResourceData, meta interface{}) erro func resourceAppOpticsServiceReadResult(d *schema.ResourceData, service appoptics.Service) error { d.SetId(strconv.FormatUint(uint64(service.ID), 10)) - d.Set("type", service.Type) - d.Set("title", service.Title) + d.Set("type", service.Type) //nolint + d.Set("title", service.Title) //nolint settings, _ := resourceAppOpticsServicesFlatten(service.Settings) - d.Set("settings", settings) + d.Set("settings", settings) //nolint return nil } @@ -223,7 +225,7 @@ func resourceAppOpticsServiceDelete(d *schema.ResourceData, meta interface{}) er return fmt.Errorf("Error deleting Service: %s", err) } - resource.Retry(1*time.Minute, func() *resource.RetryError { + retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := client.ServicesService().Retrieve(int(id)) if err != nil { if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { @@ -234,6 +236,10 @@ func resourceAppOpticsServiceDelete(d *schema.ResourceData, meta interface{}) er return resource.RetryableError(fmt.Errorf("service still exists")) }) + if retryErr != nil { + return retryErr + } + d.SetId("") return nil } diff --git a/appoptics/resource_appoptics_space.go b/appoptics/resource_appoptics_space.go index 3fa00f0..ec13b2c 100644 --- a/appoptics/resource_appoptics_space.go +++ b/appoptics/resource_appoptics_space.go @@ -38,7 +38,7 @@ func resourceAppOpticsSpaceCreate(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("Error creating AppOptics space %s: %s", name, err) } - resource.Retry(1*time.Minute, func() *resource.RetryError { + retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := client.SpacesService().Retrieve(space.ID) if err != nil { if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { @@ -49,6 +49,10 @@ func resourceAppOpticsSpaceCreate(d *schema.ResourceData, meta interface{}) erro return nil }) + if retryErr != nil { + return retryErr + } + d.SetId(strconv.Itoa(space.ID)) return resourceAppOpticsSpaceReadResult(d, space) } @@ -116,7 +120,7 @@ func resourceAppOpticsSpaceDelete(d *schema.ResourceData, meta interface{}) erro return fmt.Errorf("Error deleting space: %s", err) } - resource.Retry(1*time.Minute, func() *resource.RetryError { + retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := client.SpacesService().Retrieve(int(id)) if err != nil { if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { @@ -127,6 +131,10 @@ func resourceAppOpticsSpaceDelete(d *schema.ResourceData, meta interface{}) erro return resource.RetryableError(fmt.Errorf("space still exists")) }) + if retryErr != nil { + return retryErr + } + d.SetId("") return nil } diff --git a/appoptics/resource_librato_space_chart.go b/appoptics/resource_librato_space_chart.go index 7201207..0d0b06b 100644 --- a/appoptics/resource_librato_space_chart.go +++ b/appoptics/resource_librato_space_chart.go @@ -258,7 +258,7 @@ func resourceAppOpticsSpaceChartCreate(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error creating AppOptics space chart %s: %s", spaceChart.Name, err) } - resource.Retry(1*time.Minute, func() *resource.RetryError { + retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := client.ChartsService().Retrieve(spaceChartResult.ID, spaceID) if err != nil { if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { @@ -269,6 +269,10 @@ func resourceAppOpticsSpaceChartCreate(d *schema.ResourceData, meta interface{}) return nil }) + if retryErr != nil { + return retryErr + } + return resourceAppOpticsSpaceChartReadResult(d, spaceChartResult) } @@ -443,10 +447,10 @@ func resourceAppOpticsSpaceChartUpdate(d *schema.ResourceData, meta interface{}) if v, ok := streamData["units_longs"].(string); ok && v != "" { stream.UnitsLong = v } - if v, ok := streamData["min"].(int); ok && !math.IsNaN(float64(v)) { + if v, ok := streamData["min"].(int); ok { stream.Min = v } - if v, ok := streamData["max"].(int); ok && !math.IsNaN(float64(v)) { + if v, ok := streamData["max"].(int); ok { stream.Max = v } streams[i] = stream @@ -503,7 +507,7 @@ func resourceAppOpticsSpaceChartDelete(d *schema.ResourceData, meta interface{}) return fmt.Errorf("Error deleting space: %s", err) } - resource.Retry(1*time.Minute, func() *resource.RetryError { + retryErr := resource.Retry(1*time.Minute, func() *resource.RetryError { _, err := client.ChartsService().Retrieve(id, spaceID) if err != nil { if errResp, ok := err.(*appoptics.ErrorResponse); ok && errResp.Response.StatusCode == 404 { @@ -514,6 +518,10 @@ func resourceAppOpticsSpaceChartDelete(d *schema.ResourceData, meta interface{}) return resource.RetryableError(fmt.Errorf("space chart still exists")) }) + if retryErr != nil { + return retryErr + } + d.SetId("") return nil } diff --git a/scripts/changelog-links.sh b/scripts/changelog-links.sh deleted file mode 100755 index 4927f37..0000000 --- a/scripts/changelog-links.sh +++ /dev/null @@ -1,31 +0,0 @@ -#!/bin/bash - -# This script rewrites [GH-nnnn]-style references in the CHANGELOG.md file to -# be Markdown links to the given github issues. -# -# This is run during releases so that the issue references in all of the -# released items are presented as clickable links, but we can just use the -# easy [GH-nnnn] shorthand for quickly adding items to the "Unrelease" section -# while merging things between releases. - -set -e - -if [[ ! -f CHANGELOG.md ]]; then - echo "ERROR: CHANGELOG.md not found in pwd." - echo "Please run this from the root of the terraform provider repository" - exit 1 -fi - -if [[ `uname` == "Darwin" ]]; then - echo "Using BSD sed" - SED="sed -i.bak -E -e" -else - echo "Using GNU sed" - SED="sed -i.bak -r -e" -fi - -PROVIDER_URL="https:\/\/github.com\/terraform-providers\/terraform-provider-librato\/issues" - -$SED "s/GH-([0-9]+)/\[#\1\]\($PROVIDER_URL\/\1\)/g" -e 's/\[\[#(.+)([0-9])\)]$/(\[#\1\2))/g' CHANGELOG.md - -rm CHANGELOG.md.bak diff --git a/scripts/errcheck.sh b/scripts/errcheck.sh deleted file mode 100755 index 15464f5..0000000 --- a/scripts/errcheck.sh +++ /dev/null @@ -1,24 +0,0 @@ -#!/usr/bin/env bash - -# Check gofmt -echo "==> Checking for unchecked errors..." - -if ! which errcheck > /dev/null; then - echo "==> Installing errcheck..." - go get -u github.com/kisielk/errcheck -fi - -err_files=$(errcheck -ignoretests \ - -ignore 'github.com/hashicorp/terraform/helper/schema:Set' \ - -ignore 'bytes:.*' \ - -ignore 'io:Close|Write' \ - $(go list ./...| grep -v /vendor/)) - -if [[ -n ${err_files} ]]; then - echo 'Unchecked errors found in the following places:' - echo "${err_files}" - echo "Please handle returned errors. You can check directly with \`make errcheck\`" - exit 1 -fi - -exit 0 diff --git a/scripts/gofmtcheck.sh b/scripts/gofmtcheck.sh deleted file mode 100755 index 1c05581..0000000 --- a/scripts/gofmtcheck.sh +++ /dev/null @@ -1,13 +0,0 @@ -#!/usr/bin/env bash - -# Check gofmt -echo "==> Checking that code complies with gofmt requirements..." -gofmt_files=$(gofmt -l `find . -name '*.go' | grep -v vendor`) -if [[ -n ${gofmt_files} ]]; then - echo 'gofmt needs running on the following files:' - echo "${gofmt_files}" - echo "You can use the command: \`make fmt\` to reformat code." - exit 1 -fi - -exit 0 diff --git a/scripts/gogetcookie.sh b/scripts/gogetcookie.sh deleted file mode 100755 index 26c63a6..0000000 --- a/scripts/gogetcookie.sh +++ /dev/null @@ -1,10 +0,0 @@ -#!/bin/bash - -touch ~/.gitcookies -chmod 0600 ~/.gitcookies - -git config --global http.cookiefile ~/.gitcookies - -tr , \\t <<\__END__ >>~/.gitcookies -.googlesource.com,TRUE,/,TRUE,2147483647,o,git-paul.hashicorp.com=1/z7s05EYPudQ9qoe6dMVfmAVwgZopEkZBb1a2mA5QtHE -__END__ diff --git a/website/docs/index.html.markdown b/website/docs/index.html.markdown deleted file mode 100644 index bc223b4..0000000 --- a/website/docs/index.html.markdown +++ /dev/null @@ -1,36 +0,0 @@ ---- -layout: "appoptics" -page_title: "Provider: AppOptics" -sidebar_current: "docs-appoptics-index" -description: |- - The AppOptics provider is used to interact with the resources supported by AppOptics. The provider needs to be configured with the proper credentials before it can be used. ---- - -# AppOptics Provider - -The AppOptics provider is used to interact with the -resources supported by AppOptics. The provider needs to be configured -with the proper credentials before it can be used. - -Use the navigation to the left to read about the available resources. - -## Example Usage - -```hcl -# Configure the AppOptics provider -provider "appoptics" { - token = "${var.librato_token}" -} - -# Create a new space -resource "appoptics_space" "default" { - # ... -} -``` - -## Argument Reference - -The following arguments are supported: - -* `token` - (Required) AppOptics API token. It must be provided, but it can also - be sourced from the `APPOPTICS_TOKEN` environment variable. diff --git a/website/docs/r/alert.html.markdown b/website/docs/r/alert.html.markdown deleted file mode 100644 index ad12b9c..0000000 --- a/website/docs/r/alert.html.markdown +++ /dev/null @@ -1,75 +0,0 @@ ---- -layout: "appoptics" -page_title: "AppOptics: appoptics_alert" -sidebar_current: "docs-appoptics-resource-alert" -description: |- - Provides a AppOptics Alert resource. This can be used to create and manage alerts on AppOptics. ---- - -# appoptics\_alert - -Provides a AppOptics Alert resource. This can be used to -create and manage alerts on AppOptics. - -## Example Usage - -```hcl -# Create a new AppOptics alert -resource "appoptics_alert" "myalert" { - name = "MyAlert" - description = "A Test Alert" - services = ["${appoptics_service.myservice.id}"] - - condition { - type = "above" - threshold = 10 - metric_name = "appoptics.cpu.percent.idle" - } -} -``` - -## Argument Reference - -The following arguments are supported: - -* `name` - (Required) The name of the alert. -* `description` - (Required) Description of the alert. -* `active` - whether the alert is active (can be triggered). Defaults to true. -* `rearm_seconds` - minimum amount of time between sending alert notifications, in seconds. -* `services` - list of notification service IDs. -* `condition` - A trigger condition for the alert. Conditions documented below. -* `attributes` - A hash of additional attribtues for the alert. Attributes documented below. - -## Attributes Reference - -The following attributes are exported: - -* `id` - The ID of the alert. -* `name` - The name of the alert. -* `description` - (Required) Description of the alert. -* `active` - whether the alert is active (can be triggered). Defaults to true. -* `rearm_seconds` - minimum amount of time between sending alert notifications, in seconds. -* `services` - list of notification service IDs. -* `condition` - A trigger condition for the alert. Conditions documented below. - -Conditions (`condition`) support the following: - -* `type` - The type of condition. Must be one of `above`, `below` or `absent`. -* `metric_name`- The name of the metric this alert condition applies to. -* `source`- A source expression which identifies which sources for the given metric to monitor. -* `detect_reset` - boolean: toggles the method used to calculate the delta from the previous sample when the summary_function is `derivative`. -* `duration` - number of seconds condition must be true to fire the alert (required for type `absent`). -* `threshold` - float: measurements over this number will fire the alert (only for `above` or `below`). -* `summary_function` - Indicates which statistic of an aggregated measurement to alert on. ((only for `above` or `below`). - -Attributes (`attributes`) support the following: - -* `runbook_url` - a URL for the runbook to be followed when this alert is firing. Used in the AppOptics UI if set. - -## Import - -Alerts can be imported using the `id`, e.g. - -``` -$ terraform import appoptics_alert.foobar 13581321 -``` diff --git a/website/docs/r/metric.html.markdown b/website/docs/r/metric.html.markdown deleted file mode 100644 index 32cba14..0000000 --- a/website/docs/r/metric.html.markdown +++ /dev/null @@ -1,71 +0,0 @@ ---- -layout: "appoptics" -page_title: "AppOptics: appoptics_metric" -sidebar_current: "docs-appoptics-resource-metric" -description: |- - Provides a AppOptics Metric resource. This can be used to create and manage metrics on AppOptics. ---- - -# appoptics\_metric - -Provides a AppOptics Metric resource. This can be used to create and manage metrics on AppOptics. - -## Example Usage - -```hcl -# Create a new AppOptics metric -resource "appoptics_metric" "mymetric" { - name = "MyMetric" - type = "counter" - description = "A Test Metric" - attributes { - display_stacked = true - } -} -``` - -## Argument Reference - -The following arguments are supported: - -* `type` - (Required) The type of metric to create (gauge, counter, or composite). -* `name` - (Required) The unique identifier of the metric. -* `display_name` - The name which will be used for the metric when viewing the Metrics website. -* `description` - Text that can be used to explain precisely what the metric is measuring. -* `period` - Number of seconds that is the standard reporting period of the metric. -* `attributes` - The attributes hash configures specific components of a metric’s visualization. -* `composite` - The definition of the composite metric. - -## Attributes Reference - -The following attributes are exported: - -* `name` - The identifier for the metric. -* `display_name` - The name which will be used for the metric when viewing the Metrics website. -* `type` - The type of metric to create (gauge, counter, or composite). -* `description` - Text that describes precisely what the metric is measuring. -* `period` - Number of seconds that is the standard reporting period of the metric. Setting the period enables Metrics to detect abnormal interruptions in reporting and aids in analytics. For gauge metrics that have service-side aggregation enabled, this option will define the period that aggregation occurs on. -* `source_lag` - -* `composite` - The composite definition. Only used when type is composite. - -Attributes (`attributes`) support the following: - -* `color` - Sets a default color to prefer when visually rendering the metric. Must be a seven character string that represents the hex code of the color e.g. #52D74C. -* `display_max` - If a metric has a known theoretical maximum value, set display_max so that visualizations can provide perspective of the current values relative to the maximum value. -* `display_min` - If a metric has a known theoretical minimum value, set display_min so that visualizations can provide perspective of the current values relative to the minimum value. -* `display_units_long` - A string that identifies the unit of measurement e.g. Microseconds. Typically the long form of display_units_short and used in visualizations e.g. the Y-axis label on a graph. -* `display_units_short` - A terse (usually abbreviated) string that identifies the unit of measurement e.g. uS (Microseconds). Typically the short form of display_units_long and used in visualizations e.g. the tooltip for a point on a graph. -* `display_stacked` - A boolean value indicating whether or not multiple metric streams should be aggregated in a visualization (e.g. stacked graphs). By default counters have display_stacked enabled while gauges have it disabled. -* `summarize_function` - Determines how to calculate values when rolling up from raw values to higher resolution intervals. Must be one of: ‘average’, 'sum’, 'count’, 'min’, 'max’. If summarize_function is not set the behavior defaults to average. - -If the values of the measurements to be rolled up are: 2, 10, 5: - -* average: 5.67 -* sum: 17 -* count: 3 -* min: 2 -* max: 10 - -* `aggregate` - Enable service-side aggregation for this metric. When enabled, measurements sent using the same tag set will be aggregated into single measurements on an interval defined by the period of the metric. If there is no period defined for the metric then all measurements will be aggregated on a 60-second interval. - -This option takes a value of true or false. If this option is not set for a metric it will default to false. diff --git a/website/docs/r/service.html.markdown b/website/docs/r/service.html.markdown deleted file mode 100644 index 18e8de1..0000000 --- a/website/docs/r/service.html.markdown +++ /dev/null @@ -1,53 +0,0 @@ ---- -layout: "appoptics" -page_title: "AppOptics: appoptics_service" -sidebar_current: "docs-appoptics-resource-service" -description: |- - Provides a AppOptics service resource. This can be used to create and manage notification services on AppOptics. ---- - -# appoptics\_service - -Provides a AppOptics Service resource. This can be used to -create and manage notification services on AppOptics. - -## Example Usage - -```hcl -# Create a new AppOptics service -resource "appoptics_service" "email" { - title = "Email the admins" - type = "mail" - - settings = < - <% content_for :sidebar do %> - - <% end %> - - <%= yield %> - <% end %>