diff --git a/.ci-mgmt.yaml b/.ci-mgmt.yaml index 165806d..0489bee 100644 --- a/.ci-mgmt.yaml +++ b/.ci-mgmt.yaml @@ -6,6 +6,7 @@ env: makeTemplate: bridged team: ecosystem pulumiConvert: 1 +registryDocs: true plugins: - name: terraform version: "1.0.16" diff --git a/Makefile b/Makefile index d7c6b0c..3a313ea 100644 --- a/Makefile +++ b/Makefile @@ -29,7 +29,7 @@ development: install_plugins provider build_sdks install_sdks build: install_plugins provider build_sdks install_sdks -build_sdks: build_nodejs build_python build_dotnet build_go build_java +build_sdks: build_nodejs build_python build_dotnet build_go build_java build_registry_docs install_go_sdk: @@ -96,6 +96,10 @@ build_python: upstream cd ./bin && \ ../venv/bin/python -m build . +# Run the bridge's registry-docs command to generated the content of the installation docs/ folder at provider repo root +build_registry_docs: + $(WORKING_DIR)/bin/$(TFGEN) registry-docs --out $(WORKING_DIR)/docs + clean: rm -rf sdk/{dotnet,nodejs,go,python} diff --git a/docs/_index.md b/docs/_index.md new file mode 100644 index 0000000..95d2ba5 --- /dev/null +++ b/docs/_index.md @@ -0,0 +1,392 @@ +--- +title: Wavefront Provider +meta_desc: Provides an overview on how to configure the Pulumi Wavefront provider. +layout: package +--- +## Installation + +The wavefront provider is available as a package in all Pulumi languages: + +* JavaScript/TypeScript: [`@pulumi/wavefront`](https://www.npmjs.com/package/@pulumi/wavefront) +* Python: [`pulumi-wavefront`](https://pypi.org/project/pulumi-wavefront/) +* Go: [`github.com/pulumi/pulumi-wavefront/sdk/v3/go/wavefront`](https://github.com/pulumi/pulumi-wavefront) +* .NET: [`Pulumi.Wavefront`](https://www.nuget.org/packages/Pulumi.Wavefront) +* Java: [`com.pulumi/wavefront`](https://central.sonatype.com/artifact/com.pulumi/wavefront) +## Overview + +The Wavefront provider is used to interact with the Wavefront monitoring service. The +provider needs to be configured with the proper credentials before it can be used. + +Use the navigation on the left to read about the available resources. +## Example Usage + +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} +{{% choosable language typescript %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: nodejs + +``` +```typescript +import * as pulumi from "@pulumi/pulumi"; +import * as wavefront from "@pulumi/wavefront"; + +const testAlert = new wavefront.Alert("test_alert", { + name: "High CPU Alert", + condition: "100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total ) > 80", + additionalInformation: "This is an Alert", + displayExpression: "100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total )", + minutes: 5, + severity: "WARN", + tags: [ + "env.preprod", + "cpu.total", + ], +}); +``` +{{% /choosable %}} +{{% choosable language python %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: python + +``` +```python +import pulumi +import pulumi_wavefront as wavefront + +test_alert = wavefront.Alert("test_alert", + name="High CPU Alert", + condition="100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total ) > 80", + additional_information="This is an Alert", + display_expression="100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total )", + minutes=5, + severity="WARN", + tags=[ + "env.preprod", + "cpu.total", + ]) +``` +{{% /choosable %}} +{{% choosable language csharp %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: dotnet + +``` +```csharp +using System.Collections.Generic; +using System.Linq; +using Pulumi; +using Wavefront = Pulumi.Wavefront; + +return await Deployment.RunAsync(() => +{ + var testAlert = new Wavefront.Alert("test_alert", new() + { + Name = "High CPU Alert", + Condition = "100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total ) > 80", + AdditionalInformation = "This is an Alert", + DisplayExpression = "100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total )", + Minutes = 5, + Severity = "WARN", + Tags = new[] + { + "env.preprod", + "cpu.total", + }, + }); + +}); + +``` +{{% /choosable %}} +{{% choosable language go %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: go + +``` +```go +package main + +import ( + "github.com/pulumi/pulumi-wavefront/sdk/v3/go/wavefront" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" +) + +func main() { + pulumi.Run(func(ctx *pulumi.Context) error { + _, err := wavefront.NewAlert(ctx, "test_alert", &wavefront.AlertArgs{ + Name: pulumi.String("High CPU Alert"), + Condition: pulumi.String("100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total ) > 80"), + AdditionalInformation: pulumi.String("This is an Alert"), + DisplayExpression: pulumi.String("100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total )"), + Minutes: pulumi.Int(5), + Severity: pulumi.String("WARN"), + Tags: pulumi.StringArray{ + pulumi.String("env.preprod"), + pulumi.String("cpu.total"), + }, + }) + if err != nil { + return err + } + return nil + }) +} +``` +{{% /choosable %}} +{{% choosable language yaml %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: yaml + +``` +```yaml +resources: + testAlert: + type: wavefront:Alert + name: test_alert + properties: + name: High CPU Alert + condition: 100-ts("cpu.usage_idle", environment=preprod and cpu=cpu-total ) > 80 + additionalInformation: This is an Alert + displayExpression: 100-ts("cpu.usage_idle", environment=preprod and cpu=cpu-total ) + minutes: 5 + severity: WARN + tags: + - env.preprod + - cpu.total +``` +{{% /choosable %}} +{{% choosable language java %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: java + +``` +```java +package generated_program; + +import com.pulumi.Context; +import com.pulumi.Pulumi; +import com.pulumi.core.Output; +import com.pulumi.wavefront.Alert; +import com.pulumi.wavefront.AlertArgs; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.io.File; +import java.nio.file.Files; +import java.nio.file.Paths; + +public class App { + public static void main(String[] args) { + Pulumi.run(App::stack); + } + + public static void stack(Context ctx) { + var testAlert = new Alert("testAlert", AlertArgs.builder() + .name("High CPU Alert") + .condition("100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total ) > 80") + .additionalInformation("This is an Alert") + .displayExpression("100-ts(\"cpu.usage_idle\", environment=preprod and cpu=cpu-total )") + .minutes(5) + .severity("WARN") + .tags( + "env.preprod", + "cpu.total") + .build()); + + } +} +``` +{{% /choosable %}} +{{< /chooser >}} +## Authentication + +The Wavefront provider offers two ways of providing credentials for authentication. + +* Static credentials +* Environment variables +### Static credentials + +Static credentials can be provided by adding an `address` and `token` in-line in +the Wavefront provider configuration. + +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} +{{% choosable language typescript %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: nodejs +config: + wavefront:address: + value: cluster.wavefront.com + wavefront:token: + value: your-wf-token-secret + +``` + +{{% /choosable %}} +{{% choosable language python %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: python +config: + wavefront:address: + value: cluster.wavefront.com + wavefront:token: + value: your-wf-token-secret + +``` + +{{% /choosable %}} +{{% choosable language csharp %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: dotnet +config: + wavefront:address: + value: cluster.wavefront.com + wavefront:token: + value: your-wf-token-secret + +``` + +{{% /choosable %}} +{{% choosable language go %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: go +config: + wavefront:address: + value: cluster.wavefront.com + wavefront:token: + value: your-wf-token-secret + +``` + +{{% /choosable %}} +{{% choosable language yaml %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: yaml +config: + wavefront:address: + value: cluster.wavefront.com + wavefront:token: + value: your-wf-token-secret + +``` + +{{% /choosable %}} +{{% choosable language java %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: java +config: + wavefront:address: + value: cluster.wavefront.com + wavefront:token: + value: your-wf-token-secret + +``` + +{{% /choosable %}} +{{< /chooser >}} +### Environment Variables + +You can provide your credentials by using the `WAVEFRONT_ADDRESS` and `WAVEFRONT_TOKEN`, +environment variables. + +{{< chooser language "typescript,python,go,csharp,java,yaml" >}} +{{% choosable language typescript %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: nodejs + +``` + +{{% /choosable %}} +{{% choosable language python %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: python + +``` + +{{% /choosable %}} +{{% choosable language csharp %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: dotnet + +``` + +{{% /choosable %}} +{{% choosable language go %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: go + +``` + +{{% /choosable %}} +{{% choosable language yaml %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: yaml + +``` + +{{% /choosable %}} +{{% choosable language java %}} +```yaml +# Pulumi.yaml provider configuration file +name: configuration-example +runtime: java + +``` + +{{% /choosable %}} +{{< /chooser >}} + +Usage: + +```sh +$ export WAVEFRONT_ADDRESS="cluster.wavefront.com" +$ export WAVEFRONT_TOKEN="your-wf-token-secret" +$ pulumi preview +``` +## Configuration Reference + +In addition to generic `provider` arguments +(e.g. `alias` and `version`), the following arguments are supported in the Wavefront +provider configuration: + +* `address` - (Optional) The URL of your Wavefront cluster that you access Wavefront from without the + leading `https://` or trailing `/` (e.g. `https://longboard.wavefront.com/` becomes `longboard.wavefront.com`) + +* `token` - (Optional) Either a User Account token or Service Account token with the permissions necessary + to manage your Wavefront account. + +* `httpProxy` - (Optional) The proxy type is determined by the URL scheme. `http`, `https`, and `socks5` are supported. + If the scheme is empty `http` is assumed. \ No newline at end of file diff --git a/provider/resources.go b/provider/resources.go index 2c0f692..f072266 100644 --- a/provider/resources.go +++ b/provider/resources.go @@ -15,6 +15,7 @@ package wavefront import ( + "bytes" "fmt" "path/filepath" "unicode" @@ -80,6 +81,7 @@ func Provider() tfbridge.ProviderInfo { Repository: "https://github.com/pulumi/pulumi-wavefront", GitHubOrg: "vmware", Config: map[string]*tfbridge.SchemaInfo{}, + DocRules: &tfbridge.DocRuleInfo{EditRules: docEditRules}, Resources: map[string]*tfbridge.ResourceInfo{ "wavefront_alert": {Tok: makeResource(mainMod, "Alert")}, "wavefront_alert_target": {Tok: makeResource(mainMod, "AlertTarget")}, @@ -188,3 +190,35 @@ func Provider() tfbridge.ProviderInfo { var noUpstreamDocs = &tfbridge.DocInfo{ Markdown: []byte(" "), } + +func docEditRules(defaults []tfbridge.DocsEdit) []tfbridge.DocsEdit { + return append( + defaults, + removeSecretsWarning, + ) +} + +// Pulumi secrets are safe, so no warning necessary. +var removeSecretsWarning = tfbridge.DocsEdit{ + Path: "index.md", + Edit: func(_ string, content []byte) ([]byte, error) { + inputs := [][]byte{ + []byte("⚠️ **Warning:** It is not recommended to hard-code credentials into any Terraform configuration.\n" + + "There's a risk of secret leakage if this file is ever committed to a public version control system."), + } + for _, input := range inputs { + + if bytes.Contains(content, input) { + content = bytes.ReplaceAll( + content, + input, + nil) + } else { + // Hard error to ensure we keep this content up to date + return nil, fmt.Errorf("could not find text in upstream index.md, "+ + "please verify input at removeGuideText \n*****\n%s\n*****\n", string(input)) + } + } + return content, nil + }, +}