diff --git a/.envrc b/.envrc new file mode 100644 index 00000000..f8d46f12 --- /dev/null +++ b/.envrc @@ -0,0 +1,6 @@ +has nix && use flake +watch_file *.nix +strict_env +dotenv_if_exists .env # You can create a .env file with your env vars for this project. You can also use .secrets if you are using act. See the line below. +dotenv_if_exists .secrets # Used by [act](https://nektosact.com/) to load secrets into the pipelines +env_vars_required SYSDIG_MONITOR_API_TOKEN SYSDIG_SECURE_API_TOKEN diff --git a/.gitignore b/.gitignore index e2ff9b06..e1b1a005 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,8 @@ *.dll *.exe .DS_Store -.envrc +.secrets +.direnv/ .env example.tf terraform.tfplan @@ -53,3 +54,9 @@ oanc # Local test folder local-terraform-test/ dist/ + +# Nix result +result + +main.tf +terraform-providers-schema/ diff --git a/GNUmakefile b/GNUmakefile index fcbb6a5b..05cb3d31 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -13,14 +13,16 @@ TERRAFORM_PROVIDER_DEV_VERSION=1.0.0 TERRAFORM_PLATFORM=$(shell terraform version -json | jq -r .platform) TERRAFORM_SYSDIG_PLUGIN_DIR=$(TERRAFORM_PLUGIN_ROOT_DIR)/$(TERRAFORM_PROVIDER_REFERENCE_NAME)/$(TERRAFORM_PROVIDER_NAME)/$(TERRAFORM_PROVIDER_DEV_VERSION)/$(TERRAFORM_PLATFORM) -install-tools: - go install golang.org/x/tools/cmd/stringer@latest - default: build build: fmtcheck go install +check: fmtcheck errcheck check-vuln doccheck lint + +check-vuln: + govulncheck . + install: fmtcheck go build -o terraform-provider-sysdig mkdir -p $(TERRAFORM_SYSDIG_PLUGIN_DIR) @@ -64,13 +66,35 @@ fmtcheck: @sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'" lint: - golangci-lint run --timeout 1h ./... + golangci-lint run --timeout 1h --build-tags unit,tf_acc_sysdig_monitor,tf_acc_sysdig_secure,tf_acc_ibm_monitor,tf_acc_ibm_secure ./... errcheck: @sh -c "'$(CURDIR)/scripts/errcheck.sh'" -vendor-status: - @govendor status +# Leverages on nix compiling and configuring the provider using the package.nix and the devshell +init-provider-to-test: + echo 'terraform { ' > main.tf + echo 'required_providers { sysdig = { ' >> main.tf + echo 'source = "sysdiglabs/sysdig" ' >> main.tf + echo 'version = "1.0.0-local" ' >> main.tf + echo '} }' >> main.tf + echo '}' >> main.tf + terraform init + +.PHONY: terraform-providers-schema +terraform-providers-schema: + rm -rf terraform-providers-schema + rm .terraform.lock.hcl + mkdir -p terraform-providers-schema + +doccheck: terraform-providers-schema init-provider-to-test + terraform providers schema -json > terraform-providers-schema/schema.json + tfproviderdocs check \ + -allowed-resource-subcategories-file website/allowed-subcategories.txt \ + -enable-contents-check \ + -provider-source registry.terraform.io/sysdiglabs/sysdig \ + -providers-schema-json terraform-providers-schema/schema.json \ + -require-resource-subcategory test-compile: @if [ "$(TEST)" = "./..." ]; then \ diff --git a/flake.lock b/flake.lock new file mode 100644 index 00000000..9e4838c6 --- /dev/null +++ b/flake.lock @@ -0,0 +1,78 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1735523292, + "narHash": "sha256-opBsbR/nrGxiiF6XzlVluiHYb6yN/hEwv+lBWTy9xoM=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "6d97d419e5a9b36e6293887a89a078cf85f5a61b", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs", + "tfproviderdocs-init": "tfproviderdocs-init" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + }, + "tfproviderdocs-init": { + "locked": { + "lastModified": 1735634314, + "narHash": "sha256-yjFJcmivdpHSnFHeuyOoHkfpJR5CNVBf1sGzUZsttOo=", + "owner": "nixos", + "repo": "nixpkgs", + "rev": "9b3a3a690cc38e55427bab590d82f9390ba80d21", + "type": "github" + }, + "original": { + "owner": "nixos", + "ref": "pull/366576/head", + "repo": "nixpkgs", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 00000000..8a6d4de5 --- /dev/null +++ b/flake.nix @@ -0,0 +1,88 @@ +{ + inputs = { + nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; + flake-utils.url = "github:numtide/flake-utils"; + tfproviderdocs-init.url = "github:nixos/nixpkgs/pull/366576/head"; # tfproviderdocs is not yet a package in nixpkgs, so this workaronuds it + }; + outputs = + { + self, + nixpkgs, + flake-utils, + tfproviderdocs-init, + }: + let + overlays.default = final: prev: { + terraform-providers = prev.terraform-providers // { + sysdig = prev.callPackage ./package.nix { }; + }; + }; + overlays.tfproviderdocs = + final: prev: + let + pkgs = import tfproviderdocs-init { inherit (prev) system; }; + in + { + inherit (pkgs) tfproviderdocs; + }; + flake = flake-utils.lib.eachDefaultSystem ( + system: + let + pkgs = import nixpkgs { + inherit system; + config.allowUnfree = true; + overlays = [ + self.overlays.default + self.overlays.tfproviderdocs + ]; + }; + in + { + # Exposes the local plugin to be consumed as a package. + packages = with pkgs.terraform-providers; { + inherit sysdig; + default = sysdig; + }; + + # To be used with `nix run`. + apps.terraform = flake-utils.lib.mkApp { + drv = pkgs.terraform.withPlugins (tf: [ tf.sysdig ]); + }; + + # Used for local development. Adds the required dependencies to work in this project. + devShells.default = + with pkgs; + mkShell { + packages = [ + go_1_23 + errcheck + govulncheck + golangci-lint + golangci-lint-langserver + (terraform.withPlugins (tf: [ tf.sysdig ])) + tfproviderdocs + ]; + }; + + # Used with `nix develop #terraform-with-plugin`. + # You can load terraform with the sysdig plugin from a commit, a branch or a tag. + # For instance: + # - `nix develop github:sysdiglabs/terraform-provider-sysdig#terraform-with-plugin` will create a local dev shell with the version from the main branch. + # - `nix develop github:sysdiglabs/terraform-provider-sysdig/branch-name#terraform-with-plugin` with create a local dev shell with the version from the `branch-name` branch code. + # - `nix develop github:sysdiglabs/terraform-provider-sysdig/v1.2.3#terraform-with-plugin` will create a local dev shell with the version from the tag `v1.2.3` code (note the provided version is just an example). + # - `nix develop .#terraform-with-plugin` will create a local dev shell with terraform with the local code. + devShells.terraform-with-plugin = + with pkgs; + mkShell { + packages = [ + (terraform.withPlugins (tf: [ tf.sysdig ])) + bashInteractive + ]; + }; + + formatter = pkgs.nixfmt-rfc-style; + } + ); + in + flake // { inherit overlays; }; +} diff --git a/go.mod b/go.mod index 0ec7b1ad..38e7f6d1 100644 --- a/go.mod +++ b/go.mod @@ -1,12 +1,14 @@ module github.com/draios/terraform-provider-sysdig -go 1.19 +go 1.23 + +toolchain go1.23.3 require ( github.com/Jeffail/gabs/v2 v2.7.0 github.com/aws/aws-sdk-go v1.44.284 github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 - github.com/hashicorp/go-retryablehttp v0.7.4 + github.com/hashicorp/go-retryablehttp v0.7.7 github.com/hashicorp/terraform-plugin-log v0.8.0 github.com/hashicorp/terraform-plugin-sdk/v2 v2.26.1 github.com/jmespath/go-jmespath v0.4.0 @@ -15,7 +17,7 @@ require ( github.com/spf13/cast v1.5.1 github.com/stretchr/testify v1.8.4 github.com/sysdiglabs/agent-kilt/runtimes/cloudformation v0.0.0-20240201123620-2272de6dee9f - google.golang.org/protobuf v1.30.0 + google.golang.org/protobuf v1.36.0 ) require ( @@ -27,15 +29,15 @@ require ( github.com/docker/distribution v2.8.2+incompatible // indirect github.com/docker/docker v24.0.2+incompatible // indirect github.com/docker/docker-credential-helpers v0.7.0 // indirect - github.com/fatih/color v1.13.0 // indirect + github.com/fatih/color v1.16.0 // indirect github.com/go-akka/configuration v0.0.0-20200606091224-a002c0330665 // indirect - github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect + github.com/golang/protobuf v1.5.4 // indirect + github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.15.2 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect github.com/hashicorp/go-checkpoint v0.5.0 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect - github.com/hashicorp/go-hclog v1.4.0 // indirect + github.com/hashicorp/go-hclog v1.6.3 // indirect github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.4.8 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect @@ -51,7 +53,7 @@ require ( github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect github.com/klauspost/compress v1.16.6 // indirect github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.19 // indirect + github.com/mattn/go-isatty v0.0.20 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-homedir v1.1.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect @@ -69,14 +71,14 @@ require ( github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect github.com/vmihailenco/tagparser v0.1.1 // indirect github.com/zclconf/go-cty v1.13.2 // indirect - golang.org/x/crypto v0.7.0 // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.9.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.14.0 // indirect - golang.org/x/text v0.9.0 // indirect + golang.org/x/crypto v0.31.0 // indirect + golang.org/x/mod v0.17.0 // indirect + golang.org/x/net v0.33.0 // indirect + golang.org/x/sync v0.10.0 // indirect + golang.org/x/sys v0.28.0 // indirect + golang.org/x/text v0.21.0 // indirect google.golang.org/appengine v1.6.7 // indirect - google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect - google.golang.org/grpc v1.51.0 // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 // indirect + google.golang.org/grpc v1.69.2 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/go.sum b/go.sum index e9d2c2b1..9371e75d 100644 --- a/go.sum +++ b/go.sum @@ -8,6 +8,7 @@ github.com/Masterminds/sprig/v3 v3.2.1/go.mod h1:UoaO7Yp8KlPnJIYWTFkMaqPUYKTfGFP github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA= github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0= github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= +github.com/Microsoft/go-winio v0.6.1/go.mod h1:LRdKpFKfdobln8UmuiYcKPot9D2v6svN5+sAH+4kjUM= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ= github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo= github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk= @@ -43,10 +44,12 @@ github.com/docker/docker-credential-helpers v0.7.0/go.mod h1:rETQfLdHNT3foU5kuNk github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg= github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= -github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc= github.com/frankban/quicktest v1.14.4 h1:g2rn0vABPOOXmZUj+vbmUp0lPoXEMuhTpIluN0XL9UY= +github.com/frankban/quicktest v1.14.4/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0= github.com/go-akka/configuration v0.0.0-20200606091224-a002c0330665 h1:Iz3aEheYgn+//VX7VisgCmF/wW3BMtXCLbvHV4jMQJA= github.com/go-akka/configuration v0.0.0-20200606091224-a002c0330665/go.mod h1:19bUnum2ZAeftfwwLZ/wRe7idyfoW2MfmXO464Hrfbw= @@ -58,24 +61,30 @@ github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0= github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4= github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc= +github.com/go-logr/logr v1.4.2 h1:6pFjapn8bFcIbiKo3XT4j/BhANplGihG6tvd+8rYgrY= +github.com/go-logr/logr v1.4.2/go.mod h1:9T104GzyrTigFIr8wt5mBrctHMim0Nb2HLGrmQ40KvY= +github.com/go-logr/stdr v1.2.2 h1:hSWxHoqTgW2S2qGc0LTAI563KZ5YKYRhT3MFKZMbjag= +github.com/go-logr/stdr v1.2.2/go.mod h1:mMo/vtBO5dYbehREoey6XUKy/eSumjCCveDpRre4VKE= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/golang/protobuf v1.1.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.4/go.mod h1:vzj43D7+SQXF/4pzW/hwtAqwc6iTitCiVSaWz5lYuqw= -github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk= -github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg= -github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= +github.com/golang/protobuf v1.5.4 h1:i7eJL8qZTpSEXOPTxNKhASYpMn+8e5Q6AdndVa1dWek= +github.com/golang/protobuf v1.5.4/go.mod h1:lnTiLA8Wa4RWRcIUkrtSVa5nRhsEGBg48fD6rSs7xps= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= -github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= -github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= +github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= +github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-containerregistry v0.15.2 h1:MMkSh+tjSdnmJZO7ljvEqV1DjfekB6VUEAZgy3a+TQE= github.com/google/go-containerregistry v0.15.2/go.mod h1:wWK+LnOv4jXMM23IT/F1wdYftGWGr47Is8CG+pmHK1Q= github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0= +github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= @@ -86,16 +95,15 @@ github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9n github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 h1:1/D3zfFHttUKaCaGKZ/dR2roBXv0vKbSCnssIldfQdI= github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v1.4.0 h1:ctuWFGrhFha8BnnzxqeRGidlEcQkDyL5u8J8t5eA11I= -github.com/hashicorp/go-hclog v1.4.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= github.com/hashicorp/go-plugin v1.4.8 h1:CHGwpxYDOttQOY7HOWgETU9dyVjOXzniXDqJcYJE1zM= github.com/hashicorp/go-plugin v1.4.8/go.mod h1:viDMjcLJuDui6pXb8U4HVfb8AamCWhHGUjr2IrTF67s= -github.com/hashicorp/go-retryablehttp v0.7.4 h1:ZQgVdpTdAL7WpMIwLzCfbalOcSUdkDZnpUv3/+BxzFA= -github.com/hashicorp/go-retryablehttp v0.7.4/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= @@ -133,6 +141,7 @@ github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOl github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo= github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4= github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE= +github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74= github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg= github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo= github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8= @@ -145,12 +154,14 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxv github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= +github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k= github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= @@ -161,8 +172,8 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= -github.com/mattn/go-isatty v0.0.19 h1:JITubQf0MOLdlGRuRq+jtsDlekdYPia9ZFsB8h/APPA= -github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/cli v1.1.5/go.mod h1:v8+iFts2sPIKUV1ltktPXMCC8fumSKFItNcD2cLtRR4= github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= @@ -192,12 +203,14 @@ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZb github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= github.com/rogpeppe/go-internal v1.9.0 h1:73kH8U+JUqXU8lRuOHeVHaa/SZPifC7BkcraZVejAe8= +github.com/rogpeppe/go-internal v1.9.0/go.mod h1:WtVeX8xhTBvf0smdhujwtBcq4Qrzq/fJaraNFVN+nFs= github.com/rs/xid v1.4.0/go.mod h1:trrq9SKmegXys3aeAKXMUTdJsYXVwGY3RLcfgqegfbg= github.com/rs/zerolog v1.29.1 h1:cO+d60CHkknCbvzEWxP0S9K6KqyTjrCNUy1LdQLCGPc= github.com/rs/zerolog v1.29.1/go.mod h1:Le6ESbR7hc+DP6Lt1THiV8CQSdkkNrd3R0XbEgp3ZBU= github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM= github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= +github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= github.com/shopspring/decimal v1.2.0/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.9.0/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= @@ -238,11 +251,23 @@ github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgq github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI= github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0= github.com/yudai/gojsondiff v1.0.0 h1:27cbfqXLVEJ1o8I6v3y9lg8Ydm53EKqHXAOMxEGlCOA= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82 h1:BHyfKlQyqbsFN5p3IfnEUduWvb9is428/nNb5L3U01M= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.13.2 h1:4GvrUxe/QUDYuJKAav4EYqdM47/kZa672LwmXFmEKT0= github.com/zclconf/go-cty v1.13.2/go.mod h1:YKQzy/7pZ7iq2jNFzy5go57xdxdWoLLpaEp4u238AE0= +go.opentelemetry.io/otel v1.31.0 h1:NsJcKPIW0D0H3NgzPDHmo0WW6SptzPdqg/L1zsIm2hY= +go.opentelemetry.io/otel v1.31.0/go.mod h1:O0C14Yl9FgkjqcCZAsE053C13OaddMYr/hz6clDkEJE= +go.opentelemetry.io/otel/metric v1.31.0 h1:FSErL0ATQAmYHUIzSezZibnyVlft1ybhy4ozRPcF2fE= +go.opentelemetry.io/otel/metric v1.31.0/go.mod h1:C3dEloVbLuYoX41KpmAhOqNriGbA+qqH6PQ5E5mUfnY= +go.opentelemetry.io/otel/sdk v1.31.0 h1:xLY3abVHYZ5HSfOg3l2E5LUj2Cwva5Y7yGxnSW9H5Gk= +go.opentelemetry.io/otel/sdk v1.31.0/go.mod h1:TfRbMdhvxIIr/B2N2LQW2S5v9m3gOQ/08KsbbO5BPT0= +go.opentelemetry.io/otel/sdk/metric v1.31.0 h1:i9hxxLJF/9kkvfHppyLL55aW7iIJz4JjxTeYusH7zMc= +go.opentelemetry.io/otel/sdk/metric v1.31.0/go.mod h1:CRInTMVvNhUKgSAMbKyTMxqOBC0zgyxzW55lZzX43Y8= +go.opentelemetry.io/otel/trace v1.31.0 h1:ffjsj1aRouKewfr85U2aGagJ46+MvodynlQ1HYdmJys= +go.opentelemetry.io/otel/trace v1.31.0/go.mod h1:TXZkRk7SM2ZQLtR6eoAWQFIHPvzQ06FJAsO1tJg480A= golang.org/x/crypto v0.0.0-20190219172222-a4c6cb3142f2/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20200414173820-0848c9571904/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= @@ -251,12 +276,12 @@ golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.5.0/go.mod h1:NK/OQwhpMQP3MwtdjgLlYHnH9ebylxKWv3e0fK+mkQU= -golang.org/x/crypto v0.7.0 h1:AvwMYaRytfdeVt3u6mLaxYtErKYjxA2OXjJ1HHq6t3A= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= +golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= +golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= golang.org/x/mod v0.7.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.17.0 h1:zY54UmvipHiNd+pm+m0x9KhZ9hl1/7QNMyxXbc6ICqA= +golang.org/x/mod v0.17.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -271,15 +296,15 @@ golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5o golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.1.0/go.mod h1:Cx3nUiGt4eDBEyega/BKRp+/AlGL8hYe7U9odMt2Cco= golang.org/x/net v0.5.0/go.mod h1:DivGGAXEgPSlEBzxGzZI+ZLohi+xUj054jfeKui00ws= -golang.org/x/net v0.9.0 h1:aWJ/m6xSmxWBx+V0XRHTlrYrPG56jKsLdTFmsSsCzOM= -golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= +golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= -golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= +golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= +golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -304,40 +329,39 @@ golang.org/x/sys v0.0.0-20220906165534-d0df966e6959/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.4.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q= -golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= +golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.1.0/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= golang.org/x/term v0.4.0/go.mod h1:9P2UbLfCdcvo3p/nzKvsmas4TnlujnuoV9hGgYzW1lQ= -golang.org/x/term v0.7.0 h1:BEvjmm5fURWqcfbSKTdpkDXYBrUS1c0m8agp14W48vQ= +golang.org/x/term v0.27.0 h1:WP60Sv1nlK1T6SupCHbXzSaN0b9wUmsPoRS9b61A23Q= +golang.org/x/term v0.27.0/go.mod h1:iMsnZpn0cago0GOrHO2+Y7u7JPn5AylBrcoWkElMTSM= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE= -golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= +golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.8.0 h1:vSDcovVPld282ceKgDimkRSC8kpaH1dgyc9UMzlt84Y= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d h1:vU5i/LfpvrRCpgM/VPfJLg5KjxD3E+hfT1SH+d9zLwg= +golang.org/x/tools v0.21.1-0.20240508182429-e35e4ccd0d2d/go.mod h1:aiJjzUbINMkxbQROHiO6hDPo2LHcIPhhQsa9DLh0yGk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= -google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 h1:jmIfw8+gSvXcZSgaFAGyInDXeWzUhvYH57G/5GKMn70= -google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37/go.mod h1:RGgjbofJ8xD9Sq1VVhDM1Vok1vRONV+rg+CjzG4SZKM= -google.golang.org/grpc v1.51.0 h1:E1eGv1FTqoLIdnBCZufiSHgKjlqG6fKFf6pPWtMTh8U= -google.golang.org/grpc v1.51.0/go.mod h1:wgNDFcnuBGmxLKI/qn4T+m5BtEBYXJPvibbUPsAIPww= -google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= -google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= -google.golang.org/protobuf v1.30.0 h1:kPPoIgf3TsEvrm0PFe15JQ+570QVxYzEvvHqChK+cng= -google.golang.org/protobuf v1.30.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484 h1:Z7FRVJPSMaHQxD0uXU8WdgFh8PseLM8Q8NzhnpMrBhQ= +google.golang.org/genproto/googleapis/rpc v0.0.0-20241216192217-9240e9c98484/go.mod h1:lcTa1sDdWEIHMWlITnIczmw5w60CF9ffkb8Z+DVmmjA= +google.golang.org/grpc v1.69.2 h1:U3S9QEtbXC0bYNvRtcoklF3xGtLViumSYxWykJS+7AU= +google.golang.org/grpc v1.69.2/go.mod h1:vyjdE6jLBI76dgpDojsFGNaHlxdjXN9ghpnd2o7JGZ4= +google.golang.org/protobuf v1.36.0 h1:mjIs9gYtt56AzC4ZaffQuh88TZurBGhIJMBZGSxNerQ= +google.golang.org/protobuf v1.36.0/go.mod h1:9fA7Ob0pmnwhb644+1+CVWFRbNajQ6iRojtC/QF5bRE= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= @@ -357,3 +381,4 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gotest.tools/v3 v3.0.3 h1:4AuOwCGf4lLR9u3YOe2awrHygurzhO/HeQ6laiA6Sx0= +gotest.tools/v3 v3.0.3/go.mod h1:Z7Lb0S5l+klDB31fvDQX8ss/FlKDxtlFlw3Oa8Ymbl8= diff --git a/package.nix b/package.nix new file mode 100644 index 00000000..47bd247b --- /dev/null +++ b/package.nix @@ -0,0 +1,21 @@ +{ + terraform-providers, +}: +# Allows testing of the provider with the following block: +# terraform { +# required_providers { +# sysdig = { +# source = "sysdiglabs/sysdig" +# version = "=1.0.0-local" +# } +# } +# } +terraform-providers.mkProvider { + owner = "sysdiglabs"; + repo = "terraform-provider-sysdig"; + homepage = "https://registry.terraform.io/providers/sysdiglabs/sysdig"; + rev = "1.0.0-local"; # Keeping this version fixed with a `-local` version, so user can just bundle the concrete plugin version with terraform using nix. + vendorHash = "sha256-eZl/UKvLG1Yi59oRl70CvrAIyLoyPW0ILWmFMzdUdDQ="; + hash = ""; + mkProviderFetcher = { ... }: ./.; +} diff --git a/sysdig/internal/client/v2/client.go b/sysdig/internal/client/v2/client.go index 19a58af5..f3cfefce 100644 --- a/sysdig/internal/client/v2/client.go +++ b/sysdig/internal/client/v2/client.go @@ -59,6 +59,7 @@ type SecureCommon interface { PostureZoneInterface PostureControlInterface PostureAcceptRiskInterface + PostureVulnerabilityAcceptRiskInterface } type Requester interface { diff --git a/sysdig/internal/client/v2/model_vulnerability_control.go b/sysdig/internal/client/v2/model_vulnerability_control.go new file mode 100644 index 00000000..4f2caee4 --- /dev/null +++ b/sysdig/internal/client/v2/model_vulnerability_control.go @@ -0,0 +1,98 @@ +package v2 + +import ( + "fmt" + "time" +) + +type ( + EntityType string + ReasonType string + StatusType string + StageType string + ContextType string +) + +const ( + EntityTypeImageName EntityType = "imageName" + EntityTypeImagePrefix EntityType = "imagePrefix" + EntityTypeImageSuffix EntityType = "imageSuffix" + EntityTypeImageNameContains EntityType = "imageNameContains" + EntityTypeVulnerability EntityType = "vulnerability" + EntityTypeHostName EntityType = "hostName" + EntityTypeHostNameContains EntityType = "hostNameContains" + EntityTypePolicyRule EntityType = "policyRule" +) + +const ( + ReasonRiskTransferred ReasonType = "RiskTransferred" + ReasonRiskAvoided ReasonType = "RiskAvoided" + ReasonRiskMitigated ReasonType = "RiskMitigated" + ReasonRiskOwned ReasonType = "RiskOwned" + ReasonRiskNotRelevant ReasonType = "RiskNotRelevant" + ReasonCustom ReasonType = "Custom" +) + +func ReasonTypeFromString(value string) (ReasonType, error) { + t := ReasonType(value) + switch t { + case ReasonRiskTransferred, ReasonRiskAvoided, ReasonRiskMitigated, ReasonRiskOwned, ReasonRiskNotRelevant, ReasonCustom: + return t, nil + default: + return "", fmt.Errorf("unsupported reason type: %s", value) + } +} + +const ( + StatusActive StatusType = "active" + StatusExpired StatusType = "expired" +) + +const ( + ContextTypeImageName ContextType = "imageName" + ContextTypeImagePrefix ContextType = "imagePrefix" + ContextTypeImageSuffix ContextType = "imageSuffix" + ContextTypeImageNameContains ContextType = "imageNameContains" + ContextTypeHostName ContextType = "hostName" + ContextTypeHostNameContains ContextType = "hostNameContains" + ContextTypePackageName ContextType = "packageName" + ContextTypePackageVersion ContextType = "packageVersion" +) + +type AcceptVulnerabilityRiskRequest struct { + EntityType EntityType `json:"entityType"` + EntityValue string `json:"entityValue"` + Reason ReasonType `json:"reason"` + Description string `json:"description"` + ExpirationDate string `json:"expirationDate,omitempty"` + Context []AcceptVulnerabilityRiskContext `json:"context"` + Stages []StageType `json:"stages,omitempty"` +} + +type UpdateAcceptVulnerabilityRiskRequest struct { + ID string `json:"id"` + ExpirationDate string `json:"expirationDate,omitempty"` + Reason ReasonType `json:"reason"` + Description string `json:"description"` +} + +type AcceptVulnerabilityRisk struct { + ID string `json:"id"` + EntityType EntityType `json:"entityType"` + EntityValue string `json:"entityValue"` + Reason ReasonType `json:"reason"` + Description string `json:"description"` + ExpirationDate string `json:"expirationDate,omitempty"` + Status StatusType `json:"status"` + CreatedAt time.Time `json:"createdAt,omitempty"` + UpdatedAt time.Time `json:"updatedAt,omitempty"` + CreatedBy string `json:"createdBy,omitempty"` + UpdatedBy string `json:"updatedBy,omitempty"` + Context []AcceptVulnerabilityRiskContext `json:"context"` + Stages []StageType `json:"stages,omitempty"` +} + +type AcceptVulnerabilityRiskContext struct { + ContextType ContextType `json:"contextType"` + ContextValue string `json:"contextValue"` +} diff --git a/sysdig/internal/client/v2/vulnerability_accept_risk.go b/sysdig/internal/client/v2/vulnerability_accept_risk.go new file mode 100644 index 00000000..f1a3f6e2 --- /dev/null +++ b/sysdig/internal/client/v2/vulnerability_accept_risk.go @@ -0,0 +1,107 @@ +package v2 + +import ( + "context" + "fmt" + "net/http" +) + +type PostureVulnerabilityAcceptRiskInterface interface { + Base + + SaveAcceptVulnerabilityRisk(ctx context.Context, p *AcceptVulnerabilityRiskRequest) (*AcceptVulnerabilityRisk, string, error) + GetAcceptanceVulnerabilityRisk(ctx context.Context, id string) (*AcceptVulnerabilityRisk, string, error) + DeleteAcceptanceVulnerabilityRisk(ctx context.Context, id string) error + UpdateAcceptanceVulnerabilityRisk(ctx context.Context, p *UpdateAcceptVulnerabilityRiskRequest) (*AcceptVulnerabilityRisk, string, error) +} + +const ( + AcceptVulnerabilityRiskCreatePath = "%s/secure/vulnerability/v1beta1/accepted-risks" + AcceptVulnerabilityRiskGetPath = "%s/secure/vulnerability/v1beta1/accepted-risks/%s" + AcceptVulnerabilityRiskDeletePath = "%s/secure/vulnerability/v1beta1/accepted-risks/%s" + AcceptVulnerabilityRiskUpdatePath = "%s/secure/vulnerability/v1beta1/accepted-risks/%s" +) + +func (c *Client) SaveAcceptVulnerabilityRisk(ctx context.Context, p *AcceptVulnerabilityRiskRequest) (*AcceptVulnerabilityRisk, string, error) { + payload, err := Marshal(p) + if err != nil { + return nil, "", err + } + + response, err := c.requester.Request(ctx, http.MethodPost, fmt.Sprintf(AcceptVulnerabilityRiskCreatePath, c.config.url), payload) + if err != nil { + return nil, "", err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusCreated { + errStatus, err := c.ErrorAndStatusFromResponse(response) + return nil, errStatus, err + } + + resp, err := Unmarshal[AcceptVulnerabilityRisk](response.Body) + if err != nil { + return nil, "", err + } + + return &resp, "", nil +} + +func (c *Client) GetAcceptanceVulnerabilityRisk(ctx context.Context, id string) (*AcceptVulnerabilityRisk, string, error) { + response, err := c.requester.Request(ctx, http.MethodGet, fmt.Sprintf(AcceptVulnerabilityRiskGetPath, c.config.url, id), nil) + if err != nil { + return nil, "", err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + errStatus, err := c.ErrorAndStatusFromResponse(response) + return nil, errStatus, err + } + + resp, err := Unmarshal[AcceptVulnerabilityRisk](response.Body) + if err != nil { + return nil, "", err + } + + return &resp, "", nil +} + +func (c *Client) DeleteAcceptanceVulnerabilityRisk(ctx context.Context, id string) error { + response, err := c.requester.Request(ctx, http.MethodDelete, fmt.Sprintf(AcceptVulnerabilityRiskDeletePath, c.config.url, id), nil) + if err != nil { + return err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusNoContent { + return c.ErrorFromResponse(response) + } + + return nil +} + +func (c *Client) UpdateAcceptanceVulnerabilityRisk(ctx context.Context, p *UpdateAcceptVulnerabilityRiskRequest) (*AcceptVulnerabilityRisk, string, error) { + payload, err := Marshal(p) + if err != nil { + return nil, "", err + } + + response, err := c.requester.Request(ctx, http.MethodPut, fmt.Sprintf(AcceptVulnerabilityRiskUpdatePath, c.config.url, p.ID), payload) + if err != nil { + return nil, "", err + } + defer response.Body.Close() + + if response.StatusCode != http.StatusOK { + errStatus, err := c.ErrorAndStatusFromResponse(response) + return nil, errStatus, err + } + + resp, err := Unmarshal[AcceptVulnerabilityRisk](response.Body) + if err != nil { + return nil, "", err + } + + return &resp, "", nil +} diff --git a/sysdig/provider.go b/sysdig/provider.go index 830d4168..3d86a76c 100644 --- a/sysdig/provider.go +++ b/sysdig/provider.go @@ -197,6 +197,7 @@ func (p *SysdigProvider) Provider() *schema.Provider { "sysdig_secure_posture_policy": resourceSysdigSecurePosturePolicy(), "sysdig_secure_posture_control": resourceSysdigSecurePostureControl(), "sysdig_secure_posture_accept_risk": resourceSysdigSecureAcceptPostureRisk(), + "sysdig_secure_vulnerability_accept_risk": resourceSysdigSecureVulnerabilityAcceptRisk(), }, DataSourcesMap: map[string]*schema.Resource{ "sysdig_secure_agentless_scanning_assets": dataSourceSysdigSecureAgentlessScanningAssets(), diff --git a/sysdig/resource_sysdig_secure_accept_vulnerability_risk.go b/sysdig/resource_sysdig_secure_accept_vulnerability_risk.go new file mode 100644 index 00000000..7d1e8916 --- /dev/null +++ b/sysdig/resource_sysdig_secure_accept_vulnerability_risk.go @@ -0,0 +1,378 @@ +package sysdig + +import ( + "context" + "fmt" + "regexp" + "strings" + + v2 "github.com/draios/terraform-provider-sysdig/sysdig/internal/client/v2" + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" +) + +func resourceSysdigSecureVulnerabilityAcceptRisk() *schema.Resource { + return &schema.Resource{ + CreateContext: resourceSysdigSecureVulnerabilityAcceptRiskCreate, + ReadContext: resourceSysdigSecureVulnerabilityAcceptRiskRead, + UpdateContext: resourceSysdigSecureVulnerabilityAcceptRiskUpdate, + DeleteContext: resourceSysdigSecureVulnerabilityAcceptRiskDelete, + Schema: map[string]*schema.Schema{ + "cve": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "image": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringDoesNotMatch(regexp.MustCompile(`^\\*$`), "image value '*' is not valid"), + ForceNew: true, + }, + "stages": { + Type: schema.TypeList, + Optional: true, + Elem: &schema.Schema{Type: schema.TypeString}, + ForceNew: true, + }, + "reason": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validation.StringInSlice([]string{"RiskTransferred", "RiskAvoided", "RiskMitigated", "RiskOwned", "RiskNotRelevant", "Custom"}, false), + }, + "description": { + Type: schema.TypeString, + Required: true, + }, + "expiration_date": { + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringMatch(regexp.MustCompile(`^\d{4}-\d{2}-\d{2}$`), "must be in YYYY-MM-DD format"), + }, + "hostname": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "hostname_contains": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "rule_id": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "package_name": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + "package_version": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + }, + }, + } +} + +func resourceSysdigSecureVulnerabilityAcceptRiskCreate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client, err := getVulnerabilityAcceptRiskClient(meta.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + reasonType, err := v2.ReasonTypeFromString(d.Get("reason").(string)) + if err != nil { + return diag.FromErr(err) + } + + req := &v2.AcceptVulnerabilityRiskRequest{ + Reason: reasonType, + Description: d.Get("description").(string), + Context: []v2.AcceptVulnerabilityRiskContext{}, + } + + if err := validateCombination(d); err != nil { + return diag.Errorf("%s", err) + } + + if cve, ok := d.GetOk("cve"); ok { + req.EntityType = v2.EntityTypeVulnerability + req.EntityValue = cve.(string) + setContextFromFields(d, req) + } else if ruleID, ok := d.GetOk("rule_id"); ok { + req.EntityType = v2.EntityTypePolicyRule + req.EntityValue = ruleID.(string) + setContextFromFields(d, req) + } else if image, ok := d.GetOk("image"); ok { + entityType, entityValue := getImageTypeAndValue(image.(string)) + req.EntityType = v2.EntityType(entityType) + req.EntityValue = entityValue + } else if hostname, ok := d.GetOk("hostname"); ok { + req.EntityType = v2.EntityTypeHostName + req.EntityValue = hostname.(string) + } else if hostnameContains, ok := d.GetOk("hostname_contains"); ok { + req.EntityType = v2.EntityTypeHostNameContains + req.EntityValue = hostnameContains.(string) + } else { + return diag.Errorf("invalid combination of fields provided") + } + + if expirationDate, ok := d.GetOk("expiration_date"); ok { + req.ExpirationDate = expirationDate.(string) + } + + if stages, ok := d.GetOk("stages"); ok { + for _, stage := range stages.([]interface{}) { + req.Stages = append(req.Stages, v2.StageType(stage.(string))) + } + } + + created, _, err := client.SaveAcceptVulnerabilityRisk(ctx, req) + if err != nil { + return diag.FromErr(err) + } + d.SetId(created.ID) + + return resourceSysdigSecureVulnerabilityAcceptRiskRead(ctx, d, meta) +} + +func validateCombination(d *schema.ResourceData) error { + _, hasCVE := d.GetOk("cve") + _, hasRuleID := d.GetOk("rule_id") + _, hasImage := d.GetOk("image") + _, hasHostname := d.GetOk("hostname") + _, hasHostnameContains := d.GetOk("hostname_contains") + _, hasPackageName := d.GetOk("package_name") + _, hasPackageVersion := d.GetOk("package_version") + + switch { + // Valid case: only hostname specified + case !hasCVE && !hasRuleID && !hasImage && hasHostname && !hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only hostname_contains specified + case !hasCVE && !hasRuleID && !hasImage && !hasHostname && hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only image specified + case !hasCVE && !hasRuleID && hasImage && !hasHostname && !hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only rule_id is specified + case !hasCVE && hasRuleID && !hasImage && !hasHostname && !hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only rule_id with image is specified + case !hasCVE && hasRuleID && hasImage && !hasHostname && !hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only rule_id with hostname is specified + case !hasCVE && hasRuleID && !hasImage && hasHostname && !hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only rule_id with hostname_contains is specified + case !hasCVE && hasRuleID && !hasImage && !hasHostname && hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only CVE is specified + case hasCVE && !hasRuleID && !hasImage && !hasHostname && !hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only CVE with image is specified + case hasCVE && !hasRuleID && hasImage && !hasHostname && !hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only CVE with hostname is specified + case hasCVE && !hasRuleID && !hasImage && hasHostname && !hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only CVE with hostname_contains is specified + case hasCVE && !hasRuleID && !hasImage && !hasHostname && hasHostnameContains && !hasPackageName && !hasPackageVersion: + return nil + // Valid case: only CVE with package is specified + case hasCVE && !hasRuleID && !hasImage && !hasHostname && !hasHostnameContains && hasPackageName: + return nil + } + + return fmt.Errorf("no valid combination of fields provided, check the provided examples in the docs for valid combinations") +} + +func getImageTypeAndValue(image string) (string, string) { + trimmedImage := strings.Trim(image, "*") + if len(image) == 0 { + return string(v2.EntityTypeImageName), trimmedImage + } + + switch { + case image[0] == '*' && image[len(image)-1] == '*': + return string(v2.EntityTypeImageNameContains), trimmedImage + case image[0] == '*': + return string(v2.EntityTypeImageSuffix), trimmedImage + case image[len(image)-1] == '*': + return string(v2.EntityTypeImagePrefix), trimmedImage + default: + return string(v2.EntityTypeImageName), trimmedImage + } +} + +func setContextFromFields(d *schema.ResourceData, req *v2.AcceptVulnerabilityRiskRequest) { + if image, ok := d.GetOk("image"); ok { + contextType, contextValue := getImageTypeAndValue(image.(string)) + req.Context = append(req.Context, v2.AcceptVulnerabilityRiskContext{ + ContextType: v2.ContextType(contextType), + ContextValue: contextValue, + }) + } + if hostname, ok := d.GetOk("hostname"); ok { + req.Context = append(req.Context, v2.AcceptVulnerabilityRiskContext{ + ContextType: v2.ContextTypeHostName, + ContextValue: hostname.(string), + }) + } + if hostnameContains, ok := d.GetOk("hostname_contains"); ok { + req.Context = append(req.Context, v2.AcceptVulnerabilityRiskContext{ + ContextType: v2.ContextTypeHostNameContains, + ContextValue: hostnameContains.(string), + }) + } + if pkg, ok := d.GetOk("package_name"); ok { + req.Context = append(req.Context, v2.AcceptVulnerabilityRiskContext{ + ContextType: v2.ContextTypePackageName, + ContextValue: pkg.(string), + }) + } + if pkgVersion, ok := d.GetOk("package_version"); ok { + req.Context = append(req.Context, v2.AcceptVulnerabilityRiskContext{ + ContextType: v2.ContextTypePackageVersion, + ContextValue: pkgVersion.(string), + }) + } +} + +func resourceSysdigSecureVulnerabilityAcceptRiskRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client, err := getVulnerabilityAcceptRiskClient(meta.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + id := d.Id() + result, _, err := client.GetAcceptanceVulnerabilityRisk(ctx, id) + if err != nil { + return diag.FromErr(err) + } + _ = d.Set("reason", result.Reason) + _ = d.Set("description", result.Description) + if result.ExpirationDate != "" { + _ = d.Set("expiration_date", result.ExpirationDate) + } + _ = d.Set("stages", result.Stages) + switch result.EntityType { + case v2.EntityTypeImageName: + _ = d.Set("image", result.EntityValue) + case v2.EntityTypeImagePrefix: + _ = d.Set("image", result.EntityValue+"*") + case v2.EntityTypeImageSuffix: + _ = d.Set("image", "*"+result.EntityValue) + case v2.EntityTypeImageNameContains: + _ = d.Set("image", "*"+result.EntityValue+"*") + case v2.EntityTypeVulnerability: + _ = d.Set("cve", result.EntityValue) + fillResourceDataFromContextSlice(d, result.Context) + case v2.EntityTypeHostName: + _ = d.Set("hostname", result.EntityValue) + case v2.EntityTypeHostNameContains: + _ = d.Set("hostname_contains", result.EntityValue) + case v2.EntityTypePolicyRule: + _ = d.Set("rule_id", result.EntityValue) + fillResourceDataFromContextSlice(d, result.Context) + default: + panic(fmt.Sprintf("unexpected v2.EntityType: %#v", result.EntityType)) + } + return nil +} + +func fillResourceDataFromContextSlice(d *schema.ResourceData, contextSlice []v2.AcceptVulnerabilityRiskContext) { + for _, context := range contextSlice { + fillResourceDataFromContext(d, context) + } +} + +func fillResourceDataFromContext(d *schema.ResourceData, context v2.AcceptVulnerabilityRiskContext) { + switch context.ContextType { + case v2.ContextTypeHostName: + _ = d.Set("hostname", context.ContextValue) + case v2.ContextTypeHostNameContains: + _ = d.Set("hostname_contains", context.ContextValue) + case v2.ContextTypeImageName: + _ = d.Set("image", context.ContextValue) + case v2.ContextTypeImageNameContains: + _ = d.Set("image", "*"+context.ContextValue+"*") + case v2.ContextTypeImagePrefix: + _ = d.Set("image", context.ContextValue+"*") + case v2.ContextTypeImageSuffix: + _ = d.Set("image", "*"+context.ContextValue) + case v2.ContextTypePackageName: + _ = d.Set("package_name", context.ContextValue) + case v2.ContextTypePackageVersion: + _ = d.Set("package_version", context.ContextValue) + default: + panic(fmt.Sprintf("unexpected v2.ContextType: %#v", context.ContextType)) + } +} + +func resourceSysdigSecureVulnerabilityAcceptRiskUpdate(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client, err := getVulnerabilityAcceptRiskClient(meta.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + id := d.Id() + + reasonType, err := v2.ReasonTypeFromString(d.Get("reason").(string)) + if err != nil { + return diag.FromErr(err) + } + + req := &v2.UpdateAcceptVulnerabilityRiskRequest{ + ID: id, + Reason: reasonType, + Description: d.Get("description").(string), + } + + if expirationDate, ok := d.GetOk("expiration_date"); ok { + req.ExpirationDate = expirationDate.(string) + } + + _, _, err = client.UpdateAcceptanceVulnerabilityRisk(ctx, req) + if err != nil { + return diag.FromErr(err) + } + return resourceSysdigSecureVulnerabilityAcceptRiskRead(ctx, d, meta) +} + +func resourceSysdigSecureVulnerabilityAcceptRiskDelete(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client, err := getVulnerabilityAcceptRiskClient(meta.(SysdigClients)) + if err != nil { + return diag.FromErr(err) + } + + id := d.Id() + if err := client.DeleteAcceptanceVulnerabilityRisk(ctx, id); err != nil { + return diag.FromErr(err) + } + d.SetId("") + return nil +} + +func getVulnerabilityAcceptRiskClient(c SysdigClients) (v2.PostureVulnerabilityAcceptRiskInterface, error) { + var client v2.PostureVulnerabilityAcceptRiskInterface + var err error + switch c.GetClientType() { + case IBMSecure: + client, err = c.ibmSecureClient() + if err != nil { + return nil, err + } + default: + client, err = c.sysdigSecureClientV2() + if err != nil { + return nil, err + } + } + return client, nil +} diff --git a/sysdig/resource_sysdig_secure_accept_vulnerability_risk_test.go b/sysdig/resource_sysdig_secure_accept_vulnerability_risk_test.go new file mode 100644 index 00000000..bfd74ae5 --- /dev/null +++ b/sysdig/resource_sysdig_secure_accept_vulnerability_risk_test.go @@ -0,0 +1,264 @@ +//go:build tf_acc_sysdig_secure + +package sysdig_test + +import ( + "os" + "testing" + + "github.com/draios/terraform-provider-sysdig/sysdig" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func TestAcceptSecureVulnerabilityRisk(t *testing.T) { + // Temporal hack to validate the resource in the CI. + // The endpoint https://secure.sysdig.com cannot be used for this, and is the default if the env var is not provided. + // It works in all other regions but US1, in US1 you need to specify https://api.us1.sysdig.com. The fix is on it's way. + // We only need this for the tests to pass. A workaround for this bug can be applied by users by specifying a new alias + // provider and specifying the concrete url for this alias provider. + url, urlSet := os.LookupEnv("SYSDIG_SECURE_URL") + if url == "https://secure.sysdig.com" || url == "" { + os.Setenv("SYSDIG_SECURE_URL", "https://api.us1.sysdig.com") + } + + defer func() { + if urlSet { + os.Setenv("SYSDIG_SECURE_URL", url) + } else { + os.Unsetenv("SYSDIG_SECURE_URL") + } + }() + + resource.Test(t, resource.TestCase{ + PreCheck: preCheckAnyEnv(t, SysdigSecureApiTokenEnv), + ProviderFactories: map[string]func() (*schema.Provider, error){ + "sysdig": func() (*schema.Provider, error) { + return sysdig.Provider(), nil + }, + }, + Steps: []resource.TestStep{ + { + Config: acceptVulnerabilityRiskResourceImageExact(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "image", "foo"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceImageExactWithExpirationDate(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "expiration_date", "2025-01-02"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceImageExact(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "expiration_date", ""), + ), + }, + { + Config: acceptVulnerabilityRiskResourceImagePrefix(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "image", "foo*"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceImageSuffix(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "image", "*foo"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceImageContains(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "image", "*foo*"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceHostname(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "hostname", "foo"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceHostnameContains(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "hostname_contains", "foo"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceCVE(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource", "cve", "CVE-1234"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceCVEWithImages(), + Check: resource.ComposeTestCheckFunc( + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource_image_exact", "cve", "CVE-1234"), + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource_image_exact", "image", "foo"), + + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource_image_prefix", "cve", "CVE-1234"), + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource_image_prefix", "image", "bar*"), + + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource_image_suffix", "cve", "CVE-1234"), + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource_image_suffix", "image", "*baz"), + + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource_image_contains", "cve", "CVE-1234"), + resource.TestCheckResourceAttr("sysdig_secure_vulnerability_accept_risk.accept_resource_image_contains", "image", "*quix*"), + ), + }, + { + Config: acceptVulnerabilityRiskResourceCVEWithHosts(), + }, + { + Config: acceptVulnerabilityRiskResourceCVEWithPackage(), + }, + { + Config: acceptVulnerabilityRiskResourceCVEWithPackageAndVersion(), + }, + }, + }) +} + +func acceptVulnerabilityRiskResourceImageExact() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + image = "foo" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +}` +} + +func acceptVulnerabilityRiskResourceImageExactWithExpirationDate() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + image = "foo" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" + expiration_date = "2025-01-02" +}` +} + +func acceptVulnerabilityRiskResourceImagePrefix() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + image = "foo*" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +}` +} + +func acceptVulnerabilityRiskResourceImageSuffix() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + image = "*foo" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +}` +} + +func acceptVulnerabilityRiskResourceImageContains() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + image = "*foo*" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +}` +} + +func acceptVulnerabilityRiskResourceHostname() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + hostname = "foo" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +}` +} + +func acceptVulnerabilityRiskResourceHostnameContains() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + hostname_contains = "foo" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +}` +} + +func acceptVulnerabilityRiskResourceCVE() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + cve = "CVE-1234" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +}` +} + +func acceptVulnerabilityRiskResourceCVEWithImages() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_image_exact" { + cve = "CVE-1234" + image = "foo" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +} +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_image_prefix" { + cve = "CVE-1234" + image = "bar*" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +} +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_image_suffix" { + cve = "CVE-1234" + image = "*baz" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +} +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_image_contains" { + cve = "CVE-1234" + image = "*quix*" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +} +` +} + +func acceptVulnerabilityRiskResourceCVEWithHosts() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_host_exact" { + cve = "CVE-1234" + hostname = "foo" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +} +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_host_contains" { + cve = "CVE-1234" + hostname_contains = "bar" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +} +` +} + +func acceptVulnerabilityRiskResourceCVEWithPackage() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + cve = "CVE-1234" + package_name = "nginx" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +} +` +} + +func acceptVulnerabilityRiskResourceCVEWithPackageAndVersion() string { + return ` +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource" { + cve = "CVE-1234" + package_name = "nginx" + package_version = "1.2.3" + description = "test accept vulnerability risk resource" + reason = "RiskTransferred" +} +` +} diff --git a/website/docs/r/secure_vulnerability_accept_risk.md b/website/docs/r/secure_vulnerability_accept_risk.md new file mode 100644 index 00000000..bedc9bab --- /dev/null +++ b/website/docs/r/secure_vulnerability_accept_risk.md @@ -0,0 +1,295 @@ +--- +subcategory: "Sysdig Secure" +layout: "sysdig" +page_title: "Sysdig: sysdig_secure_vulnerability_accept_risk" +description: |- + Accepts Sysdig Secure Vulnerability Risk. +--- + +# Resource: sysdig_secure_vulnerability_accept_risk + +Creates a Sysdig Secure Vulnerability Accept Risk. + +-> **Note:** Sysdig Terraform Provider is under rapid development at this point. If you experience any issue or discrepancy while using it, please make sure you have the latest version. If the issue persists, or you have a Feature Request to support an additional set of resources, please open a [new issue](https://github.com/sysdiglabs/terraform-provider-sysdig/issues/new) in the GitHub repository. + +## Example Usage + +### Image risk acceptance + +```terraform +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_image_exact" { + image = "docker.io/library/nginx:1.21.0" + description = "Accept risk for exact NGINX image" + reason = "RiskOwned" + stages = ["pipeline", "runtime"] +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_image_prefix" { + image = "docker.io/company/app:*" + description = "Accept risk for all versions of app image" + reason = "RiskMitigated" + stages = ["pipeline"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_image_suffix" { + image = "*:1.0.0" + description = "Accept risk for version 1.0.0 images" + reason = "RiskTransferred" + stages = ["runtime"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_image_contains" { + image = "*nodejs*" + description = "Accept risk for any image containing 'nodejs'" + reason = "RiskNotRelevant" + stages = [] + expiration_date = "2025-01-02" +} +``` + +### Hostname risk acceptance + +```terraform +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_hostname_exact" { + hostname = "webserver-prod-01.mydomain.com" + description = "Accept risk for production webserver" + reason = "RiskOwned" + stages = ["runtime"] +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_hostname_contains" { + hostname_contains = "staging-" + description = "Accept risk for all staging hosts" + reason = "RiskMitigated" + stages = [] + expiration_date = "2025-01-02" +} +``` + +### CVE Risk acceptance + +```terraform +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_globally" { + cve = "CVE-2021-44228" + description = "Accept risk for CVE-2021-44228 globally" + reason = "RiskMitigated" + stages = ["runtime"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_image_exact" { + cve = "CVE-2022-1234" + image = "docker.io/library/python:3.9" + description = "Accept risk for Python 3.9 image" + reason = "RiskOwned" + stages = ["pipeline"] +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_image_prefix" { + cve = "CVE-2023-4567" + image = "docker.io/company/frontend:*" + description = "Accept risk for all frontend image versions" + reason = "RiskAvoided" + stages = ["runtime"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_image_suffix" { + cve = "CVE-2020-5678" + image = "*:stable" + description = "Accept risk for stable tag images" + reason = "RiskNotRelevant" + stages = [] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_image_contains" { + cve = "CVE-2019-7890" + image = "*golang*" + description = "Accept risk for Go-based images" + reason = "Custom" + stages = ["pipeline"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_hostname_exact" { + cve = "CVE-2022-8901" + hostname = "api-prod-01.mydomain.com" + description = "Accept risk for production API server" + reason = "RiskTransferred" + stages = ["runtime"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_hostname_contains" { + cve = "CVE-2021-5678" + hostname_contains = "cache" + description = "Accept risk for cache servers" + reason = "RiskMitigated" + stages = [] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_package" { + cve = "CVE-2018-12345" + package_name = "openssl" + description = "Accept risk for OpenSSL package" + reason = "RiskOwned" + stages = ["pipeline", "runtime"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_cve_package_and_version" { + cve = "CVE-2017-6543" + package_name = "glibc" + package_version = "2.17" + description = "Accept risk for glibc 2.17 package" + reason = "RiskAvoided" + stages = [] + expiration_date = "2025-01-02" +} +``` + +### Rule risk acceptance + +```terraform +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_rule_globally" { + rule_id = 12345 + description = "Accept risk for rule globally" + reason = "Custom" + stages = ["pipeline", "runtime"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_rule_image_exact" { + rule_id = 12345 + image = "docker.io/library/mysql:8.0" + description = "Accept risk for MySQL 8.0 image" + reason = "RiskAvoided" + stages = ["pipeline"] +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_rule_image_prefix" { + rule_id = 12345 + image = "docker.io/company/backend:*" + description = "Accept risk for backend images" + reason = "RiskMitigated" + stages = ["runtime"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_rule_image_suffix" { + rule_id = 12345 + image = "*:latest" + description = "Accept risk for images tagged as 'latest'" + reason = "RiskOwned" + stages = [] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_rule_image_contains" { + rule_id = 12345 + image = "*redis*" + description = "Accept risk for Redis images" + reason = "RiskNotRelevant" + stages = ["pipeline"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_rule_hostname_exact" { + rule_id = 12345 + hostname = "db-prod-01.mydomain.com" + description = "Accept risk for production database host" + reason = "RiskTransferred" + stages = ["runtime"] + expiration_date = "2025-01-02" +} + +resource "sysdig_secure_vulnerability_accept_risk" "accept_resource_rule_hostname_contains" { + rule_id = 12345 + hostname_contains = "worker" + description = "Accept risk for worker nodes" + reason = "Custom" + stages = [] + expiration_date = "2025-01-02" +} +``` + +## Argument Reference + +### Required Arguments + +#### Context Arguments + +-> **Note:** Not all context arguments can be combined freely. Some combinations are valid while others are not. For more information on valid combinations, please refer to the examples provided above. You need to specify at least some context arguments, so they are not completely optional. + +- `cve` - The CVE (Common Vulnerabilities and Exposures) identifier for the vulnerability being accepted. + - **Type**: `string` + - **Example**: `"CVE-2021-44228"` + +- `hostname` - The exact hostname for which the vulnerability risk is being accepted. + - **Type**: `string` + - **Example**: `"webserver-prod-01.mydomain.com"` + +- `hostname_contains` - A substring to match hostnames for which the risk acceptance applies. + - **Type**: `string` + - **Example**: `"worker"` + +- `image` - The image name for which the vulnerability risk is being accepted. Wildcards can be used in both the beginning or the end of the name, but `*` alone is not allowed, nor is `*` in the middle. + - **Type**: `string` + - **Examples**: `"docker.io/library/nginx:1.21.0"`, `"*nginx:1.21.0"`, `"docker.io/library/nginx:*"`, `"*nginx*"` + +- `package_name` - The name of the package for which the vulnerability risk is being accepted. + - **Type**: `string` + - **Example**: `"org.apache.logging.log4j:log4j-jcl"` + +- `package_version` - The version of the package for which the vulnerability risk is being accepted. + - **Type**: `string` + - **Example**: `"2.14.1"` + +- `rule_id` - The vulnerability scanning rule identifier to accept risks on. + - **Type**: `string` + - **Example**: `"12345"` + +- `stages` - The stages where the risk acceptance applies. Possible values are `pipeline`, `runtime`, or both. It can also be an empty array. + - **Type**: `list of strings` + - **Example**: `["pipeline", "runtime"]` + +#### Other required arguments + +- `description` - A description providing details about the risk acceptance. + - **Type**: `string` + - **Example**: `"Accept risk for exact NGINX image due to mitigations applied"` + +- `reason` - The reason for accepting the risk. Possible values are: + - `RiskTransferred` + - `RiskAvoided` + - `RiskMitigated` + - `RiskOwned` + - `RiskNotRelevant` + - `Custom` + - **Type**: `string` + - **Example**: `"RiskMitigated"` + +### Optional arguments + +- `expiration_date` - The date when the risk acceptance expires. The date must be in `YYYY-MM-DD` format. + - **Type**: `string` + - **Example**: `"2025-01-02"` + + +## Attributes Reference + +In addition to all arguments above, the following attributes are exported: + +- `id` - (Computed) The ID of the Accept Risk. + +## Import + +The vulnerability accept risk can be imported using the ID, e.g. + +``` +$ terraform import sysdig_secure_vulnerability_accept_risk.example 12345 +```