diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index f022e7d1..f5e590ed 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,34 +1,24 @@ name: build on: + push: + branches: [ master ] pull_request: - branches: [ master, main ] + branches: [ master ] jobs: build: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Set up Go - uses: actions/setup-go@v3 + uses: actions/setup-go@v4 with: - go-version: 1.20.2 + go-version: 1.21.3 - name: Linters - run: make linters + run: make lint - - name: Build - run: go build -v ./... - - - name: Tests data_source - env: - EC_USERNAME: ${{ secrets.EC_USERNAME }} - EC_PASSWORD: ${{ secrets.EC_PASSWORD }} - run: make test_cloud_data_source - - - name: Tests resource - env: - EC_USERNAME: ${{ secrets.EC_USERNAME }} - EC_PASSWORD: ${{ secrets.EC_PASSWORD }} - run: make test_cloud_resource + - name: Tests + run: make test diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml deleted file mode 100644 index b0a841a4..00000000 --- a/.github/workflows/release.yml +++ /dev/null @@ -1,49 +0,0 @@ -# This GitHub action can publish assets for release when a tag is created. -# Currently its setup to run on any tag that matches the pattern "v*" (ie. v0.1.0). -# -# This uses an action (hashicorp/ghaction-import-gpg) that assumes you set your -# private key in the `GPG_PRIVATE_KEY` secret and passphrase in the `PASSPHRASE` -# secret. If you would rather own your own GPG handling, please fork this action -# or use an alternative one for key handling. -# -# You will need to pass the `--batch` flag to `gpg` in your signing step -# in `goreleaser` to indicate this is being used in a non-interactive mode. -# -name: release -on: - push: - tags: - - 'v*' -jobs: - goreleaser: - runs-on: ubuntu-latest - steps: - - - name: Checkout - uses: actions/checkout@v3 - - - name: Unshallow - run: git fetch --prune --unshallow - - - name: Set up Go - uses: actions/setup-go@v3 - with: - go-version: 1.20.2 - - - name: Import GPG key - id: import_gpg - uses: crazy-max/ghaction-import-gpg@v5 - with: - # These secrets will need to be configured for the repository: - gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }} - passphrase: ${{ secrets.PASSPHRASE }} - - - name: Run GoReleaser - uses: goreleaser/goreleaser-action@v4 - with: - version: latest - args: release --rm-dist - env: - GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }} -# # GitHub sets this automatically - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} \ No newline at end of file diff --git a/.golangci.yml b/.golangci.yml index f1048b22..691c158a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,32 +1,19 @@ run: timeout: 10m - go: "1.20" + go: "1.21.3" issues: max-per-linter: 0 max-same-issues: 0 - exclude: - # revive, stylecheck: ignore constants in all caps - - don't use ALL_CAPS in Go names; use CamelCase - - ST1003 - # gosec - - G401 - - G501 exclude-rules: - - path: \.go + - path: (.+)_test.go linters: - - nolintlint - text: should be written without leading space - - text: lifecyclepolicy.CreateScheduleOpts - linters: - - ireturn - - path: utils|_test - linters: - - wrapcheck + - funlen linters: enable-all: true disable: + # deprecated - deadcode - maligned - varcheck @@ -40,37 +27,36 @@ linters: - rowserrcheck - sqlclosecheck - wastedassign - # skip - - gochecknoglobals # check that no global variables exist - - nilnil # Checks that there is no simultaneous return of nil error and an invalid value. - - gomnd # An analyzer to detect magic numbers. - - goerr113 # Golang linter to check the errors handling expressions - - exhaustruct # Checks if all structure fields are initialized - - lll # Reports long lines + # skip: dubious benefit + - gochecknoglobals # Checks that no global variables exist. + - exhaustruct # Checks if all structure fields are initialized. + - lll # Reports long lines. - godox # Tool for detection of FIXME, TODO and other comment keywords - wsl # Whitespace Linter - Forces you to use empty lines! + - tagliatelle # Checks the struct tags. + - nonamedreturns # Reports all named returns. + - wrapcheck # Checks that errors returned from external packages are wrapped. + - ireturn # Accept Interfaces, Return Concrete Types. + - tagalign # Checks that struct tags are well aligned + - depguard # Checks if package imports are in a list of acceptable packages + - musttag # Enforce field tags in (un)marshaled structs. + - dupl # Tool for code clone detection. + - cyclop # Checks function and package cyclomatic complexity. - forcetypeassert # finds forced type assertions - # complexity: need to refactor - - cyclop - - funlen - - gocognit - - gocyclo - - maintidx - - nestif - - dupl - - depguard + - goerr113 # Golang linter to check the errors handling expressions + # tests + - testpackage # Makes you use a separate _test package. + - paralleltest # Detects missing usage of t.Parallel() method in your Go test. linters-settings: nlreturn: - block-size: 10 + block-size: 5 gci: sections: - standard # Standard section: captures all standard packages. - default # Default section: contains all imports that could not be matched to another section type. - prefix(github.com/Edge-Center) errcheck: - ignore: github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema:ForceNew|Set,fmt:.*,io:Close,io:WriteString - nakedret: - max-func-lines: 40 + ignore: github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema:ForceNew|Set,fmt varnamelen: min-name-length: 1 diff --git a/.goreleaser.yml b/.goreleaser.yml index f51b9e6e..531b6911 100644 --- a/.goreleaser.yml +++ b/.goreleaser.yml @@ -1,60 +1,13 @@ -# Visit https://goreleaser.com for documentation on how to customize this -# behavior. before: hooks: - # this is just an example and not a requirement for provider building/publishing - go mod tidy builds: - - env: - # goreleaser does not work with CGO, it could also complicate - # usage by users in CI/CD systems like Terraform Cloud where - # they are unable to install libraries. - - CGO_ENABLED=0 - mod_timestamp: '{{ .CommitTimestamp }}' - flags: - - -trimpath - ldflags: - - '-s -w -X main.version={{.Version}} -X main.commit={{.Commit}}' - goos: - - freebsd - - windows - - linux - - darwin - goarch: - - amd64 - - '386' - - arm - - arm64 - ignore: - - goos: darwin - goarch: '386' - binary: '{{ .ProjectName }}_v{{ .Version }}' + - skip: true archives: - format: zip name_template: '{{ .ProjectName }}_{{ .Version }}_{{ .Os }}_{{ .Arch }}' checksum: - extra_files: - - glob: 'terraform-registry-manifest.json' - name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' name_template: '{{ .ProjectName }}_{{ .Version }}_SHA256SUMS' algorithm: sha256 -signs: - - artifacts: checksum - args: - # if you are using this in a GitHub action or some other automated pipeline, you - # need to pass the batch flag to indicate its not interactive. - - "--batch" - - "--local-user" - - "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key - - "--output" - - "${signature}" - - "--detach-sign" - - "${artifact}" -release: - extra_files: - - glob: 'terraform-registry-manifest.json' - name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json' - # If you want to manually examine the release before its live, uncomment this line: - # draft: true changelog: - skip: true \ No newline at end of file + skip: true diff --git a/Makefile b/Makefile index 371b6376..2c816408 100644 --- a/Makefile +++ b/Makefile @@ -1,98 +1,28 @@ -# ENVS -ifeq ($(OS),Windows_NT) - PROJECT_DIR = $(shell cd) - OS := windows - ifeq ($(PROCESSOR_ARCHITECTURE),AMD64) - ARCH := amd64 - endif - ifeq ($(PROCESSOR_ARCHITECTURE),x86) - ARCH := 386 - endif -else - PROJECT_DIR = $(shell pwd) - OS := $(shell uname | tr '[:upper:]' '[:lower:]') - ARCH := $(shell uname -m) -endif -BIN_DIR = $(PROJECT_DIR)/bin -TEST_DIR = $(PROJECT_DIR)/edgecenter/test -ENV_TESTS_FILE = $(TEST_DIR)/.env +PROJECT_DIR=$(shell pwd) +BIN_DIR=$(PROJECT_DIR)/bin # BINARY -BINARY_NAME = terraform-provider-edgecenter -TAG_PREFIX = "v" -TAG = $(shell git describe --tags) -VERSION = $(shell git describe --tags $(LAST_TAG_COMMIT) | sed "s/^$(TAG_PREFIX)//") -PLUGIN_PATH = ~/.terraform.d/plugins/local.edgecenter.ru/repo/edgecenter/$(VERSION)/$(OS)_$(ARCH) - -tidy: - go mod tidy - -# BUILD -build: tidy +BINARY_NAME=terraform-provider-edgecenter +TAG_PREFIX="v" +TAG=$(shell git describe --tags) +VERSION=$(shell git describe --tags $(LAST_TAG_COMMIT) | sed "s/^$(TAG_PREFIX)//") +PLUGIN_PATH=~/.terraform.d/plugins/local.edgecenter.ru/repo/edgecenter/$(VERSION)/$(OS)_$(ARCH) + +.PHONY: build +build: fmtcheck mkdir -p $(PLUGIN_PATH) go build -o $(PLUGIN_PATH)/$(BINARY_NAME)_v$(VERSION) go build -o bin/$(BINARY_NAME) -build_debug: tidy - mkdir -p $(PLUGIN_PATH) - go build -o $(PLUGIN_PATH)/$(BINARY_NAME)_v$(VERSION) -gcflags '-N -l' - go build -o bin/$(BINARY_NAME) -gcflags '-N -l' - -# CHECKS -err_check: - @sh -c "'$(PROJECT_DIR)/scripts/errcheck.sh'" - -linters: - @test -f $(BIN_DIR)/golangci-lint || curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s v1.54.2 - @$(BIN_DIR)/golangci-lint run - -linters_docker: # for windows - docker run --rm -v $(PROJECT_DIR):/app -w /app golangci/golangci-lint:v1.54.2 golangci-lint run -v - -# TESTS -envs_reader: - go install github.com/joho/godotenv/cmd/godotenv@latest - -test_cloud_data_source: envs_reader - godotenv -f $(ENV_TESTS_FILE) go test $(TEST_DIR) -tags cloud_data_source -short -timeout=20m - -test_cloud_resource: envs_reader - godotenv -f $(ENV_TESTS_FILE) go test $(TEST_DIR) -tags cloud_resource -short -timeout=20m - -test_not_cloud: envs_reader - godotenv -f $(ENV_TESTS_FILE) go test $(TEST_DIR) -tags dns storage cdn -v -timeout=5m - -# local test run (need to export VAULT_TOKEN env) -install_jq: - if test "$(OS)" = "linux"; then \ - curl -L -o $(BIN_DIR)/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-linux64; \ - else \ - curl -L -o $(BIN_DIR)/jq https://github.com/stedolan/jq/releases/download/jq-1.6/jq-osx-amd64; \ - fi - chmod +x $(BIN_DIR)/jq - -install_vault: - curl -L -o vault.zip https://releases.hashicorp.com/vault/1.13.3/vault_1.13.3_$(OS)_$(ARCH).zip - unzip vault.zip && rm -f vault.zip && chmod +x vault - mv vault $(BIN_DIR)/ - -download_env_file: envs_reader - godotenv -f $(ENV_TESTS_FILE) $(BIN_DIR)/vault login -method=token $(VAULT_TOKEN) - godotenv -f $(ENV_TESTS_FILE) $(BIN_DIR)/vault kv get -format=json --field data /CLOUD/terraform | $(BIN_DIR)/jq -r 'to_entries|map("\(.key)=\(.value)")|.[]' >> $(ENV_TESTS_FILE) - -test_local_data_source: envs_reader - godotenv -f .local.env go test $(TEST_DIR) -tags cloud_data_source -short -timeout=5m -v - -test_local_resource: envs_reader - godotenv -f .local.env go test $(TEST_DIR) -tags cloud_resource -short -timeout=10m -v - -# DOCS -docs_fmt: - terraform fmt -recursive ./examples/ +.PHONY: lint +lint: + @go install github.com/golangci/golangci-lint/cmd/golangci-lint@latest + @golangci-lint run -v ./... -docs: docs_fmt - go get github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs@v0.16 - make tidy - tfplugindocs --tf-version=1.5.0 --provider-name=edgecenter +.PHONY: test +test: + go test -v -timeout=2m -.PHONY: tidy build build_debug err_check linters linters_docker envs_reader test_cloud_data_source test_cloud_resource test_not_cloud install_jq install_vault download_env_file test_local_data_source test_local_resource docs_fmt docs +.PHONY: fmtcheck +fmtcheck: + @sh -c "'$(PROJECT_DIR)/scripts/gofmtcheck.sh'" diff --git a/README.md b/README.md index fc9380db..cf525c69 100644 --- a/README.md +++ b/README.md @@ -1,150 +1,17 @@ -Terraform EdgeCenter Provider ------------------------------- +# !!! v2 Beta, not production ready !!! +EdgeCenter Terraform Provider +================== -EdgeCenter -==================================================================================== - -- [![Gitter chat](https://badges.gitter.im/hashicorp-terraform/Lobby.png)](https://gitter.im/hashicorp-terraform/Lobby) -- Mailing list: [Google Groups](http://groups.google.com/group/terraform-tool) +- Documentation: Requirements ------------ -- [Terraform](https://www.terraform.io/downloads.html) 0.13.x -- [Go](https://golang.org/doc/install) 1.19 (to build the provider plugin) - -Latest provider ------------- -- [edge-center provider](https://registry.terraform.io/providers/Edge-Center/edgecenter/latest) +- [Terraform](https://www.terraform.io/downloads.html) v1.5.0 +- [Go](https://golang.org/doc/install) 1.21 (to build the provider plugin) -Building the provider +Building The Provider --------------------- -```sh -$ mkdir -p $GOPATH/src/github.com/terraform-providers -$ cd $GOPATH/src/github.com/terraform-providers -$ git clone https://github.com/Edge-Center/terraform-provider-edgecenter.git -$ cd $GOPATH/src/github.com/terraform-providers/terraform-provider-edgecenter -$ make build -``` - -### Override Terraform provider - -To override terraform provider for development goals you do next steps: - -create Terraform configuration file -```shell -$ touch ~/.terraformrc -``` - -point provider to development path -```shell -provider_installation { - - dev_overrides { - "local.edgecenter.ru/repo/edgecenter" = "//terraform-provider-edgecenter/bin" - } - - # For all other providers, install them directly from their origin provider - # registries as normal. If you omit this, Terraform will _only_ use - # the dev_overrides block, and so no other providers will be available. - direct {} -} -``` - -add `local.edgecenter.ru/repo/edgecenter` to .tf configuration file -```shell -terraform { - required_version = ">= 0.13.0" - - required_providers { - edgecenter = { - source = "local.edgecenter.ru/repo/edgecenter" - version = "{version_number}" # need to specify - } - } -} -``` Using the provider ------------------- -To use the provider, prepare configuration files based on examples - -```sh -$ cp ./examples/... . -$ terraform init -``` - -Testing ------------------- -Remote: Tests are run with provided secrets envs in the GitHub repository. -Local: execute the command `make test_local_data_source` and `make test_local_resource`. For this command to work, you need to: -* Create a `.local.env` file and fill it with the necessary envs. -* Run `make envs` to automatically fill the envs from Vault (don't forget to export `VAULT_TOKEN` to terminal). -* `make envs` requires the installation of `jq` and the `vault` binary. You can install them with the `make install_vault` and `make install_jq` commands, respectively. - -Docs generating ------------------- -To generate Terraform documentation, use the command `make docs`. This command uses the `terraform-plugin-docs` library to create provider documentation with examples and places it in the `docs` folder. These docs can be viewed on the provider registry page. - -Debugging ------------------- -There are two ways to debug the provider: -### VSCode debugging -1. Create a `launch.json` file: - * In the Run view, click `create a launch.json file`. - * Choose Go: Launch Package from the debug configuration drop-down menu. - * VS Code will create a `launch.json` file in a `.vscode` folder in your workspace. -2. Add a new configuration to `launch.json`: - * The `address` argument must be equal to the `source` field from your `provider.tf`. - ``` { - "version": "0.2.0", - "configurations": [ - { - "name": "Debug Terraform Provider", - "type": "go", - "request": "launch", - "mode": "debug", - "program": "${workspaceFolder}", - "env": {}, - "args": [ - "-debug", - "-address=local.edgecenter.ru/repo/edgecenter" - ] - } - ] - } - ``` -3. Launch the debug mode: `Run > Start Debugging (F5)`. -4. Copy the `TF_REATTACH_PROVIDERS` env from the console and export it to the terminal as follows: - ```shell - export TF_REATTACH_PROVIDERS='{"local.edgecenter.ru/repo/edgecenter":{...' - ``` -5. Set a breakpoint in your code and apply the Terraform config: `terraform apply`. -6. Debugging. - -### using delve -1. Install the Delve library - [installation](https://github.com/go-delve/delve/tree/master/Documentation/installation) -2. Build binary without optimization or use `make build_debug` - ```shell - go build -o bin/$(BINARY_NAME) -gcflags '-N -l' - ``` -3. Open the first terminal: - * Run the binary with the debug option: - ```shell - dlv exec bin/terraform-provider-edgecenter -- -debug - ``` - * Set a breakpoint for the create function with a resource that you want to debug, e.g, - ```shell - break resourceFloatingIPCreate - ``` - * `continue` - * Copy `TF_REATTACH_PROVIDERS` with its value from output -4. Open the second terminal: - * Export `TF_REATTACH_PROVIDERS`: - ```shell - export TF_REATTACH_PROVIDERS='{"local.edgecenter.ru/repo/edgecenter":{...' - ``` - * Launch ```terraform apply``` - * Debug with the `continue` command in the first terminal via `delve` - -Thank You +---------------------- diff --git a/docs/data-sources/floatingip.md b/docs/data-sources/floatingip.md deleted file mode 100644 index 91ae492b..00000000 --- a/docs/data-sources/floatingip.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_floatingip Data Source - edgecenter" -subcategory: "" -description: |- - A floating IP is a static IP address that can be associated with one of your instances or loadbalancers, - allowing it to have a static public IP address. The floating IP can be re-associated to any other instance in the same datacenter. ---- - -# edgecenter_floatingip (Data Source) - -A floating IP is a static IP address that can be associated with one of your instances or loadbalancers, -allowing it to have a static public IP address. The floating IP can be re-associated to any other instance in the same datacenter. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_floatingip" "ip" { - floating_ip_address = "10.100.179.172" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_floatingip.ip -} -``` - - -## Schema - -### Required - -- `floating_ip_address` (String) The floating IP address assigned to the resource. It must be a valid IP address. - -### Optional - -- `metadata_k` (String) Filtration query opts (only key). -- `metadata_kv` (Map of String) Filtration query opts, for example, {offset = "10", limit = "10"}. -- `port_id` (String) The ID (uuid) of the network port that the floating IP is associated with. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `fixed_ip_address` (String) The fixed (reserved) IP address that is associated with the floating IP. -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `router_id` (String) The ID (uuid) of the router that the floating IP is associated with. -- `status` (String) The current status of the floating IP resource. Can be 'DOWN' or 'ACTIVE'. - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - - diff --git a/docs/data-sources/image.md b/docs/data-sources/image.md deleted file mode 100644 index f2d62cfb..00000000 --- a/docs/data-sources/image.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_image Data Source - edgecenter" -subcategory: "" -description: |- - A cloud image is a pre-configured virtual machine template that you can use to create new instances. ---- - -# edgecenter_image (Data Source) - -A cloud image is a pre-configured virtual machine template that you can use to create new instances. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_image" "ubuntu" { - name = "ubuntu-20.04" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_image.ubuntu -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the image. Use 'os-version', for example 'ubuntu-20.04'. - -### Optional - -- `is_baremetal` (Boolean) Set to true if need to get the baremetal image. -- `metadata_k` (String) Filtration query opts (only key). -- `metadata_kv` (Map of String) Filtration query opts, for example, {offset = "10", limit = "10"}. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `description` (String) A detailed description of the image. -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `min_disk` (Number) Minimum disk space (in GB) required to launch an instance using this image. -- `min_ram` (Number) Minimum VM RAM (in MB) required to launch an instance using this image. -- `os_distro` (String) The distribution of the OS present in the image, e.g. Debian, CentOS, Ubuntu etc. -- `os_version` (String) The version of the OS present in the image. e.g. 19.04 (for Ubuntu) or 9.4 for Debian. - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - - diff --git a/docs/data-sources/instance.md b/docs/data-sources/instance.md deleted file mode 100644 index 88214e8c..00000000 --- a/docs/data-sources/instance.md +++ /dev/null @@ -1,120 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_instance Data Source - edgecenter" -subcategory: "" -description: |- - A cloud instance is a virtual machine in a cloud environment. Could be used with baremetal also. ---- - -# edgecenter_instance (Data Source) - -A cloud instance is a virtual machine in a cloud environment. Could be used with baremetal also. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_instance" "vm" { - name = "test-vm" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_instance.vm -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the instance. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `addresses` (List of Object) A list of network addresses associated with the instance, for example "pub_net": [...]. (see [below for nested schema](#nestedatt--addresses)) -- `flavor` (Map of String) A map defining the flavor of the instance, for example, {"flavor_name": "g1-standard-2-4", "ram": 4096, ...}. -- `flavor_id` (String) The ID of the flavor to be used for the instance, determining its compute and memory, for example 'g1-standard-2-4'. -- `id` (String) The ID of this resource. -- `interface` (List of Object) A list defining the network interfaces to be attached to the instance. (see [below for nested schema](#nestedatt--interface)) -- `metadata` (List of Object) (see [below for nested schema](#nestedatt--metadata)) -- `security_group` (List of Object) A list of firewall configurations applied to the instance, defined by their id and name. (see [below for nested schema](#nestedatt--security_group)) -- `status` (String) The current status of the instance. This is computed automatically and can be used to track the instance's state. -- `vm_state` (String) The current virtual machine state of the instance, -allowing you to start or stop the VM. Possible values are stopped and active. -- `volume` (Set of Object) A set defining the volumes to be attached to the instance. (see [below for nested schema](#nestedatt--volume)) - - -### Nested Schema for `addresses` - -Read-Only: - -- `net` (List of Object) (see [below for nested schema](#nestedobjatt--addresses--net)) - - -### Nested Schema for `addresses.net` - -Read-Only: - -- `addr` (String) -- `type` (String) - - - - -### Nested Schema for `interface` - -Read-Only: - -- `ip_address` (String) -- `network_id` (String) -- `port_id` (String) -- `subnet_id` (String) - - - -### Nested Schema for `metadata` - -Read-Only: - -- `key` (String) -- `value` (String) - - - -### Nested Schema for `security_group` - -Read-Only: - -- `name` (String) - - - -### Nested Schema for `volume` - -Read-Only: - -- `delete_on_termination` (Boolean) -- `volume_id` (String) - - diff --git a/docs/data-sources/k8s.md b/docs/data-sources/k8s.md deleted file mode 100644 index 52a56586..00000000 --- a/docs/data-sources/k8s.md +++ /dev/null @@ -1,86 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_k8s Data Source - edgecenter" -subcategory: "" -description: |- - Represent k8s cluster with one default pool. ---- - -# edgecenter_k8s (Data Source) - -Represent k8s cluster with one default pool. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_k8s" "cluster" { - project_id = 1 - region_id = 1 - cluster_id = "dc3a3ea9-86ae-47ad-a8e8-79df0ce04839" -} -``` - - -## Schema - -### Required - -- `cluster_id` (String) The uuid of the Kubernetes cluster. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `api_address` (String) API endpoint address for the Kubernetes cluster. -- `auto_healing_enabled` (Boolean) Indicates whether auto-healing is enabled for the Kubernetes cluster. -- `certificate_authority_data` (String) The certificate_authority_data field from the Kubernetes cluster config. -- `cluster_template_id` (String) Template identifier from which the Kubernetes cluster was instantiated. -- `container_version` (String) The container runtime version used in the Kubernetes cluster. -- `created_at` (String) The timestamp when the Kubernetes cluster was created. -- `discovery_url` (String) URL used for node discovery within the Kubernetes cluster. -- `faults` (Map of String) -- `fixed_network` (String) Fixed network (uuid) associated with the Kubernetes cluster. -- `fixed_subnet` (String) Subnet (uuid) associated with the fixed network. -- `health_status` (String) Overall health status of the Kubernetes cluster. -- `health_status_reason` (Map of String) -- `id` (String) The ID of this resource. -- `keypair` (String) -- `master_addresses` (List of String) List of IP addresses for master nodes in the Kubernetes cluster. -- `master_flavor_id` (String) Identifier for the master node flavor in the Kubernetes cluster. -- `master_lb_floating_ip_enabled` (Boolean) Flag indicating if the master LoadBalancer should have a floating IP. -- `name` (String) The name of the Kubernetes cluster. -- `node_addresses` (List of String) List of IP addresses for worker nodes in the Kubernetes cluster. -- `node_count` (Number) Total number of nodes in the Kubernetes cluster. -- `pool` (List of Object) Configuration details of the node pool in the Kubernetes cluster. (see [below for nested schema](#nestedatt--pool)) -- `status` (String) The current status of the Kubernetes cluster. -- `status_reason` (String) The reason for the current status of the Kubernetes cluster, if ERROR. -- `updated_at` (String) The timestamp when the Kubernetes cluster was updated. -- `user_id` (String) User identifier associated with the Kubernetes cluster. -- `version` (String) The version of the Kubernetes cluster. - - -### Nested Schema for `pool` - -Read-Only: - -- `created_at` (String) -- `docker_volume_size` (Number) -- `docker_volume_type` (String) -- `flavor_id` (String) -- `max_node_count` (Number) -- `min_node_count` (Number) -- `name` (String) -- `node_count` (Number) -- `stack_id` (String) -- `uuid` (String) - - diff --git a/docs/data-sources/k8s_client_config.md b/docs/data-sources/k8s_client_config.md deleted file mode 100644 index 8ddf6775..00000000 --- a/docs/data-sources/k8s_client_config.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_k8s_client_config Data Source - edgecenter" -subcategory: "" -description: |- - Represent k8s cluster with one default pool. ---- - -# edgecenter_k8s_client_config (Data Source) - -Represent k8s cluster with one default pool. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_k8s_client_config" "cfg" { - project_id = 1 - region_id = 1 - cluster_id = "dc3a3ea9-86ae-47ad-a8e8-79df0ce04839" -} -``` - - -## Schema - -### Required - -- `cluster_id` (String) The uuid of the Kubernetes cluster. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `client_certificate_data` (String) The client_certificate_data field from k8s config. -- `client_key_data` (String) The client_key_data field from k8s config. -- `id` (String) The ID of this resource. - - diff --git a/docs/data-sources/k8s_pool.md b/docs/data-sources/k8s_pool.md deleted file mode 100644 index fa0f111b..00000000 --- a/docs/data-sources/k8s_pool.md +++ /dev/null @@ -1,59 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_k8s_pool Data Source - edgecenter" -subcategory: "" -description: |- - Represent k8s cluster's pool. ---- - -# edgecenter_k8s_pool (Data Source) - -Represent k8s cluster's pool. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_k8s_pool" "pool" { - project_id = 1 - region_id = 1 - cluster_id = "6bf878c1-1ce4-47c3-a39b-6b5f1d79bf25" - pool_id = "dc3a3ea9-86ae-47ad-a8e8-79df0ce04839" -} -``` - - -## Schema - -### Required - -- `cluster_id` (String) The uuid of the Kubernetes cluster this pool belongs to. -- `pool_id` (String) The uuid of the Kubernetes pool within the cluster. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `created_at` (String) The timestamp when the Kubernetes pool was created. -- `docker_volume_size` (Number) The size of the volume used for Docker containers, in gigabytes. -- `docker_volume_type` (String) The type of volume used for the Docker containers. Available values are 'standard', 'ssd_hiiops', 'cold', and 'ultra'. -- `flavor_id` (String) The identifier of the flavor used for nodes in this pool. -- `id` (String) The ID of this resource. -- `is_default` (Boolean) Indicates whether this pool is the default pool in the cluster. -- `max_node_count` (Number) The maximum number of nodes the pool can scale to. -- `min_node_count` (Number) The minimum number of nodes in the pool. -- `name` (String) The name of the Kubernetes pool. -- `node_addresses` (List of String) A list of IP addresses of nodes within the pool. -- `node_count` (Number) The current number of nodes in the pool. -- `node_names` (List of String) A list of names of nodes within the pool. -- `stack_id` (String) The identifier of the underlying infrastructure stack used by this pool. - - diff --git a/docs/data-sources/lblistener.md b/docs/data-sources/lblistener.md deleted file mode 100644 index 610cb7a5..00000000 --- a/docs/data-sources/lblistener.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_lblistener Data Source - edgecenter" -subcategory: "" -description: |- - ---- - -# edgecenter_lblistener (Data Source) - - - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_lblistener" "l" { - name = "test-listener" - loadbalancer_id = "59b2eabc-c0a8-4545-8081-979bd963c6ab" //optional - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_lblistener.l -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the load balancer listener. - -### Optional - -- `loadbalancer_id` (String) The uuid for the load balancer. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `operating_status` (String) The current operational status of the load balancer. -- `pool_count` (Number) Number of pools associated with the load balancer. -- `protocol` (String) Available values is 'HTTP', 'HTTPS', 'TCP', 'UDP' -- `protocol_port` (Number) The port on which the protocol is bound. -- `provisioning_status` (String) The current provisioning status of the load balancer. - - diff --git a/docs/data-sources/lbpool.md b/docs/data-sources/lbpool.md deleted file mode 100644 index 3c0bc40d..00000000 --- a/docs/data-sources/lbpool.md +++ /dev/null @@ -1,91 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_lbpool Data Source - edgecenter" -subcategory: "" -description: |- - ---- - -# edgecenter_lbpool (Data Source) - - - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_lbpool" "pool" { - name = "test-pool" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_lbpool.pool -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the load balancer pool. - -### Optional - -- `listener_id` (String) The uuid for the load balancer listener. -- `loadbalancer_id` (String) The uuid for the load balancer. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `health_monitor` (List of Object) Configuration for health checks to test the health and state of the backend members. -It determines how the load balancer identifies whether the backend members are healthy or unhealthy. (see [below for nested schema](#nestedatt--health_monitor)) -- `id` (String) The ID of this resource. -- `lb_algorithm` (String) Available values is 'ROUND_ROBIN', 'LEAST_CONNECTIONS', 'SOURCE_IP', 'SOURCE_IP_PORT' -- `protocol` (String) Available values is 'HTTP' (currently work, other do not work on ed-8), 'HTTPS', 'TCP', 'UDP' -- `session_persistence` (List of Object) Configuration that enables the load balancer to bind a user's session to a specific backend member. -This ensures that all requests from the user during the session are sent to the same member. (see [below for nested schema](#nestedatt--session_persistence)) - - -### Nested Schema for `health_monitor` - -Read-Only: - -- `delay` (Number) -- `expected_codes` (String) -- `http_method` (String) -- `id` (String) -- `max_retries` (Number) -- `max_retries_down` (Number) -- `timeout` (Number) -- `type` (String) -- `url_path` (String) - - - -### Nested Schema for `session_persistence` - -Read-Only: - -- `cookie_name` (String) -- `persistence_granularity` (String) -- `persistence_timeout` (Number) -- `type` (String) - - diff --git a/docs/data-sources/loadbalancer.md b/docs/data-sources/loadbalancer.md deleted file mode 100644 index dc6a47f9..00000000 --- a/docs/data-sources/loadbalancer.md +++ /dev/null @@ -1,83 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_loadbalancer Data Source - edgecenter" -subcategory: "" -description: |- - ---- - -# edgecenter_loadbalancer (Data Source) - - - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_loadbalancer" "lb" { - name = "test-lb" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_loadbalancer.lb -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the router. - -### Optional - -- `metadata_k` (String) Filtration query opts (only key). -- `metadata_kv` (Map of String) Filtration query opts, for example, {offset = "10", limit = "10"} -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `listener` (List of Object) (see [below for nested schema](#nestedatt--listener)) -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `vip_address` (String) -- `vip_port_id` (String) - - -### Nested Schema for `listener` - -Read-Only: - -- `id` (String) -- `name` (String) -- `protocol` (String) -- `protocol_port` (Number) - - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - - diff --git a/docs/data-sources/loadbalancerv2.md b/docs/data-sources/loadbalancerv2.md deleted file mode 100644 index 256a5a05..00000000 --- a/docs/data-sources/loadbalancerv2.md +++ /dev/null @@ -1,72 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_loadbalancerv2 Data Source - edgecenter" -subcategory: "" -description: |- - ---- - -# edgecenter_loadbalancerv2 (Data Source) - - - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_loadbalancerv2" "lb" { - name = "test-lb" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_loadbalancerv2.lb -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the load balancer. - -### Optional - -- `metadata_k` (String) Filtration query opts (only key). -- `metadata_kv` (Map of String) Filtration query opts, for example, {offset = "10", limit = "10"} -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `security_group_id` (String) Load balancer security group ID -- `vip_address` (String) Load balancer IP address -- `vip_port_id` (String) Attached reserved IP. - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - - diff --git a/docs/data-sources/network.md b/docs/data-sources/network.md deleted file mode 100644 index 29133f02..00000000 --- a/docs/data-sources/network.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_network Data Source - edgecenter" -subcategory: "" -description: |- - Represent network. A network is a software-defined network in a cloud computing infrastructure ---- - -# edgecenter_network (Data Source) - -Represent network. A network is a software-defined network in a cloud computing infrastructure - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_network" "tnw" { - name = "example" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_network.tnw -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the network. - -### Optional - -- `metadata_k` (String) Filtration query opts (only key). -- `metadata_kv` (Map of String) Filtration query opts, for example, {offset = "10", limit = "10"} -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `shared_with_subnets` (Boolean) Get shared networks with details of subnets. - -### Read-Only - -- `external` (Boolean) -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `mtu` (Number) Maximum Transmission Unit (MTU) for the network. It determines the maximum packet size that can be transmitted without fragmentation. -- `shared` (Boolean) -- `subnets` (Block List) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedblock--subnets)) -- `type` (String) 'vlan' or 'vxlan' network type is allowed. Default value is 'vxlan' - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - - - -### Nested Schema for `subnets` - -Read-Only: - -- `available_ips` (Number) The number of available IPs in the subnet. -- `cidr` (String) Represents the IP address range of the subnet. -- `dns_nameservers` (List of String) List of DNS name servers for the subnet. -- `enable_dhcp` (Boolean) Enable DHCP for this subnet. If true, DHCP will be used to assign IP addresses to instances within this subnet. -- `gateway_ip` (String) The IP address of the gateway for this subnet. -- `has_router` (Boolean) Indicates whether the subnet has a router attached to it. -- `host_routes` (List of Object) List of additional routes to be added to instances that are part of this subnet. (see [below for nested schema](#nestedatt--subnets--host_routes)) -- `id` (String) The ID of the subnet. -- `name` (String) The name of the subnet. -- `total_ips` (Number) The total number of IPs in the subnet. - - -### Nested Schema for `subnets.host_routes` - -Read-Only: - -- `destination` (String) -- `nexthop` (String) - - diff --git a/docs/data-sources/project.md b/docs/data-sources/project.md deleted file mode 100644 index e267efb9..00000000 --- a/docs/data-sources/project.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_project Data Source - edgecenter" -subcategory: "" -description: |- - Represent project data ---- - -# edgecenter_project (Data Source) - -Represent project data - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} -``` - - -## Schema - -### Required - -- `name` (String) Displayed project name - -### Read-Only - -- `id` (String) The ID of this resource. - - diff --git a/docs/data-sources/region.md b/docs/data-sources/region.md deleted file mode 100644 index 0351bff3..00000000 --- a/docs/data-sources/region.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_region Data Source - edgecenter" -subcategory: "" -description: |- - Represent region data ---- - -# edgecenter_region (Data Source) - -Represent region data - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} -``` - - -## Schema - -### Required - -- `name` (String) Displayed region name - -### Read-Only - -- `id` (String) The ID of this resource. - - diff --git a/docs/data-sources/reservedfixedip.md b/docs/data-sources/reservedfixedip.md deleted file mode 100644 index 9edae5a4..00000000 --- a/docs/data-sources/reservedfixedip.md +++ /dev/null @@ -1,71 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_reservedfixedip Data Source - edgecenter" -subcategory: "" -description: |- - Represent reserved ips ---- - -# edgecenter_reservedfixedip (Data Source) - -Represent reserved ips - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_reservedfixedip" "ip" { - fixed_ip_address = "192.168.0.66" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_reservedfixedip.ip -} -``` - - -## Schema - -### Required - -- `fixed_ip_address` (String) The IP address that is associated with the reserved IP. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `allowed_address_pairs` (List of Object) Group of IP addresses that share the current IP as VIP. (see [below for nested schema](#nestedatt--allowed_address_pairs)) -- `id` (String) The ID of this resource. -- `is_vip` (Boolean) Flag to determine if the reserved fixed IP should be treated as a Virtual IP (VIP). -- `network_id` (String) ID of the network to which the reserved fixed IP is associated. -- `port_id` (String) ID of the port_id underlying the reserved fixed IP -- `status` (String) The current status of the reserved fixed IP. -- `subnet_id` (String) ID of the subnet from which the fixed IP should be reserved. - - -### Nested Schema for `allowed_address_pairs` - -Read-Only: - -- `ip_address` (String) -- `mac_address` (String) - - diff --git a/docs/data-sources/router.md b/docs/data-sources/router.md deleted file mode 100644 index 43a0572e..00000000 --- a/docs/data-sources/router.md +++ /dev/null @@ -1,101 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_router Data Source - edgecenter" -subcategory: "" -description: |- - ---- - -# edgecenter_router (Data Source) - - - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_router" "tr" { - name = "test_router" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_router.tr -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the load router. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `external_gateway_info` (List of Object) Information related to the external gateway. (see [below for nested schema](#nestedatt--external_gateway_info)) -- `id` (String) The ID of this resource. -- `interfaces` (List of Object) Set of interfaces associated with the router. (see [below for nested schema](#nestedatt--interfaces)) -- `routes` (List of Object) List of static routes to be applied to the router. (see [below for nested schema](#nestedatt--routes)) -- `status` (String) The current status of the router resource. - - -### Nested Schema for `external_gateway_info` - -Read-Only: - -- `enable_snat` (Boolean) -- `external_fixed_ips` (List of Object) (see [below for nested schema](#nestedobjatt--external_gateway_info--external_fixed_ips)) -- `network_id` (String) - - -### Nested Schema for `external_gateway_info.external_fixed_ips` - -Read-Only: - -- `ip_address` (String) -- `subnet_id` (String) - - - - -### Nested Schema for `interfaces` - -Read-Only: - -- `ip_address` (String) -- `mac_address` (String) -- `network_id` (String) -- `port_id` (String) -- `subnet_id` (String) -- `type` (String) - - - -### Nested Schema for `routes` - -Read-Only: - -- `destination` (String) -- `nexthop` (String) - - diff --git a/docs/data-sources/secret.md b/docs/data-sources/secret.md deleted file mode 100644 index 4ee24d2e..00000000 --- a/docs/data-sources/secret.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_secret Data Source - edgecenter" -subcategory: "" -description: |- - Represent secret ---- - -# edgecenter_secret (Data Source) - -Represent secret - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_secret" "lb_https" { - name = "lb_https" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_secret.lb_https -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the secret. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `algorithm` (String) The encryption algorithm used for the secret. -- `bit_length` (Number) The bit length of the encryption algorithm. -- `content_types` (Map of String) The content types associated with the secret's payload. -- `created` (String) Datetime when the secret was created. The format is 2025-12-28T19:14:44.180394 -- `expiration` (String) Datetime when the secret will expire. The format is 2025-12-28T19:14:44.180394 -- `id` (String) The ID of this resource. -- `mode` (String) The mode of the encryption algorithm. -- `status` (String) The current status of the secret. - - diff --git a/docs/data-sources/securitygroup.md b/docs/data-sources/securitygroup.md deleted file mode 100644 index 75610362..00000000 --- a/docs/data-sources/securitygroup.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_securitygroup Data Source - edgecenter" -subcategory: "" -description: |- - Represent SecurityGroups(Firewall) ---- - -# edgecenter_securitygroup (Data Source) - -Represent SecurityGroups(Firewall) - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_securitygroup" "default" { - name = "default" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_securitygroup.default -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the security group. - -### Optional - -- `metadata_k` (String) Filtration query opts (only key). -- `metadata_kv` (Map of String) Filtration query opts, for example, {offset = "10", limit = "10"} -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `description` (String) A detailed description of the security group. -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `security_group_rules` (Set of Object) Firewall rules control what inbound(ingress) and outbound(egress) traffic is allowed to enter or leave a Instance. At least one 'egress' rule should be set (see [below for nested schema](#nestedatt--security_group_rules)) - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - - - -### Nested Schema for `security_group_rules` - -Read-Only: - -- `created_at` (String) -- `description` (String) -- `direction` (String) -- `ethertype` (String) -- `id` (String) -- `port_range_max` (Number) -- `port_range_min` (Number) -- `protocol` (String) -- `remote_ip_prefix` (String) -- `updated_at` (String) - - diff --git a/docs/data-sources/servergroup.md b/docs/data-sources/servergroup.md deleted file mode 100644 index 4cbc4651..00000000 --- a/docs/data-sources/servergroup.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_servergroup Data Source - edgecenter" -subcategory: "" -description: |- - Represent server group data ---- - -# edgecenter_servergroup (Data Source) - -Represent server group data - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_servergroup" "default" { - name = "default" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_servergroup.default -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the server group. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `instances` (List of Object) Instances in this server group (see [below for nested schema](#nestedatt--instances)) -- `policy` (String) Server group policy. Available value is 'affinity', 'anti-affinity' - - -### Nested Schema for `instances` - -Read-Only: - -- `instance_id` (String) -- `instance_name` (String) - - diff --git a/docs/data-sources/storage_s3.md b/docs/data-sources/storage_s3.md deleted file mode 100644 index 8e726c4a..00000000 --- a/docs/data-sources/storage_s3.md +++ /dev/null @@ -1,42 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_storage_s3 Data Source - edgecenter" -subcategory: "" -description: |- - Represent s3 storage resource. https://storage.edgecenter.ru/storage/list ---- - -# edgecenter_storage_s3 (Data Source) - -Represent s3 storage resource. https://storage.edgecenter.ru/storage/list - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_storage_s3" "example_s3" { - name = "example" -} -``` - - -## Schema - -### Optional - -- `name` (String) A name of new storage resource. -- `storage_id` (Number) An id of new storage resource. - -### Read-Only - -- `client_id` (Number) An client id of new storage resource. -- `generated_endpoint` (String) A s3 entry point for new storage resource. -- `generated_http_endpoint` (String) A http s3 entry point for new storage resource. -- `generated_s3_endpoint` (String) A s3 endpoint for new storage resource. -- `id` (String) The ID of this resource. -- `location` (String) A location of new storage resource. One of (s-dt2) - - diff --git a/docs/data-sources/storage_s3_bucket.md b/docs/data-sources/storage_s3_bucket.md deleted file mode 100644 index 08223c02..00000000 --- a/docs/data-sources/storage_s3_bucket.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_storage_s3_bucket Data Source - edgecenter" -subcategory: "" -description: |- - Represent storage s3 bucket resource. ---- - -# edgecenter_storage_s3_bucket (Data Source) - -Represent storage s3 bucket resource. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_storage_s3_bucket" "example_s3_bucket" { - storage_id = 1 - name = "example1bucket2name" -} -``` - - -## Schema - -### Required - -- `name` (String) A name of storage bucket resource. -- `storage_id` (Number) An id of existing storage resource. - -### Read-Only - -- `id` (String) The ID of this resource. - - diff --git a/docs/data-sources/subnet.md b/docs/data-sources/subnet.md deleted file mode 100644 index b7444fe3..00000000 --- a/docs/data-sources/subnet.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_subnet Data Source - edgecenter" -subcategory: "" -description: |- - ---- - -# edgecenter_subnet (Data Source) - - - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_subnet" "tsn" { - name = "subtest" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_subnet.tsn -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the subnet. - -### Optional - -- `metadata_k` (String) Filtration query opts (only key). -- `metadata_kv` (Map of String) Filtration query opts, for example, {offset = "10", limit = "10"} -- `network_id` (String) The ID of the network to which this subnet belongs. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `cidr` (String) Represents the IP address range of the subnet. -- `connect_to_network_router` (Boolean) True if the network's router should get a gateway in this subnet. Must be explicitly 'false' when gateway_ip is null. -- `dns_nameservers` (List of String) List of DNS name servers for the subnet. -- `enable_dhcp` (Boolean) Enable DHCP for this subnet. If true, DHCP will be used to assign IP addresses to instances within this subnet. -- `gateway_ip` (String) The IP address of the gateway for this subnet. -- `host_routes` (List of Object) List of additional routes to be added to instances that are part of this subnet. (see [below for nested schema](#nestedatt--host_routes)) -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) - - -### Nested Schema for `host_routes` - -Read-Only: - -- `destination` (String) -- `nexthop` (String) - - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - - diff --git a/docs/data-sources/volume.md b/docs/data-sources/volume.md deleted file mode 100644 index aa99d73f..00000000 --- a/docs/data-sources/volume.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_volume Data Source - edgecenter" -subcategory: "" -description: |- - A volume is a detachable block storage device akin to a USB hard drive or SSD, but located remotely in the cloud. - Volumes can be attached to a virtual machine and manipulated like a physical hard drive. ---- - -# edgecenter_volume (Data Source) - -A volume is a detachable block storage device akin to a USB hard drive or SSD, but located remotely in the cloud. -Volumes can be attached to a virtual machine and manipulated like a physical hard drive. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_volume" "tv" { - name = "test-hd" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_volume.tv -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the volume. - -### Optional - -- `metadata_k` (String) Filtration query opts (only key). -- `metadata_kv` (Map of String) Filtration query opts, for example, {offset = "10", limit = "10"} -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `size` (Number) The size of the volume, specified in gigabytes (GB). -- `type_name` (String) The type of volume to create. Valid values are 'ssd_hiiops', 'standard', 'cold', and 'ultra'. Defaults to 'standard'. - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - - diff --git a/docs/index.md b/docs/index.md deleted file mode 100644 index 1c0540ca..00000000 --- a/docs/index.md +++ /dev/null @@ -1,255 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter Provider" -subcategory: "" -description: |- - ---- - -# edgecenter Provider - - - -## Example Usage - -```terraform -terraform { - required_providers { - edgecenter = { - source = "Edge-Center/edgecenter" - version = ">= 0.1.12" - } - } -} - -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_keypair" "kp" { - project_id = 1 - public_key = "your oub key" - sshkey_name = "testkey" -} - -resource "edgecenter_network" "network" { - name = "network_example" - mtu = 1450 - type = "vxlan" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_subnet" "subnet" { - name = "subnet_example" - cidr = "192.168.10.0/24" - network_id = edgecenter_network.network.id - dns_nameservers = ["8.8.4.4", "1.1.1.1"] - - host_routes { - destination = "10.0.3.0/24" - nexthop = "10.0.0.13" - } - - gateway_ip = "192.168.10.1" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_subnet" "subnet2" { - name = "subnet2_example" - cidr = "192.168.20.0/24" - network_id = edgecenter_network.network.id - dns_nameservers = ["8.8.4.4", "1.1.1.1"] - - host_routes { - destination = "10.0.3.0/24" - nexthop = "10.0.0.13" - } - - gateway_ip = "192.168.20.1" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "first_volume" { - name = "boot volume" - type_name = "ssd_hiiops" - size = 6 - image_id = "f4ce3d30-e29c-4cfd-811f-46f383b6081f" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "second_volume" { - name = "second volume" - type_name = "ssd_hiiops" - image_id = "f4ce3d30-e29c-4cfd-811f-46f383b6081f" - size = 6 - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "third_volume" { - name = "third volume" - type_name = "ssd_hiiops" - size = 6 - region_id = 1 - project_id = 1 -} - -resource "edgecenter_instance" "instance" { - flavor_id = "g1-standard-2-4" - name = "test" - keypair_name = edgecenter_keypair.kp.sshkey_name - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.first_volume.id - boot_index = 0 - } - - interface { - type = "subnet" - network_id = edgecenter_network.network.id - subnet_id = edgecenter_subnet.subnet.id - } - - interface { - type = "subnet" - network_id = edgecenter_network.network.id - subnet_id = edgecenter_subnet.subnet2.id - } - - security_group { - id = "66988147-f1b9-43b2-aaef-dee6d009b5b7" - name = "default" - } - - metadata { - key = "some_key" - value = "some_data" - } - - configuration { - key = "some_key" - value = "some_data" - } - - region_id = 1 - project_id = 1 -} - -resource "edgecenter_loadbalancer" "lb" { - project_id = 1 - region_id = 1 - name = "test1" - flavor = "lb1-1-2" - listener { - name = "test" - protocol = "HTTP" - protocol_port = 80 - } -} - -resource "edgecenter_lbpool" "pl" { - project_id = 1 - region_id = 1 - name = "test_pool1" - protocol = "HTTP" - lb_algorithm = "LEAST_CONNECTIONS" - loadbalancer_id = edgecenter_loadbalancer.lb.id - listener_id = edgecenter_loadbalancer.lb.listener.0.id - health_monitor { - type = "PING" - delay = 60 - max_retries = 5 - timeout = 10 - } - session_persistence { - type = "APP_COOKIE" - cookie_name = "test_new_cookie" - } -} - -resource "edgecenter_lbmember" "lbm" { - project_id = 1 - region_id = 1 - pool_id = edgecenter_lbpool.pl.id - instance_id = edgecenter_instance.instance.id - address = tolist(edgecenter_instance.instance.interface).0.ip_address - protocol_port = 8081 - weight = 5 -} - -resource "edgecenter_instance" "instance2" { - flavor_id = "g1-standard-2-4" - name = "test2" - keypair_name = edgecenter_keypair.kp.sshkey_name - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.second_volume.id - boot_index = 0 - } - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.third_volume.id - boot_index = 1 - } - - interface { - type = "subnet" - network_id = edgecenter_network.network.id - subnet_id = edgecenter_subnet.subnet.id - } - - security_group { - id = "66988147-f1b9-43b2-aaef-dee6d009b5b7" - name = "default" - } - - metadata { - key = "some_key" - value = "some_data" - } - - configuration { - key = "some_key" - value = "some_data" - } - - region_id = 1 - project_id = 1 -} - -resource "edgecenter_lbmember" "lbm2" { - project_id = 1 - region_id = 1 - pool_id = edgecenter_lbpool.pl.id - instance_id = edgecenter_instance.instance2.id - address = tolist(edgecenter_instance.instance2.interface).0.ip_address - protocol_port = 8081 - weight = 5 -} -``` - - -## Schema - -### Optional - -- `api_endpoint` (String) A single API endpoint for all products. Will be used when specific product API url is not defined. -- `edgecenter_api` (String, Deprecated) Region API -- `edgecenter_cdn_api` (String) CDN API (define only if you want to override CDN API endpoint) -- `edgecenter_client_id` (String) Client id -- `edgecenter_cloud_api` (String) Region API (define only if you want to override Region API endpoint) -- `edgecenter_dns_api` (String) DNS API (define only if you want to override DNS API endpoint) -- `edgecenter_platform` (String, Deprecated) Platform URL is used for generate JWT -- `edgecenter_platform_api` (String) Platform URL is used for generate JWT (define only if you want to override Platform API endpoint) -- `edgecenter_storage_api` (String) Storage API (define only if you want to override Storage API endpoint) -- `ignore_creds_auth_error` (Boolean, Deprecated) Should be set to true when you are gonna to use storage resource with permanent API-token only. -- `password` (String, Deprecated) -- `permanent_api_token` (String, Sensitive) A permanent [API-token](https://support.edgecenter.ru/knowledge_base/item/257788) -- `user_name` (String, Deprecated) diff --git a/docs/resources/baremetal.md b/docs/resources/baremetal.md deleted file mode 100644 index e0aca31f..00000000 --- a/docs/resources/baremetal.md +++ /dev/null @@ -1,138 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_baremetal Resource - edgecenter" -subcategory: "" -description: |- - Represent baremetal instance ---- - -# edgecenter_baremetal (Resource) - -Represent baremetal instance - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_baremetal" "bm" { - name = "test bm instance" - region_id = 1 - project_id = 1 - flavor_id = "bm1-infrastructure-small" - image_id = "1ee7ccee-5003-48c9-8ae0-d96063af75b2" // your image id - - //additional interface, available type is 'subnet' or 'external' - // interface { - // type = "subnet" - // network_id = "9c7867fb-f404-4a2d-8bb5-24acf2fccaf1" //your network_id - // subnet_id = "b68ea6e2-c2b6-4a8d-95eb-7194d12a2156" // your subnet_id - // } - - // interface { - // type = "external" - // is_parent = "true" // if is_parent = true interface cant be detached, and always connected first - // } - - keypair_name = "test" // your keypair name -} -``` - - -## Schema - -### Required - -- `flavor_id` (String) -- `interface` (Block List, Min: 1) (see [below for nested schema](#nestedblock--interface)) - -### Optional - -- `app_config` (Map of String) -- `apptemplate_id` (String) -- `image_id` (String) -- `keypair_name` (String) -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata` (Block List, Deprecated) (see [below for nested schema](#nestedblock--metadata)) -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `name` (String) The name of the baremetal instance. -- `name_template` (String) -- `name_templates` (List of String, Deprecated) -- `password` (String) -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) -- `user_data` (String) -- `username` (String) - -### Read-Only - -- `addresses` (List of Object) (see [below for nested schema](#nestedatt--addresses)) -- `flavor` (Map of String) -- `id` (String) The ID of this resource. -- `status` (String) -- `vm_state` (String) - - -### Nested Schema for `interface` - -Required: - -- `type` (String) Available value is 'subnet', 'any_subnet', 'external', 'reserved_fixed_ip' - -Optional: - -- `existing_fip_id` (String) -- `fip_source` (String) -- `ip_address` (String) -- `is_parent` (Boolean) If not set will be calculated after creation. Trunk interface always attached first. Can't detach interface if is_parent true. Fields affect only on creation -- `network_id` (String) required if type is 'subnet' or 'any_subnet' -- `order` (Number) Order of attaching interface. Trunk interface always attached first, fields affect only on creation -- `port_id` (String) required if type is 'reserved_fixed_ip' -- `subnet_id` (String) required if type is 'subnet' - - - -### Nested Schema for `metadata` - -Required: - -- `key` (String) -- `value` (String) - - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) - - - -### Nested Schema for `addresses` - -Read-Only: - -- `net` (List of Object) (see [below for nested schema](#nestedobjatt--addresses--net)) - - -### Nested Schema for `addresses.net` - -Read-Only: - -- `addr` (String) -- `type` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_baremetal.instance1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/cdn_origingroup.md b/docs/resources/cdn_origingroup.md deleted file mode 100644 index 17853aed..00000000 --- a/docs/resources/cdn_origingroup.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_cdn_origingroup Resource - edgecenter" -subcategory: "" -description: |- - Represent origin group ---- - -# edgecenter_cdn_origingroup (Resource) - -Represent origin group - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_cdn_origingroup" "origin_group_1" { - name = "origin_group_1" - use_next = true - origin { - source = "example.com" - enabled = true - } - origin { - source = "mirror.example.com" - enabled = true - backup = true - } -} -``` - - -## Schema - -### Required - -- `name` (String) Name of the origin group -- `origin` (Block Set, Min: 1) Contains information about all IP address or Domain names of your origin and the port if custom (see [below for nested schema](#nestedblock--origin)) -- `use_next` (Boolean) This options have two possible values: true — The option is active. In case the origin responds with 4XX or 5XX codes, use the next origin from the list. false — The option is disabled. - -### Read-Only - -- `id` (String) The ID of this resource. - - -### Nested Schema for `origin` - -Required: - -- `source` (String) IP address or Domain name of your origin and the port if custom - -Optional: - -- `backup` (Boolean) true — The option is active. The origin will not be used until one of active origins become unavailable. false — The option is disabled. -- `enabled` (Boolean) The setting allows to enable or disable an Origin source in the Origins group - -Read-Only: - -- `id` (Number) The ID of this resource. - - diff --git a/docs/resources/cdn_resource.md b/docs/resources/cdn_resource.md deleted file mode 100644 index 9ca6c652..00000000 --- a/docs/resources/cdn_resource.md +++ /dev/null @@ -1,622 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_cdn_resource Resource - edgecenter" -subcategory: "" -description: |- - Represent CDN resource ---- - -# edgecenter_cdn_resource (Resource) - -Represent CDN resource - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - - -resource "edgecenter_cdn_resource" "cdn_example_com" { - cname = "cdn.example.com" - origin_group = edgecenter_cdn_origingroup.origin_group_1.id - origin_protocol = "MATCH" - secondary_hostnames = ["cdn2.example.com"] - - options { - edge_cache_settings { - default = "8d" - } - browser_cache_settings { - value = "1d" - } - redirect_http_to_https { - value = true - } - gzip_on { - value = true - } - cors { - value = [ - "*" - ] - } - rewrite { - body = "/(.*) /$1" - } - webp { - jpg_quality = 55 - png_quality = 66 - } - - tls_versions { - enabled = true - value = [ - "TLSv1.2", - ] - } - } -} -``` - - -## Schema - -### Required - -- `cname` (String) A CNAME that will be used to deliver content though a CDN. If you update this field new resource will be created. - -### Optional - -- `active` (Boolean) The setting allows to enable or disable a CDN Resource -- `description` (String) Custom client description of the resource. -- `issue_le_cert` (Boolean) Generate LE certificate. -- `options` (Block List, Max: 1) Each option in CDN resource settings. Each option added to CDN resource settings should have the following mandatory request fields: enabled, value. (see [below for nested schema](#nestedblock--options)) -- `origin` (String) A domain name or IP of your origin source. Specify a port if custom. You can use either 'origin' parameter or 'originGroup' in the resource definition. -- `origin_group` (Number) ID of the Origins Group. Use one of your Origins Group or create a new one. You can use either 'origin' parameter or 'originGroup' in the resource definition. -- `origin_protocol` (String) This option defines the protocol that will be used by CDN servers to request content from an origin source. If not specified, we will use HTTP to connect to an origin server. Possible values are: HTTPS, HTTP, MATCH. -- `secondary_hostnames` (Set of String) List of additional CNAMEs. -- `ssl_automated` (Boolean) generate LE certificate automatically. -- `ssl_data` (Number) Specify the SSL Certificate ID which should be used for the CDN Resource. -- `ssl_enabled` (Boolean) Use HTTPS protocol for content delivery. - -### Read-Only - -- `id` (String) The ID of this resource. -- `status` (String) Status of a CDN resource content availability. Possible values are: Active, Suspended, Processed. - - -### Nested Schema for `options` - -Optional: - -- `allowed_http_methods` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--allowed_http_methods)) -- `brotli_compression` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--brotli_compression)) -- `browser_cache_settings` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--browser_cache_settings)) -- `cache_http_headers` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--cache_http_headers)) -- `cors` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--cors)) -- `country_acl` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--country_acl)) -- `disable_proxy_force_ranges` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--disable_proxy_force_ranges)) -- `edge_cache_settings` (Block List, Max: 1) The cache expiration time for CDN servers. (see [below for nested schema](#nestedblock--options--edge_cache_settings)) -- `fetch_compressed` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--fetch_compressed)) -- `follow_origin_redirect` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--follow_origin_redirect)) -- `force_return` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--force_return)) -- `forward_host_header` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--forward_host_header)) -- `gzip_on` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--gzip_on)) -- `host_header` (Block List, Max: 1) Specify the Host header that CDN servers use when request content from an origin server. Your server must be able to process requests with the chosen header. If the option is in NULL state Host Header value is taken from the CNAME field. (see [below for nested schema](#nestedblock--options--host_header)) -- `http3_enabled` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--http3_enabled)) -- `ignore_cookie` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--ignore_cookie)) -- `ignore_query_string` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--ignore_query_string)) -- `image_stack` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--image_stack)) -- `ip_address_acl` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--ip_address_acl)) -- `limit_bandwidth` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--limit_bandwidth)) -- `proxy_cache_methods_set` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--proxy_cache_methods_set)) -- `query_params_blacklist` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--query_params_blacklist)) -- `query_params_whitelist` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--query_params_whitelist)) -- `redirect_http_to_https` (Block List, Max: 1) Sets redirect from HTTP protocol to HTTPS for all resource requests. (see [below for nested schema](#nestedblock--options--redirect_http_to_https)) -- `redirect_https_to_http` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--redirect_https_to_http)) -- `referrer_acl` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--referrer_acl)) -- `response_headers_hiding_policy` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--response_headers_hiding_policy)) -- `rewrite` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--rewrite)) -- `secure_key` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--secure_key)) -- `slice` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--slice)) -- `sni` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--sni)) -- `stale` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--stale)) -- `static_headers` (Block List, Max: 1) Option has been deprecated. Use - static_response_headers. (see [below for nested schema](#nestedblock--options--static_headers)) -- `static_request_headers` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--static_request_headers)) -- `static_response_headers` (Block List, Max: 1) Specify custom HTTP Headers that a CDN server adds to a response. (see [below for nested schema](#nestedblock--options--static_response_headers)) -- `tls_versions` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--tls_versions)) -- `use_default_le_chain` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--use_default_le_chain)) -- `user_agent_acl` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--user_agent_acl)) -- `websockets` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--websockets)) - - -### Nested Schema for `options.allowed_http_methods` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.brotli_compression` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.browser_cache_settings` - -Optional: - -- `enabled` (Boolean) -- `value` (String) - - - -### Nested Schema for `options.cache_http_headers` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.cors` - -Required: - -- `value` (Set of String) - -Optional: - -- `always` (Boolean) -- `enabled` (Boolean) - - - -### Nested Schema for `options.country_acl` - -Required: - -- `excepted_values` (Set of String) -- `policy_type` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.disable_proxy_force_ranges` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.edge_cache_settings` - -Optional: - -- `custom_values` (Map of String) Caching time for a response with specific codes. These settings have a higher priority than the value field. Response code ('304', '404' for example). Use 'any' to specify caching time for all response codes. Caching time in seconds ('0s', '600s' for example). Use '0s' to disable caching for a specific response code. -- `default` (String) Content will be cached according to origin cache settings. The value applies for a response with codes 200, 201, 204, 206, 301, 302, 303, 304, 307, 308 if an origin server does not have caching HTTP headers. Responses with other codes will not be cached. -- `enabled` (Boolean) -- `value` (String) Caching time for a response with codes 200, 206, 301, 302. Responses with codes 4xx, 5xx will not be cached. Use '0s' disable to caching. Use custom_values field to specify a custom caching time for a response with specific codes. - - - -### Nested Schema for `options.fetch_compressed` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.follow_origin_redirect` - -Required: - -- `codes` (Set of Number) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.force_return` - -Required: - -- `code` (Number) - -Optional: - -- `body` (String) -- `enabled` (Boolean) - - - -### Nested Schema for `options.forward_host_header` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.gzip_on` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.host_header` - -Required: - -- `value` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.http3_enabled` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.ignore_cookie` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.ignore_query_string` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.image_stack` - -Required: - -- `quality` (Number) - -Optional: - -- `avif_enabled` (Boolean) -- `enabled` (Boolean) -- `png_lossless` (Boolean) -- `webp_enabled` (Boolean) - - - -### Nested Schema for `options.ip_address_acl` - -Required: - -- `excepted_values` (Set of String) -- `policy_type` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.limit_bandwidth` - -Required: - -- `limit_type` (String) - -Optional: - -- `buffer` (Number) -- `enabled` (Boolean) -- `speed` (Number) - - - -### Nested Schema for `options.proxy_cache_methods_set` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.query_params_blacklist` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.query_params_whitelist` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.redirect_http_to_https` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.redirect_https_to_http` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.referrer_acl` - -Required: - -- `excepted_values` (Set of String) -- `policy_type` (String) Possible values: allow, deny. - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.response_headers_hiding_policy` - -Required: - -- `excepted` (Set of String) -- `mode` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.rewrite` - -Required: - -- `body` (String) - -Optional: - -- `enabled` (Boolean) -- `flag` (String) - - - -### Nested Schema for `options.secure_key` - -Required: - -- `key` (String) -- `type` (Number) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.slice` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.sni` - -Optional: - -- `custom_hostname` (String) Required to set custom hostname in case sni-type='custom' -- `enabled` (Boolean) -- `sni_type` (String) Available values 'dynamic' or 'custom' - - - -### Nested Schema for `options.stale` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.static_headers` - -Required: - -- `value` (Map of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.static_request_headers` - -Required: - -- `value` (Map of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.static_response_headers` - -Required: - -- `value` (Block List, Min: 1) (see [below for nested schema](#nestedblock--options--static_response_headers--value)) - -Optional: - -- `enabled` (Boolean) - - -### Nested Schema for `options.static_response_headers.value` - -Required: - -- `name` (String) -- `value` (Set of String) - -Optional: - -- `always` (Boolean) - - - - -### Nested Schema for `options.tls_versions` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.use_default_le_chain` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.user_agent_acl` - -Required: - -- `excepted_values` (Set of String) -- `policy_type` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.websockets` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - diff --git a/docs/resources/cdn_rule.md b/docs/resources/cdn_rule.md deleted file mode 100644 index 3c1422bc..00000000 --- a/docs/resources/cdn_rule.md +++ /dev/null @@ -1,611 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_cdn_rule Resource - edgecenter" -subcategory: "" -description: |- - Represent cdn resource rule ---- - -# edgecenter_cdn_rule (Resource) - -Represent cdn resource rule - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_cdn_rule" "cdn_example_com_rule_1" { - resource_id = edgecenter_cdn_resource.cdn_example_com.id - name = "All PNG images" - rule = "/folder/images/*.png" - - options { - edge_cache_settings { - default = "14d" - } - browser_cache_settings { - value = "14d" - } - redirect_http_to_https { - value = true - } - gzip_on { - value = true - } - cors { - value = [ - "*" - ] - } - rewrite { - body = "/(.*) /$1" - } - webp { - jpg_quality = 55 - png_quality = 66 - } - ignore_query_string { - value = true - } - } -} - -resource "edgecenter_cdn_rule" "cdn_example_com_rule_2" { - resource_id = edgecenter_cdn_resource.cdn_example_com.id - name = "All JS scripts" - rule = "/folder/images/*.js" - origin_protocol = "HTTP" - - options { - redirect_http_to_https { - enabled = false - value = true - } - gzip_on { - enabled = false - value = true - } - query_params_whitelist { - value = [ - "abc", - ] - } - } -} - -resource "edgecenter_cdn_origingroup" "origin_group_1" { - name = "origin_group_1" - use_next = true - origin { - source = "example.com" - enabled = true - } -} - -resource "edgecenter_cdn_resource" "cdn_example_com" { - cname = "cdn.example.com" - origin_group = edgecenter_cdn_origingroup.origin_group_1.id - origin_protocol = "MATCH" - secondary_hostnames = ["cdn2.example.com"] -} -``` - - -## Schema - -### Required - -- `name` (String) Rule name -- `resource_id` (Number) -- `rule` (String) A pattern that defines when the rule is triggered. By default, we add a leading forward slash to any rule pattern. Specify a pattern without a forward slash. - -### Optional - -- `active` (Boolean) Shows if the location is enabled. -- `options` (Block List, Max: 1) Each option in CDN resource settings. Each option added to CDN resource settings should have the following mandatory request fields: enabled, value. (see [below for nested schema](#nestedblock--options)) -- `origin_group` (Number) ID of the Origins Group. Use one of your Origins Group or create a new one. You can use either 'origin' parameter or 'originGroup' in the resource definition. -- `origin_protocol` (String) This option defines the protocol that will be used by CDN servers to request content from an origin source. If not specified, it will be inherit from resource. Possible values are: HTTPS, HTTP, MATCH. -- `weight` (Number) - -### Read-Only - -- `id` (String) The ID of this resource. - - -### Nested Schema for `options` - -Optional: - -- `allowed_http_methods` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--allowed_http_methods)) -- `brotli_compression` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--brotli_compression)) -- `browser_cache_settings` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--browser_cache_settings)) -- `cache_http_headers` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--cache_http_headers)) -- `cors` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--cors)) -- `country_acl` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--country_acl)) -- `disable_proxy_force_ranges` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--disable_proxy_force_ranges)) -- `edge_cache_settings` (Block List, Max: 1) The cache expiration time for CDN servers. (see [below for nested schema](#nestedblock--options--edge_cache_settings)) -- `fetch_compressed` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--fetch_compressed)) -- `follow_origin_redirect` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--follow_origin_redirect)) -- `force_return` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--force_return)) -- `forward_host_header` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--forward_host_header)) -- `gzip_on` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--gzip_on)) -- `host_header` (Block List, Max: 1) Specify the Host header that CDN servers use when request content from an origin server. Your server must be able to process requests with the chosen header. If the option is in NULL state Host Header value is taken from the CNAME field. (see [below for nested schema](#nestedblock--options--host_header)) -- `ignore_cookie` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--ignore_cookie)) -- `ignore_query_string` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--ignore_query_string)) -- `image_stack` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--image_stack)) -- `ip_address_acl` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--ip_address_acl)) -- `limit_bandwidth` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--limit_bandwidth)) -- `proxy_cache_methods_set` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--proxy_cache_methods_set)) -- `query_params_blacklist` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--query_params_blacklist)) -- `query_params_whitelist` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--query_params_whitelist)) -- `redirect_http_to_https` (Block List, Max: 1) Sets redirect from HTTP protocol to HTTPS for all resource requests. (see [below for nested schema](#nestedblock--options--redirect_http_to_https)) -- `redirect_https_to_http` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--redirect_https_to_http)) -- `referrer_acl` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--referrer_acl)) -- `response_headers_hiding_policy` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--response_headers_hiding_policy)) -- `rewrite` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--rewrite)) -- `secure_key` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--secure_key)) -- `slice` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--slice)) -- `sni` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--sni)) -- `stale` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--stale)) -- `static_headers` (Block List, Max: 1) Option has been deprecated. Use - static_response_headers. (see [below for nested schema](#nestedblock--options--static_headers)) -- `static_request_headers` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--static_request_headers)) -- `static_response_headers` (Block List, Max: 1) Specify custom HTTP Headers that a CDN server adds to a response. (see [below for nested schema](#nestedblock--options--static_response_headers)) -- `user_agent_acl` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--user_agent_acl)) -- `websockets` (Block List, Max: 1) (see [below for nested schema](#nestedblock--options--websockets)) - - -### Nested Schema for `options.allowed_http_methods` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.brotli_compression` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.browser_cache_settings` - -Optional: - -- `enabled` (Boolean) -- `value` (String) - - - -### Nested Schema for `options.cache_http_headers` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.cors` - -Required: - -- `value` (Set of String) - -Optional: - -- `always` (Boolean) -- `enabled` (Boolean) - - - -### Nested Schema for `options.country_acl` - -Required: - -- `excepted_values` (Set of String) -- `policy_type` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.disable_proxy_force_ranges` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.edge_cache_settings` - -Optional: - -- `custom_values` (Map of String) Caching time for a response with specific codes. These settings have a higher priority than the value field. Response code ('304', '404' for example). Use 'any' to specify caching time for all response codes. Caching time in seconds ('0s', '600s' for example). Use '0s' to disable caching for a specific response code. -- `default` (String) Content will be cached according to origin cache settings. The value applies for a response with codes 200, 201, 204, 206, 301, 302, 303, 304, 307, 308 if an origin server does not have caching HTTP headers. Responses with other codes will not be cached. -- `enabled` (Boolean) -- `value` (String) Caching time for a response with codes 200, 206, 301, 302. Responses with codes 4xx, 5xx will not be cached. Use '0s' disable to caching. Use custom_values field to specify a custom caching time for a response with specific codes. - - - -### Nested Schema for `options.fetch_compressed` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.follow_origin_redirect` - -Required: - -- `codes` (Set of Number) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.force_return` - -Required: - -- `code` (Number) - -Optional: - -- `body` (String) -- `enabled` (Boolean) - - - -### Nested Schema for `options.forward_host_header` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.gzip_on` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.host_header` - -Required: - -- `value` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.ignore_cookie` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.ignore_query_string` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.image_stack` - -Required: - -- `quality` (Number) - -Optional: - -- `avif_enabled` (Boolean) -- `enabled` (Boolean) -- `png_lossless` (Boolean) -- `webp_enabled` (Boolean) - - - -### Nested Schema for `options.ip_address_acl` - -Required: - -- `excepted_values` (Set of String) -- `policy_type` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.limit_bandwidth` - -Required: - -- `limit_type` (String) - -Optional: - -- `buffer` (Number) -- `enabled` (Boolean) -- `speed` (Number) - - - -### Nested Schema for `options.proxy_cache_methods_set` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.query_params_blacklist` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.query_params_whitelist` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.redirect_http_to_https` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.redirect_https_to_http` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.referrer_acl` - -Required: - -- `excepted_values` (Set of String) -- `policy_type` (String) Possible values: allow, deny. - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.response_headers_hiding_policy` - -Required: - -- `excepted` (Set of String) -- `mode` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.rewrite` - -Required: - -- `body` (String) - -Optional: - -- `enabled` (Boolean) -- `flag` (String) - - - -### Nested Schema for `options.secure_key` - -Required: - -- `key` (String) -- `type` (Number) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.slice` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.sni` - -Optional: - -- `custom_hostname` (String) Required to set custom hostname in case sni-type='custom' -- `enabled` (Boolean) -- `sni_type` (String) Available values 'dynamic' or 'custom' - - - -### Nested Schema for `options.stale` - -Required: - -- `value` (Set of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.static_headers` - -Required: - -- `value` (Map of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.static_request_headers` - -Required: - -- `value` (Map of String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.static_response_headers` - -Required: - -- `value` (Block List, Min: 1) (see [below for nested schema](#nestedblock--options--static_response_headers--value)) - -Optional: - -- `enabled` (Boolean) - - -### Nested Schema for `options.static_response_headers.value` - -Required: - -- `name` (String) -- `value` (Set of String) - -Optional: - -- `always` (Boolean) - - - - -### Nested Schema for `options.user_agent_acl` - -Required: - -- `excepted_values` (Set of String) -- `policy_type` (String) - -Optional: - -- `enabled` (Boolean) - - - -### Nested Schema for `options.websockets` - -Required: - -- `value` (Boolean) - -Optional: - -- `enabled` (Boolean) - - diff --git a/docs/resources/cdn_sslcert.md b/docs/resources/cdn_sslcert.md deleted file mode 100644 index 0b909e6e..00000000 --- a/docs/resources/cdn_sslcert.md +++ /dev/null @@ -1,52 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_cdn_sslcert Resource - edgecenter" -subcategory: "" -description: |- - ---- - -# edgecenter_cdn_sslcert (Resource) - - - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -variable "cert" { - type = string - sensitive = true -} - -variable "private_key" { - type = string - sensitive = true -} - -resource "edgecenter_cdn_sslcert" "cdnopt_cert" { - name = "Test cert for cdnopt_bookatest_by" - cert = var.cert - private_key = var.private_key -} -``` - - -## Schema - -### Required - -- `cert` (String, Sensitive) The public part of the SSL certificate. All chain of the SSL certificate should be added. -- `name` (String) Name of the SSL certificate. Must be unique. -- `private_key` (String, Sensitive) The private key of the SSL certificate. - -### Read-Only - -- `automated` (Boolean) The way SSL certificate was issued. -- `has_related_resources` (Boolean) It shows if the SSL certificate is used by a CDN resource. -- `id` (String) The ID of this resource. - - diff --git a/docs/resources/dns_zone.md b/docs/resources/dns_zone.md deleted file mode 100644 index f17f8f56..00000000 --- a/docs/resources/dns_zone.md +++ /dev/null @@ -1,43 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_dns_zone Resource - edgecenter" -subcategory: "" -description: |- - Represent DNS zone resource. https://dns.edgecenter.ru/zones ---- - -# edgecenter_dns_zone (Resource) - -Represent DNS zone resource. https://dns.edgecenter.ru/zones - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_dns_zone" "example_zone" { - name = "example_zone.com" -} -``` - - -## Schema - -### Required - -- `name` (String) A name of DNS Zone resource. - -### Read-Only - -- `id` (String) The ID of this resource. - -## Import - -Import is supported using the following syntax: - -```shell -# import using zone name format -terraform import edgecenter_dns_zone.example_zone example_zone.com -``` diff --git a/docs/resources/dns_zone_record.md b/docs/resources/dns_zone_record.md deleted file mode 100644 index 7517591e..00000000 --- a/docs/resources/dns_zone_record.md +++ /dev/null @@ -1,168 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_dns_zone_record Resource - edgecenter" -subcategory: "" -description: |- - Represent DNS Zone Record resource. https://dns.edgecenter.ru/zones ---- - -# edgecenter_dns_zone_record (Resource) - -Represent DNS Zone Record resource. https://dns.edgecenter.ru/zones - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -// -// example0: managing zone and records by TF using variables -// -variable "example_domain0" { - type = string - default = "examplezone.com" -} - -resource "edgecenter_dns_zone" "examplezone0" { - name = var.example_domain0 -} - -resource "edgecenter_dns_zone_record" "example_rrset0" { - zone = edgecenter_dns_zone.examplezone0.name - domain = edgecenter_dns_zone.examplezone0.name - type = "A" - ttl = 100 - - resource_record { - content = "127.0.0.100" - } - resource_record { - content = "127.0.0.200" - // enabled = false - } -} - -// -// example1: managing zone outside of TF -// -resource "edgecenter_dns_zone_record" "subdomain_examplezone" { - zone = "examplezone.com" - domain = "subdomain.examplezone.com" - type = "TXT" - ttl = 10 - - filter { - type = "geodistance" - limit = 1 - strict = true - } - - resource_record { - content = "1234" - enabled = true - - meta { - latlong = [52.367, 4.9041] - asn = [12345] - ip = ["1.1.1.1"] - notes = ["notes"] - continents = ["asia"] - countries = ["russia"] - default = true - } - } -} - -resource "edgecenter_dns_zone_record" "subdomain_examplezone_mx" { - zone = "examplezone.com" - domain = "subdomain.examplezone.com" - type = "MX" - ttl = 10 - - resource_record { - content = "10 mail.my.com." - enabled = true - } -} - -resource "edgecenter_dns_zone_record" "subdomain_examplezone_caa" { - zone = "examplezone.com" - domain = "subdomain.examplezone.com" - type = "CAA" - ttl = 10 - - resource_record { - content = "0 issue \"company.org; account=12345\"" - enabled = true - } -} -``` - - -## Schema - -### Required - -- `domain` (String) A domain of DNS Zone Record resource. -- `resource_record` (Block Set, Min: 1) An array of contents with meta of DNS Zone Record resource. (see [below for nested schema](#nestedblock--resource_record)) -- `type` (String) A type of DNS Zone Record resource. -- `zone` (String) A zone of DNS Zone Record resource. - -### Optional - -- `filter` (Block Set) (see [below for nested schema](#nestedblock--filter)) -- `ttl` (Number) A ttl of DNS Zone Record resource. - -### Read-Only - -- `id` (String) The ID of this resource. - - -### Nested Schema for `resource_record` - -Required: - -- `content` (String) A content of DNS Zone Record resource. (TXT: 'anyString', MX: '50 mail.company.io.', CAA: '0 issue "company.org; account=12345"') - -Optional: - -- `enabled` (Boolean) Manage of public appearing of DNS Zone Record resource. -- `meta` (Block Set, Max: 1) (see [below for nested schema](#nestedblock--resource_record--meta)) - - -### Nested Schema for `resource_record.meta` - -Optional: - -- `asn` (List of Number) An asn meta (e.g. 12345) of DNS Zone Record resource. -- `continents` (List of String) Continents meta (e.g. Asia) of DNS Zone Record resource. -- `countries` (List of String) Countries meta (e.g. USA) of DNS Zone Record resource. -- `default` (Boolean) Fallback meta equals true marks records which are used as a default answer (when nothing was selected by specified meta fields). -- `ip` (List of String) An ip meta (e.g. 127.0.0.0) of DNS Zone Record resource. -- `latlong` (List of Number) A latlong meta (e.g. 27.988056, 86.925278) of DNS Zone Record resource. -- `notes` (List of String) A notes meta (e.g. Miami DC) of DNS Zone Record resource. - - - - -### Nested Schema for `filter` - -Required: - -- `type` (String) A DNS Zone Record filter option that describe a name of filter. - -Optional: - -- `limit` (Number) A DNS Zone Record filter option that describe how many records will be percolated. -- `strict` (Boolean) A DNS Zone Record filter option that describe possibility to return answers if no records were percolated through filter. - -## Import - -Import is supported using the following syntax: - -```shell -# import using zone:domain:type format -terraform import edgecenter_dns_zone_record.example_rrset0 example.com:domain.example.com:A -``` diff --git a/docs/resources/floatingip.md b/docs/resources/floatingip.md deleted file mode 100644 index 70ec4093..00000000 --- a/docs/resources/floatingip.md +++ /dev/null @@ -1,73 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_floatingip Resource - edgecenter" -subcategory: "" -description: |- - A floating IP is a static IP address that can be associated with one of your instances or loadbalancers, - allowing it to have a static public IP address. The floating IP can be re-associated to any other instance in the same datacenter. ---- - -# edgecenter_floatingip (Resource) - -A floating IP is a static IP address that can be associated with one of your instances or loadbalancers, -allowing it to have a static public IP address. The floating IP can be re-associated to any other instance in the same datacenter. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_floatingip" "floating_ip" { - project_id = 1 - region_id = 1 - metadata_map = { - tag1 = "tag1_value" - } - // fixed_ip_address = "192.168.10.39" // instance`s interface ip - // port_id = "5c992875-f653-4b7b-af5b-1dc3019e5ffa" //instance`s interface port_id -} -``` - - -## Schema - -### Optional - -- `fixed_ip_address` (String) The fixed (reserved) IP address that is associated with the floating IP. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `port_id` (String) The ID (uuid) of the network port that the floating IP is associated with. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `created_at` (String) The timestamp when the floating IP was created. -- `floating_ip_address` (String) The floating IP address assigned to the resource. -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `router_id` (String) The ID (uuid) of the router that the floating IP is associated with. -- `status` (String) The current status of the floating IP. Can be 'DOWN' or 'ACTIVE'. -- `updated_at` (String) The timestamp when the floating IP was updated. - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_floatingip.fip1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/instance.md b/docs/resources/instance.md deleted file mode 100644 index b7b4dc9a..00000000 --- a/docs/resources/instance.md +++ /dev/null @@ -1,280 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_instance Resource - edgecenter" -subcategory: "" -description: |- - A cloud instance is a virtual machine in a cloud environment. ---- - -# edgecenter_instance (Resource) - -A cloud instance is a virtual machine in a cloud environment. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_network" "network" { - name = "network_example" - mtu = 1450 - type = "vxlan" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_subnet" "subnet" { - name = "subnet_example" - cidr = "192.168.10.0/24" - network_id = edgecenter_network.network.id - dns_nameservers = ["8.8.4.4", "1.1.1.1"] - - host_routes { - destination = "10.0.3.0/24" - nexthop = "10.0.0.13" - } - - gateway_ip = "192.168.10.1" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "first_volume" { - name = "boot volume" - type_name = "ssd_hiiops" - size = 5 - image_id = "f4ce3d30-e29c-4cfd-811f-46f383b6081f" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "second_volume" { - name = "second volume" - type_name = "ssd_hiiops" - size = 5 - region_id = 1 - project_id = 1 -} - -resource "edgecenter_instance" "instance" { - flavor_id = "g1-standard-2-4" - name = "test" - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.first_volume.id - boot_index = 0 - } - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.second_volume.id - boot_index = 1 - } - - interface { - type = "subnet" - network_id = edgecenter_network.network.id - subnet_id = edgecenter_subnet.subnet.id - security_groups = ["d75db0b2-58f1-4a11-88c6-a932bb897310"] - } - - metadata_map = { - some_key = "some_value" - stage = "dev" - } - - configuration { - key = "some_key" - value = "some_data" - } - - region_id = 1 - project_id = 1 -} - -//*** -// another one example with one interface to private network and fip to internet -//*** - -resource "edgecenter_reservedfixedip" "fixed_ip" { - project_id = 1 - region_id = 1 - type = "ip_address" - network_id = "faf6507b-1ff1-4ebf-b540-befd5c09fe06" - fixed_ip_address = "192.168.13.6" - is_vip = false -} - -resource "edgecenter_volume" "first_volume" { - name = "boot volume" - type_name = "ssd_hiiops" - size = 10 - image_id = "6dc4e061-6fab-41f3-91a3-0ba848fb32d9" - project_id = 1 - region_id = 1 -} - -resource "edgecenter_floatingip" "fip" { - project_id = 1 - region_id = 1 - fixed_ip_address = edgecenter_reservedfixedip.fixed_ip.fixed_ip_address - port_id = edgecenter_reservedfixedip.fixed_ip.port_id -} - - -resource "edgecenter_instance" "v" { - project_id = 1 - region_id = 1 - name = "hello" - flavor_id = "g1-standard-1-2" - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.first_volume.id - boot_index = 0 - } - - interface { - type = "reserved_fixed_ip" - port_id = edgecenter_reservedfixedip.fixed_ip.port_id - fip_source = "existing" - existing_fip_id = edgecenter_floatingip.fip.id - security_groups = ["ada84751-fcca-4491-9249-2dfceb321616"] - } -} -``` - - -## Schema - -### Required - -- `flavor_id` (String) The ID of the flavor to be used for the instance, determining its compute and memory, for example 'g1-standard-2-4'. -- `interface` (Block List, Min: 1) A list defining the network interfaces to be attached to the instance. (see [below for nested schema](#nestedblock--interface)) -- `volume` (Block Set, Min: 1) A set defining the volumes to be attached to the instance. (see [below for nested schema](#nestedblock--volume)) - -### Optional - -- `addresses` (Block List) A list of network addresses associated with the instance, for example "pub_net": [...] (see [below for nested schema](#nestedblock--addresses)) -- `allow_app_ports` (Boolean) A boolean indicating whether to allow application ports on the instance. -- `configuration` (Block List) A list of key-value pairs specifying configuration settings for the instance when created -from a template (marketplace), e.g. {"gitlab_external_url": "https://gitlab/..."} (see [below for nested schema](#nestedblock--configuration)) -- `flavor` (Map of String) A map defining the flavor of the instance, for example, {"flavor_name": "g1-standard-2-4", "ram": 4096, ...}. -- `keypair_name` (String) The name of the key pair to be associated with the instance for SSH access. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata` (Block List, Deprecated) (see [below for nested schema](#nestedblock--metadata)) -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `name` (String) The name of the instance. -- `name_template` (String) A template used to generate the instance name. This field cannot be used with 'name_templates'. -- `name_templates` (List of String, Deprecated) -- `password` (String) The password to be used for accessing the instance. Required with username. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `server_group` (String) The ID (uuid) of the server group to which the instance should belong. -- `status` (String) The current status of the instance. This is computed automatically and can be used to track the instance's state. -- `user_data` (String) A field for specifying user data to be used for configuring the instance at launch time. -- `userdata` (String, Deprecated) **Deprecated** -- `username` (String) The username to be used for accessing the instance. Required with password. -- `vm_state` (String) The current virtual machine state of the instance, -allowing you to start or stop the VM. Possible values are stopped and active. - -### Read-Only - -- `id` (String) The ID of this resource. -- `security_group` (List of Object) A list of firewall configurations applied to the instance, defined by their ID and name. (see [below for nested schema](#nestedatt--security_group)) - - -### Nested Schema for `interface` - -Optional: - -- `existing_fip_id` (String) -- `fip_source` (String) -- `ip_address` (String) -- `network_id` (String) Required if type is 'subnet' or 'any_subnet'. -- `order` (Number) Order of attaching interface -- `port_id` (String) required if type is 'reserved_fixed_ip' -- `security_groups` (List of String) list of security group IDs -- `subnet_id` (String) Required if type is 'subnet'. -- `type` (String) Available value is 'subnet', 'any_subnet', 'external', 'reserved_fixed_ip' - - - -### Nested Schema for `volume` - -Required: - -- `source` (String) Currently available only 'existing-volume' value - -Optional: - -- `attachment_tag` (String) -- `boot_index` (Number) If boot_index==0 volumes can not detached -- `delete_on_termination` (Boolean) -- `image_id` (String) -- `name` (String) The name assigned to the volume. Defaults to 'system'. -- `size` (Number) The size of the volume, specified in gigabytes (GB). -- `type_name` (String) The type of volume to create. Valid values are 'ssd_hiiops', 'standard', 'cold', and 'ultra'. Defaults to 'standard'. -- `volume_id` (String) - -Read-Only: - -- `id` (String) The ID of this resource. - - - -### Nested Schema for `addresses` - -Required: - -- `net` (Block List, Min: 1) (see [below for nested schema](#nestedblock--addresses--net)) - - -### Nested Schema for `addresses.net` - -Required: - -- `addr` (String) The net ip address, for example '45.147.163.112'. -- `type` (String) The net type, for example 'fixed'. - - - - -### Nested Schema for `configuration` - -Required: - -- `key` (String) -- `value` (String) - - - -### Nested Schema for `metadata` - -Required: - -- `key` (String) -- `value` (String) - - - -### Nested Schema for `security_group` - -Read-Only: - -- `id` (String) -- `name` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_instance.instance1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/k8s.md b/docs/resources/k8s.md deleted file mode 100644 index 3e95be07..00000000 --- a/docs/resources/k8s.md +++ /dev/null @@ -1,122 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_k8s Resource - edgecenter" -subcategory: "" -description: |- - Represent k8s cluster with one default pool. ---- - -# edgecenter_k8s (Resource) - -Represent k8s cluster with one default pool. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_k8s" "v" { - project_id = 1 - region_id = 1 - version = "1.25.11" - name = "tf-k8s" - fixed_network = "6bf878c1-1ce4-47c3-a39b-6b5f1d79bf25" - fixed_subnet = "dc3a3ea9-86ae-47ad-a8e8-79df0ce04839" - keypair = "tf-keypair" - pool { - name = "tf-pool" - flavor_id = "g1-standard-1-2" - min_node_count = 1 - max_node_count = 2 - node_count = 1 - docker_volume_size = 2 - } -} -``` - - -## Schema - -### Required - -- `fixed_network` (String) Fixed network (uuid) associated with the Kubernetes cluster. -- `fixed_subnet` (String) Subnet (uuid) associated with the fixed network. Ensure there's a router on this subnet. -- `keypair` (String) The name of the keypair -- `name` (String) The name of the Kubernetes cluster. -- `pool` (Block List, Min: 1, Max: 1) Configuration details of the node pool in the Kubernetes cluster. (see [below for nested schema](#nestedblock--pool)) -- `version` (String) The version of the Kubernetes cluster. - -### Optional - -- `auto_healing_enabled` (Boolean) Indicates whether auto-healing is enabled for the Kubernetes cluster. true by default. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `master_lb_floating_ip_enabled` (Boolean) Flag indicating if the master LoadBalancer should have a floating IP. -- `pods_ip_pool` (String) IP pool to be used for pods within the Kubernetes cluster. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `services_ip_pool` (String) IP pool to be used for services within the Kubernetes cluster. -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) - -### Read-Only - -- `api_address` (String) API endpoint address for the Kubernetes cluster. -- `cluster_template_id` (String) Template identifier from which the Kubernetes cluster was instantiated. -- `container_version` (String) The container runtime version used in the Kubernetes cluster. -- `created_at` (String) The timestamp when the Kubernetes cluster was created. -- `discovery_url` (String) URL used for node discovery within the Kubernetes cluster. -- `faults` (Map of String) -- `health_status` (String) Overall health status of the Kubernetes cluster. -- `health_status_reason` (Map of String) -- `id` (String) The ID of this resource. -- `master_addresses` (List of String) List of IP addresses for master nodes in the Kubernetes cluster. -- `master_flavor_id` (String) Identifier for the master node flavor in the Kubernetes cluster. -- `node_addresses` (List of String) List of IP addresses for worker nodes in the Kubernetes cluster. -- `node_count` (Number) Total number of nodes in the Kubernetes cluster. -- `status` (String) The current status of the Kubernetes cluster. -- `status_reason` (String) The reason for the current status of the Kubernetes cluster, if ERROR. -- `updated_at` (String) The timestamp when the Kubernetes cluster was updated. -- `user_id` (String) User identifier associated with the Kubernetes cluster. - - -### Nested Schema for `pool` - -Required: - -- `flavor_id` (String) -- `max_node_count` (Number) -- `min_node_count` (Number) -- `name` (String) -- `node_count` (Number) - -Optional: - -- `docker_volume_size` (Number) -- `docker_volume_type` (String) Available value is 'standard', 'ssd_hiiops', 'cold', 'ultra'. - -Read-Only: - -- `created_at` (String) -- `stack_id` (String) -- `uuid` (String) - - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) -- `update` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_k8s.cluster1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/k8s_pool.md b/docs/resources/k8s_pool.md deleted file mode 100644 index 87d5b2df..00000000 --- a/docs/resources/k8s_pool.md +++ /dev/null @@ -1,77 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_k8s_pool Resource - edgecenter" -subcategory: "" -description: |- - Represent k8s cluster's pool. ---- - -# edgecenter_k8s_pool (Resource) - -Represent k8s cluster's pool. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_k8s_pool" "v" { - project_id = 1 - region_id = 1 - cluster_id = "6bf878c1-1ce4-47c3-a39b-6b5f1d79bf25" - name = "tf-pool" - flavor_id = "g1-standard-1-2" - min_node_count = 1 - max_node_count = 2 - node_count = 1 - docker_volume_size = 2 -} -``` - - -## Schema - -### Required - -- `cluster_id` (String) The uuid of the Kubernetes cluster this pool belongs to. -- `flavor_id` (String) The identifier of the flavor used for nodes in this pool, e.g. g1-standard-2-4. -- `max_node_count` (Number) The maximum number of nodes the pool can scale to. -- `min_node_count` (Number) The minimum number of nodes in the pool. -- `name` (String) The name of the Kubernetes pool. -- `node_count` (Number) The current number of nodes in the pool. - -### Optional - -- `docker_volume_size` (Number) The size of the volume used for Docker containers, in gigabytes. -- `docker_volume_type` (String) The type of volume used for the Docker containers. Available values are 'standard', 'ssd_hiiops', 'cold', and 'ultra'. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) - -### Read-Only - -- `created_at` (String) The timestamp when the Kubernetes pool was created. -- `id` (String) The ID of this resource. -- `stack_id` (String) The identifier of the underlying infrastructure stack used by this pool. - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) -- `update` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using ::: format -terraform import edgecenter_k8s_pool.k8s_pool1 1:6:a775dd94-4e9c-4da7-9f0e-ffc9ae34446b:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/keypair.md b/docs/resources/keypair.md deleted file mode 100644 index 74519a64..00000000 --- a/docs/resources/keypair.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_keypair Resource - edgecenter" -subcategory: "" -description: |- - Represent a ssh key, do not depends on region ---- - -# edgecenter_keypair (Resource) - -Represent a ssh key, do not depends on region - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_keypair" "kp" { - project_id = 1 - public_key = "your public key here" - sshkey_name = "test" -} - -output "kp" { - value = edgecenter_keypair.kp -} -``` - - -## Schema - -### Required - -- `public_key` (String) The public portion of the SSH key pair. -- `sshkey_name` (String) The name assigned to the SSH key pair, used for identification purposes. - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. - -### Read-Only - -- `fingerprint` (String) A fingerprint of the SSH public key, used to verify the integrity of the key. -- `id` (String) The ID of this resource. -- `sshkey_id` (String) The unique identifier assigned by the provider to the SSH key pair. - - diff --git a/docs/resources/lblistener.md b/docs/resources/lblistener.md deleted file mode 100644 index 53770418..00000000 --- a/docs/resources/lblistener.md +++ /dev/null @@ -1,81 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_lblistener Resource - edgecenter" -subcategory: "" -description: |- - Represent a load balancer listener. Can not be created without a load balancer. A listener is a process that checks for connection requests using the protocol and port that you configure. ---- - -# edgecenter_lblistener (Resource) - -Represent a load balancer listener. Can not be created without a load balancer. A listener is a process that checks for connection requests using the protocol and port that you configure. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancerv2" "lb" { - project_id = 1 - region_id = 1 - name = "test" - flavor = "lb1-1-2" -} - -resource "edgecenter_lblistener" "listener" { - project_id = 1 - region_id = 1 - name = "test" - protocol = "TCP" - protocol_port = 36621 - loadbalancer_id = edgecenter_loadbalancerv2.lb.id -} -``` - - -## Schema - -### Required - -- `loadbalancer_id` (String) The uuid for the load balancer. -- `name` (String) The name of the load balancer listener. -- `protocol` (String) Available values are 'TCP', 'UDP', 'HTTP', 'HTTPS' and 'Terminated HTTPS'. -- `protocol_port` (Number) The port on which the protocol is bound. - -### Optional - -- `insert_x_forwarded` (Boolean) Insert *-forwarded headers -- `last_updated` (String) The timestamp of the last update (use with update context). -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `secret_id` (String) The identifier for the associated secret, typically used for SSL configurations. -- `sni_secret_id` (List of String) List of secret identifiers used for Server Name Indication (SNI). -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) - -### Read-Only - -- `id` (String) The ID of this resource. -- `operating_status` (String) The current operational status of the load balancer. -- `pool_count` (Number) Number of pools associated with the load balancer. -- `provisioning_status` (String) The current provisioning status of the load balancer. - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) -- `delete` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using ::: format -terraform import edgecenter_lblistener.lblistener1 1:6:a775dd94-4e9c-4da7-9f0e-ffc9ae34446b:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/lbmember.md b/docs/resources/lbmember.md deleted file mode 100644 index c3abacff..00000000 --- a/docs/resources/lbmember.md +++ /dev/null @@ -1,103 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_lbmember Resource - edgecenter" -subcategory: "" -description: |- - Represent load balancer member ---- - -# edgecenter_lbmember (Resource) - -Represent load balancer member - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancer" "lb" { - project_id = 1 - region_id = 1 - name = "test1" - flavor = "lb1-1-2" - listeners { - name = "test" - protocol = "HTTP" - protocol_port = 80 - } -} - -resource "edgecenter_lbpool" "pl" { - project_id = 1 - region_id = 1 - name = "test_pool1" - protocol = "HTTP" - lb_algorithm = "LEAST_CONNECTIONS" - loadbalancer_id = edgecenter_loadbalancer.lb.id - listener_id = edgecenter_loadbalancer.lb.listeners.0.id - health_monitor { - type = "PING" - delay = 60 - max_retries = 5 - timeout = 10 - } - session_persistence { - type = "APP_COOKIE" - cookie_name = "test_new_cookie" - } -} - -resource "edgecenter_lbmember" "lbm" { - project_id = 1 - region_id = 1 - pool_id = edgecenter_lbpool.pl.id - address = "10.10.2.15" - protocol_port = 8081 - weight = 5 -} -``` - - -## Schema - -### Required - -- `address` (String) The IP address of the load balancer pool member. -- `pool_id` (String) The uuid for the load balancer pool. -- `protocol_port` (Number) The port on which the member listens for requests. - -### Optional - -- `instance_id` (String) The uuid of the instance (amphora) associated with the pool member. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `subnet_id` (String) The uuid of the subnet in which the pool member is located. -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) -- `weight` (Number) A weight value between 0 and 256, determining the distribution of requests among the members of the pool. - -### Read-Only - -- `id` (String) The ID of this resource. -- `operating_status` (String) The current operating status of the pool member. - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) -- `delete` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using ::: format -terraform import edgecenter_lbmember.lbmember1 1:6:a775dd94-4e9c-4da7-9f0e-ffc9ae34446b:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/lbpool.md b/docs/resources/lbpool.md deleted file mode 100644 index 79c93f3b..00000000 --- a/docs/resources/lbpool.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_lbpool Resource - edgecenter" -subcategory: "" -description: |- - Represent load balancer listener pool. A pool is a list of virtual machines to which the listener will redirect incoming traffic ---- - -# edgecenter_lbpool (Resource) - -Represent load balancer listener pool. A pool is a list of virtual machines to which the listener will redirect incoming traffic - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancer" "lb" { - project_id = 1 - region_id = 1 - name = "test1" - flavor = "lb1-1-2" - listener { - name = "test" - protocol = "HTTP" - protocol_port = 80 - } -} - -resource "edgecenter_lbpool" "pl" { - project_id = 1 - region_id = 1 - name = "test_pool1" - protocol = "HTTP" - lb_algorithm = "LEAST_CONNECTIONS" - loadbalancer_id = edgecenter_loadbalancer.lb.id - listener_id = edgecenter_loadbalancer.lb.listener.0.id - health_monitor { - type = "PING" - delay = 60 - max_retries = 5 - timeout = 10 - } - session_persistence { - type = "APP_COOKIE" - cookie_name = "test_new_cookie" - } -} -``` - - -## Schema - -### Required - -- `lb_algorithm` (String) Available values is 'ROUND_ROBIN', 'LEAST_CONNECTIONS', 'SOURCE_IP', 'SOURCE_IP_PORT' -- `name` (String) The name of the load balancer listener pool. -- `protocol` (String) Available values is 'HTTP' (currently work, other do not work on ed-8), 'HTTPS', 'TCP', 'UDP' - -### Optional - -- `health_monitor` (Block List, Max: 1) Configuration for health checks to test the health and state of the backend members. -It determines how the load balancer identifies whether the backend members are healthy or unhealthy. (see [below for nested schema](#nestedblock--health_monitor)) -- `last_updated` (String) The timestamp of the last update (use with update context). -- `listener_id` (String) The uuid for the load balancer listener. -- `loadbalancer_id` (String) The uuid for the load balancer. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `session_persistence` (Block List, Max: 1) Configuration that enables the load balancer to bind a user's session to a specific backend member. -This ensures that all requests from the user during the session are sent to the same member. (see [below for nested schema](#nestedblock--session_persistence)) -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) - -### Read-Only - -- `id` (String) The ID of this resource. - - -### Nested Schema for `health_monitor` - -Required: - -- `delay` (Number) -- `max_retries` (Number) -- `timeout` (Number) -- `type` (String) Available values is 'HTTP', 'HTTPS', 'PING', 'TCP', 'TLS-HELLO', 'UDP-CONNECT - -Optional: - -- `expected_codes` (String) -- `http_method` (String) -- `max_retries_down` (Number) -- `url_path` (String) - -Read-Only: - -- `id` (String) The ID of this resource. - - - -### Nested Schema for `session_persistence` - -Required: - -- `type` (String) - -Optional: - -- `cookie_name` (String) -- `persistence_granularity` (String) -- `persistence_timeout` (Number) - - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) -- `delete` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_lbpool.lbpool1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/lifecyclepolicy.md b/docs/resources/lifecyclepolicy.md deleted file mode 100644 index 0df07384..00000000 --- a/docs/resources/lifecyclepolicy.md +++ /dev/null @@ -1,142 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_lifecyclepolicy Resource - edgecenter" -subcategory: "" -description: |- - Represent lifecycle policy. Use to periodically take snapshots ---- - -# edgecenter_lifecyclepolicy (Resource) - -Represent lifecycle policy. Use to periodically take snapshots - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_lifecyclepolicy" "lp" { - project_id = 1 - region_id = 1 - name = "test" - status = "active" - action = "volume_snapshot" - volume { - id = "fe93bfdd-4ce3-4041-b89b-4f10d0d49498" - } - schedule { - max_quantity = 4 - interval { - weeks = 1 - days = 2 - hours = 3 - minutes = 4 - } - resource_name_template = "reserve snap of the volume {volume_id}" - retention_time { - weeks = 4 - days = 3 - hours = 2 - minutes = 1 - } - } -} -``` - - -## Schema - -### Required - -- `name` (String) - -### Optional - -- `action` (String) -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `schedule` (Block List) (see [below for nested schema](#nestedblock--schedule)) -- `status` (String) -- `volume` (Block Set) List of managed volumes (see [below for nested schema](#nestedblock--volume)) - -### Read-Only - -- `id` (String) The ID of this resource. -- `user_id` (Number) - - -### Nested Schema for `schedule` - -Required: - -- `max_quantity` (Number) Maximum number of stored resources - -Optional: - -- `cron` (Block List, Max: 1) Use for taking actions at specified moments of time. Exactly one of interval and cron blocks should be provided (see [below for nested schema](#nestedblock--schedule--cron)) -- `interval` (Block List, Max: 1) Use for taking actions with equal time intervals between them. Exactly one of interval and cron blocks should be provided (see [below for nested schema](#nestedblock--schedule--interval)) -- `resource_name_template` (String) Used to name snapshots. {volume_id} is substituted with volume.id on creation -- `retention_time` (Block List, Max: 1) If it is set, new resource will be deleted after time (see [below for nested schema](#nestedblock--schedule--retention_time)) - -Read-Only: - -- `id` (String) The ID of this resource. -- `type` (String) - - -### Nested Schema for `schedule.cron` - -Optional: - -- `day` (String) Either single asterisk or comma-separated list of integers (1-31) -- `day_of_week` (String) Either single asterisk or comma-separated list of integers (0-6) -- `hour` (String) Either single asterisk or comma-separated list of integers (0-23) -- `minute` (String) Either single asterisk or comma-separated list of integers (0-59) -- `month` (String) Either single asterisk or comma-separated list of integers (1-12) -- `timezone` (String) -- `week` (String) Either single asterisk or comma-separated list of integers (1-53) - - - -### Nested Schema for `schedule.interval` - -Optional: - -- `days` (Number) Number of days to wait between actions -- `hours` (Number) Number of hours to wait between actions -- `minutes` (Number) Number of minutes to wait between actions -- `weeks` (Number) Number of weeks to wait between actions - - - -### Nested Schema for `schedule.retention_time` - -Optional: - -- `days` (Number) Number of days to wait before deleting snapshot -- `hours` (Number) Number of hours to wait before deleting snapshot -- `minutes` (Number) Number of minutes to wait before deleting snapshot -- `weeks` (Number) Number of weeks to wait before deleting snapshot - - - - -### Nested Schema for `volume` - -Read-Only: - -- `id` (String) The ID of this resource. -- `name` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_lifecyclepolicy.lifecyclepolicy1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/loadbalancer.md b/docs/resources/loadbalancer.md deleted file mode 100644 index 0aec2241..00000000 --- a/docs/resources/loadbalancer.md +++ /dev/null @@ -1,112 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_loadbalancer Resource - edgecenter" -subcategory: "" -description: |- - Represent load balancer ---- - -# edgecenter_loadbalancer (Resource) - -Represent load balancer - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancer" "lb" { - project_id = 1 - region_id = 1 - name = "test" - flavor = "lb1-1-2" - //when upgrading to version 0.2.28 nested listener max length reduced to 1 - //that mean, if you had more than one nested listener and removed them from - //schema they not delete in the cloud. User has to delete it manually and - //recreate as edgecenter_lblistener resource - listener { - name = "test" - protocol = "HTTP" - protocol_port = 80 - } -} -``` - - -## Schema - -### Required - -- `listener` (Block List, Min: 1, Max: 1) (see [below for nested schema](#nestedblock--listener)) -- `name` (String) The name of the load balancer. - -### Optional - -- `flavor` (String) -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) -- `vip_network_id` (String) -- `vip_subnet_id` (String) - -### Read-Only - -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `vip_address` (String) Load balancer IP address - - -### Nested Schema for `listener` - -Required: - -- `name` (String) -- `protocol` (String) Available values is 'HTTP' (currently work, other do not work on ed-8), 'HTTPS', 'TCP', 'UDP' -- `protocol_port` (Number) - -Optional: - -- `certificate` (String) -- `certificate_chain` (String) -- `insert_x_forwarded` (Boolean) -- `private_key` (String) -- `secret_id` (String) -- `sni_secret_id` (List of String) - -Read-Only: - -- `id` (String) The ID of this resource. - - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) -- `delete` (String) - - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using ::: format, listener_id - nested listener id -terraform import edgecenter_loadbalancer.loadbalancer1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7:a336f28c-fbb0-4256-9545-e905bed9f48f -``` diff --git a/docs/resources/loadbalancerv2.md b/docs/resources/loadbalancerv2.md deleted file mode 100644 index 690dc3f5..00000000 --- a/docs/resources/loadbalancerv2.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_loadbalancerv2 Resource - edgecenter" -subcategory: "" -description: |- - Represent load balancer without nested listener ---- - -# edgecenter_loadbalancerv2 (Resource) - -Represent load balancer without nested listener - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancerv2" "lb" { - project_id = 1 - region_id = 1 - name = "test" - flavor = "lb1-1-2" - metadata_map = { - tag1 = "tag1_value" - } -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the load balancer. - -### Optional - -- `flavor` (String) The flavor or specification of the load balancer to be created. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `security_group` (String) Creates a new security group with the specified name -- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts)) -- `vip_network_id` (String) Attaches the created network. -- `vip_port_id` (String) Attaches the created reserved IP. -- `vip_subnet_id` (String) The ID of the subnet in which to allocate the VIP address for the load balancer. - -### Read-Only - -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) -- `security_group_id` (String) Load balancer security group ID -- `vip_address` (String) Load balancer IP address - - -### Nested Schema for `timeouts` - -Optional: - -- `create` (String) -- `delete` (String) - - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_loadbalancer.loadbalancer1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/network.md b/docs/resources/network.md deleted file mode 100644 index 13dc9f53..00000000 --- a/docs/resources/network.md +++ /dev/null @@ -1,68 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_network Resource - edgecenter" -subcategory: "" -description: |- - Represent network. A network is a software-defined network in a cloud computing infrastructure ---- - -# edgecenter_network (Resource) - -Represent network. A network is a software-defined network in a cloud computing infrastructure - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_network" "network" { - name = "network_example" - type = "vxlan" - region_id = 1 - project_id = 1 -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the network. - -### Optional - -- `create_router` (Boolean) Create external router to the network, default true -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `mtu` (Number) Maximum Transmission Unit (MTU) for the network. It determines the maximum packet size that can be transmitted without fragmentation. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `type` (String) 'vlan' or 'vxlan' network type is allowed. Default value is 'vxlan' - -### Read-Only - -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_network.metwork1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/reservedfixedip.md b/docs/resources/reservedfixedip.md deleted file mode 100644 index b98b9215..00000000 --- a/docs/resources/reservedfixedip.md +++ /dev/null @@ -1,69 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_reservedfixedip Resource - edgecenter" -subcategory: "" -description: |- - Represent reserved ips ---- - -# edgecenter_reservedfixedip (Resource) - -Represent reserved ips - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_reservedfixedip" "fixed_ip" { - project_id = 1 - region_id = 1 - type = "external" - is_vip = false -} -``` - - -## Schema - -### Required - -- `is_vip` (Boolean) Flag to determine if the reserved fixed IP should be treated as a Virtual IP (VIP). -- `type` (String) The type of reserved fixed IP. Valid values are 'external', 'subnet', 'any_subnet', and 'ip_address' - -### Optional - -- `allowed_address_pairs` (Block List) Group of IP addresses that share the current IP as VIP. (see [below for nested schema](#nestedblock--allowed_address_pairs)) -- `fixed_ip_address` (String) The IP address that is associated with the reserved IP. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `network_id` (String) ID of the network to which the reserved fixed IP is associated. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `subnet_id` (String) ID of the subnet from which the fixed IP should be reserved. - -### Read-Only - -- `id` (String) The ID of this resource. -- `port_id` (String) ID of the port_id underlying the reserved fixed IP. -- `status` (String) The current status of the reserved fixed IP. - - -### Nested Schema for `allowed_address_pairs` - -Optional: - -- `ip_address` (String) -- `mac_address` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_reservedfixedip.reservedfixedip1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/router.md b/docs/resources/router.md deleted file mode 100644 index 3b9f8315..00000000 --- a/docs/resources/router.md +++ /dev/null @@ -1,132 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_router Resource - edgecenter" -subcategory: "" -description: |- - Represent router. Router enables you to dynamically exchange routes between networks ---- - -# edgecenter_router (Resource) - -Represent router. Router enables you to dynamically exchange routes between networks - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_router" "router" { - name = "router_example" - - dynamic "external_gateway_info" { - iterator = egi - for_each = var.external_gateway_info - content { - type = egi.value.type - enable_snat = egi.value.enable_snat - network_id = egi.value.network_id - } - } - - dynamic "interfaces" { - iterator = ifaces - for_each = var.interfaces - content { - type = ifaces.value.type - subnet_id = ifaces.value.subnet_id - } - } - - dynamic "routes" { - iterator = rs - for_each = var.routes - content { - destination = rs.value.destination - nexthop = rs.value.nexthop - } - } - - region_id = 1 - project_id = 1 -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the router. - -### Optional - -- `external_gateway_info` (Block List, Max: 1) Information related to the external gateway. (see [below for nested schema](#nestedblock--external_gateway_info)) -- `interfaces` (Block Set) Set of interfaces associated with the router. (see [below for nested schema](#nestedblock--interfaces)) -- `last_updated` (String) The timestamp of the last update (use with update context). -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `routes` (Block List) List of static routes to be applied to the router. (see [below for nested schema](#nestedblock--routes)) - -### Read-Only - -- `id` (String) The ID of this resource. - - -### Nested Schema for `external_gateway_info` - -Optional: - -- `enable_snat` (Boolean) -- `network_id` (String) Id of the external network -- `type` (String) Must be 'manual' or 'default' - -Read-Only: - -- `external_fixed_ips` (List of Object) (see [below for nested schema](#nestedatt--external_gateway_info--external_fixed_ips)) - - -### Nested Schema for `external_gateway_info.external_fixed_ips` - -Read-Only: - -- `ip_address` (String) -- `subnet_id` (String) - - - - -### Nested Schema for `interfaces` - -Required: - -- `subnet_id` (String) Subnet for router interface must have a gateway IP -- `type` (String) must be 'subnet' - -Read-Only: - -- `ip_address` (String) -- `mac_address` (String) -- `network_id` (String) -- `port_id` (String) - - - -### Nested Schema for `routes` - -Required: - -- `destination` (String) -- `nexthop` (String) IPv4 address to forward traffic to if it's destination IP matches 'destination' CIDR - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_router.router1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/secret.md b/docs/resources/secret.md deleted file mode 100644 index 278cf9cf..00000000 --- a/docs/resources/secret.md +++ /dev/null @@ -1,67 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_secret Resource - edgecenter" -subcategory: "" -description: |- - Represent secret ---- - -# edgecenter_secret (Resource) - -Represent secret - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_secret" "lb_https" { - region_id = 1 - project_id = 1 - - name = "test" - private_key = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQ4E6U0vql4EST\n8o41TlHRz6MKmMhddVUjM2juTKjxv4WuB4T3z/wokznEjQg4H7gfYEKeCJqelrfq\ntdOtbPsznSceMOXB5uA2Sc9WVKwk7owoRJxPd4LQeOcarVOFdIzudzkgSK/oV7Za\nL8Y2hylsB4SX2cfbULtmW/WDePp3YZAL6zYV1fXJSnK+hL2iUSqikiViEGRta+47\nnaTKZnnmSgojdshzsw0wlF/PgRJ/Anf9j9J8ratdJP81yAG5daU3L2NdJ3qx9UbV\ntKnSq2z2u4yx6xdb4t4WFQBKNjC6+YZN/gI5lp96p3FNTNS4PKYxAAUrnCwf0EE3\n7dOR4eWlAgMBAAECggEBALPm3ge0h4li1e4PVYh4AmSRT74KxVgpfMCqwM+uWzyM\nVpkDhPTjwC06UOEHD3M3bqAninkOtA2vhoyzOrP+T4Wu70hDmUAemDJp9BhJKVNN\n2o28Olz/dD4WRAZoDq29Kr0hFqTFtiyJj1eyGihQ1c5j00HuowI0UJPi1Fz+T8uN\nPwukUtTPYwEds6SApii3v9VKjmvbRDmsbHU3KkUoaeqpRnRagyp1vtoLXigezUcK\nrQcoh6wlKtvj0YLR2lxq9Wmj1nn6m3F5Bom54X8o18tcOmFSRudRb+Fxjb0jnqSK\nAsyVlZg4alTBQUmx9gIKv0oSJAIh2nXdclECkGjs8WkCgYEA9xvdDWephsbv+X3k\nndnDG9JTxfrR6HMHPrUrTaZ8/VD+Qw4zuReoNGkcQbV3Cb26egprWQWfYc9+l6mU\nAWgOjFgeGie1uwOwkhv6CfhE/iVvotJ3hOOsC5pLEhz4vRpO75C9wSehjfTYkP1m\nXEAhRTRbgMnvzChWyh5CEjosX5sCgYEA2GRHrG0JVxsYSCugLPKf9fSK4CQDm0bK\nywBwZtAWX0xhiHO/BW6PeK1Mqx2nbiWl1hXNpZKJNS9bnrZWym/yUqOvg2XJKjb6\nhHBvwAD1MOQ8Ysby4JHGCrMBEwlcDpI2wpMpXkKhU3X0XWjkqrhqCH/TETFKkqLt\nfJX/c9PTQ78CgYAEPek0grQJST7zVHLpNsS/pIOloWGbEOZt8CQ3KAV7P7mtov/G\nTJ6pj6hZhGjvtN8Pm0Aufgc3YZ11swaEY6nkRNr3bfkTpcORLoPDSgy9JB1feSdu\nE45vgI2LWQ34CQyT1jM7rpd6XVqeWos4SC2KB5UOh+ji40piG9TchT0fwwKBgA/M\nmpMTTvhGKSqzzLkbaeR6W11sI7tFmu7hdFN9Y/THTeO5l7vcy6ri9FMWEjBvnUEZ\nTG+HWG9CquzWoVWcgNPZ0anFV7+2Teo3j2E0cLKGJ4aKwhb1bcFAOpbaOxdxQ4BH\nYGDaeo7ucM4VJ4TzfAJs2stJjwlPzgknpoQddjJfAoGBAIFfnU8x/SrNhAqZrG9d\n3kpJ5LmbVswOYtj01KHM+KpEwOQVF+s2NOeHqyC7QUIWrue00+1MT88F9cNHDeWk\n0dEOJNWCfzcV85l8A+0p6/4qAW7h7RNiFqeA8GyVKCT8f7fu/7WpYw8D0aq8w5X/\nKZl+AjB+MzYFs71+SC4ohTlI\n-----END PRIVATE KEY-----" - certificate = "-----BEGIN CERTIFICATE-----\nMIIDpDCCAoygAwIBAgIJAIUvym0uaBHbMA0GCSqGSIb3DQEBCwUAMD0xCzAJBgNV\nBAYTAlJVMQ8wDQYDVQQIDAZNT1NDT1cxCzAJBgNVBAoMAkNBMRAwDgYDVQQDDAdS\nT09UIENBMB4XDTIxMDczMDE1MTU0NVoXDTMxMDcyODE1MTU0NVowTDELMAkGA1UE\nBhMCQ0ExDTALBgNVBAgMBE5vbmUxCzAJBgNVBAcMAk5CMQ0wCwYDVQQKDAROb25l\nMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQDQ4E6U0vql4EST8o41TlHRz6MKmMhddVUjM2juTKjxv4WuB4T3z/wokznE\njQg4H7gfYEKeCJqelrfqtdOtbPsznSceMOXB5uA2Sc9WVKwk7owoRJxPd4LQeOca\nrVOFdIzudzkgSK/oV7ZaL8Y2hylsB4SX2cfbULtmW/WDePp3YZAL6zYV1fXJSnK+\nhL2iUSqikiViEGRta+47naTKZnnmSgojdshzsw0wlF/PgRJ/Anf9j9J8ratdJP81\nyAG5daU3L2NdJ3qx9UbVtKnSq2z2u4yx6xdb4t4WFQBKNjC6+YZN/gI5lp96p3FN\nTNS4PKYxAAUrnCwf0EE37dOR4eWlAgMBAAGjgZcwgZQwVwYDVR0jBFAwTqFBpD8w\nPTELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1PU0NPVzELMAkGA1UECgwCQ0ExEDAO\nBgNVBAMMB1JPT1QgQ0GCCQCectJTETy4lTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE\n8DAhBgNVHREEGjAYgglsb2NhbGhvc3SCCyoubG9jYWxob3N0MA0GCSqGSIb3DQEB\nCwUAA4IBAQBqzJcwygLsVCTPlReUpcKVn84aFqzfZA0m7hYvH+7PDH/FM8SbX3zg\nteBL/PgQAZw1amO8xjeMc2Pe2kvi9VrpfTeGqNia/9axhGu3q/NEP0tyDFXAE2bR\njBdGhd5gCmg+X4WdHigCgn51cz5r2k3fSOIWP+TQWHqc8Yt+vZXnkwnQkRA1Ki7N\nWOiJjj/ae5RWwma/kJNmShTZn754gbQn06bAjNbPjclsHRLkawmLqikd1rYUhIdk\nOr1Nrl+CWMx3CXg0TVVdJ6rH3dO31uyvb+3qEY7WnL+HhZyr08ay8gJsEKPuPFA2\nxvveXqt9ceU5qh+8T7mHwGALEUw96QcP\n-----END CERTIFICATE-----" - certificate_chain = "-----BEGIN CERTIFICATE-----\nMIIC9jCCAd4CCQCectJTETy4lTANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQGEwJS\nVTEPMA0GA1UECAwGTU9TQ09XMQswCQYDVQQKDAJDQTEQMA4GA1UEAwwHUk9PVCBD\nQTAeFw0yMTA3MzAxNTExMzVaFw0yNDA1MTkxNTExMzVaMD0xCzAJBgNVBAYTAlJV\nMQ8wDQYDVQQIDAZNT1NDT1cxCzAJBgNVBAoMAkNBMRAwDgYDVQQDDAdST09UIENB\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo6tZ0NV6QIR/mvsqtAII\nzTTuBMrZR5OTwKvcGnhe4GVDwzJ/OgEWkghLAzOojcJvkfzJOtWwOXqwgphksc+7\n+vwIPTPt3iWjbQUzXK8pFLkjxrO8px/QxPuUrp+U6DTVvvgQesjMZ9jQRUFKOiCc\nu0st1N5Q/CJR4VOJxtYoLy1ZUlsABhwJ+6trkoOFTLRPlMUX1EIG57jYAotHvQFo\nc8UNx3KzvJsJJ56SniXCIkeu61IOt8aOXHU+3TLYhZnPiP311cMbXA0J3vGPRZwz\n25BZjF3IF/ShXlfzz76FjWUTAThc0+HA8lzx53xD4/n8HN+sGubGx9TvLyZimG/U\nGwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAnK8Wzw33fR6R6pqV05XI9Yu8J+BwC\nCn2bKxxYwwQWZyX1as+UIlGuvyBRJba9W2UGMj95FQfWVdDyFC98spUur+O/5yL+\nNHH+dxGnkxIRc6RMIy+GXJwPrLiB/t70hSvwgVa249zNJVcwYN/5SGX5wLaJKnim\neY99xm75nr03O/RJK/DR8HvWysH7zxvrMWs0ppfwxkxrwOcg0Cb9xODVkg/wyClw\nLiHWlmH/eyC8nkiLYJKmV7566VWCV+gy+hC/DRstVVjIMG6LsqaPq6ycm7N8EV8s\nBb5uXIVHW6w5a20c40+W9G4EDYiQjdgEaf0FoMAWGDnOEaPsvjQk2/z5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIDPDCCAiQCCQDxA75ydLHVoTANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJS\nVTEPMA0GA1UECAwGTU9TQ09XMQ8wDQYDVQQHDAZNT1NDT1cxFTATBgNVBAoMDElO\nVEVSTUVESUFURTEYMBYGA1UEAwwPSU5URVJNRURJQVRFIENBMB4XDTIxMDczMDE1\nMTIyMloXDTI0MDUxOTE1MTIyMlowYDELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1P\nU0NPVzEPMA0GA1UEBwwGTU9TQ09XMRUwEwYDVQQKDAxJTlRFUk1FRElBVEUxGDAW\nBgNVBAMMD0lOVEVSTUVESUFURSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAKOrWdDVekCEf5r7KrQCCM007gTK2UeTk8Cr3Bp4XuBlQ8MyfzoBFpII\nSwMzqI3Cb5H8yTrVsDl6sIKYZLHPu/r8CD0z7d4lo20FM1yvKRS5I8azvKcf0MT7\nlK6flOg01b74EHrIzGfY0EVBSjognLtLLdTeUPwiUeFTicbWKC8tWVJbAAYcCfur\na5KDhUy0T5TFF9RCBue42AKLR70BaHPFDcdys7ybCSeekp4lwiJHrutSDrfGjlx1\nPt0y2IWZz4j99dXDG1wNCd7xj0WcM9uQWYxdyBf0oV5X88++hY1lEwE4XNPhwPJc\n8ed8Q+P5/BzfrBrmxsfU7y8mYphv1BsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA\ngOHvrh66+bQoG3Lo8bfp7D1Xvm/Md3gJq2nMotl2BH1TvNzMV93fCXygRX8J8rTL\n7xjUC2SbOrFDWFq2hNJQagdecAeuG+U55BY6Wi8SsHw+fhgxQyl9wtXWwotQPmsD\nuRhR1rL3vEphgPLbxNBzA7Lvj+P89Ar988Qy+o5AiUzHMUuqZbGOqs8UcKCQP7e/\nIX+zqqFwqyI8f90SVySGgs574jo8jQFy3l5fnp6yK0MPWg2cBCjpa5H1A+5DADF+\nnryV6Ie/m/wfxmitZZN+YCJu+8Bmmdl/FCwbmiH+HCLhrO8gonH3K21cQujMyFF5\nc7OFj86hvhqbr4kzz1J8lg==\n-----END CERTIFICATE-----" - expiration = "2025-12-28T19:14:44.213" -} -``` - - -## Schema - -### Required - -- `certificate` (String) SSL certificate in PEM format -- `certificate_chain` (String) SSL certificate chain of intermediates and root certificates in PEM format -- `name` (String) The name of the secret. -- `private_key` (String) SSL private key in PEM format - -### Optional - -- `expiration` (String) Datetime when the secret will expire. The format is 2025-12-28T19:14:44 -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `algorithm` (String) The encryption algorithm used for the secret. -- `bit_length` (Number) The bit length of the encryption algorithm. -- `content_types` (Map of String) The content types associated with the secret's payload. -- `created` (String) Datetime when the secret was created. The format is 2025-12-28T19:14:44.180394 -- `id` (String) The ID of this resource. -- `mode` (String) The mode of the encryption algorithm. -- `status` (String) The current status of the secret. - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_secret.secret_id 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/securitygroup.md b/docs/resources/securitygroup.md deleted file mode 100644 index 696e909f..00000000 --- a/docs/resources/securitygroup.md +++ /dev/null @@ -1,111 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_securitygroup Resource - edgecenter" -subcategory: "" -description: |- - Represent SecurityGroups(Firewall) ---- - -# edgecenter_securitygroup (Resource) - -Represent SecurityGroups(Firewall) - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_securitygroup" "sg" { - name = "test sg" - region_id = 1 - project_id = 1 - - security_group_rules { - direction = "egress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 19990 - port_range_max = 19990 - } - - security_group_rules { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 19990 - port_range_max = 19990 - } - - security_group_rules { - direction = "egress" - ethertype = "IPv4" - protocol = "vrrp" - } -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the security group. -- `security_group_rules` (Block Set, Min: 1) Firewall rules control what inbound(ingress) and outbound(egress) traffic is allowed to enter or leave a Instance. At least one 'egress' rule should be set (see [below for nested schema](#nestedblock--security_group_rules)) - -### Optional - -- `description` (String) A detailed description of the security group. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) - - -### Nested Schema for `security_group_rules` - -Required: - -- `direction` (String) Available value is 'ingress', 'egress' -- `ethertype` (String) Available value is 'IPv4', 'IPv6' -- `protocol` (String) Available value is udp,tcp,any,icmp,ah,dccp,egp,esp,gre,igmp,ospf,pgm,rsvp,sctp,udplite,vrrp,51,50,112,0,4,ipip,ipencap - -Optional: - -- `description` (String) -- `port_range_max` (Number) -- `port_range_min` (Number) -- `remote_ip_prefix` (String) - -Read-Only: - -- `created_at` (String) -- `id` (String) The ID of this resource. -- `updated_at` (String) - - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_securitygroup.securitygroup1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/servergroup.md b/docs/resources/servergroup.md deleted file mode 100644 index 714afa5b..00000000 --- a/docs/resources/servergroup.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_servergroup Resource - edgecenter" -subcategory: "" -description: |- - Represent server group resource ---- - -# edgecenter_servergroup (Resource) - -Represent server group resource - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_servergroup" "default" { - name = "default" - policy = "affinity" - region_id = 1 - project_id = 1 -} -``` - - -## Schema - -### Required - -- `name` (String) Displayed server group name -- `policy` (String) Server group policy. Available value is 'affinity', 'anti-affinity' - -### Optional - -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `instances` (List of Object) Instances in this server group (see [below for nested schema](#nestedatt--instances)) - - -### Nested Schema for `instances` - -Read-Only: - -- `instance_id` (String) -- `instance_name` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_servergroup.servergroup1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/snapshot.md b/docs/resources/snapshot.md deleted file mode 100644 index e15bafab..00000000 --- a/docs/resources/snapshot.md +++ /dev/null @@ -1,63 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_snapshot Resource - edgecenter" -subcategory: "" -description: |- - ---- - -# edgecenter_snapshot (Resource) - - - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_snapshot" "snapshot" { - project_id = 1 - region_id = 1 - name = "snapshot example" - volume_id = "28e9edcb-1593-41fe-971b-da729c6ec301" - description = "snapshot example description" - metadata = { - env = "test" - } -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the snapshot. -- `volume_id` (String) The ID of the volume from which the snapshot was created. - -### Optional - -- `description` (String) A detailed description of the snapshot. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata` (Map of String) -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `size` (Number) The size of the snapshot in GB. -- `status` (String) The current status of the snapshot. - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_snapshot.snapshot1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/storage_s3.md b/docs/resources/storage_s3.md deleted file mode 100644 index 31a9e86d..00000000 --- a/docs/resources/storage_s3.md +++ /dev/null @@ -1,48 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_storage_s3 Resource - edgecenter" -subcategory: "" -description: |- - Represent s3 storage resource. https://storage.edgecenter.ru/storage/list ---- - -# edgecenter_storage_s3 (Resource) - -Represent s3 storage resource. https://storage.edgecenter.ru/storage/list - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_storage_s3" "example_s3" { - name = "example" - location = "s-ed1" -} -``` - - -## Schema - -### Required - -- `location` (String) A location of new storage resource. One of (s-ed1, s-darz1, s-ws1, s-dt2, s-drc2) -- `name` (String) A name of new storage resource. - -### Optional - -- `client_id` (Number) An client id of new storage resource. -- `generated_access_key` (String) A s3 access key for new storage resource. -- `generated_endpoint` (String) A s3 entry point for new storage resource. -- `generated_http_endpoint` (String) A http s3 entry point for new storage resource. -- `generated_s3_endpoint` (String) A s3 endpoint for new storage resource. -- `generated_secret_key` (String) A s3 secret key for new storage resource. -- `storage_id` (Number) An id of new storage resource. - -### Read-Only - -- `id` (String) The ID of this resource. - - diff --git a/docs/resources/storage_s3_bucket.md b/docs/resources/storage_s3_bucket.md deleted file mode 100644 index 436760c2..00000000 --- a/docs/resources/storage_s3_bucket.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_storage_s3_bucket Resource - edgecenter" -subcategory: "" -description: |- - Represent s3 storage bucket resource. https://storage.edgecenter.ru/storage/list ---- - -# edgecenter_storage_s3_bucket (Resource) - -Represent s3 storage bucket resource. https://storage.edgecenter.ru/storage/list - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_storage_s3_bucket" "example_s3_bucket" { - name = "example1bucket2name" - storage_id = 1 -} -``` - - -## Schema - -### Required - -- `name` (String) A name of new storage bucket resource. -- `storage_id` (Number) An id of existing storage resource. - -### Read-Only - -- `id` (String) The ID of this resource. - - diff --git a/docs/resources/subnet.md b/docs/resources/subnet.md deleted file mode 100644 index a135fb1f..00000000 --- a/docs/resources/subnet.md +++ /dev/null @@ -1,102 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_subnet Resource - edgecenter" -subcategory: "" -description: |- - Represent subnets. Subnetwork is a range of IP addresses in a cloud network. Addresses from this range will be assigned to machines in the cloud ---- - -# edgecenter_subnet (Resource) - -Represent subnets. Subnetwork is a range of IP addresses in a cloud network. Addresses from this range will be assigned to machines in the cloud - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_network" "network" { - name = "network_example" - mtu = 1450 - type = "vxlan" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_subnet" "subnet" { - name = "subnet_example" - cidr = "192.168.10.0/24" - network_id = edgecenter_network.network.id - dns_nameservers = var.dns_nameservers - - dynamic "host_routes" { - iterator = hr - for_each = var.host_routes - content { - destination = hr.value.destination - nexthop = hr.value.nexthop - } - } - - gateway_ip = "192.168.10.1" - region_id = 1 - project_id = 1 -} -``` - - -## Schema - -### Required - -- `cidr` (String) Represents the IP address range of the subnet. -- `name` (String) The name of the subnet. -- `network_id` (String) The ID of the network to which this subnet belongs. - -### Optional - -- `connect_to_network_router` (Boolean) True if the network's router should get a gateway in this subnet. Must be explicitly 'false' when gateway_ip is null. Default true. -- `dns_nameservers` (List of String) List of DNS name servers for the subnet. -- `enable_dhcp` (Boolean) Enable DHCP for this subnet. If true, DHCP will be used to assign IP addresses to instances within this subnet. -- `gateway_ip` (String) The IP address of the gateway for this subnet. -- `host_routes` (Block List) List of additional routes to be added to instances that are part of this subnet. (see [below for nested schema](#nestedblock--host_routes)) -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. - -### Read-Only - -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) - - -### Nested Schema for `host_routes` - -Required: - -- `destination` (String) -- `nexthop` (String) IPv4 address to forward traffic to if it's destination IP matches 'destination' CIDR - - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_subnet.subnet1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/docs/resources/volume.md b/docs/resources/volume.md deleted file mode 100644 index 26593b66..00000000 --- a/docs/resources/volume.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -# generated by https://github.com/hashicorp/terraform-plugin-docs -page_title: "edgecenter_volume Resource - edgecenter" -subcategory: "" -description: |- - A volume is a detachable block storage device akin to a USB hard drive or SSD, but located remotely in the cloud. - Volumes can be attached to a virtual machine and manipulated like a physical hard drive. ---- - -# edgecenter_volume (Resource) - -A volume is a detachable block storage device akin to a USB hard drive or SSD, but located remotely in the cloud. -Volumes can be attached to a virtual machine and manipulated like a physical hard drive. - -## Example Usage - -```terraform -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_volume" "volume" { - name = "volume_example" - type_name = "standard" - size = 1 - region_id = 1 - project_id = 1 - metadata_map = { - tag1 = "tag1_value" - } -} -``` - - -## Schema - -### Required - -- `name` (String) The name of the volume. -- `size` (Number) The size of the volume, specified in gigabytes (GB). - -### Optional - -- `image_id` (String) (ForceNew) The ID of the image to create the volume from. This field is mandatory if creating a volume from an image. -- `last_updated` (String) The timestamp of the last update (use with update context). -- `metadata_map` (Map of String) A map containing metadata, for example tags. -- `project_id` (Number) The uuid of the project. Either 'project_id' or 'project_name' must be specified. -- `project_name` (String) The name of the project. Either 'project_id' or 'project_name' must be specified. -- `region_id` (Number) The uuid of the region. Either 'region_id' or 'region_name' must be specified. -- `region_name` (String) The name of the region. Either 'region_id' or 'region_name' must be specified. -- `snapshot_id` (String) (ForceNew) The ID of the snapshot to create the volume from. This field is mandatory if creating a volume from a snapshot. -- `type_name` (String) The type of volume to create. Valid values are 'ssd_hiiops', 'standard', 'cold', and 'ultra'. Defaults to 'standard'. - -### Read-Only - -- `id` (String) The ID of this resource. -- `metadata_read_only` (List of Object) A list of read-only metadata items, e.g. tags. (see [below for nested schema](#nestedatt--metadata_read_only)) - - -### Nested Schema for `metadata_read_only` - -Read-Only: - -- `key` (String) -- `read_only` (Boolean) -- `value` (String) - -## Import - -Import is supported using the following syntax: - -```shell -# import using :: format -terraform import edgecenter_volume.volume1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 -``` diff --git a/edgecenter/config/config.go b/edgecenter/config/config.go new file mode 100644 index 00000000..9bafe45d --- /dev/null +++ b/edgecenter/config/config.go @@ -0,0 +1,44 @@ +package config + +import ( + "fmt" + "log" + + "github.com/hashicorp/terraform-plugin-sdk/v2/diag" + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/logging" + + edgecloud "github.com/Edge-Center/edgecentercloud-go" +) + +type Config struct { + TerraformVersion string + APIKey string + CloudAPIURL string +} + +type CombinedConfig struct { + cloud *edgecloud.Client +} + +func (c *CombinedConfig) EdgeCloudClient() *edgecloud.Client { return c.cloud } + +// Client returns a new client for accessing Edgecenter Cloud client. +func (c *Config) Client() (*CombinedConfig, diag.Diagnostics) { + userAgent := fmt.Sprintf("Terraform/%s", c.TerraformVersion) + + client, err := edgecloud.NewWithRetries(nil, + edgecloud.SetUserAgent(userAgent), + edgecloud.SetAPIKey(c.APIKey), + edgecloud.SetBaseURL(c.CloudAPIURL), + ) + if err != nil { + return nil, diag.FromErr(fmt.Errorf("edgecloud client create error: %w", err)) + } + + clientTransport := logging.NewSubsystemLoggingHTTPTransport("EdgeCenter", client.HTTPClient.Transport) + client.HTTPClient.Transport = clientTransport + + log.Printf("[INFO] EdgeCenter Client configured for URL: %s", client.BaseURL.String()) + + return &CombinedConfig{cloud: client}, nil +} diff --git a/edgecenter/data_source_edgecenter_floatingip.go b/edgecenter/data_source_edgecenter_floatingip.go deleted file mode 100644 index 868bc6a4..00000000 --- a/edgecenter/data_source_edgecenter_floatingip.go +++ /dev/null @@ -1,187 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "net" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/floatingip/v1/floatingips" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" -) - -func dataSourceFloatingIP() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceFloatingIPRead, - Description: `A floating IP is a static IP address that can be associated with one of your instances or loadbalancers, -allowing it to have a static public IP address. The floating IP can be re-associated to any other instance in the same datacenter.`, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "floating_ip_address": { - Type: schema.TypeString, - Required: true, - Description: "The floating IP address assigned to the resource. It must be a valid IP address.", - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - ip := net.ParseIP(v) - if ip != nil { - return diag.Diagnostics{} - } - - return diag.FromErr(fmt.Errorf("%q must be a valid ip, got: %s", key, v)) - }, - }, - "port_id": { - Type: schema.TypeString, - Optional: true, - Description: "The ID (uuid) of the network port that the floating IP is associated with.", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the floating IP resource. Can be 'DOWN' or 'ACTIVE'.", - }, - "fixed_ip_address": { - Type: schema.TypeString, - Computed: true, - Description: "The fixed (reserved) IP address that is associated with the floating IP.", - }, - "router_id": { - Type: schema.TypeString, - Computed: true, - Description: "The ID (uuid) of the router that the floating IP is associated with.", - }, - "metadata_k": { - Type: schema.TypeString, - Optional: true, - Description: "Filtration query opts (only key).", - }, - "metadata_kv": { - Type: schema.TypeMap, - Optional: true, - Description: `Filtration query opts, for example, {offset = "10", limit = "10"}.`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceFloatingIPRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start FloatingIP reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, FloatingIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - ipAddr := d.Get("floating_ip_address").(string) - metaOpts := &floatingips.ListOpts{} - - if metadataK, ok := d.GetOk("metadata_k"); ok { - metaOpts.MetadataK = metadataK.(string) - } - - if metadataRaw, ok := d.GetOk("metadata_kv"); ok { - meta, err := utils.MapInterfaceToMapString(metadataRaw) - if err != nil { - return diag.FromErr(err) - } - metaOpts.MetadataKV = meta - } - - ips, err := floatingips.ListAll(client, *metaOpts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var floatingIP floatingips.FloatingIPDetail - for _, ip := range ips { - if ip.FloatingIPAddress.String() == ipAddr { - floatingIP = ip - found = true - break - } - } - - if !found { - return diag.Errorf("floatingIP %s not found", ipAddr) - } - - d.SetId(floatingIP.ID) - if floatingIP.FixedIPAddress != nil { - d.Set("fixed_ip_address", floatingIP.FixedIPAddress.String()) - } else { - d.Set("fixed_ip_address", "") - } - - d.Set("project_id", floatingIP.ProjectID) - d.Set("region_id", floatingIP.RegionID) - d.Set("status", floatingIP.Status) - d.Set("port_id", floatingIP.PortID) - d.Set("router_id", floatingIP.RouterID) - d.Set("floating_ip_address", floatingIP.FloatingIPAddress.String()) - - metadataReadOnly := PrepareMetadataReadonly(floatingIP.Metadata) - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish FloatingIP reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_image.go b/edgecenter/data_source_edgecenter_image.go deleted file mode 100644 index 82e81d05..00000000 --- a/edgecenter/data_source_edgecenter_image.go +++ /dev/null @@ -1,187 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - "strings" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/image/v1/images" -) - -const ( - ImagesPoint = "images" - bmImagesPoint = "bmimages" -) - -func dataSourceImage() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceImageRead, - Description: "A cloud image is a pre-configured virtual machine template that you can use to create new instances.", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Description: "The name of the image. Use 'os-version', for example 'ubuntu-20.04'.", - Required: true, - }, - "is_baremetal": { - Type: schema.TypeBool, - Description: "Set to true if need to get the baremetal image.", - Optional: true, - }, - "min_disk": { - Type: schema.TypeInt, - Computed: true, - Description: "Minimum disk space (in GB) required to launch an instance using this image.", - }, - "min_ram": { - Type: schema.TypeInt, - Computed: true, - Description: "Minimum VM RAM (in MB) required to launch an instance using this image.", - }, - "os_distro": { - Type: schema.TypeString, - Computed: true, - Description: "The distribution of the OS present in the image, e.g. Debian, CentOS, Ubuntu etc.", - }, - "os_version": { - Type: schema.TypeString, - Computed: true, - Description: "The version of the OS present in the image. e.g. 19.04 (for Ubuntu) or 9.4 for Debian.", - }, - "description": { - Type: schema.TypeString, - Computed: true, - Description: "A detailed description of the image.", - }, - "metadata_k": { - Type: schema.TypeString, - Optional: true, - Description: "Filtration query opts (only key).", - }, - "metadata_kv": { - Type: schema.TypeMap, - Optional: true, - Description: `Filtration query opts, for example, {offset = "10", limit = "10"}.`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceImageRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Image reading") - name := d.Get("name").(string) - - config := m.(*Config) - provider := config.Provider - - point := ImagesPoint - if isBm, _ := d.Get("is_baremetal").(bool); isBm { - point = bmImagesPoint - } - client, err := CreateClient(provider, d, point, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - listOpts := &images.ListOpts{} - - if metadataK, ok := d.GetOk("metadata_k"); ok { - listOpts.MetadataK = metadataK.(string) - } - - if metadataRaw, ok := d.GetOk("metadata_kv"); ok { - typedMetadataKV := make(map[string]string, len(metadataRaw.(map[string]interface{}))) - for k, v := range metadataRaw.(map[string]interface{}) { - typedMetadataKV[k] = v.(string) - } - listOpts.MetadataKV = typedMetadataKV - } - - allImages, err := images.ListAll(client, *listOpts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var image images.Image - for _, img := range allImages { - if strings.HasPrefix(strings.ToLower(img.Name), strings.ToLower(name)) { - image = img - found = true - break - } - } - - if !found { - return diag.Errorf("image with name %s not found", name) - } - - d.SetId(image.ID) - d.Set("project_id", d.Get("project_id").(int)) - d.Set("region_id", d.Get("region_id").(int)) - d.Set("min_disk", image.MinDisk) - d.Set("min_ram", image.MinRAM) - d.Set("os_distro", image.OsDistro) - d.Set("os_version", image.OsVersion) - d.Set("description", image.Description) - - metadataReadOnly := PrepareMetadataReadonly(image.Metadata) - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish Image reading") - - return nil -} diff --git a/edgecenter/data_source_edgecenter_instance.go b/edgecenter/data_source_edgecenter_instance.go deleted file mode 100644 index 558f7ba5..00000000 --- a/edgecenter/data_source_edgecenter_instance.go +++ /dev/null @@ -1,297 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "strconv" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/instances" -) - -func dataSourceInstance() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceInstanceRead, - Description: `A cloud instance is a virtual machine in a cloud environment. Could be used with baremetal also.`, - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the instance.", - }, - "flavor_id": { - Type: schema.TypeString, - Computed: true, - Description: "The ID of the flavor to be used for the instance, determining its compute and memory, for example 'g1-standard-2-4'.", - }, - "volume": { - Type: schema.TypeSet, - Computed: true, - Set: volumeUniqueID, - Description: "A set defining the volumes to be attached to the instance.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "volume_id": { - Type: schema.TypeString, - Computed: true, - }, - "delete_on_termination": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - "interface": { - Type: schema.TypeList, - Computed: true, - Description: "A list defining the network interfaces to be attached to the instance.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "network_id": { - Type: schema.TypeString, - Computed: true, - }, - "subnet_id": { - Type: schema.TypeString, - Computed: true, - }, - "port_id": { - Type: schema.TypeString, - Computed: true, - }, - "ip_address": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "security_group": { - Type: schema.TypeList, - Computed: true, - Description: "A list of firewall configurations applied to the instance, defined by their id and name.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "metadata": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "flavor": { - Type: schema.TypeMap, - Computed: true, - Description: `A map defining the flavor of the instance, for example, {"flavor_name": "g1-standard-2-4", "ram": 4096, ...}.`, - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the instance. This is computed automatically and can be used to track the instance's state.", - }, - "vm_state": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf(`The current virtual machine state of the instance, -allowing you to start or stop the VM. Possible values are %s and %s.`, InstanceVMStateStopped, InstanceVMStateActive), - }, - "addresses": { - Type: schema.TypeList, - Computed: true, - Description: `A list of network addresses associated with the instance, for example "pub_net": [...].`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "net": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "addr": { - Type: schema.TypeString, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - }, - }, - }, - }, - } -} - -func dataSourceInstanceRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Instance reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, InstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - name := d.Get("name").(string) - insts, err := instances.ListAll(client, instances.ListOpts{Name: name}) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var instance instances.Instance - for _, l := range insts { - if l.Name == name { - instance = l - found = true - break - } - } - - if !found { - return diag.Errorf("instance with name %s not found", name) - } - - d.SetId(instance.ID) - d.Set("name", instance.Name) - - d.Set("flavor_id", instance.Flavor.FlavorID) - d.Set("status", instance.Status) - d.Set("vm_state", instance.VMState) - - flavor := make(map[string]interface{}, 4) - flavor["flavor_id"] = instance.Flavor.FlavorID - flavor["flavor_name"] = instance.Flavor.FlavorName - flavor["ram"] = strconv.Itoa(instance.Flavor.RAM) - flavor["vcpus"] = strconv.Itoa(instance.Flavor.VCPUS) - d.Set("flavor", flavor) - - extVolumes := make([]interface{}, 0, len(instance.Volumes)) - for _, vol := range instance.Volumes { - v := make(map[string]interface{}) - v["volume_id"] = vol.ID - v["delete_on_termination"] = vol.DeleteOnTermination - extVolumes = append(extVolumes, v) - } - - if err := d.Set("volume", schema.NewSet(volumeUniqueID, extVolumes)); err != nil { - return diag.FromErr(err) - } - - ifs, err := instances.ListInterfacesAll(client, instance.ID) - log.Printf("instance data source interfaces: %+v", ifs) - if err != nil { - return diag.FromErr(err) - } - var cleanInterfaces []interface{} - for _, iface := range ifs { - if len(iface.IPAssignments) == 0 { - continue - } - - for _, assignment := range iface.IPAssignments { - subnetID := assignment.SubnetID - - i := make(map[string]interface{}) - - i["network_id"] = iface.NetworkID - i["subnet_id"] = subnetID - i["port_id"] = iface.PortID - i["ip_address"] = iface.IPAssignments[0].IPAddress.String() - - cleanInterfaces = append(cleanInterfaces, i) - } - } - if err := d.Set("interface", cleanInterfaces); err != nil { - return diag.FromErr(err) - } - - sliced := make([]map[string]interface{}, 0, len(instance.Metadata)) - for k, data := range instance.Metadata { - mdata := make(map[string]interface{}, 2) - mdata["key"] = k - mdata["value"] = data - sliced = append(sliced, mdata) - } - if err := d.Set("metadata", sliced); err != nil { - return diag.FromErr(err) - } - - secGrps := make([]map[string]interface{}, 0, len(instance.SecurityGroups)) - for _, sg := range instance.SecurityGroups { - i := make(map[string]interface{}) - i["name"] = sg.Name - secGrps = append(secGrps, i) - } - if err := d.Set("security_group", secGrps); err != nil { - return diag.FromErr(err) - } - - addresses := []map[string][]map[string]string{} - for _, data := range instance.Addresses { - d := map[string][]map[string]string{} - netd := make([]map[string]string, len(data)) - for i, iaddr := range data { - ndata := make(map[string]string, 2) - ndata["type"] = iaddr.Type.String() - ndata["addr"] = iaddr.Address.String() - netd[i] = ndata - } - d["net"] = netd - addresses = append(addresses, d) - } - if err := d.Set("addresses", addresses); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish Instance reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_k8s.go b/edgecenter/data_source_edgecenter_k8s.go deleted file mode 100644 index 11b392d2..00000000 --- a/edgecenter/data_source_edgecenter_k8s.go +++ /dev/null @@ -1,330 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/clusters" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/pools" -) - -func dataSourceK8s() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceK8sRead, - Description: "Represent k8s cluster with one default pool.", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "cluster_id": { - Type: schema.TypeString, - Required: true, - Description: "The uuid of the Kubernetes cluster.", - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: "The name of the Kubernetes cluster.", - }, - "fixed_network": { - Type: schema.TypeString, - Computed: true, - Description: "Fixed network (uuid) associated with the Kubernetes cluster.", - }, - "fixed_subnet": { - Type: schema.TypeString, - Computed: true, - Description: "Subnet (uuid) associated with the fixed network.", - }, - "auto_healing_enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Indicates whether auto-healing is enabled for the Kubernetes cluster.", - }, - "master_lb_floating_ip_enabled": { - Type: schema.TypeBool, - Computed: true, - Description: "Flag indicating if the master LoadBalancer should have a floating IP.", - }, - "keypair": { - Type: schema.TypeString, - Computed: true, - }, - "pool": { - Type: schema.TypeList, - Computed: true, - Description: "Configuration details of the node pool in the Kubernetes cluster.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Computed: true, - }, - "flavor_id": { - Type: schema.TypeString, - Computed: true, - }, - "min_node_count": { - Type: schema.TypeInt, - Computed: true, - }, - "max_node_count": { - Type: schema.TypeInt, - Computed: true, - }, - "node_count": { - Type: schema.TypeInt, - Computed: true, - }, - "docker_volume_type": { - Type: schema.TypeString, - Computed: true, - }, - "docker_volume_size": { - Type: schema.TypeInt, - Computed: true, - }, - "uuid": { - Type: schema.TypeString, - Computed: true, - }, - "stack_id": { - Type: schema.TypeString, - Computed: true, - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "node_count": { - Type: schema.TypeInt, - Computed: true, - Description: "Total number of nodes in the Kubernetes cluster.", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the Kubernetes cluster.", - }, - "status_reason": { - Type: schema.TypeString, - Computed: true, - Description: "The reason for the current status of the Kubernetes cluster, if ERROR.", - }, - "master_addresses": { - Type: schema.TypeList, - Computed: true, - Description: "List of IP addresses for master nodes in the Kubernetes cluster.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "node_addresses": { - Type: schema.TypeList, - Computed: true, - Description: "List of IP addresses for worker nodes in the Kubernetes cluster.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "container_version": { - Type: schema.TypeString, - Computed: true, - Description: "The container runtime version used in the Kubernetes cluster.", - }, - "api_address": { - Type: schema.TypeString, - Computed: true, - Description: "API endpoint address for the Kubernetes cluster.", - }, - "user_id": { - Type: schema.TypeString, - Computed: true, - Description: "User identifier associated with the Kubernetes cluster.", - }, - "discovery_url": { - Type: schema.TypeString, - Computed: true, - Description: "URL used for node discovery within the Kubernetes cluster.", - }, - "health_status": { - Type: schema.TypeString, - Computed: true, - Description: "Overall health status of the Kubernetes cluster.", - }, - "health_status_reason": { - Type: schema.TypeMap, - Computed: true, - }, - "faults": { - Type: schema.TypeMap, - Computed: true, - }, - "master_flavor_id": { - Type: schema.TypeString, - Computed: true, - Description: "Identifier for the master node flavor in the Kubernetes cluster.", - }, - "cluster_template_id": { - Type: schema.TypeString, - Computed: true, - Description: "Template identifier from which the Kubernetes cluster was instantiated.", - }, - "version": { - Type: schema.TypeString, - Computed: true, - Description: "The version of the Kubernetes cluster.", - }, - "updated_at": { - Type: schema.TypeString, - Computed: true, - Description: "The timestamp when the Kubernetes cluster was updated.", - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - Description: "The timestamp when the Kubernetes cluster was created.", - }, - "certificate_authority_data": { - Type: schema.TypeString, - Computed: true, - Description: "The certificate_authority_data field from the Kubernetes cluster config.", - }, - }, - } -} - -func dataSourceK8sRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - clusterID := d.Get("cluster_id").(string) - cluster, err := clusters.Get(client, clusterID).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.SetId(cluster.UUID) - - d.Set("name", cluster.Name) - d.Set("fixed_network", cluster.FixedNetwork) - d.Set("fixed_subnet", cluster.FixedSubnet) - d.Set("master_lb_floating_ip_enabled", cluster.FloatingIPEnabled) - d.Set("keypair", cluster.KeyPair) - d.Set("node_count", cluster.NodeCount) - d.Set("status", cluster.Status) - d.Set("status_reason", cluster.StatusReason) - - masterAddresses := make([]string, len(cluster.MasterAddresses)) - for i, addr := range cluster.MasterAddresses { - masterAddresses[i] = addr.String() - } - if err := d.Set("master_addresses", masterAddresses); err != nil { - return diag.FromErr(err) - } - - nodeAddresses := make([]string, len(cluster.NodeAddresses)) - for i, addr := range cluster.NodeAddresses { - nodeAddresses[i] = addr.String() - } - if err := d.Set("node_addresses", nodeAddresses); err != nil { - return diag.FromErr(err) - } - - d.Set("container_version", cluster.ContainerVersion) - d.Set("api_address", cluster.APIAddress.String()) - d.Set("user_id", cluster.UserID) - d.Set("discovery_url", cluster.DiscoveryURL.String()) - - d.Set("health_status", cluster.HealthStatus) - if err := d.Set("health_status_reason", cluster.HealthStatusReason); err != nil { - return diag.FromErr(err) - } - - if err := d.Set("faults", cluster.Faults); err != nil { - return diag.FromErr(err) - } - - d.Set("master_flavor_id", cluster.MasterFlavorID) - d.Set("cluster_template_id", cluster.ClusterTemplateID) - d.Set("version", cluster.Version) - d.Set("updated_at", cluster.UpdatedAt.Format(time.RFC850)) - d.Set("created_at", cluster.CreatedAt.Format(time.RFC850)) - - var pool pools.ClusterPool - for _, p := range cluster.Pools { - if p.IsDefault { - pool = p - } - } - - p := make(map[string]interface{}) - p["uuid"] = pool.UUID - p["name"] = pool.Name - p["flavor_id"] = pool.FlavorID - p["min_node_count"] = pool.MinNodeCount - p["max_node_count"] = pool.MaxNodeCount - p["node_count"] = pool.NodeCount - p["docker_volume_type"] = pool.DockerVolumeType.String() - p["docker_volume_size"] = pool.DockerVolumeSize - p["stack_id"] = pool.StackID - p["created_at"] = pool.CreatedAt.Format(time.RFC850) - - if err := d.Set("pool", []interface{}{p}); err != nil { - return diag.FromErr(err) - } - - getConfigResult, err := clusters.GetConfig(client, clusterID).Extract() - if err != nil { - return diag.FromErr(err) - } - - clusterConfig, err := parseK8sConfig(getConfigResult.Config) - if err != nil { - return diag.Errorf("failed to parse k8s config: %s", err) - } - - certificateAuthorityData := clusterConfig.Clusters[0].Cluster.CertificateAuthorityData - if err := d.Set("certificate_authority_data", certificateAuthorityData); err != nil { - return diag.Errorf("couldn't get certificate_authority_data: %s", err) - } - - log.Println("[DEBUG] Finish K8s reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_k8s_client_config.go b/edgecenter/data_source_edgecenter_k8s_client_config.go deleted file mode 100644 index 83aa7dcb..00000000 --- a/edgecenter/data_source_edgecenter_k8s_client_config.go +++ /dev/null @@ -1,99 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/clusters" -) - -func dataSourceK8sClientConfig() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceK8sReadClientConfig, - Description: "Represent k8s cluster with one default pool.", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "cluster_id": { - Type: schema.TypeString, - Required: true, - Description: "The uuid of the Kubernetes cluster.", - }, - "client_certificate_data": { - Type: schema.TypeString, - Computed: true, - Description: "The client_certificate_data field from k8s config.", - }, - "client_key_data": { - Type: schema.TypeString, - Computed: true, - Description: "The client_key_data field from k8s config.", - }, - }, - } -} - -func dataSourceK8sReadClientConfig(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s client config reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - clusterID := d.Get("cluster_id").(string) - - d.SetId(clusterID) - - getConfigResult, err := clusters.GetConfig(client, clusterID).Extract() - if err != nil { - return diag.FromErr(err) - } - - clusterConfig, err := parseK8sConfig(getConfigResult.Config) - if err != nil { - return diag.Errorf("failed to parse k8s config: %s", err) - } - - clientCertificateData := clusterConfig.Users[0].User.ClientCertificateData - if err := d.Set("client_certificate_data", clientCertificateData); err != nil { - return diag.Errorf("couldn't get client_certificate_data: %s", err) - } - - clientKeyData := clusterConfig.Users[0].User.ClientKeyData - if err := d.Set("client_key_data", clientKeyData); err != nil { - return diag.Errorf("couldn't get client_key_data: %s", err) - } - - log.Println("[DEBUG] Finish K8s client config reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_k8s_pool.go b/edgecenter/data_source_edgecenter_k8s_pool.go deleted file mode 100644 index 9ac6255b..00000000 --- a/edgecenter/data_source_edgecenter_k8s_pool.go +++ /dev/null @@ -1,175 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/pools" -) - -func dataSourceK8sPool() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceK8sPoolRead, - Description: "Represent k8s cluster's pool.", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "pool_id": { - Type: schema.TypeString, - Required: true, - Description: "The uuid of the Kubernetes pool within the cluster.", - }, - "cluster_id": { - Type: schema.TypeString, - Required: true, - Description: "The uuid of the Kubernetes cluster this pool belongs to.", - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: "The name of the Kubernetes pool.", - }, - "is_default": { - Type: schema.TypeBool, - Computed: true, - Description: "Indicates whether this pool is the default pool in the cluster.", - }, - "flavor_id": { - Type: schema.TypeString, - Computed: true, - Description: "The identifier of the flavor used for nodes in this pool.", - }, - "min_node_count": { - Type: schema.TypeInt, - Computed: true, - Description: "The minimum number of nodes in the pool.", - }, - "max_node_count": { - Type: schema.TypeInt, - Computed: true, - Description: "The maximum number of nodes the pool can scale to.", - }, - "node_count": { - Type: schema.TypeInt, - Computed: true, - Description: "The current number of nodes in the pool.", - }, - "docker_volume_type": { - Type: schema.TypeString, - Computed: true, - Description: "The type of volume used for the Docker containers. Available values are 'standard', 'ssd_hiiops', 'cold', and 'ultra'.", - }, - "docker_volume_size": { - Type: schema.TypeInt, - Computed: true, - Description: "The size of the volume used for Docker containers, in gigabytes.", - }, - "stack_id": { - Type: schema.TypeString, - Computed: true, - Description: "The identifier of the underlying infrastructure stack used by this pool.", - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - Description: "The timestamp when the Kubernetes pool was created.", - }, - "node_addresses": { - Type: schema.TypeList, - Computed: true, - Description: "A list of IP addresses of nodes within the pool.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "node_names": { - Type: schema.TypeList, - Computed: true, - Description: "A list of names of nodes within the pool.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - }, - } -} - -func dataSourceK8sPoolRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s pool reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - clusterID := d.Get("cluster_id").(string) - poolID := d.Get("pool_id").(string) - - pool, err := pools.Get(client, clusterID, poolID).Extract() - if err != nil { - return diag.FromErr(err) - } - d.SetId(pool.UUID) - - d.Set("name", pool.Name) - d.Set("cluster_id", clusterID) - d.Set("is_default", pool.IsDefault) - d.Set("flavor_id", pool.FlavorID) - d.Set("min_node_count", pool.MinNodeCount) - d.Set("max_node_count", pool.MaxNodeCount) - d.Set("node_count", pool.NodeCount) - d.Set("docker_volume_type", pool.DockerVolumeType.String()) - d.Set("docker_volume_size", pool.DockerVolumeSize) - d.Set("stack_id", pool.StackID) - d.Set("created_at", pool.CreatedAt.Format(time.RFC850)) - - nodeAddresses := make([]string, len(pool.NodeAddresses)) - for i, na := range pool.NodeAddresses { - nodeAddresses[i] = na.String() - } - d.Set("node_addresses", nodeAddresses) - - poolInstances, err := pools.InstancesAll(client, clusterID, poolID) - if err != nil { - return diag.FromErr(err) - } - - nodeNames := make([]string, len(poolInstances)) - for j, instance := range poolInstances { - nodeNames[j] = instance.Name - } - d.Set("node_names", nodeNames) - - log.Println("[DEBUG] Finish K8s pool reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_lblistener.go b/edgecenter/data_source_edgecenter_lblistener.go deleted file mode 100644 index 3ef96f4b..00000000 --- a/edgecenter/data_source_edgecenter_lblistener.go +++ /dev/null @@ -1,132 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/listeners" -) - -func dataSourceLBListener() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceLBListenerRead, - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the load balancer listener.", - }, - "loadbalancer_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The uuid for the load balancer.", - }, - "protocol": { - Type: schema.TypeString, - Computed: true, - Description: "Available values is 'HTTP', 'HTTPS', 'TCP', 'UDP'", - }, - "protocol_port": { - Type: schema.TypeInt, - Computed: true, - Description: "The port on which the protocol is bound.", - }, - "pool_count": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of pools associated with the load balancer.", - }, - "operating_status": { - Type: schema.TypeString, - Computed: true, - Description: "The current operational status of the load balancer.", - }, - "provisioning_status": { - Type: schema.TypeString, - Computed: true, - Description: "The current provisioning status of the load balancer.", - }, - }, - } -} - -func dataSourceLBListenerRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBListener reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBListenersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - var opts listeners.ListOpts - name := d.Get("name").(string) - lbID := d.Get("loadbalancer_id").(string) - if lbID != "" { - opts.LoadBalancerID = &lbID - } - - ls, err := listeners.ListAll(client, opts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var lb listeners.Listener - for _, l := range ls { - if l.Name == name { - lb = l - found = true - break - } - } - - if !found { - return diag.Errorf("lb listener with name %s not found", name) - } - - d.SetId(lb.ID) - d.Set("name", lb.Name) - d.Set("protocol", lb.Protocol.String()) - d.Set("protocol_port", lb.ProtocolPort) - d.Set("pool_count", lb.PoolCount) - d.Set("operating_status", lb.OperationStatus.String()) - d.Set("provisioning_status", lb.ProvisioningStatus.String()) - d.Set("loadbalancer_id", lbID) - d.Set("project_id", d.Get("project_id").(int)) - d.Set("region_id", d.Get("region_id").(int)) - - log.Println("[DEBUG] Finish LBListener reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_lbpool.go b/edgecenter/data_source_edgecenter_lbpool.go deleted file mode 100644 index 50e83634..00000000 --- a/edgecenter/data_source_edgecenter_lbpool.go +++ /dev/null @@ -1,240 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/lbpools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" -) - -func dataSourceLBPool() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceLBPoolRead, - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the load balancer pool.", - }, - "lb_algorithm": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Available values is '%s', '%s', '%s', '%s'", types.LoadBalancerAlgorithmRoundRobin, types.LoadBalancerAlgorithmLeastConnections, types.LoadBalancerAlgorithmSourceIP, types.LoadBalancerAlgorithmSourceIPPort), - }, - "protocol": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Available values is '%s' (currently work, other do not work on ed-8), '%s', '%s', '%s'", types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS, types.ProtocolTypeTCP, types.ProtocolTypeUDP), - }, - "loadbalancer_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The uuid for the load balancer.", - }, - "listener_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The uuid for the load balancer listener.", - }, - "health_monitor": { - Type: schema.TypeList, - Computed: true, - Description: `Configuration for health checks to test the health and state of the backend members. -It determines how the load balancer identifies whether the backend members are healthy or unhealthy.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Available values is '%s', '%s', '%s', '%s', '%s', '%s", types.HealthMonitorTypeHTTP, types.HealthMonitorTypeHTTPS, types.HealthMonitorTypePING, types.HealthMonitorTypeTCP, types.HealthMonitorTypeTLSHello, types.HealthMonitorTypeUDPConnect), - }, - "delay": { - Type: schema.TypeInt, - Computed: true, - }, - "max_retries": { - Type: schema.TypeInt, - Computed: true, - }, - "timeout": { - Type: schema.TypeInt, - Computed: true, - }, - "max_retries_down": { - Type: schema.TypeInt, - Computed: true, - }, - "http_method": { - Type: schema.TypeString, - Computed: true, - }, - "url_path": { - Type: schema.TypeString, - Computed: true, - }, - "expected_codes": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "session_persistence": { - Type: schema.TypeList, - Computed: true, - Description: `Configuration that enables the load balancer to bind a user's session to a specific backend member. -This ensures that all requests from the user during the session are sent to the same member.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Computed: true, - }, - "cookie_name": { - Type: schema.TypeString, - Computed: true, - }, - "persistence_granularity": { - Type: schema.TypeString, - Computed: true, - }, - "persistence_timeout": { - Type: schema.TypeInt, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceLBPoolRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBPool reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - var opts lbpools.ListOpts - name := d.Get("name").(string) - lbID := d.Get("loadbalancer_id").(string) - if lbID != "" { - opts.LoadBalancerID = &lbID - } - lID := d.Get("listener_id").(string) - if lbID != "" { - opts.ListenerID = &lID - } - - pools, err := lbpools.ListAll(client, opts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var lb lbpools.Pool - for _, p := range pools { - if p.Name == name { - lb = p - found = true - break - } - } - - if !found { - return diag.Errorf("lb listener with name %s not found", name) - } - - d.SetId(lb.ID) - d.Set("name", lb.Name) - d.Set("lb_algorithm", lb.LoadBalancerAlgorithm.String()) - d.Set("protocol", lb.Protocol.String()) - - if len(lb.LoadBalancers) > 0 { - d.Set("loadbalancer_id", lb.LoadBalancers[0].ID) - } - - if len(lb.Listeners) > 0 { - d.Set("listener_id", lb.Listeners[0].ID) - } - - if lb.HealthMonitor != nil { - healthMonitor := map[string]interface{}{ - "id": lb.HealthMonitor.ID, - "type": lb.HealthMonitor.Type.String(), - "delay": lb.HealthMonitor.Delay, - "timeout": lb.HealthMonitor.Timeout, - "max_retries": lb.HealthMonitor.MaxRetries, - "max_retries_down": lb.HealthMonitor.MaxRetriesDown, - "url_path": lb.HealthMonitor.URLPath, - "expected_codes": lb.HealthMonitor.ExpectedCodes, - } - if lb.HealthMonitor.HTTPMethod != nil { - healthMonitor["http_method"] = lb.HealthMonitor.HTTPMethod.String() - } - - if err := d.Set("health_monitor", []interface{}{healthMonitor}); err != nil { - return diag.FromErr(err) - } - } - - if lb.SessionPersistence != nil { - sessionPersistence := map[string]interface{}{ - "type": lb.SessionPersistence.Type.String(), - "cookie_name": lb.SessionPersistence.CookieName, - "persistence_granularity": lb.SessionPersistence.PersistenceGranularity, - "persistence_timeout": lb.SessionPersistence.PersistenceTimeout, - } - - if err := d.Set("session_persistence", []interface{}{sessionPersistence}); err != nil { - return diag.FromErr(err) - } - } - - d.Set("project_id", d.Get("project_id").(int)) - d.Set("region_id", d.Get("region_id").(int)) - - log.Println("[DEBUG] Finish LBPool reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_loadbalancer.go b/edgecenter/data_source_edgecenter_loadbalancer.go deleted file mode 100644 index 7c1c3195..00000000 --- a/edgecenter/data_source_edgecenter_loadbalancer.go +++ /dev/null @@ -1,205 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/listeners" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/loadbalancers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" -) - -func dataSourceLoadBalancer() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceLoadBalancerRead, - DeprecationMessage: "!> **WARNING:** This data-source is deprecated and will be removed in the next major version. Use edgecenter_loadbalancerv2 data-source instead", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the router.", - }, - "metadata_k": { - Type: schema.TypeString, - Optional: true, - Description: "Filtration query opts (only key).", - }, - "metadata_kv": { - Type: schema.TypeMap, - Optional: true, - Description: `Filtration query opts, for example, {offset = "10", limit = "10"}`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "vip_address": { - Type: schema.TypeString, - Computed: true, - }, - "vip_port_id": { - Type: schema.TypeString, - Computed: true, - }, - "listener": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Computed: true, - }, - "protocol": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Available values is '%s' (currently work, other do not work on ed-8), '%s', '%s', '%s'", types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS, types.ProtocolTypeTCP, types.ProtocolTypeUDP), - }, - "protocol_port": { - Type: schema.TypeInt, - Computed: true, - }, - }, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceLoadBalancerRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LoadBalancer reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LoadBalancersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - name := d.Get("name").(string) - metaOpts := &loadbalancers.ListOpts{} - - if metadataK, ok := d.GetOk("metadata_k"); ok { - metaOpts.MetadataK = metadataK.(string) - } - - if metadataRaw, ok := d.GetOk("metadata_kv"); ok { - meta, err := utils.MapInterfaceToMapString(metadataRaw) - if err != nil { - return diag.FromErr(err) - } - metaOpts.MetadataKV = meta - } - - lbs, err := loadbalancers.ListAll(client, *metaOpts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var lb loadbalancers.LoadBalancer - for _, l := range lbs { - if l.Name == name { - lb = l - found = true - break - } - } - - if !found { - return diag.Errorf("load balancer with name %s not found", name) - } - - d.SetId(lb.ID) - d.Set("project_id", lb.ProjectID) - d.Set("region_id", lb.RegionID) - d.Set("name", lb.Name) - d.Set("vip_address", lb.VipAddress.String()) - d.Set("vip_port_id", lb.VipPortID) - - metadataReadOnly := PrepareMetadataReadonly(lb.Metadata) - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - listenersClient, err := CreateClient(provider, d, LBListenersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - newListeners := make([]map[string]interface{}, len(lb.Listeners)) - for i, l := range lb.Listeners { - listener, err := listeners.Get(listenersClient, l.ID).Extract() - if err != nil { - return diag.FromErr(err) - } - - newListeners[i] = map[string]interface{}{ - "id": listener.ID, - "name": listener.Name, - "protocol": listener.Protocol.String(), - "protocol_port": listener.ProtocolPort, - } - } - if err := d.Set("listener", newListeners); err != nil { - diag.FromErr(err) - } - - log.Println("[DEBUG] Finish LoadBalancer reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_loadbalancerv2.go b/edgecenter/data_source_edgecenter_loadbalancerv2.go deleted file mode 100644 index 9e275685..00000000 --- a/edgecenter/data_source_edgecenter_loadbalancerv2.go +++ /dev/null @@ -1,185 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/loadbalancers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" -) - -func dataSourceLoadBalancerV2() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceLoadBalancerV2Read, - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the load balancer.", - }, - "metadata_k": { - Type: schema.TypeString, - Optional: true, - Description: "Filtration query opts (only key).", - }, - "metadata_kv": { - Type: schema.TypeMap, - Optional: true, - Description: `Filtration query opts, for example, {offset = "10", limit = "10"}`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "vip_address": { - Type: schema.TypeString, - Computed: true, - Description: "Load balancer IP address", - }, - "vip_port_id": { - Type: schema.TypeString, - Computed: true, - Description: "Attached reserved IP.", - }, - "security_group_id": { - Type: schema.TypeString, - Computed: true, - Description: "Load balancer security group ID", - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceLoadBalancerV2Read(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LoadBalancer reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LoadBalancersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - name := d.Get("name").(string) - - metaOpts := &loadbalancers.ListOpts{} - - if metadataK, ok := d.GetOk("metadata_k"); ok { - metaOpts.MetadataK = metadataK.(string) - } - - if metadataRaw, ok := d.GetOk("metadata_kv"); ok { - meta, err := utils.MapInterfaceToMapString(metadataRaw) - if err != nil { - return diag.FromErr(err) - } - metaOpts.MetadataKV = meta - } - - lbs, err := loadbalancers.ListAll(client, *metaOpts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var lb loadbalancers.LoadBalancer - for _, l := range lbs { - if l.Name == name { - lb = l - found = true - break - } - } - - if !found { - return diag.Errorf("load balancer with name %s not found", name) - } - - d.SetId(lb.ID) - d.Set("project_id", lb.ProjectID) - d.Set("region_id", lb.RegionID) - d.Set("name", lb.Name) - d.Set("vip_address", lb.VipAddress.String()) - d.Set("vip_port_id", lb.VipPortID) - - metadataList, err := metadata.ResourceMetadataListAll(client, d.Id()) - if err != nil { - return diag.FromErr(err) - } - - metadataReadOnly := make([]map[string]interface{}, 0, len(metadataList)) - if len(metadataList) > 0 { - for _, metadataItem := range metadataList { - metadataReadOnly = append(metadataReadOnly, map[string]interface{}{ - "key": metadataItem.Key, - "value": metadataItem.Value, - "read_only": metadataItem.ReadOnly, - }) - } - } - - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - sgInfo, err := loadbalancers.ListCustomSecurityGroup(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - if len(sgInfo) > 0 { - d.Set("security_group_id", sgInfo[0].ID) - } - - log.Println("[DEBUG] Finish LoadBalancer reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_network.go b/edgecenter/data_source_edgecenter_network.go deleted file mode 100644 index 63f4e216..00000000 --- a/edgecenter/data_source_edgecenter_network.go +++ /dev/null @@ -1,278 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/availablenetworks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" -) - -func dataSourceNetwork() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceNetworkRead, - Description: "Represent network. A network is a software-defined network in a cloud computing infrastructure", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the network.", - }, - "shared_with_subnets": { - Type: schema.TypeBool, - Optional: true, - Description: "Get shared networks with details of subnets.", - }, - "mtu": { - Type: schema.TypeInt, - Computed: true, - Description: "Maximum Transmission Unit (MTU) for the network. It determines the maximum packet size that can be transmitted without fragmentation.", - }, - "type": { - Type: schema.TypeString, - Computed: true, - Description: "'vlan' or 'vxlan' network type is allowed. Default value is 'vxlan'", - }, - "external": { - Type: schema.TypeBool, - Computed: true, - }, - "shared": { - Type: schema.TypeBool, - Computed: true, - }, - "subnets": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - Description: "The ID of the subnet.", - }, - "name": { - Type: schema.TypeString, - Computed: true, - Description: "The name of the subnet.", - }, - "available_ips": { - Type: schema.TypeInt, - Computed: true, - Description: "The number of available IPs in the subnet.", - }, - "total_ips": { - Type: schema.TypeInt, - Computed: true, - Description: "The total number of IPs in the subnet.", - }, - "enable_dhcp": { - Type: schema.TypeBool, - Computed: true, - Description: "Enable DHCP for this subnet. If true, DHCP will be used to assign IP addresses to instances within this subnet.", - }, - "has_router": { - Type: schema.TypeBool, - Computed: true, - Description: "Indicates whether the subnet has a router attached to it.", - }, - "cidr": { - Type: schema.TypeString, - Computed: true, - Description: "Represents the IP address range of the subnet.", - }, - "dns_nameservers": { - Type: schema.TypeList, - Computed: true, - Description: "List of DNS name servers for the subnet.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "host_routes": { - Type: schema.TypeList, - Computed: true, - Description: "List of additional routes to be added to instances that are part of this subnet.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "destination": { - Type: schema.TypeString, - Computed: true, - }, - "nexthop": { - Type: schema.TypeString, - Computed: true, - Description: "IPv4 address to forward traffic to if it's destination IP matches 'destination' CIDR", - }, - }, - }, - }, - "gateway_ip": { - Type: schema.TypeString, - Computed: true, - Description: "The IP address of the gateway for this subnet.", - }, - }, - }, - }, - "metadata_k": { - Type: schema.TypeString, - Optional: true, - Description: "Filtration query opts (only key).", - }, - "metadata_kv": { - Type: schema.TypeMap, - Optional: true, - Description: `Filtration query opts, for example, {offset = "10", limit = "10"}`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceNetworkRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Network reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, NetworksPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - clientShared, err := CreateClient(provider, d, SharedNetworksPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - name := d.Get("name").(string) - metaOpts := &networks.ListOpts{} - - if metadataK, ok := d.GetOk("metadata_k"); ok { - metaOpts.MetadataK = metadataK.(string) - } - - if metadataRaw, ok := d.GetOk("metadata_kv"); ok { - typedMetadataKV := make(map[string]string, len(metadataRaw.(map[string]interface{}))) - for k, v := range metadataRaw.(map[string]interface{}) { - typedMetadataKV[k] = v.(string) - } - metaOpts.MetadataKV = typedMetadataKV - } - - var ( - withDetails = d.Get("shared_with_subnets").(bool) - rawNetwork map[string]interface{} - subs []subnets.Subnet - meta []metadata.Metadata - ) - - if !withDetails { - nets, err := networks.ListAll(client, *metaOpts) - if err != nil { - return diag.FromErr(err) - } - network, found := findNetworkByName(name, nets) - if !found { - return diag.Errorf("network with name %s not found. you can try to set 'shared_with_subnets' parameter", name) - } - meta = network.Metadata - rawNetwork, err = StructToMap(network) - if err != nil { - return diag.FromErr(err) - } - } else { - nets, err := availablenetworks.ListAll(clientShared, nil) - if err != nil { - return diag.FromErr(err) - } - sharedNetwork, found := findSharedNetworkByName(name, nets) - if !found { - return diag.Errorf("shared network with name %s not found", name) - } - subs = sharedNetwork.Subnets - rawNetwork, err = StructToMap(sharedNetwork) - if err != nil { - return diag.FromErr(err) - } - } - - d.SetId(rawNetwork["id"].(string)) - d.Set("name", rawNetwork["name"]) - d.Set("mtu", rawNetwork["mtu"]) - d.Set("type", rawNetwork["type"]) - d.Set("region_id", rawNetwork["region_id"]) - d.Set("project_id", rawNetwork["project_id"]) - d.Set("external", rawNetwork["external"]) - d.Set("shared", rawNetwork["shared"]) - if withDetails { - if len(subs) > 0 { - if err := d.Set("subnets", prepareSubnets(subs)); err != nil { - return diag.FromErr(err) - } - } - } else { - metadataReadOnly := PrepareMetadataReadonly(meta) - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - } - - log.Println("[DEBUG] Finish Network reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_project.go b/edgecenter/data_source_edgecenter_project.go deleted file mode 100644 index faac615d..00000000 --- a/edgecenter/data_source_edgecenter_project.go +++ /dev/null @@ -1,42 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - "strconv" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -func dataSourceProject() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceProjectRead, - Description: "Represent project data", - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Description: "Displayed project name", - Required: true, - }, - }, - } -} - -func dataSourceProjectRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Project reading") - name := d.Get("name").(string) - config := m.(*Config) - provider := config.Provider - projectID, err := GetProject(provider, 0, name) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(strconv.Itoa(projectID)) - d.Set("name", name) - - log.Println("[DEBUG] Finish Project reading") - - return nil -} diff --git a/edgecenter/data_source_edgecenter_region.go b/edgecenter/data_source_edgecenter_region.go deleted file mode 100644 index dd6494cb..00000000 --- a/edgecenter/data_source_edgecenter_region.go +++ /dev/null @@ -1,43 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - "strconv" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -func dataSourceRegion() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceRegionRead, - Description: "Represent region data", - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Description: "Displayed region name", - Required: true, - }, - }, - } -} - -func dataSourceRegionRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Region reading") - - name := d.Get("name").(string) - config := m.(*Config) - provider := config.Provider - regionID, err := GetRegion(provider, 0, name) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(strconv.Itoa(regionID)) - d.Set("name", name) - - log.Println("[DEBUG] Finish Region reading") - - return nil -} diff --git a/edgecenter/data_source_edgecenter_reservedfixedip.go b/edgecenter/data_source_edgecenter_reservedfixedip.go deleted file mode 100644 index d425b806..00000000 --- a/edgecenter/data_source_edgecenter_reservedfixedip.go +++ /dev/null @@ -1,163 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "net" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/reservedfixedip/v1/reservedfixedips" -) - -func dataSourceReservedFixedIP() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceReservedFixedIPRead, - Description: "Represent reserved ips", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "fixed_ip_address": { - Type: schema.TypeString, - Required: true, - Description: "The IP address that is associated with the reserved IP.", - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - ip := net.ParseIP(v) - if ip != nil { - return diag.Diagnostics{} - } - - return diag.FromErr(fmt.Errorf("%q must be a valid ip, got: %s", key, v)) - }, - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the reserved fixed IP.", - }, - "subnet_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the subnet from which the fixed IP should be reserved.", - }, - "network_id": { - Type: schema.TypeString, - Computed: true, - Description: "ID of the network to which the reserved fixed IP is associated.", - }, - "is_vip": { - Type: schema.TypeBool, - Computed: true, - Description: "Flag to determine if the reserved fixed IP should be treated as a Virtual IP (VIP).", - }, - "port_id": { - Type: schema.TypeString, - Description: "ID of the port_id underlying the reserved fixed IP", - Computed: true, - }, - "allowed_address_pairs": { - Type: schema.TypeList, - Computed: true, - Description: "Group of IP addresses that share the current IP as VIP.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip_address": { - Type: schema.TypeString, - Computed: true, - }, - "mac_address": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceReservedFixedIPRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ReservedFixedIP reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ReservedFixedIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - ipAddr := d.Get("fixed_ip_address").(string) - ips, err := reservedfixedips.ListAll(client, reservedfixedips.ListOpts{}) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var reservedFixedIP reservedfixedips.ReservedFixedIP - for _, ip := range ips { - if ip.FixedIPAddress.String() == ipAddr { - reservedFixedIP = ip - found = true - break - } - } - - if !found { - return diag.Errorf("reserved fixed ip %s not found", ipAddr) - } - - // should we use PortID as id? - d.SetId(reservedFixedIP.PortID) - d.Set("project_id", reservedFixedIP.ProjectID) - d.Set("region_id", reservedFixedIP.RegionID) - d.Set("status", reservedFixedIP.Status) - d.Set("fixed_ip_address", reservedFixedIP.FixedIPAddress.String()) - d.Set("subnet_id", reservedFixedIP.SubnetID) - d.Set("network_id", reservedFixedIP.NetworkID) - d.Set("is_vip", reservedFixedIP.IsVip) - d.Set("port_id", reservedFixedIP.PortID) - - allowedPairs := make([]map[string]interface{}, len(reservedFixedIP.AllowedAddressPairs)) - for i, p := range reservedFixedIP.AllowedAddressPairs { - pair := make(map[string]interface{}) - - pair["ip_address"] = p.IPAddress - pair["mac_address"] = p.MacAddress - - allowedPairs[i] = pair - } - if err := d.Set("allowed_address_pairs", allowedPairs); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish ReservedFixedIP reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_router.go b/edgecenter/data_source_edgecenter_router.go deleted file mode 100644 index f91f9db0..00000000 --- a/edgecenter/data_source_edgecenter_router.go +++ /dev/null @@ -1,220 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/router/v1/routers" -) - -func dataSourceRouter() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceRouterRead, - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the load router.", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the router resource.", - }, - "external_gateway_info": { - Type: schema.TypeList, - Computed: true, - Description: "Information related to the external gateway.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enable_snat": { - Type: schema.TypeBool, - Computed: true, - }, - "network_id": { - Type: schema.TypeString, - Computed: true, - }, - "external_fixed_ips": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip_address": { - Type: schema.TypeString, - Computed: true, - }, - "subnet_id": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - }, - }, - }, - "interfaces": { - Type: schema.TypeList, - Computed: true, - Description: "Set of interfaces associated with the router.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "port_id": { - Type: schema.TypeString, - Computed: true, - }, - "network_id": { - Type: schema.TypeString, - Computed: true, - }, - "mac_address": { - Type: schema.TypeString, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Computed: true, - }, - "ip_address": { - Type: schema.TypeString, - Computed: true, - }, - "subnet_id": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "routes": { - Type: schema.TypeList, - Computed: true, - Description: "List of static routes to be applied to the router.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "destination": { - Type: schema.TypeString, - Computed: true, - }, - "nexthop": { - Type: schema.TypeString, - Computed: true, - Description: "IPv4 address to forward traffic to if it's destination IP matches 'destination' CIDR", - }, - }, - }, - }, - }, - } -} - -func dataSourceRouterRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Router reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, RouterPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - name := d.Get("name").(string) - rs, err := routers.ListAll(client, routers.ListOpts{}) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var router routers.Router - for _, r := range rs { - if r.Name == name { - router = r - found = true - break - } - } - - if !found { - return diag.Errorf("router with name %s not found", name) - } - - d.SetId(router.ID) - d.Set("name", router.Name) - d.Set("status", router.Status) - - if len(router.ExternalGatewayInfo.ExternalFixedIPs) > 0 { - egi := make(map[string]interface{}, 4) - egilst := make([]map[string]interface{}, 1) - egi["enable_snat"] = router.ExternalGatewayInfo.EnableSNat - egi["network_id"] = router.ExternalGatewayInfo.NetworkID - - efip := make([]map[string]string, len(router.ExternalGatewayInfo.ExternalFixedIPs)) - for i, fip := range router.ExternalGatewayInfo.ExternalFixedIPs { - tmpfip := make(map[string]string, 1) - tmpfip["ip_address"] = fip.IPAddress - tmpfip["subnet_id"] = fip.SubnetID - efip[i] = tmpfip - } - egi["external_fixed_ips"] = efip - - egilst[0] = egi - d.Set("external_gateway_info", egilst) - } - - ifs := make([]map[string]interface{}, 0, len(router.Interfaces)) - for _, iface := range router.Interfaces { - for _, subnet := range iface.IPAssignments { - smap := make(map[string]interface{}, 6) - smap["port_id"] = iface.PortID - smap["network_id"] = iface.NetworkID - smap["mac_address"] = iface.MacAddress.String() - smap["type"] = "subnet" - smap["subnet_id"] = subnet.SubnetID - smap["ip_address"] = subnet.IPAddress.String() - ifs = append(ifs, smap) - } - } - d.Set("interfaces", ifs) - - rss := make([]map[string]string, len(router.Routes)) - for i, r := range router.Routes { - rmap := make(map[string]string, 2) - rmap["destination"] = r.Destination.String() - rmap["nexthop"] = r.NextHop.String() - rss[i] = rmap - } - d.Set("routes", rss) - - log.Println("[DEBUG] Finish router reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_secret.go b/edgecenter/data_source_edgecenter_secret.go deleted file mode 100644 index 55ea4484..00000000 --- a/edgecenter/data_source_edgecenter_secret.go +++ /dev/null @@ -1,136 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/secret/v1/secrets" -) - -func dataSourceSecret() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceSecretRead, - Description: "Represent secret", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the secret.", - }, - "algorithm": { - Type: schema.TypeString, - Computed: true, - Description: "The encryption algorithm used for the secret.", - }, - "bit_length": { - Type: schema.TypeInt, - Computed: true, - Description: "The bit length of the encryption algorithm.", - }, - "mode": { - Type: schema.TypeString, - Computed: true, - Description: "The mode of the encryption algorithm.", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the secret.", - }, - "content_types": { - Type: schema.TypeMap, - Computed: true, - Description: "The content types associated with the secret's payload.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "expiration": { - Type: schema.TypeString, - Description: "Datetime when the secret will expire. The format is 2025-12-28T19:14:44.180394", - Computed: true, - }, - "created": { - Type: schema.TypeString, - Description: "Datetime when the secret was created. The format is 2025-12-28T19:14:44.180394", - Computed: true, - }, - }, - } -} - -func dataSourceSecretRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start secret reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - secretID := d.Id() - log.Printf("[DEBUG] Secret id = %s", secretID) - - client, err := CreateClient(provider, d, SecretPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - allSecrets, err := secrets.ListAll(client) - if err != nil { - return diag.Errorf("cannot get secrets. Error: %s", err.Error()) - } - - var found bool - name := d.Get("name").(string) - for _, secret := range allSecrets { - if name == secret.Name { - d.SetId(secret.ID) - d.Set("name", name) - d.Set("algorithm", secret.Algorithm) - d.Set("bit_length", secret.BitLength) - d.Set("mode", secret.Mode) - d.Set("status", secret.Status) - d.Set("expiration", secret.Expiration.Format(edgecloud.RFC3339ZColon)) - d.Set("created", secret.CreatedAt.Format(edgecloud.RFC3339ZColon)) - if err := d.Set("content_types", secret.ContentTypes); err != nil { - return diag.FromErr(err) - } - found = true - - break - } - } - - if !found { - return diag.Errorf("secret with name %s does not exit", name) - } - - log.Println("[DEBUG] Finish secret reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_securitygroup.go b/edgecenter/data_source_edgecenter_securitygroup.go deleted file mode 100644 index 47ee12d2..00000000 --- a/edgecenter/data_source_edgecenter_securitygroup.go +++ /dev/null @@ -1,259 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "strings" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/securitygroups" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/types" -) - -func dataSourceSecurityGroup() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceSecurityGroupRead, - Description: "Represent SecurityGroups(Firewall)", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the security group.", - }, - "metadata_k": { - Type: schema.TypeString, - Optional: true, - Description: "Filtration query opts (only key).", - }, - "metadata_kv": { - Type: schema.TypeMap, - Optional: true, - Description: `Filtration query opts, for example, {offset = "10", limit = "10"}`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "description": { - Type: schema.TypeString, - Computed: true, - Description: "A detailed description of the security group.", - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - "security_group_rules": { - Type: schema.TypeSet, - Computed: true, - Description: "Firewall rules control what inbound(ingress) and outbound(egress) traffic is allowed to enter or leave a Instance. At least one 'egress' rule should be set", - Set: secGroupUniqueID, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - }, - "direction": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Available value is '%s', '%s'", types.RuleDirectionIngress, types.RuleDirectionEgress), - }, - "ethertype": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Available value is '%s', '%s'", types.EtherTypeIPv4, types.EtherTypeIPv6), - }, - "protocol": { - Type: schema.TypeString, - Computed: true, - Description: fmt.Sprintf("Available value is %s", strings.Join(types.Protocol("").StringList(), ",")), - }, - "port_range_min": { - Type: schema.TypeInt, - Computed: true, - }, - "port_range_max": { - Type: schema.TypeInt, - Computed: true, - }, - "description": { - Type: schema.TypeString, - Computed: true, - }, - "remote_ip_prefix": { - Type: schema.TypeString, - Computed: true, - }, - "updated_at": { - Type: schema.TypeString, - Computed: true, - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceSecurityGroupRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start SecurityGroup reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - name := d.Get("name").(string) - metaOpts := &securitygroups.ListOpts{} - - if metadataK, ok := d.GetOk("metadata_k"); ok { - metaOpts.MetadataK = metadataK.(string) - } - - if metadataRaw, ok := d.GetOk("metadata_kv"); ok { - typedMetadataKV := make(map[string]string, len(metadataRaw.(map[string]interface{}))) - for k, v := range metadataRaw.(map[string]interface{}) { - typedMetadataKV[k] = v.(string) - } - metaOpts.MetadataKV = typedMetadataKV - } - sgs, err := securitygroups.ListAll(client, *metaOpts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var sg securitygroups.SecurityGroup - for _, s := range sgs { - if s.Name == name { - sg = s - found = true - break - } - } - - if !found { - return diag.Errorf("security group with name %s not found", name) - } - - d.SetId(sg.ID) - d.Set("project_id", sg.ProjectID) - d.Set("region_id", sg.RegionID) - d.Set("name", sg.Name) - d.Set("description", sg.Description) - - metadataReadOnly := make([]map[string]interface{}, 0, len(sg.Metadata)) - if len(sg.Metadata) > 0 { - for _, metadataItem := range sg.Metadata { - metadataReadOnly = append(metadataReadOnly, map[string]interface{}{ - "key": metadataItem.Key, - "value": metadataItem.Value, - "read_only": metadataItem.ReadOnly, - }) - } - } - - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - newSgRules := make([]interface{}, len(sg.SecurityGroupRules)) - for i, sgr := range sg.SecurityGroupRules { - r := make(map[string]interface{}) - r["id"] = sgr.ID - r["direction"] = sgr.Direction.String() - - r["ethertype"] = "" - if sgr.EtherType != nil { - r["ethertype"] = sgr.EtherType.String() - } - - r["protocol"] = types.ProtocolAny.String() - if sgr.Protocol != nil { - r["protocol"] = sgr.Protocol.String() - } - - r["port_range_max"] = 65535 - if sgr.PortRangeMax != nil { - r["port_range_max"] = *sgr.PortRangeMax - } - - r["port_range_min"] = 1 - if sgr.PortRangeMin != nil { - r["port_range_min"] = *sgr.PortRangeMin - } - - r["description"] = "" - if sgr.Description != nil { - r["description"] = *sgr.Description - } - - r["remote_ip_prefix"] = "" - if sgr.RemoteIPPrefix != nil { - r["remote_ip_prefix"] = *sgr.RemoteIPPrefix - } - - r["updated_at"] = sgr.UpdatedAt.String() - r["created_at"] = sgr.CreatedAt.String() - - newSgRules[i] = r - } - - if err := d.Set("security_group_rules", schema.NewSet(secGroupUniqueID, newSgRules)); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish SecurityGroup reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_servergroup.go b/edgecenter/data_source_edgecenter_servergroup.go deleted file mode 100644 index f09547c0..00000000 --- a/edgecenter/data_source_edgecenter_servergroup.go +++ /dev/null @@ -1,123 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/servergroup/v1/servergroups" -) - -func dataSourceServerGroup() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceServerGroupRead, - Description: "Represent server group data", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Description: "The name of the server group.", - Required: true, - }, - "policy": { - Type: schema.TypeString, - Description: "Server group policy. Available value is 'affinity', 'anti-affinity'", - Computed: true, - }, - "instances": { - Type: schema.TypeList, - Description: "Instances in this server group", - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "instance_id": { - Type: schema.TypeString, - Computed: true, - }, - "instance_name": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceServerGroupRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ServerGroup reading") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ServerGroupsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - var serverGroup servergroups.ServerGroup - serverGroups, err := servergroups.ListAll(client) - if err != nil { - return diag.FromErr(err) - } - - var found bool - name := d.Get("name").(string) - for _, sg := range serverGroups { - if sg.Name == name { - serverGroup = sg - found = true - break - } - } - - if !found { - return diag.Errorf("server group with name %s not found", name) - } - - d.SetId(serverGroup.ServerGroupID) - d.Set("name", name) - d.Set("project_id", serverGroup.ProjectID) - d.Set("region_id", serverGroup.RegionID) - d.Set("policy", serverGroup.Policy.String()) - - instances := make([]map[string]string, len(serverGroup.Instances)) - for i, instance := range serverGroup.Instances { - rawInstance := make(map[string]string) - rawInstance["instance_id"] = instance.InstanceID - rawInstance["instance_name"] = instance.InstanceName - instances[i] = rawInstance - } - if err := d.Set("instances", instances); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish ServerGroup reading") - - return nil -} diff --git a/edgecenter/data_source_edgecenter_storage_s3.go b/edgecenter/data_source_edgecenter_storage_s3.go deleted file mode 100644 index 1e722527..00000000 --- a/edgecenter/data_source_edgecenter_storage_s3.go +++ /dev/null @@ -1,68 +0,0 @@ -package edgecenter - -import ( - "regexp" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -func dataSourceStorageS3() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - StorageSchemaID: { - Type: schema.TypeInt, - Optional: true, - AtLeastOneOf: []string{ - StorageSchemaID, - StorageSchemaName, - }, - Description: "An id of new storage resource.", - }, - StorageSchemaClientID: { - Type: schema.TypeInt, - Computed: true, - Description: "An client id of new storage resource.", - }, - StorageSchemaName: { - Type: schema.TypeString, - Optional: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - storageName := i.(string) - if !regexp.MustCompile(`^[\w\-]+$`).MatchString(storageName) || len(storageName) > 255 { - return diag.Errorf("storage name can't be empty and can have only letters, numbers, dashes and underscores, it also should be less than 256 symbols") - } - return nil - }, - AtLeastOneOf: []string{ - StorageSchemaID, - StorageSchemaName, - }, - Description: "A name of new storage resource.", - }, - StorageSchemaLocation: { - Type: schema.TypeString, - Computed: true, - Description: "A location of new storage resource. One of (s-dt2)", - }, - StorageSchemaGenerateHTTPEndpoint: { - Type: schema.TypeString, - Computed: true, - Description: "A http s3 entry point for new storage resource.", - }, - StorageSchemaGenerateS3Endpoint: { - Type: schema.TypeString, - Computed: true, - Description: "A s3 endpoint for new storage resource.", - }, - StorageSchemaGenerateEndpoint: { - Type: schema.TypeString, - Computed: true, - Description: "A s3 entry point for new storage resource.", - }, - }, - ReadContext: resourceStorageS3Read, - Description: "Represent s3 storage resource. https://storage.edgecenter.ru/storage/list", - } -} diff --git a/edgecenter/data_source_edgecenter_storage_s3_bucket.go b/edgecenter/data_source_edgecenter_storage_s3_bucket.go deleted file mode 100644 index ca7847eb..00000000 --- a/edgecenter/data_source_edgecenter_storage_s3_bucket.go +++ /dev/null @@ -1,37 +0,0 @@ -package edgecenter - -import ( - "regexp" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -func dataSourceStorageS3Bucket() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - StorageS3BucketSchemaStorageID: { - Type: schema.TypeInt, - Required: true, - Description: "An id of existing storage resource.", - }, - StorageS3BucketSchemaName: { - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - storageName := i.(string) - if !regexp.MustCompile(`^[\w\-]+$`).MatchString(storageName) || - len(storageName) > 63 || - len(storageName) < 3 { - return diag.Errorf("bucket name can't be empty and can have only letters & numbers. it also should be less than 63 symbols") - } - return nil - }, - Description: "A name of storage bucket resource.", - }, - }, - ReadContext: resourceStorageS3BucketRead, - Description: "Represent storage s3 bucket resource.", - } -} diff --git a/edgecenter/data_source_edgecenter_subnet.go b/edgecenter/data_source_edgecenter_subnet.go deleted file mode 100644 index 005e76be..00000000 --- a/edgecenter/data_source_edgecenter_subnet.go +++ /dev/null @@ -1,207 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" -) - -func dataSourceSubnet() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceSubnetRead, - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the subnet.", - }, - "metadata_k": { - Type: schema.TypeString, - Optional: true, - Description: "Filtration query opts (only key).", - }, - "metadata_kv": { - Type: schema.TypeMap, - Optional: true, - Description: `Filtration query opts, for example, {offset = "10", limit = "10"}`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "network_id": { - Type: schema.TypeString, - Computed: true, - Optional: true, - Description: "The ID of the network to which this subnet belongs.", - }, - "enable_dhcp": { - Type: schema.TypeBool, - Computed: true, - Description: "Enable DHCP for this subnet. If true, DHCP will be used to assign IP addresses to instances within this subnet.", - }, - "cidr": { - Type: schema.TypeString, - Computed: true, - Description: "Represents the IP address range of the subnet.", - }, - "connect_to_network_router": { - Type: schema.TypeBool, - Computed: true, - Description: "True if the network's router should get a gateway in this subnet. Must be explicitly 'false' when gateway_ip is null.", - }, - "dns_nameservers": { - Type: schema.TypeList, - Computed: true, - Description: "List of DNS name servers for the subnet.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "host_routes": { - Type: schema.TypeList, - Computed: true, - Description: "List of additional routes to be added to instances that are part of this subnet.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "destination": { - Type: schema.TypeString, - Computed: true, - }, - "nexthop": { - Type: schema.TypeString, - Computed: true, - Description: "IPv4 address to forward traffic to if it's destination IP matches 'destination' CIDR", - }, - }, - }, - }, - "gateway_ip": { - Type: schema.TypeString, - Computed: true, - Description: "The IP address of the gateway for this subnet.", - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceSubnetRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Subnet reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, SubnetPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - name := d.Get("name").(string) - networkID := d.Get("network_id").(string) - subnetsOpts := &subnets.ListOpts{NetworkID: networkID} - - if metadataK, ok := d.GetOk("metadata_k"); ok { - subnetsOpts.MetadataK = metadataK.(string) - } - if metadataRaw, ok := d.GetOk("metadata_kv"); ok { - typedMetadataKV := make(map[string]string, len(metadataRaw.(map[string]interface{}))) - for k, v := range metadataRaw.(map[string]interface{}) { - typedMetadataKV[k] = v.(string) - } - subnetsOpts.MetadataKV = typedMetadataKV - } - - snets, err := subnets.ListAll(client, *subnetsOpts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var subnet subnets.Subnet - for _, sn := range snets { - if sn.Name == name { - subnet = sn - found = true - break - } - } - - if !found { - return diag.Errorf("subnet with name %s not found", name) - } - - d.SetId(subnet.ID) - d.Set("name", subnet.Name) - d.Set("enable_dhcp", subnet.EnableDHCP) - d.Set("cidr", subnet.CIDR.String()) - d.Set("network_id", subnet.NetworkID) - - metadataReadOnly := PrepareMetadataReadonly(subnet.Metadata) - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - d.Set("dns_nameservers", dnsNameserversToStringList(subnet.DNSNameservers)) - d.Set("host_routes", hostRoutesToListOfMaps(subnet.HostRoutes)) - d.Set("region_id", subnet.RegionID) - d.Set("project_id", subnet.ProjectID) - d.Set("gateway_ip", subnet.GatewayIP.String()) - - d.Set("connect_to_network_router", true) - if subnet.GatewayIP == nil { - d.Set("connect_to_network_router", false) - d.Set("gateway_ip", "disable") - } - - log.Println("[DEBUG] Finish Subnet reading") - - return diags -} diff --git a/edgecenter/data_source_edgecenter_volume.go b/edgecenter/data_source_edgecenter_volume.go deleted file mode 100644 index c612a005..00000000 --- a/edgecenter/data_source_edgecenter_volume.go +++ /dev/null @@ -1,156 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" -) - -func dataSourceVolume() *schema.Resource { - return &schema.Resource{ - ReadContext: dataSourceVolumeRead, - Description: `A volume is a detachable block storage device akin to a USB hard drive or SSD, but located remotely in the cloud. -Volumes can be attached to a virtual machine and manipulated like a physical hard drive.`, - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the volume.", - }, - "metadata_k": { - Type: schema.TypeString, - Optional: true, - Description: "Filtration query opts (only key).", - }, - "metadata_kv": { - Type: schema.TypeMap, - Optional: true, - Description: `Filtration query opts, for example, {offset = "10", limit = "10"}`, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - - "size": { - Type: schema.TypeInt, - Computed: true, - Description: "The size of the volume, specified in gigabytes (GB).", - }, - "type_name": { - Type: schema.TypeString, - Computed: true, - Description: "The type of volume to create. Valid values are 'ssd_hiiops', 'standard', 'cold', and 'ultra'. Defaults to 'standard'.", - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func dataSourceVolumeRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Volume reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, VolumesPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - name := d.Get("name").(string) - volumeOpts := &volumes.ListOpts{} - if metadataK, ok := d.GetOk("metadata_k"); ok { - volumeOpts.MetadataK = metadataK.(string) - } - - if metadataRaw, ok := d.GetOk("metadata_kv"); ok { - typedMetadataKV := make(map[string]string, len(metadataRaw.(map[string]interface{}))) - for k, v := range metadataRaw.(map[string]interface{}) { - typedMetadataKV[k] = v.(string) - } - volumeOpts.MetadataKV = typedMetadataKV - } - - vols, err := volumes.ListAll(client, volumeOpts) - if err != nil { - return diag.FromErr(err) - } - - var found bool - var volume volumes.Volume - for _, v := range vols { - if v.Name == name { - volume = v - found = true - break - } - } - - if !found { - return diag.Errorf("volume with name %s not found", name) - } - - d.SetId(volume.ID) - d.Set("name", volume.Name) - d.Set("size", volume.Size) - d.Set("type_name", volume.VolumeType) - d.Set("region_id", volume.RegionID) - d.Set("project_id", volume.ProjectID) - - metadataReadOnly := PrepareMetadataReadonly(volume.Metadata) - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish Volume reading") - - return diags -} diff --git a/edgecenter/floatingip/datasource_floatingip.go b/edgecenter/floatingip/datasource_floatingip.go new file mode 100644 index 00000000..893286b2 --- /dev/null +++ b/edgecenter/floatingip/datasource_floatingip.go @@ -0,0 +1,88 @@ +package floatingip + +import ( + "context" + "fmt" + "net" + + "github.com/hashicorp/go-cty/cty" + "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" + + edgecloud "github.com/Edge-Center/edgecentercloud-go" + "github.com/Edge-Center/edgecentercloud-go/util" + "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter/config" +) + +func DataSourceEdgeCenterFloatingIP() *schema.Resource { + return &schema.Resource{ + ReadContext: dataSourceEdgeCenterFloatingIPRead, + Schema: map[string]*schema.Schema{ + "project_id": { + Type: schema.TypeInt, + Required: true, + Description: "uuid of the project", + }, + "region_id": { + Type: schema.TypeInt, + Required: true, + Description: "uuid of the region", + }, + "id": { + Type: schema.TypeString, + Optional: true, + Description: "floating IP uuid", + ValidateFunc: validation.IsUUID, + ExactlyOneOf: []string{"id", "floating_ip_address"}, + }, + "floating_ip_address": { + Type: schema.TypeString, + Optional: true, + Description: "floating IP address assigned to the resource, must be a valid IP address", + ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { + v := val.(string) + ip := net.ParseIP(v) + if ip != nil { + return diag.Diagnostics{} + } + + return diag.FromErr(fmt.Errorf("%q must be a valid ip, got: %s", key, v)) + }, + ExactlyOneOf: []string{"id", "floating_ip_address"}, + }, + // computed attributes + }, + } +} + +func dataSourceEdgeCenterFloatingIPRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics { + client := meta.(*config.CombinedConfig).EdgeCloudClient() + client.Region = d.Get("region_id").(int) + client.Project = d.Get("project_id").(int) + + var foundFloatingIP *edgecloud.FloatingIP + + if id, ok := d.GetOk("id"); ok { + floatingIP, _, err := client.Floatingips.Get(ctx, id.(string)) + if err != nil { + return diag.FromErr(err) + } + + foundFloatingIP = floatingIP + } else if floatingIPAddress, ok := d.GetOk("floating_ip_address"); ok { + floatingIP, err := util.FloatingIPByIPAddress(ctx, client, floatingIPAddress.(string)) + if err != nil { + return diag.FromErr(err) + } + + foundFloatingIP = floatingIP + } else { + return diag.Errorf("Error: specify either a floating_ip_address or id to lookup the floating ip") + } + + d.SetId(foundFloatingIP.ID) + d.Set("floating_ip_address", foundFloatingIP.FloatingIPAddress) + + return nil +} diff --git a/edgecenter/metadata.go b/edgecenter/metadata.go deleted file mode 100644 index 15b25ed9..00000000 --- a/edgecenter/metadata.go +++ /dev/null @@ -1,39 +0,0 @@ -package edgecenter - -import "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" - -func PrepareMetadata(apiMetadata []metadata.Metadata) (map[string]string, []map[string]interface{}) { - metadataMap := make(map[string]string) - metadataReadOnly := make([]map[string]interface{}, 0, len(apiMetadata)) - - if len(apiMetadata) > 0 { - for _, metadataItem := range apiMetadata { - if !metadataItem.ReadOnly { - metadataMap[metadataItem.Key] = metadataItem.Value - } - metadataReadOnly = append(metadataReadOnly, map[string]interface{}{ - "key": metadataItem.Key, - "value": metadataItem.Value, - "read_only": metadataItem.ReadOnly, - }) - } - } - - return metadataMap, metadataReadOnly -} - -func PrepareMetadataReadonly(apiMetadata []metadata.Metadata) []map[string]interface{} { - metadataReadOnly := make([]map[string]interface{}, 0, len(apiMetadata)) - - if len(apiMetadata) > 0 { - for _, metadataItem := range apiMetadata { - metadataReadOnly = append(metadataReadOnly, map[string]interface{}{ - "key": metadataItem.Key, - "value": metadataItem.Value, - "read_only": metadataItem.ReadOnly, - }) - } - } - - return metadataReadOnly -} diff --git a/edgecenter/provider.go b/edgecenter/provider.go index 0c02bad9..0999ab4d 100644 --- a/edgecenter/provider.go +++ b/edgecenter/provider.go @@ -2,93 +2,24 @@ package edgecenter import ( "context" - "fmt" - "log" - "net/http" - "net/url" - "os" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - dnssdk "github.com/Edge-Center/edgecenter-dns-sdk-go" - storageSDK "github.com/Edge-Center/edgecenter-storage-sdk-go" - cdn "github.com/Edge-Center/edgecentercdn-go" - eccdnProvider "github.com/Edge-Center/edgecentercdn-go/edgecenter/provider" - edgecloud "github.com/Edge-Center/edgecentercloud-go" - ec "github.com/Edge-Center/edgecentercloud-go/edgecenter" -) - -const ( - ProviderOptPermanentToken = "permanent_api_token" - ProviderOptSkipCredsAuthErr = "ignore_creds_auth_error" // nolint: gosec - ProviderOptSingleAPIEndpoint = "api_endpoint" - - LifecyclePolicyResource = "edgecenter_lifecyclepolicy" + "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter/config" + "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter/floatingip" ) +// Provider returns a schema.Provider for Edgecenter. func Provider() *schema.Provider { p := &schema.Provider{ Schema: map[string]*schema.Schema{ - "user_name": { - Type: schema.TypeString, - Optional: true, - // commented because it's broke all tests - // AtLeastOneOf: []string{ProviderOptPermanentToken, "user_name"}, - // RequiredWith: []string{"user_name", "password"}, - Deprecated: fmt.Sprintf("Use %s instead", ProviderOptPermanentToken), - DefaultFunc: schema.EnvDefaultFunc("EC_USERNAME", nil), - }, - "password": { - Type: schema.TypeString, - Optional: true, - // commented because it's broke all tests - // RequiredWith: []string{"user_name", "password"}, - Deprecated: fmt.Sprintf("Use %s instead", ProviderOptPermanentToken), - DefaultFunc: schema.EnvDefaultFunc("EC_PASSWORD", nil), - }, - ProviderOptPermanentToken: { - Type: schema.TypeString, - Optional: true, - // commented because it's broke all tests - // AtLeastOneOf: []string{ProviderOptPermanentToken, "user_name"}, - Sensitive: true, - Description: "A permanent [API-token](https://support.edgecenter.ru/knowledge_base/item/257788)", - DefaultFunc: schema.EnvDefaultFunc("EC_PERMANENT_TOKEN", nil), - }, - ProviderOptSingleAPIEndpoint: { + "api_key": { Type: schema.TypeString, Optional: true, - Description: "A single API endpoint for all products. Will be used when specific product API url is not defined.", - DefaultFunc: schema.EnvDefaultFunc("EC_API_ENDPOINT", "https://api.edgecenter.ru"), - }, - ProviderOptSkipCredsAuthErr: { - Type: schema.TypeBool, - Optional: true, - Deprecated: "It doesn't make any effect anymore", - Description: "Should be set to true when you are gonna to use storage resource with permanent API-token only.", - }, - "edgecenter_platform": { - Type: schema.TypeString, - Optional: true, - Deprecated: "Use edgecenter_platform_api instead", - ConflictsWith: []string{"edgecenter_platform_api"}, - Description: "Platform URL is used for generate JWT", - DefaultFunc: schema.EnvDefaultFunc("EC_PLATFORM", nil), - }, - "edgecenter_platform_api": { - Type: schema.TypeString, - Optional: true, - Description: "Platform URL is used for generate JWT (define only if you want to override Platform API endpoint)", - DefaultFunc: schema.EnvDefaultFunc("EC_PLATFORM_API", nil), - }, - "edgecenter_api": { - Type: schema.TypeString, - Optional: true, - Deprecated: "Use edgecenter_cloud_api instead", - ConflictsWith: []string{"edgecenter_cloud_api"}, - Description: "Region API", - DefaultFunc: schema.EnvDefaultFunc("EC_API", nil), + DefaultFunc: schema.MultiEnvDefaultFunc([]string{"EC_PERMANENT_TOKEN", "API_KEY"}, nil), + Sensitive: true, + Description: "A permanent [API-token](https://support.edgecenter.ru/knowledge_base/item/257788)", }, "edgecenter_cloud_api": { Type: schema.TypeString, @@ -96,86 +27,11 @@ func Provider() *schema.Provider { Description: "Region API (define only if you want to override Region API endpoint)", DefaultFunc: schema.EnvDefaultFunc("EC_CLOUD_API", nil), }, - "edgecenter_cdn_api": { - Type: schema.TypeString, - Optional: true, - Description: "CDN API (define only if you want to override CDN API endpoint)", - DefaultFunc: schema.EnvDefaultFunc("EC_CDN_API", ""), - }, - "edgecenter_storage_api": { - Type: schema.TypeString, - Optional: true, - Description: "Storage API (define only if you want to override Storage API endpoint)", - DefaultFunc: schema.EnvDefaultFunc("EC_STORAGE_API", ""), - }, - "edgecenter_dns_api": { - Type: schema.TypeString, - Optional: true, - Description: "DNS API (define only if you want to override DNS API endpoint)", - DefaultFunc: schema.EnvDefaultFunc("EC_DNS_API", ""), - }, - "edgecenter_client_id": { - Type: schema.TypeString, - Optional: true, - Description: "Client id", - DefaultFunc: schema.EnvDefaultFunc("EC_CLIENT_ID", ""), - }, - }, - ResourcesMap: map[string]*schema.Resource{ - "edgecenter_volume": resourceVolume(), - "edgecenter_network": resourceNetwork(), - "edgecenter_subnet": resourceSubnet(), - "edgecenter_router": resourceRouter(), - "edgecenter_instance": resourceInstance(), - "edgecenter_keypair": resourceKeypair(), - "edgecenter_reservedfixedip": resourceReservedFixedIP(), - "edgecenter_floatingip": resourceFloatingIP(), - "edgecenter_loadbalancer": resourceLoadBalancer(), - "edgecenter_loadbalancerv2": resourceLoadBalancerV2(), - "edgecenter_lblistener": resourceLbListener(), - "edgecenter_lbpool": resourceLBPool(), - "edgecenter_lbmember": resourceLBMember(), - "edgecenter_securitygroup": resourceSecurityGroup(), - "edgecenter_baremetal": resourceBmInstance(), - "edgecenter_snapshot": resourceSnapshot(), - "edgecenter_servergroup": resourceServerGroup(), - "edgecenter_k8s": resourceK8s(), - "edgecenter_k8s_pool": resourceK8sPool(), - "edgecenter_secret": resourceSecret(), - "edgecenter_storage_s3": resourceStorageS3(), - "edgecenter_storage_s3_bucket": resourceStorageS3Bucket(), - DNSZoneResource: resourceDNSZone(), - DNSZoneRecordResource: resourceDNSZoneRecord(), - "edgecenter_cdn_resource": resourceCDNResource(), - "edgecenter_cdn_origingroup": resourceCDNOriginGroup(), - "edgecenter_cdn_rule": resourceCDNRule(), - "edgecenter_cdn_sslcert": resourceCDNCert(), - LifecyclePolicyResource: resourceLifecyclePolicy(), }, DataSourcesMap: map[string]*schema.Resource{ - "edgecenter_project": dataSourceProject(), - "edgecenter_region": dataSourceRegion(), - "edgecenter_securitygroup": dataSourceSecurityGroup(), - "edgecenter_image": dataSourceImage(), - "edgecenter_volume": dataSourceVolume(), - "edgecenter_network": dataSourceNetwork(), - "edgecenter_subnet": dataSourceSubnet(), - "edgecenter_router": dataSourceRouter(), - "edgecenter_loadbalancer": dataSourceLoadBalancer(), - "edgecenter_loadbalancerv2": dataSourceLoadBalancerV2(), - "edgecenter_lblistener": dataSourceLBListener(), - "edgecenter_lbpool": dataSourceLBPool(), - "edgecenter_instance": dataSourceInstance(), - "edgecenter_floatingip": dataSourceFloatingIP(), - "edgecenter_storage_s3": dataSourceStorageS3(), - "edgecenter_storage_s3_bucket": dataSourceStorageS3Bucket(), - "edgecenter_reservedfixedip": dataSourceReservedFixedIP(), - "edgecenter_servergroup": dataSourceServerGroup(), - "edgecenter_k8s": dataSourceK8s(), - "edgecenter_k8s_pool": dataSourceK8sPool(), - "edgecenter_k8s_client_config": dataSourceK8sClientConfig(), - "edgecenter_secret": dataSourceSecret(), + "edgecenter_floatingip": floatingip.DataSourceEdgeCenterFloatingIP(), }, + ResourcesMap: map[string]*schema.Resource{}, } p.ConfigureContextFunc = func(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) { @@ -190,115 +46,11 @@ func Provider() *schema.Provider { } func providerConfigure(_ context.Context, d *schema.ResourceData, terraformVersion string) (interface{}, diag.Diagnostics) { - username := d.Get("user_name").(string) - password := d.Get("password").(string) - permanentToken := d.Get(ProviderOptPermanentToken).(string) - apiEndpoint := d.Get(ProviderOptSingleAPIEndpoint).(string) - - cloudAPI := d.Get("edgecenter_cloud_api").(string) - if cloudAPI == "" { - cloudAPI = d.Get("edgecenter_api").(string) - } - if cloudAPI == "" { - cloudAPI = apiEndpoint + "/cloud" - } - - cdnAPI := d.Get("edgecenter_cdn_api").(string) - if cdnAPI == "" { - cdnAPI = apiEndpoint - } - - storageAPI := d.Get("edgecenter_storage_api").(string) - if storageAPI == "" { - storageAPI = apiEndpoint + "/storage" - } - - dnsAPI := d.Get("edgecenter_dns_api").(string) - if dnsAPI == "" { - dnsAPI = apiEndpoint + "/dns" - } - - platform := d.Get("edgecenter_platform_api").(string) - if platform == "" { - platform = d.Get("edgecenter_platform").(string) - } - if platform == "" { - platform = apiEndpoint + "/iam" - } - - clientID := d.Get("edgecenter_client_id").(string) - - var diags diag.Diagnostics - - var err error - var provider *edgecloud.ProviderClient - if permanentToken != "" { - provider, err = ec.APITokenClient(edgecloud.APITokenOptions{ - APIURL: cloudAPI, - APIToken: permanentToken, - }) - } else { - provider, err = ec.AuthenticatedClient(edgecloud.AuthOptions{ - APIURL: cloudAPI, - AuthURL: platform, - Username: username, - Password: password, - AllowReauth: true, - ClientID: clientID, - }) - } - if err != nil { - provider = &edgecloud.ProviderClient{} - log.Printf("[WARN] init auth client: %s\n", err) - } - - cdnProvider := eccdnProvider.NewClient(cdnAPI, eccdnProvider.WithSignerFunc(func(req *http.Request) error { - for k, v := range provider.AuthenticatedHeaders() { - req.Header.Set(k, v) - } - - return nil - })) - cdnService := cdn.NewService(cdnProvider) - - config := Config{ - Provider: provider, - CDNClient: cdnService, - } - - userAgent := fmt.Sprintf("terraform/%s", terraformVersion) - if storageAPI != "" { - stHost, stPath, err := ExtractHostAndPath(storageAPI) - if err != nil { - return nil, diag.FromErr(fmt.Errorf("storage api url: %w", err)) - } - config.StorageClient = storageSDK.NewSDK( - stHost, - stPath, - storageSDK.WithBearerAuth(provider.AccessToken), - storageSDK.WithPermanentTokenAuth(func() string { return permanentToken }), - storageSDK.WithUserAgent(userAgent), - ) - } - if dnsAPI != "" { - baseURL, err := url.Parse(dnsAPI) - if err != nil { - return nil, diag.FromErr(fmt.Errorf("dns api url: %w", err)) - } - authorizer := dnssdk.BearerAuth(provider.AccessToken()) - if permanentToken != "" { - authorizer = dnssdk.PermanentAPIKeyAuth(permanentToken) - } - config.DNSClient = dnssdk.NewClient( - authorizer, - func(client *dnssdk.Client) { - client.BaseURL = baseURL - client.Debug = os.Getenv("TF_LOG") == "DEBUG" - }, - func(client *dnssdk.Client) { - client.UserAgent = userAgent - }) + conf := config.Config{ + TerraformVersion: terraformVersion, + APIKey: d.Get("api_key").(string), + CloudAPIURL: d.Get("edgecenter_cloud_api").(string), } - return &config, diags + return conf.Client() } diff --git a/edgecenter/resource_edgecenter_baremetal.go b/edgecenter/resource_edgecenter_baremetal.go deleted file mode 100644 index d0ead172..00000000 --- a/edgecenter/resource_edgecenter_baremetal.go +++ /dev/null @@ -1,772 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "sort" - "strconv" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/baremetal/v1/bminstances" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/instances" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -const ( - BmInstanceDeleting int = 1200 - BmInstanceCreatingTimeout int = 3600 - BmInstancePoint = "bminstances" -) - -var bmCreateTimeout = time.Second * time.Duration(BmInstanceCreatingTimeout) - -func resourceBmInstance() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceBmInstanceCreate, - ReadContext: resourceBmInstanceRead, - UpdateContext: resourceBmInstanceUpdate, - DeleteContext: resourceBmInstanceDelete, - Description: "Represent baremetal instance", - Timeouts: &schema.ResourceTimeout{ - Create: &bmCreateTimeout, - }, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, InstanceID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(InstanceID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "flavor_id": { - Type: schema.TypeString, - Required: true, - }, - "interface": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Required: true, - Description: fmt.Sprintf("Available value is '%s', '%s', '%s', '%s'", types.SubnetInterfaceType, types.AnySubnetInterfaceType, types.ExternalInterfaceType, types.ReservedFixedIPType), - }, - "is_parent": { - Type: schema.TypeBool, - Computed: true, - Optional: true, - Description: "If not set will be calculated after creation. Trunk interface always attached first. Can't detach interface if is_parent true. Fields affect only on creation", - }, - "order": { - Type: schema.TypeInt, - Optional: true, - Description: "Order of attaching interface. Trunk interface always attached first, fields affect only on creation", - }, - "network_id": { - Type: schema.TypeString, - Description: "required if type is 'subnet' or 'any_subnet'", - Optional: true, - Computed: true, - }, - "subnet_id": { - Type: schema.TypeString, - Description: "required if type is 'subnet'", - Optional: true, - Computed: true, - }, - "port_id": { - Type: schema.TypeString, - Computed: true, - Description: "required if type is 'reserved_fixed_ip'", - Optional: true, - }, - // nested map is not supported, in this case, you do not need to use the list for the map - "fip_source": { - Type: schema.TypeString, - Optional: true, - }, - "existing_fip_id": { - Type: schema.TypeString, - Optional: true, - }, - "ip_address": { - Type: schema.TypeString, - Computed: true, - Optional: true, - }, - }, - }, - }, - "name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The name of the baremetal instance.", - }, - "name_templates": { - Type: schema.TypeList, - Optional: true, - Deprecated: "Use name_template instead", - ConflictsWith: []string{"name_template"}, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "name_template": { - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"name_templates"}, - }, - "image_id": { - Type: schema.TypeString, - Optional: true, - ExactlyOneOf: []string{ - "image_id", - "apptemplate_id", - }, - }, - "apptemplate_id": { - Type: schema.TypeString, - Optional: true, - ExactlyOneOf: []string{ - "image_id", - "apptemplate_id", - }, - }, - "keypair_name": { - Type: schema.TypeString, - Optional: true, - }, - "password": { - Type: schema.TypeString, - Optional: true, - }, - "username": { - Type: schema.TypeString, - Optional: true, - }, - "metadata": { - Type: schema.TypeList, - Optional: true, - Deprecated: "Use metadata_map instead", - ConflictsWith: []string{"metadata_map"}, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Required: true, - }, - "value": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - ConflictsWith: []string{"metadata"}, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "app_config": { - Type: schema.TypeMap, - Optional: true, - }, - "user_data": { - Type: schema.TypeString, - Optional: true, - }, - - // computed - "flavor": { - Type: schema.TypeMap, - Computed: true, - }, - "status": { - Type: schema.TypeString, - Computed: true, - }, - "vm_state": { - Type: schema.TypeString, - Computed: true, - }, - "addresses": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "net": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "addr": { - Type: schema.TypeString, - Required: true, - }, - "type": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - }, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceBmInstanceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start BaremetalInstance creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, BmInstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - ifs := d.Get("interface").([]interface{}) - // sort interfaces by 'is_parent' at first and by 'order' key to attach it in right order - sort.Sort(instanceInterfaces(ifs)) - interfaceOptsList := make([]bminstances.InterfaceOpts, len(ifs)) - for i, iFace := range ifs { - raw := iFace.(map[string]interface{}) - interfaceOpts := bminstances.InterfaceOpts{ - Type: types.InterfaceType(raw["type"].(string)), - NetworkID: raw["network_id"].(string), - SubnetID: raw["subnet_id"].(string), - PortID: raw["port_id"].(string), - } - - fipSource := raw["fip_source"].(string) - fipID := raw["existing_fip_id"].(string) - if fipSource != "" { - interfaceOpts.FloatingIP = &bminstances.CreateNewInterfaceFloatingIPOpts{ - Source: types.FloatingIPSource(fipSource), - ExistingFloatingID: fipID, - } - } - interfaceOptsList[i] = interfaceOpts - } - - log.Printf("[DEBUG] Baremetal interfaces: %+v", interfaceOptsList) - opts := bminstances.CreateOpts{ - Flavor: d.Get("flavor_id").(string), - ImageID: d.Get("image_id").(string), - AppTemplateID: d.Get("apptemplate_id").(string), - Keypair: d.Get("keypair_name").(string), - Password: d.Get("password").(string), - Username: d.Get("username").(string), - UserData: d.Get("user_data").(string), - AppConfig: d.Get("app_config").(map[string]interface{}), - Interfaces: interfaceOptsList, - } - - name := d.Get("name").(string) - if len(name) > 0 { - opts.Names = []string{name} - } - - if nameTemplatesRaw, ok := d.GetOk("name_templates"); ok { - nameTemplates := nameTemplatesRaw.([]interface{}) - if len(nameTemplates) > 0 { - NameTemp := make([]string, len(nameTemplates)) - for i, nametemp := range nameTemplates { - NameTemp[i] = nametemp.(string) - } - opts.NameTemplates = NameTemp - } - } else if nameTemplate, ok := d.GetOk("name_template"); ok { - opts.NameTemplates = []string{nameTemplate.(string)} - } - - if metadata, ok := d.GetOk("metadata"); ok { - if len(metadata.([]interface{})) > 0 { - md, err := extractKeyValue(metadata.([]interface{})) - if err != nil { - return diag.FromErr(err) - } - opts.Metadata = &md - } - } else if metadataRaw, ok := d.GetOk("metadata_map"); ok { - md := extractMetadataMap(metadataRaw.(map[string]interface{})) - opts.Metadata = &md - } - - results, err := bminstances.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - - InstanceID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, BmInstanceCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - Instance, err := instances.ExtractInstanceIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve Instance ID from task info: %w", err) - } - return Instance, nil - }, - ) - log.Printf("[DEBUG] Baremetal Instance id (%s)", InstanceID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(InstanceID.(string)) - resourceBmInstanceRead(ctx, d, m) - - log.Printf("[DEBUG] Finish Baremetal Instance creating (%s)", InstanceID) - - return diags -} - -func resourceBmInstanceRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Baremetal Instance reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - instanceID := d.Id() - log.Printf("[DEBUG] Instance id = %s", instanceID) - - client, err := CreateClient(provider, d, InstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - instance, err := instances.Get(client, instanceID).Extract() - if err != nil { - return diag.Errorf("cannot get instance with ID: %s. Error: %s", instanceID, err) - } - - d.Set("name", instance.Name) - d.Set("flavor_id", instance.Flavor.FlavorID) - d.Set("status", instance.Status) - d.Set("vm_state", instance.VMState) - - flavor := make(map[string]interface{}, 4) - flavor["flavor_id"] = instance.Flavor.FlavorID - flavor["flavor_name"] = instance.Flavor.FlavorName - flavor["ram"] = strconv.Itoa(instance.Flavor.RAM) - flavor["vcpus"] = strconv.Itoa(instance.Flavor.VCPUS) - d.Set("flavor", flavor) - - interfacesListAPI, err := instances.ListInterfacesAll(client, instanceID) - if err != nil { - return diag.FromErr(err) - } - - if len(interfacesListAPI) == 0 { - return diag.Errorf("interface not found") - } - - ifs := d.Get("interface").([]interface{}) - sort.Sort(instanceInterfaces(ifs)) - interfacesListExtracted, err := extractInstanceInterfaceToListRead(ifs) - if err != nil { - return diag.FromErr(err) - } - - var interfacesList []interface{} - for order, iFace := range interfacesListAPI { - if len(iFace.IPAssignments) == 0 { - continue - } - - portID := iFace.PortID - for _, assignment := range iFace.IPAssignments { - subnetID := assignment.SubnetID - ipAddress := assignment.IPAddress.String() - - var interfaceOpts instances.InterfaceOpts - for _, interfaceExtracted := range interfacesListExtracted { - if interfaceExtracted.SubnetID == subnetID || - interfaceExtracted.IPAddress == ipAddress || - interfaceExtracted.PortID == portID { - interfaceOpts = interfaceExtracted - break - } - } - - i := make(map[string]interface{}) - i["type"] = interfaceOpts.Type.String() - i["order"] = order - i["network_id"] = iFace.NetworkID - i["subnet_id"] = subnetID - i["port_id"] = portID - i["is_parent"] = true - if interfaceOpts.FloatingIP != nil { - i["fip_source"] = interfaceOpts.FloatingIP.Source.String() - i["existing_fip_id"] = interfaceOpts.FloatingIP.ExistingFloatingID - } - i["ip_address"] = ipAddress - - interfacesList = append(interfacesList, i) - } - - for _, iFaceSubPort := range iFace.SubPorts { - subPortID := iFaceSubPort.PortID - for _, assignmentSubPort := range iFaceSubPort.IPAssignments { - assignmentSubnetID := assignmentSubPort.SubnetID - assignmentIPAddress := assignmentSubPort.IPAddress.String() - - var subPortInterfaceOpts instances.InterfaceOpts - for _, interfaceExtracted := range interfacesListExtracted { - if interfaceExtracted.SubnetID == assignmentSubnetID || - interfaceExtracted.IPAddress == assignmentIPAddress || - interfaceExtracted.PortID == subPortID { - subPortInterfaceOpts = interfaceExtracted - break - } - } - - i := make(map[string]interface{}) - - i["type"] = subPortInterfaceOpts.Type.String() - i["order"] = order - i["network_id"] = iFaceSubPort.NetworkID - i["subnet_id"] = assignmentSubnetID - i["port_id"] = subPortID - i["is_parent"] = false - if subPortInterfaceOpts.FloatingIP != nil { - i["fip_source"] = subPortInterfaceOpts.FloatingIP.Source.String() - i["existing_fip_id"] = subPortInterfaceOpts.FloatingIP.ExistingFloatingID - } - i["ip_address"] = assignmentIPAddress - - interfacesList = append(interfacesList, i) - } - } - } - if err := d.Set("interface", interfacesList); err != nil { - return diag.FromErr(err) - } - - if metadataRaw, ok := d.GetOk("metadata"); ok { - metadata := metadataRaw.([]interface{}) - sliced := make([]map[string]string, len(metadata)) - for i, data := range metadata { - d := data.(map[string]interface{}) - mdata := make(map[string]string, 2) - md, err := instances.MetadataGet(client, instanceID, d["key"].(string)).Extract() - if err != nil { - return diag.Errorf("cannot get metadata with key: %s. Error: %s", instanceID, err) - } - mdata["key"] = md.Key - mdata["value"] = md.Value - sliced[i] = mdata - } - d.Set("metadata", sliced) - } else { - metadata := d.Get("metadata_map").(map[string]interface{}) - newMetadata := make(map[string]interface{}, len(metadata)) - for k := range metadata { - md, err := instances.MetadataGet(client, instanceID, k).Extract() - if err != nil { - return diag.Errorf("cannot get metadata with key: %s. Error: %s", instanceID, err) - } - newMetadata[k] = md.Value - } - if err := d.Set("metadata_map", newMetadata); err != nil { - return diag.FromErr(err) - } - } - - addresses := []map[string][]map[string]string{} - for _, data := range instance.Addresses { - d := map[string][]map[string]string{} - netd := make([]map[string]string, len(data)) - for i, iaddr := range data { - ndata := make(map[string]string, 2) - ndata["type"] = iaddr.Type.String() - ndata["addr"] = iaddr.Address.String() - netd[i] = ndata - } - d["net"] = netd - addresses = append(addresses, d) - } - if err := d.Set("addresses", addresses); err != nil { - return diag.FromErr(err) - } - - fields := []string{"user_data", "app_config"} - revertState(d, &fields) - - log.Println("[DEBUG] Finish Instance reading") - - return diags -} - -func resourceBmInstanceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Baremetal Instance updating") - instanceID := d.Id() - log.Printf("[DEBUG] Instance id = %s", instanceID) - config := m.(*Config) - provider := config.Provider - client, err := CreateClient(provider, d, InstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("name") { - nameTemplates := d.Get("name_templates").([]interface{}) - nameTemplate := d.Get("name_template").(string) - if len(nameTemplate) == 0 && len(nameTemplates) == 0 { - opts := instances.RenameInstanceOpts{ - Name: d.Get("name").(string), - } - if _, err := instances.RenameInstance(client, instanceID, opts).Extract(); err != nil { - return diag.FromErr(err) - } - } - } - - if d.HasChange("metadata") { - omd, nmd := d.GetChange("metadata") - if len(omd.([]interface{})) > 0 { - for _, data := range omd.([]interface{}) { - d := data.(map[string]interface{}) - k := d["key"].(string) - err := instances.MetadataDelete(client, instanceID, k).Err - if err != nil { - return diag.Errorf("cannot delete metadata key: %s. Error: %s", k, err) - } - } - } - if len(nmd.([]interface{})) > 0 { - var MetaData []instances.MetadataOpts - for _, data := range nmd.([]interface{}) { - d := data.(map[string]interface{}) - var md instances.MetadataOpts - md.Key = d["key"].(string) - md.Value = d["value"].(string) - MetaData = append(MetaData, md) - } - createOpts := instances.MetadataSetOpts{ - Metadata: MetaData, - } - err := instances.MetadataCreate(client, instanceID, createOpts).Err - if err != nil { - return diag.Errorf("cannot create metadata. Error: %s", err) - } - } - } else if d.HasChange("metadata_map") { - omd, nmd := d.GetChange("metadata_map") - if len(omd.(map[string]interface{})) > 0 { - for k := range omd.(map[string]interface{}) { - err := instances.MetadataDelete(client, instanceID, k).Err - if err != nil { - return diag.Errorf("cannot delete metadata key: %s. Error: %s", k, err) - } - } - } - if len(nmd.(map[string]interface{})) > 0 { - var MetaData []instances.MetadataOpts - for k, v := range nmd.(map[string]interface{}) { - md := instances.MetadataOpts{ - Key: k, - Value: v.(string), - } - MetaData = append(MetaData, md) - } - createOpts := instances.MetadataSetOpts{ - Metadata: MetaData, - } - err := instances.MetadataCreate(client, instanceID, createOpts).Err - if err != nil { - return diag.Errorf("cannot create metadata. Error: %s", err) - } - } - } - - if d.HasChange("interface") { - ifsOldRaw, ifsNewRaw := d.GetChange("interface") - - ifsOld := ifsOldRaw.([]interface{}) - ifsNew := ifsNewRaw.([]interface{}) - - for _, i := range ifsOld { - iface := i.(map[string]interface{}) - if isInterfaceContains(iface, ifsNew) { - log.Println("[DEBUG] Skipped, dont need detach") - continue - } - - if iface["is_parent"].(bool) { - return diag.Errorf("could not detach trunk interface") - } - - var opts instances.InterfaceOpts - opts.PortID = iface["port_id"].(string) - opts.IPAddress = iface["ip_address"].(string) - - log.Printf("[DEBUG] detach interface: %+v", opts) - results, err := instances.DetachInterface(client, instanceID, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, InstanceCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w, task: %+v", task, err, taskInfo) - } - return nil, nil - }, - ) - if err != nil { - return diag.FromErr(err) - } - } - - currentIfs, err := instances.ListInterfacesAll(client, d.Id()) - if err != nil { - return diag.FromErr(err) - } - - sort.Sort(instanceInterfaces(ifsNew)) - for _, i := range ifsNew { - iface := i.(map[string]interface{}) - if isInterfaceContains(iface, ifsOld) { - log.Println("[DEBUG] Skipped, dont need attach") - continue - } - if isInterfaceAttached(currentIfs, iface) { - continue - } - - iType := types.InterfaceType(iface["type"].(string)) - opts := instances.InterfaceOpts{Type: iType} - switch iType { - case types.SubnetInterfaceType: - opts.SubnetID = iface["subnet_id"].(string) - case types.AnySubnetInterfaceType: - opts.NetworkID = iface["network_id"].(string) - case types.ReservedFixedIPType: - opts.PortID = iface["port_id"].(string) - case types.ExternalInterfaceType: - } - - log.Printf("[DEBUG] attach interface: %+v", opts) - results, err := instances.AttachInterface(client, instanceID, opts).Extract() - if err != nil { - return diag.Errorf("cannot attach interface: %s. Error: %s", iType, err) - } - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, InstanceCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w, task: %+v", task, err, taskInfo) - } - return nil, nil - }, - ) - if err != nil { - return diag.FromErr(err) - } - } - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish Instance updating") - - return resourceBmInstanceRead(ctx, d, m) -} - -func resourceBmInstanceDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Baremetal Instance deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - instanceID := d.Id() - log.Printf("[DEBUG] Instance id = %s", instanceID) - - client, err := CreateClient(provider, d, InstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - var delOpts instances.DeleteOpts - delOpts.DeleteFloatings = true - - results, err := instances.Delete(client, instanceID, delOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, BmInstanceDeleting, func(task tasks.TaskID) (interface{}, error) { - _, err := instances.Get(client, instanceID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete instance with ID: %s", instanceID) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Instance resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of Instance deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_cdn_origin_group.go b/edgecenter/resource_edgecenter_cdn_origin_group.go deleted file mode 100644 index de7095e3..00000000 --- a/edgecenter/resource_edgecenter_cdn_origin_group.go +++ /dev/null @@ -1,218 +0,0 @@ -package edgecenter - -import ( - "context" - "crypto/md5" - "encoding/binary" - "fmt" - "io" - "log" - "strconv" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercdn-go/origingroups" -) - -func resourceCDNOriginGroup() *schema.Resource { - return &schema.Resource{ - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of the origin group", - }, - "use_next": { - Type: schema.TypeBool, - Required: true, - Description: "This options have two possible values: true — The option is active. In case the origin responds with 4XX or 5XX codes, use the next origin from the list. false — The option is disabled.", - }, - "origin": { - Type: schema.TypeSet, - Required: true, - Description: "Contains information about all IP address or Domain names of your origin and the port if custom", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "source": { - Type: schema.TypeString, - Required: true, - Description: "IP address or Domain name of your origin and the port if custom", - }, - "enabled": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "The setting allows to enable or disable an Origin source in the Origins group", - }, - "backup": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "true — The option is active. The origin will not be used until one of active origins become unavailable. false — The option is disabled.", - }, - "id": { - Type: schema.TypeInt, - Computed: true, - }, - }, - }, - }, - }, - CreateContext: resourceCDNOriginGroupCreate, - ReadContext: resourceCDNOriginGroupRead, - UpdateContext: resourceCDNOriginGroupUpdate, - DeleteContext: resourceCDNOriginGroupDelete, - Description: "Represent origin group", - } -} - -func resourceCDNOriginGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start CDN OriginGroup creating") - config := m.(*Config) - client := config.CDNClient - - var req origingroups.GroupRequest - req.Name = d.Get("name").(string) - req.UseNext = d.Get("use_next").(bool) - req.Origins = setToOriginRequests(d.Get("origin").(*schema.Set)) - - result, err := client.OriginGroups().Create(ctx, &req) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(fmt.Sprintf("%d", result.ID)) - resourceCDNOriginGroupRead(ctx, d, m) - - log.Printf("[DEBUG] Finish CDN OriginGroup creating (id=%d)\n", result.ID) - - return nil -} - -func resourceCDNOriginGroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - groupID := d.Id() - log.Printf("[DEBUG] Start CDN OriginGroup reading (id=%s)\n", groupID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(groupID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - result, err := client.OriginGroups().Get(ctx, id) - if err != nil { - return diag.FromErr(err) - } - - d.Set("name", result.Name) - d.Set("use_next", result.UseNext) - if err := d.Set("origin", originsToSet(result.Origins)); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish CDN OriginGroup reading") - - return nil -} - -func resourceCDNOriginGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - groupID := d.Id() - log.Printf("[DEBUG] Start CDN OriginGroup updating (id=%s)\n", groupID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(groupID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - var req origingroups.GroupRequest - req.Name = d.Get("name").(string) - req.UseNext = d.Get("use_next").(bool) - req.Origins = setToOriginRequests(d.Get("origin").(*schema.Set)) - - if _, err := client.OriginGroups().Update(ctx, id, &req); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish CDN OriginGroup updating") - - return resourceCDNOriginGroupRead(ctx, d, m) -} - -func resourceCDNOriginGroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - resourceID := d.Id() - log.Printf("[DEBUG] Start CDN OriginGroup deleting (id=%s)\n", resourceID) - - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(resourceID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - if err := client.OriginGroups().Delete(ctx, id); err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Println("[DEBUG] Finish CDN Resource deleting") - - return nil -} - -func setToOriginRequests(s *schema.Set) []origingroups.OriginRequest { - origins := make([]origingroups.OriginRequest, 0) - for _, fields := range s.List() { - var originReq origingroups.OriginRequest - - for key, val := range fields.(map[string]interface{}) { - switch key { - case "source": - originReq.Source = val.(string) - case "enabled": - originReq.Enabled = val.(bool) - case "backup": - originReq.Backup = val.(bool) - } - } - - origins = append(origins, originReq) - } - - return origins -} - -func originsToSet(origins []origingroups.Origin) *schema.Set { - s := &schema.Set{F: originSetIDFunc} - - for _, origin := range origins { - fields := make(map[string]interface{}) - fields["id"] = origin.ID - fields["source"] = origin.Source - fields["enabled"] = origin.Enabled - fields["backup"] = origin.Backup - - s.Add(fields) - } - - return s -} - -func originSetIDFunc(i interface{}) int { - fields := i.(map[string]interface{}) - h := md5.New() - - key := fmt.Sprintf("%d-%s-%t-%t", fields["id"], fields["source"], fields["enabled"], fields["backup"]) - log.Printf("[DEBUG] Origin Set ID = %s\n", key) - - io.WriteString(h, key) - - return int(binary.BigEndian.Uint64(h.Sum(nil))) -} diff --git a/edgecenter/resource_edgecenter_cdn_resource.go b/edgecenter/resource_edgecenter_cdn_resource.go deleted file mode 100644 index da8633df..00000000 --- a/edgecenter/resource_edgecenter_cdn_resource.go +++ /dev/null @@ -1,1694 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "reflect" - "strconv" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - cdn "github.com/Edge-Center/edgecentercdn-go/edgecenter" - "github.com/Edge-Center/edgecentercdn-go/resources" -) - -var resourceOptionsSchema = &schema.Schema{ - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "Each option in CDN resource settings. Each option added to CDN resource settings should have the following mandatory request fields: enabled, value.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "allowed_http_methods": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "brotli_compression": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "browser_cache_settings": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeString, - Optional: true, - Description: "", - }, - }, - }, - }, - "cache_http_headers": { // Deprecated. Use - response_headers_hiding_policy. - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "cors": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - "always": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - }, - }, - }, - "country_acl": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "policy_type": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "excepted_values": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "disable_proxy_force_ranges": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "edge_cache_settings": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "The cache expiration time for CDN servers.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeString, - Optional: true, - Description: "Caching time for a response with codes 200, 206, 301, 302. Responses with codes 4xx, 5xx will not be cached. Use '0s' disable to caching. Use custom_values field to specify a custom caching time for a response with specific codes.", - }, - "default": { - Type: schema.TypeString, - Optional: true, - Description: "Content will be cached according to origin cache settings. The value applies for a response with codes 200, 201, 204, 206, 301, 302, 303, 304, 307, 308 if an origin server does not have caching HTTP headers. Responses with other codes will not be cached.", - }, - "custom_values": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - DefaultFunc: func() (interface{}, error) { - return map[string]interface{}{}, nil - }, - Elem: schema.TypeString, - Description: "Caching time for a response with specific codes. These settings have a higher priority than the value field. Response code ('304', '404' for example). Use 'any' to specify caching time for all response codes. Caching time in seconds ('0s', '600s' for example). Use '0s' to disable caching for a specific response code.", - }, - }, - }, - }, - "fetch_compressed": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "follow_origin_redirect": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "codes": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeInt}, - Required: true, - Description: "", - }, - }, - }, - }, - "force_return": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "code": { - Type: schema.TypeInt, - Required: true, - Description: "", - }, - "body": { - Type: schema.TypeString, - Optional: true, - Default: "", - Description: "", - }, - }, - }, - }, - "forward_host_header": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "gzip_on": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "host_header": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Specify the Host header that CDN servers use when request content from an origin server. Your server must be able to process requests with the chosen header. If the option is in NULL state Host Header value is taken from the CNAME field.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - "http3_enabled": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "ignore_cookie": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "ignore_query_string": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "image_stack": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "avif_enabled": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - "webp_enabled": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - "quality": { - Type: schema.TypeInt, - Required: true, - Description: "", - }, - "png_lossless": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - }, - }, - }, - "ip_address_acl": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "policy_type": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "excepted_values": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "limit_bandwidth": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "limit_type": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "speed": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "", - }, - "buffer": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "", - }, - }, - }, - }, - "proxy_cache_methods_set": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "query_params_blacklist": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - }, - }, - }, - }, - "query_params_whitelist": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - }, - }, - }, - }, - "redirect_http_to_https": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Sets redirect from HTTP protocol to HTTPS for all resource requests.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "redirect_https_to_http": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "referrer_acl": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "policy_type": { - Type: schema.TypeString, - Required: true, - Description: "Possible values: allow, deny.", - }, - "excepted_values": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "response_headers_hiding_policy": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "mode": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "excepted": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "rewrite": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "body": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "flag": { - Type: schema.TypeString, - Optional: true, - Default: "break", - Description: "", - }, - }, - }, - }, - "secure_key": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "key": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "type": { - Type: schema.TypeInt, - Required: true, - Description: "", - }, - }, - }, - }, - "slice": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "sni": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "sni_type": { - Type: schema.TypeString, - Optional: true, - Description: "Available values 'dynamic' or 'custom'", - }, - "custom_hostname": { - Type: schema.TypeString, - Optional: true, - Description: "Required to set custom hostname in case sni-type='custom'", - }, - }, - }, - }, - "stale": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "static_headers": { // Deprecated. Use - static_response_headers. - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Option has been deprecated. Use - static_response_headers.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeMap, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - }, - }, - }, - }, - "static_request_headers": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeMap, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "static_response_headers": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Specify custom HTTP Headers that a CDN server adds to a response.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - "always": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - }, - }, - }, - }, - }, - }, - "tls_versions": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "use_default_le_chain": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "user_agent_acl": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "policy_type": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "excepted_values": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "websockets": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - }, - }, -} - -func resourceCDNResource() *schema.Resource { - return &schema.Resource{ - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - Schema: map[string]*schema.Schema{ - "cname": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "A CNAME that will be used to deliver content though a CDN. If you update this field new resource will be created.", - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: "Custom client description of the resource.", - }, - "origin_group": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - ExactlyOneOf: []string{ - "origin_group", - "origin", - }, - Description: "ID of the Origins Group. Use one of your Origins Group or create a new one. You can use either 'origin' parameter or 'originGroup' in the resource definition.", - }, - "origin": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ExactlyOneOf: []string{ - "origin_group", - "origin", - }, - Description: "A domain name or IP of your origin source. Specify a port if custom. You can use either 'origin' parameter or 'originGroup' in the resource definition.", - }, - "origin_protocol": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "This option defines the protocol that will be used by CDN servers to request content from an origin source. If not specified, we will use HTTP to connect to an origin server. Possible values are: HTTPS, HTTP, MATCH.", - }, - "secondary_hostnames": { - Type: schema.TypeSet, - Optional: true, - Computed: true, - DefaultFunc: func() (interface{}, error) { - return []string{}, nil - }, - Elem: &schema.Schema{Type: schema.TypeString}, - Description: "List of additional CNAMEs.", - }, - "ssl_enabled": { - Type: schema.TypeBool, - Optional: true, - Description: "Use HTTPS protocol for content delivery.", - }, - "ssl_data": { - Type: schema.TypeInt, - Optional: true, - RequiredWith: []string{"ssl_enabled"}, - Description: "Specify the SSL Certificate ID which should be used for the CDN Resource.", - }, - "ssl_automated": { - Type: schema.TypeBool, - Optional: true, - Description: "generate LE certificate automatically.", - }, - "issue_le_cert": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "Generate LE certificate.", - }, - "active": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "The setting allows to enable or disable a CDN Resource", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "Status of a CDN resource content availability. Possible values are: Active, Suspended, Processed.", - }, - "options": resourceOptionsSchema, - }, - CreateContext: resourceCDNResourceCreate, - ReadContext: resourceCDNResourceRead, - UpdateContext: resourceCDNResourceUpdate, - DeleteContext: resourceCDNResourceDelete, - Description: "Represent CDN resource", - } -} - -func resourceCDNResourceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start CDN Resource creating") - config := m.(*Config) - client := config.CDNClient - - var req resources.CreateRequest - req.Cname = d.Get("cname").(string) - req.Description = d.Get("description").(string) - req.Origin = d.Get("origin").(string) - req.OriginGroup = d.Get("origin_group").(int) - req.OriginProtocol = resources.Protocol(d.Get("origin_protocol").(string)) - req.SSlEnabled = d.Get("ssl_enabled").(bool) - req.SSLData = d.Get("ssl_data").(int) - req.SSLAutomated = d.Get("ssl_automated").(bool) - - if d.Get("issue_le_cert") != nil { - req.IssueLECert = d.Get("issue_le_cert").(bool) - } - - req.Options = listToResourceOptions(d.Get("options").([]interface{})) - - for _, hostname := range d.Get("secondary_hostnames").(*schema.Set).List() { - req.SecondaryHostnames = append(req.SecondaryHostnames, hostname.(string)) - } - - result, err := client.Resources().Create(ctx, &req) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(fmt.Sprintf("%d", result.ID)) - resourceCDNResourceRead(ctx, d, m) - - log.Printf("[DEBUG] Finish CDN Resource creating (id=%d)\n", result.ID) - - return nil -} - -func resourceCDNResourceRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - resourceID := d.Id() - log.Printf("[DEBUG] Start CDN Resource reading (id=%s)\n", resourceID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(resourceID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - result, err := client.Resources().Get(ctx, id) - if err != nil { - return diag.FromErr(err) - } - - d.Set("cname", result.Cname) - d.Set("description", result.Description) - d.Set("origin_group", result.OriginGroup) - d.Set("origin_protocol", result.OriginProtocol) - d.Set("secondary_hostnames", result.SecondaryHostnames) - d.Set("ssl_enabled", result.SSlEnabled) - d.Set("ssl_data", result.SSLData) - d.Set("ssl_automated", result.SSLAutomated) - d.Set("status", result.Status) - d.Set("active", result.Active) - if err := d.Set("options", resourceOptionsToList(result.Options)); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish CDN Resource reading") - - return nil -} - -func resourceCDNResourceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - resourceID := d.Id() - log.Printf("[DEBUG] Start CDN Resource updating (id=%s)\n", resourceID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(resourceID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - var req resources.UpdateRequest - req.Active = d.Get("active").(bool) - req.Description = d.Get("description").(string) - req.OriginGroup = d.Get("origin_group").(int) - req.SSlEnabled = d.Get("ssl_enabled").(bool) - req.SSLData = d.Get("ssl_data").(int) - req.OriginProtocol = resources.Protocol(d.Get("origin_protocol").(string)) - req.Options = listToResourceOptions(d.Get("options").([]interface{})) - for _, hostname := range d.Get("secondary_hostnames").(*schema.Set).List() { - req.SecondaryHostnames = append(req.SecondaryHostnames, hostname.(string)) - } - - if _, err := client.Resources().Update(ctx, id, &req); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish CDN Resource updating") - - return resourceCDNResourceRead(ctx, d, m) -} - -func resourceCDNResourceDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - resourceID := d.Id() - log.Printf("[DEBUG] Start CDN Resource deleting (id=%s)\n", resourceID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(resourceID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - if err := client.Resources().Delete(ctx, id); err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Println("[DEBUG] Finish CDN Resource deleting") - - return nil -} - -func listToResourceOptions(l []interface{}) *cdn.ResourceOptions { - if len(l) == 0 { - return nil - } - - var opts cdn.ResourceOptions - fields := l[0].(map[string]interface{}) - if opt, ok := getOptByName(fields, "allowed_http_methods"); ok { - opts.AllowedHTTPMethods = &cdn.AllowedHTTPMethods{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.AllowedHTTPMethods.Value = append(opts.AllowedHTTPMethods.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "brotli_compression"); ok { - opts.BrotliCompression = &cdn.BrotliCompression{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.BrotliCompression.Value = append(opts.BrotliCompression.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "browser_cache_settings"); ok { - opts.BrowserCacheSettings = &cdn.BrowserCacheSettings{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(string), - } - } - if opt, ok := getOptByName(fields, "cache_http_headers"); ok { - opts.CacheHttpHeaders = &cdn.CacheHttpHeaders{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.CacheHttpHeaders.Value = append(opts.CacheHttpHeaders.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "cors"); ok { - opts.Cors = &cdn.Cors{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.Cors.Value = append(opts.Cors.Value, v.(string)) - } - if _, ok := opt["always"]; ok { - opts.Cors.Always = opt["always"].(bool) - } - } - if opt, ok := getOptByName(fields, "country_acl"); ok { - opts.CountryACL = &cdn.CountryACL{ - Enabled: opt["enabled"].(bool), - PolicyType: opt["policy_type"].(string), - } - for _, v := range opt["excepted_values"].(*schema.Set).List() { - opts.CountryACL.ExceptedValues = append(opts.CountryACL.ExceptedValues, v.(string)) - } - } - if opt, ok := getOptByName(fields, "disable_proxy_force_ranges"); ok { - opts.DisableProxyForceRanges = &cdn.DisableProxyForceRanges{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "edge_cache_settings"); ok { - rawCustomVals := opt["custom_values"].(map[string]interface{}) - customVals := make(map[string]string, len(rawCustomVals)) - for key, value := range rawCustomVals { - customVals[key] = value.(string) - } - - opts.EdgeCacheSettings = &cdn.EdgeCacheSettings{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(string), - CustomValues: customVals, - Default: opt["default"].(string), - } - } - if opt, ok := getOptByName(fields, "fetch_compressed"); ok { - opts.FetchCompressed = &cdn.FetchCompressed{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "follow_origin_redirect"); ok { - opts.FollowOriginRedirect = &cdn.FollowOriginRedirect{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["codes"].(*schema.Set).List() { - opts.FollowOriginRedirect.Codes = append(opts.FollowOriginRedirect.Codes, v.(int)) - } - } - if opt, ok := getOptByName(fields, "force_return"); ok { - opts.ForceReturn = &cdn.ForceReturn{ - Enabled: opt["enabled"].(bool), - Code: opt["code"].(int), - Body: opt["body"].(string), - } - } - if opt, ok := getOptByName(fields, "forward_host_header"); ok { - opts.ForwardHostHeader = &cdn.ForwardHostHeader{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "gzip_on"); ok { - opts.GzipOn = &cdn.GzipOn{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "host_header"); ok { - opts.HostHeader = &cdn.HostHeader{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(string), - } - } - if opt, ok := getOptByName(fields, "http3_enabled"); ok { - opts.HTTP3Enabled = &cdn.HTTP3Enabled{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "ignore_cookie"); ok { - opts.IgnoreCookie = &cdn.IgnoreCookie{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "ignore_query_string"); ok { - opts.IgnoreQueryString = &cdn.IgnoreQueryString{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "image_stack"); ok { - opts.ImageStack = &cdn.ImageStack{ - Enabled: opt["enabled"].(bool), - Quality: opt["quality"].(int), - } - if _, ok := opt["avif_enabled"]; ok { - opts.ImageStack.AvifEnabled = opt["avif_enabled"].(bool) - } - if _, ok := opt["webp_enabled"]; ok { - opts.ImageStack.WebpEnabled = opt["webp_enabled"].(bool) - } - if _, ok := opt["png_lossless"]; ok { - opts.ImageStack.PngLossless = opt["png_lossless"].(bool) - } - } - if opt, ok := getOptByName(fields, "ip_address_acl"); ok { - opts.IPAddressACL = &cdn.IPAddressACL{ - Enabled: opt["enabled"].(bool), - PolicyType: opt["policy_type"].(string), - } - for _, v := range opt["excepted_values"].(*schema.Set).List() { - opts.IPAddressACL.ExceptedValues = append(opts.IPAddressACL.ExceptedValues, v.(string)) - } - } - if opt, ok := getOptByName(fields, "limit_bandwidth"); ok { - opts.LimitBandwidth = &cdn.LimitBandwidth{ - Enabled: opt["enabled"].(bool), - LimitType: opt["limit_type"].(string), - } - if _, ok := opt["speed"]; ok { - opts.LimitBandwidth.Speed = opt["speed"].(int) - } - if _, ok := opt["buffer"]; ok { - opts.LimitBandwidth.Buffer = opt["buffer"].(int) - } - } - if opt, ok := getOptByName(fields, "proxy_cache_methods_set"); ok { - opts.ProxyCacheMethodsSet = &cdn.ProxyCacheMethodsSet{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "query_params_blacklist"); ok { - opts.QueryParamsBlacklist = &cdn.QueryParamsBlacklist{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.QueryParamsBlacklist.Value = append(opts.QueryParamsBlacklist.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "query_params_whitelist"); ok { - opts.QueryParamsWhitelist = &cdn.QueryParamsWhitelist{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.QueryParamsWhitelist.Value = append(opts.QueryParamsWhitelist.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "redirect_http_to_https"); ok { - opts.RedirectHttpToHttps = &cdn.RedirectHttpToHttps{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "redirect_https_to_http"); ok { - opts.RedirectHttpsToHttp = &cdn.RedirectHttpsToHttp{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "referrer_acl"); ok { - opts.ReferrerACL = &cdn.ReferrerACL{ - Enabled: opt["enabled"].(bool), - PolicyType: opt["policy_type"].(string), - } - for _, v := range opt["excepted_values"].(*schema.Set).List() { - opts.ReferrerACL.ExceptedValues = append(opts.ReferrerACL.ExceptedValues, v.(string)) - } - } - if opt, ok := getOptByName(fields, "response_headers_hiding_policy"); ok { - opts.ResponseHeadersHidingPolicy = &cdn.ResponseHeadersHidingPolicy{ - Enabled: opt["enabled"].(bool), - Mode: opt["mode"].(string), - } - for _, v := range opt["excepted"].(*schema.Set).List() { - opts.ResponseHeadersHidingPolicy.Excepted = append(opts.ResponseHeadersHidingPolicy.Excepted, v.(string)) - } - } - if opt, ok := getOptByName(fields, "rewrite"); ok { - opts.Rewrite = &cdn.Rewrite{ - Enabled: opt["enabled"].(bool), - Body: opt["body"].(string), - Flag: opt["flag"].(string), - } - } - if opt, ok := getOptByName(fields, "secure_key"); ok { - opts.SecureKey = &cdn.SecureKey{ - Enabled: opt["enabled"].(bool), - Key: opt["key"].(string), - Type: opt["type"].(int), - } - } - if opt, ok := getOptByName(fields, "slice"); ok { - opts.Slice = &cdn.Slice{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "sni"); ok { - opts.SNI = &cdn.SNIOption{ - Enabled: opt["enabled"].(bool), - SNIType: opt["sni_type"].(string), - CustomHostname: opt["custom_hostname"].(string), - } - } - if opt, ok := getOptByName(fields, "stale"); ok { - opts.Stale = &cdn.Stale{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.Stale.Value = append(opts.Stale.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "static_headers"); ok { - opts.StaticHeaders = &cdn.StaticHeaders{ - Enabled: opt["enabled"].(bool), - Value: map[string]string{}, - } - for k, v := range opt["value"].(map[string]interface{}) { - opts.StaticHeaders.Value[k] = v.(string) - } - } - if opt, ok := getOptByName(fields, "static_request_headers"); ok { - opts.StaticRequestHeaders = &cdn.StaticRequestHeaders{ - Enabled: opt["enabled"].(bool), - Value: map[string]string{}, - } - for k, v := range opt["value"].(map[string]interface{}) { - opts.StaticRequestHeaders.Value[k] = v.(string) - } - } - if opt, ok := getOptByName(fields, "static_response_headers"); ok { - opts.StaticResponseHeaders = &cdn.StaticResponseHeaders{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].([]interface{}) { - itemData := v.(map[string]interface{}) - item := &cdn.StaticResponseHeadersItem{ - Name: itemData["name"].(string), - } - for _, val := range itemData["value"].(*schema.Set).List() { - item.Value = append(item.Value, val.(string)) - } - if _, ok := itemData["always"]; ok { - item.Always = itemData["always"].(bool) - } - opts.StaticResponseHeaders.Value = append(opts.StaticResponseHeaders.Value, *item) - } - } - if opt, ok := getOptByName(fields, "tls_versions"); ok { - opts.TLSVersions = &cdn.TLSVersions{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.TLSVersions.Value = append(opts.TLSVersions.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "use_default_le_chain"); ok { - opts.UseDefaultLEChain = &cdn.UseDefaultLEChain{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "user_agent_acl"); ok { - opts.UserAgentACL = &cdn.UserAgentACL{ - Enabled: opt["enabled"].(bool), - PolicyType: opt["policy_type"].(string), - } - for _, v := range opt["excepted_values"].(*schema.Set).List() { - opts.UserAgentACL.ExceptedValues = append(opts.UserAgentACL.ExceptedValues, v.(string)) - } - } - if opt, ok := getOptByName(fields, "websockets"); ok { - opts.WebSockets = &cdn.WebSockets{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - - return &opts -} - -func getOptByName(fields map[string]interface{}, name string) (map[string]interface{}, bool) { - if _, ok := fields[name]; !ok { - return nil, false - } - - container, ok := fields[name].([]interface{}) - if !ok { - return nil, false - } - - if len(container) == 0 { - return nil, false - } - - opt, ok := container[0].(map[string]interface{}) - if !ok { - return nil, false - } - - return opt, true -} - -func resourceOptionsToList(options *cdn.ResourceOptions) []interface{} { - result := make(map[string][]interface{}) - if options.AllowedHTTPMethods != nil { - m := structToMap(options.AllowedHTTPMethods) - result["allowed_http_methods"] = []interface{}{m} - } - if options.BrotliCompression != nil { - m := structToMap(options.BrotliCompression) - result["brotli_compression"] = []interface{}{m} - } - if options.BrowserCacheSettings != nil { - m := structToMap(options.BrowserCacheSettings) - result["browser_cache_settings"] = []interface{}{m} - } - if options.CacheHttpHeaders != nil { - m := structToMap(options.CacheHttpHeaders) - result["cache_http_headers"] = []interface{}{m} - } - if options.Cors != nil { - m := structToMap(options.Cors) - result["cors"] = []interface{}{m} - } - if options.CountryACL != nil { - m := structToMap(options.CountryACL) - result["country_acl"] = []interface{}{m} - } - if options.DisableProxyForceRanges != nil { - m := structToMap(options.DisableProxyForceRanges) - result["disable_proxy_force_ranges"] = []interface{}{m} - } - if options.EdgeCacheSettings != nil { - m := structToMap(options.EdgeCacheSettings) - result["edge_cache_settings"] = []interface{}{m} - } - if options.FetchCompressed != nil { - m := structToMap(options.FetchCompressed) - result["fetch_compressed"] = []interface{}{m} - } - if options.FollowOriginRedirect != nil { - m := structToMap(options.FollowOriginRedirect) - result["follow_origin_redirect"] = []interface{}{m} - } - if options.ForceReturn != nil { - m := structToMap(options.ForceReturn) - result["force_return"] = []interface{}{m} - } - if options.ForwardHostHeader != nil { - m := structToMap(options.ForwardHostHeader) - result["forward_host_header"] = []interface{}{m} - } - if options.GzipOn != nil { - m := structToMap(options.GzipOn) - result["gzip_on"] = []interface{}{m} - } - if options.HostHeader != nil { - m := structToMap(options.HostHeader) - result["host_header"] = []interface{}{m} - } - if options.HTTP3Enabled != nil { - m := structToMap(options.HTTP3Enabled) - result["http3_enabled"] = []interface{}{m} - } - if options.IgnoreCookie != nil { - m := structToMap(options.IgnoreCookie) - result["ignore_cookie"] = []interface{}{m} - } - if options.IgnoreQueryString != nil { - m := structToMap(options.IgnoreQueryString) - result["ignore_query_string"] = []interface{}{m} - } - if options.ImageStack != nil { - m := structToMap(options.ImageStack) - result["image_stack"] = []interface{}{m} - } - if options.IPAddressACL != nil { - m := structToMap(options.IPAddressACL) - result["ip_address_acl"] = []interface{}{m} - } - if options.LimitBandwidth != nil { - m := structToMap(options.LimitBandwidth) - result["limit_bandwidth"] = []interface{}{m} - } - if options.ProxyCacheMethodsSet != nil { - m := structToMap(options.ProxyCacheMethodsSet) - result["proxy_cache_methods_set"] = []interface{}{m} - } - if options.QueryParamsBlacklist != nil { - m := structToMap(options.QueryParamsBlacklist) - result["query_params_blacklist"] = []interface{}{m} - } - if options.QueryParamsWhitelist != nil { - m := structToMap(options.QueryParamsWhitelist) - result["query_params_whitelist"] = []interface{}{m} - } - if options.RedirectHttpsToHttp != nil { - m := structToMap(options.RedirectHttpsToHttp) - result["redirect_https_to_http"] = []interface{}{m} - } - if options.RedirectHttpToHttps != nil { - m := structToMap(options.RedirectHttpToHttps) - result["redirect_http_to_https"] = []interface{}{m} - } - if options.ReferrerACL != nil { - m := structToMap(options.ReferrerACL) - result["referrer_acl"] = []interface{}{m} - } - if options.ResponseHeadersHidingPolicy != nil { - m := structToMap(options.ResponseHeadersHidingPolicy) - result["response_headers_hiding_policy"] = []interface{}{m} - } - if options.Rewrite != nil { - m := structToMap(options.Rewrite) - result["rewrite"] = []interface{}{m} - } - if options.SecureKey != nil { - m := structToMap(options.SecureKey) - result["secure_key"] = []interface{}{m} - } - if options.Slice != nil { - m := structToMap(options.Slice) - result["slice"] = []interface{}{m} - } - if options.SNI != nil { - m := structToMap(options.SNI) - result["sni"] = []interface{}{m} - } - if options.Stale != nil { - m := structToMap(options.Stale) - result["stale"] = []interface{}{m} - } - if options.StaticHeaders != nil { - m := structToMap(options.StaticHeaders) - result["static_headers"] = []interface{}{m} - } - if options.StaticRequestHeaders != nil { - m := structToMap(options.StaticRequestHeaders) - result["static_request_headers"] = []interface{}{m} - } - if options.StaticResponseHeaders != nil { - m := structToMap(options.StaticResponseHeaders) - items := []interface{}{} - for _, v := range m["value"].([]cdn.StaticResponseHeadersItem) { - items = append(items, structToMap(v)) - } - m["value"] = items - result["static_response_headers"] = []interface{}{m} - } - if options.TLSVersions != nil { - m := structToMap(options.TLSVersions) - result["tls_versions"] = []interface{}{m} - } - if options.UseDefaultLEChain != nil { - m := structToMap(options.UseDefaultLEChain) - result["use_default_le_chain"] = []interface{}{m} - } - if options.UserAgentACL != nil { - m := structToMap(options.UserAgentACL) - result["user_agent_acl"] = []interface{}{m} - } - if options.WebSockets != nil { - m := structToMap(options.WebSockets) - result["websockets"] = []interface{}{m} - } - - return []interface{}{result} -} - -func structToMap(item interface{}) map[string]interface{} { - res := map[string]interface{}{} - if item == nil { - return res - } - v := reflect.TypeOf(item) - reflectValue := reflect.ValueOf(item) - reflectValue = reflect.Indirect(reflectValue) - - if v.Kind() == reflect.Ptr { - v = v.Elem() - } - for i := 0; i < v.NumField(); i++ { - tag := v.Field(i).Tag.Get("json") - field := reflectValue.Field(i).Interface() - if tag != "" && tag != "-" { - if v.Field(i).Type.Kind() == reflect.Struct { - res[tag] = structToMap(field) - } else { - res[tag] = field - } - } - } - - return res -} diff --git a/edgecenter/resource_edgecenter_cdn_rule.go b/edgecenter/resource_edgecenter_cdn_rule.go deleted file mode 100644 index c20fc8ac..00000000 --- a/edgecenter/resource_edgecenter_cdn_rule.go +++ /dev/null @@ -1,1524 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "strconv" - - "github.com/AlekSi/pointer" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - cdn "github.com/Edge-Center/edgecentercdn-go/edgecenter" - "github.com/Edge-Center/edgecentercdn-go/rules" -) - -var locationOptionsSchema = &schema.Schema{ - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "Each option in CDN resource settings. Each option added to CDN resource settings should have the following mandatory request fields: enabled, value.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "allowed_http_methods": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "brotli_compression": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "browser_cache_settings": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeString, - Optional: true, - Description: "", - }, - }, - }, - }, - "cache_http_headers": { // Deprecated. Use - response_headers_hiding_policy. - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "cors": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - "always": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - }, - }, - }, - "country_acl": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "policy_type": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "excepted_values": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "disable_proxy_force_ranges": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "edge_cache_settings": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "The cache expiration time for CDN servers.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeString, - Optional: true, - Description: "Caching time for a response with codes 200, 206, 301, 302. Responses with codes 4xx, 5xx will not be cached. Use '0s' disable to caching. Use custom_values field to specify a custom caching time for a response with specific codes.", - }, - "default": { - Type: schema.TypeString, - Optional: true, - Description: "Content will be cached according to origin cache settings. The value applies for a response with codes 200, 201, 204, 206, 301, 302, 303, 304, 307, 308 if an origin server does not have caching HTTP headers. Responses with other codes will not be cached.", - }, - "custom_values": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - DefaultFunc: func() (interface{}, error) { - return map[string]interface{}{}, nil - }, - Elem: schema.TypeString, - Description: "Caching time for a response with specific codes. These settings have a higher priority than the value field. Response code ('304', '404' for example). Use 'any' to specify caching time for all response codes. Caching time in seconds ('0s', '600s' for example). Use '0s' to disable caching for a specific response code.", - }, - }, - }, - }, - "fetch_compressed": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "follow_origin_redirect": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "codes": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeInt}, - Required: true, - Description: "", - }, - }, - }, - }, - "force_return": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "code": { - Type: schema.TypeInt, - Required: true, - Description: "", - }, - "body": { - Type: schema.TypeString, - Optional: true, - Default: "", - Description: "", - }, - }, - }, - }, - "forward_host_header": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "gzip_on": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "host_header": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Specify the Host header that CDN servers use when request content from an origin server. Your server must be able to process requests with the chosen header. If the option is in NULL state Host Header value is taken from the CNAME field.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - "ignore_cookie": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "ignore_query_string": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "image_stack": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "avif_enabled": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - "webp_enabled": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - "quality": { - Type: schema.TypeInt, - Required: true, - Description: "", - }, - "png_lossless": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - }, - }, - }, - "ip_address_acl": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "policy_type": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "excepted_values": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "limit_bandwidth": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "limit_type": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "speed": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "", - }, - "buffer": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "", - }, - }, - }, - }, - "proxy_cache_methods_set": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "query_params_blacklist": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - }, - }, - }, - }, - "query_params_whitelist": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - }, - }, - }, - }, - "redirect_http_to_https": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Sets redirect from HTTP protocol to HTTPS for all resource requests.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "redirect_https_to_http": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "referrer_acl": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "policy_type": { - Type: schema.TypeString, - Required: true, - Description: "Possible values: allow, deny.", - }, - "excepted_values": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "response_headers_hiding_policy": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "mode": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "excepted": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "rewrite": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "body": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "flag": { - Type: schema.TypeString, - Optional: true, - Default: "break", - Description: "", - }, - }, - }, - }, - "secure_key": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "key": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "type": { - Type: schema.TypeInt, - Required: true, - Description: "", - }, - }, - }, - }, - "slice": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - "sni": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "sni_type": { - Type: schema.TypeString, - Optional: true, - Description: "Available values 'dynamic' or 'custom'", - }, - "custom_hostname": { - Type: schema.TypeString, - Optional: true, - Description: "Required to set custom hostname in case sni-type='custom'", - }, - }, - }, - }, - "stale": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Computed: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "static_headers": { // Deprecated. Use - static_response_headers. - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Option has been deprecated. Use - static_response_headers.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeMap, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - }, - }, - }, - }, - "static_request_headers": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeMap, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "static_response_headers": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "Specify custom HTTP Headers that a CDN server adds to a response.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "value": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - "always": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "", - }, - }, - }, - }, - }, - }, - }, - "user_agent_acl": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "policy_type": { - Type: schema.TypeString, - Required: true, - Description: "", - }, - "excepted_values": { - Type: schema.TypeSet, - Elem: &schema.Schema{Type: schema.TypeString}, - Required: true, - Description: "", - }, - }, - }, - }, - "websockets": { - Type: schema.TypeList, - MaxItems: 1, - Optional: true, - Description: "", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "enabled": { - Type: schema.TypeBool, - Optional: true, - Default: true, - }, - "value": { - Type: schema.TypeBool, - Required: true, - }, - }, - }, - }, - }, - }, -} - -func resourceCDNRule() *schema.Resource { - return &schema.Resource{ - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - Schema: map[string]*schema.Schema{ - "resource_id": { - Type: schema.TypeInt, - Required: true, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "Rule name", - }, - "rule": { - Type: schema.TypeString, - Required: true, - Description: "A pattern that defines when the rule is triggered. By default, we add a leading forward slash to any rule pattern. Specify a pattern without a forward slash.", - }, - "active": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "Shows if the location is enabled.", - }, - "weight": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "", - }, - "origin_group": { - Type: schema.TypeInt, - Optional: true, - Description: "ID of the Origins Group. Use one of your Origins Group or create a new one. You can use either 'origin' parameter or 'originGroup' in the resource definition.", - }, - "origin_protocol": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "This option defines the protocol that will be used by CDN servers to request content from an origin source. If not specified, it will be inherit from resource. Possible values are: HTTPS, HTTP, MATCH.", - }, - "options": locationOptionsSchema, - }, - CreateContext: resourceCDNRuleCreate, - ReadContext: resourceCDNRuleRead, - UpdateContext: resourceCDNRuleUpdate, - DeleteContext: resourceCDNRuleDelete, - Description: "Represent cdn resource rule", - } -} - -func resourceCDNRuleCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start CDN Rule creating") - config := m.(*Config) - client := config.CDNClient - - var req rules.CreateRequest - req.Name = d.Get("name").(string) - req.Rule = d.Get("rule").(string) - - if d.Get("active") != nil { - req.Active = d.Get("active").(bool) - } - - if d.Get("weight") != nil { - req.Weight = d.Get("weight").(int) - } - - if d.Get("origin_group") != nil && d.Get("origin_group").(int) > 0 { - req.OriginGroup = pointer.ToInt(d.Get("origin_group").(int)) - } - - if d.Get("origin_protocol") != nil && d.Get("origin_protocol") != "" { - req.OverrideOriginProtocol = pointer.ToString(d.Get("origin_protocol").(string)) - } - - resourceID := d.Get("resource_id").(int) - - req.Options = listToLocationOptions(d.Get("options").([]interface{})) - - result, err := client.Rules().Create(ctx, int64(resourceID), &req) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(fmt.Sprintf("%d", result.ID)) - resourceCDNRuleRead(ctx, d, m) - - log.Printf("[DEBUG] Finish CDN Rule creating (id=%d)\n", result.ID) - - return nil -} - -func resourceCDNRuleRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - ruleID := d.Id() - log.Printf("[DEBUG] Start CDN Rule reading (id=%s)\n", ruleID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(ruleID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - resourceID := d.Get("resource_id").(int) - - result, err := client.Rules().Get(ctx, int64(resourceID), id) - if err != nil { - return diag.FromErr(err) - } - - d.Set("name", result.Name) - d.Set("rule", result.Pattern) - d.Set("active", result.Active) - d.Set("origin_group", result.OriginGroup) - d.Set("origin_protocol", result.OriginProtocol) - d.Set("weight", result.Weight) - if err := d.Set("options", locationOptionsToList(result.Options)); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish CDN Rule reading") - - return nil -} - -func resourceCDNRuleUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - ruleID := d.Id() - log.Printf("[DEBUG] Start CDN Rule updating (id=%s)\n", ruleID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(ruleID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - var req rules.UpdateRequest - req.Name = d.Get("name").(string) - req.Rule = d.Get("rule").(string) - req.Active = d.Get("active").(bool) - - if d.Get("weight") != nil { - req.Weight = d.Get("weight").(int) - } - - if d.Get("origin_group") != nil && d.Get("origin_group").(int) > 0 { - req.OriginGroup = pointer.ToInt(d.Get("origin_group").(int)) - } - - if d.Get("origin_protocol") != nil && d.Get("origin_protocol") != "" { - req.OverrideOriginProtocol = pointer.ToString(d.Get("origin_protocol").(string)) - } - - req.Options = listToLocationOptions(d.Get("options").([]interface{})) - - resourceID := d.Get("resource_id").(int) - - if _, err := client.Rules().Update(ctx, int64(resourceID), id, &req); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish CDN Rule updating") - - return resourceCDNRuleRead(ctx, d, m) -} - -func resourceCDNRuleDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - ruleID := d.Id() - log.Printf("[DEBUG] Start CDN Rule deleting (id=%s)\n", ruleID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(ruleID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - resourceID := d.Get("resource_id").(int) - - if err := client.Rules().Delete(ctx, int64(resourceID), id); err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Println("[DEBUG] Finish CDN Rule deleting") - - return nil -} - -func listToLocationOptions(l []interface{}) *cdn.LocationOptions { - if len(l) == 0 { - return nil - } - - var opts cdn.LocationOptions - fields := l[0].(map[string]interface{}) - if opt, ok := getOptByName(fields, "allowed_http_methods"); ok { - opts.AllowedHTTPMethods = &cdn.AllowedHTTPMethods{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.AllowedHTTPMethods.Value = append(opts.AllowedHTTPMethods.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "brotli_compression"); ok { - opts.BrotliCompression = &cdn.BrotliCompression{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.BrotliCompression.Value = append(opts.BrotliCompression.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "browser_cache_settings"); ok { - opts.BrowserCacheSettings = &cdn.BrowserCacheSettings{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(string), - } - } - if opt, ok := getOptByName(fields, "cache_http_headers"); ok { - opts.CacheHttpHeaders = &cdn.CacheHttpHeaders{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.CacheHttpHeaders.Value = append(opts.CacheHttpHeaders.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "cors"); ok { - opts.Cors = &cdn.Cors{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.Cors.Value = append(opts.Cors.Value, v.(string)) - } - if _, ok := opt["always"]; ok { - opts.Cors.Always = opt["always"].(bool) - } - } - if opt, ok := getOptByName(fields, "country_acl"); ok { - opts.CountryACL = &cdn.CountryACL{ - Enabled: opt["enabled"].(bool), - PolicyType: opt["policy_type"].(string), - } - for _, v := range opt["excepted_values"].(*schema.Set).List() { - opts.CountryACL.ExceptedValues = append(opts.CountryACL.ExceptedValues, v.(string)) - } - } - if opt, ok := getOptByName(fields, "disable_proxy_force_ranges"); ok { - opts.DisableProxyForceRanges = &cdn.DisableProxyForceRanges{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "edge_cache_settings"); ok { - rawCustomVals := opt["custom_values"].(map[string]interface{}) - customVals := make(map[string]string, len(rawCustomVals)) - for key, value := range rawCustomVals { - customVals[key] = value.(string) - } - - opts.EdgeCacheSettings = &cdn.EdgeCacheSettings{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(string), - CustomValues: customVals, - Default: opt["default"].(string), - } - } - if opt, ok := getOptByName(fields, "fetch_compressed"); ok { - opts.FetchCompressed = &cdn.FetchCompressed{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "follow_origin_redirect"); ok { - opts.FollowOriginRedirect = &cdn.FollowOriginRedirect{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["codes"].(*schema.Set).List() { - opts.FollowOriginRedirect.Codes = append(opts.FollowOriginRedirect.Codes, v.(int)) - } - } - if opt, ok := getOptByName(fields, "force_return"); ok { - opts.ForceReturn = &cdn.ForceReturn{ - Enabled: opt["enabled"].(bool), - Code: opt["code"].(int), - Body: opt["body"].(string), - } - } - if opt, ok := getOptByName(fields, "forward_host_header"); ok { - opts.ForwardHostHeader = &cdn.ForwardHostHeader{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "gzip_on"); ok { - opts.GzipOn = &cdn.GzipOn{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "host_header"); ok { - opts.HostHeader = &cdn.HostHeader{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(string), - } - } - if opt, ok := getOptByName(fields, "ignore_cookie"); ok { - opts.IgnoreCookie = &cdn.IgnoreCookie{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "ignore_query_string"); ok { - opts.IgnoreQueryString = &cdn.IgnoreQueryString{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "image_stack"); ok { - opts.ImageStack = &cdn.ImageStack{ - Enabled: opt["enabled"].(bool), - Quality: opt["quality"].(int), - } - if _, ok := opt["avif_enabled"]; ok { - opts.ImageStack.AvifEnabled = opt["avif_enabled"].(bool) - } - if _, ok := opt["webp_enabled"]; ok { - opts.ImageStack.WebpEnabled = opt["webp_enabled"].(bool) - } - if _, ok := opt["png_lossless"]; ok { - opts.ImageStack.PngLossless = opt["png_lossless"].(bool) - } - } - if opt, ok := getOptByName(fields, "ip_address_acl"); ok { - opts.IPAddressACL = &cdn.IPAddressACL{ - Enabled: opt["enabled"].(bool), - PolicyType: opt["policy_type"].(string), - } - for _, v := range opt["excepted_values"].(*schema.Set).List() { - opts.IPAddressACL.ExceptedValues = append(opts.IPAddressACL.ExceptedValues, v.(string)) - } - } - if opt, ok := getOptByName(fields, "limit_bandwidth"); ok { - opts.LimitBandwidth = &cdn.LimitBandwidth{ - Enabled: opt["enabled"].(bool), - LimitType: opt["limit_type"].(string), - } - if _, ok := opt["speed"]; ok { - opts.LimitBandwidth.Speed = opt["speed"].(int) - } - if _, ok := opt["buffer"]; ok { - opts.LimitBandwidth.Buffer = opt["buffer"].(int) - } - } - if opt, ok := getOptByName(fields, "proxy_cache_methods_set"); ok { - opts.ProxyCacheMethodsSet = &cdn.ProxyCacheMethodsSet{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "query_params_blacklist"); ok { - opts.QueryParamsBlacklist = &cdn.QueryParamsBlacklist{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.QueryParamsBlacklist.Value = append(opts.QueryParamsBlacklist.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "query_params_whitelist"); ok { - opts.QueryParamsWhitelist = &cdn.QueryParamsWhitelist{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.QueryParamsWhitelist.Value = append(opts.QueryParamsWhitelist.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "redirect_http_to_https"); ok { - opts.RedirectHttpToHttps = &cdn.RedirectHttpToHttps{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "redirect_https_to_http"); ok { - opts.RedirectHttpsToHttp = &cdn.RedirectHttpsToHttp{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "referrer_acl"); ok { - opts.ReferrerACL = &cdn.ReferrerACL{ - Enabled: opt["enabled"].(bool), - PolicyType: opt["policy_type"].(string), - } - for _, v := range opt["excepted_values"].(*schema.Set).List() { - opts.ReferrerACL.ExceptedValues = append(opts.ReferrerACL.ExceptedValues, v.(string)) - } - } - if opt, ok := getOptByName(fields, "response_headers_hiding_policy"); ok { - opts.ResponseHeadersHidingPolicy = &cdn.ResponseHeadersHidingPolicy{ - Enabled: opt["enabled"].(bool), - Mode: opt["mode"].(string), - } - for _, v := range opt["excepted"].(*schema.Set).List() { - opts.ResponseHeadersHidingPolicy.Excepted = append(opts.ResponseHeadersHidingPolicy.Excepted, v.(string)) - } - } - if opt, ok := getOptByName(fields, "rewrite"); ok { - opts.Rewrite = &cdn.Rewrite{ - Enabled: opt["enabled"].(bool), - Body: opt["body"].(string), - Flag: opt["flag"].(string), - } - } - if opt, ok := getOptByName(fields, "secure_key"); ok { - opts.SecureKey = &cdn.SecureKey{ - Enabled: opt["enabled"].(bool), - Key: opt["key"].(string), - Type: opt["type"].(int), - } - } - if opt, ok := getOptByName(fields, "slice"); ok { - opts.Slice = &cdn.Slice{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - if opt, ok := getOptByName(fields, "sni"); ok { - opts.SNI = &cdn.SNIOption{ - Enabled: opt["enabled"].(bool), - SNIType: opt["sni_type"].(string), - CustomHostname: opt["custom_hostname"].(string), - } - } - if opt, ok := getOptByName(fields, "stale"); ok { - opts.Stale = &cdn.Stale{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].(*schema.Set).List() { - opts.Stale.Value = append(opts.Stale.Value, v.(string)) - } - } - if opt, ok := getOptByName(fields, "static_headers"); ok { - opts.StaticHeaders = &cdn.StaticHeaders{ - Enabled: opt["enabled"].(bool), - Value: map[string]string{}, - } - for k, v := range opt["value"].(map[string]interface{}) { - opts.StaticHeaders.Value[k] = v.(string) - } - } - if opt, ok := getOptByName(fields, "static_request_headers"); ok { - opts.StaticRequestHeaders = &cdn.StaticRequestHeaders{ - Enabled: opt["enabled"].(bool), - Value: map[string]string{}, - } - for k, v := range opt["value"].(map[string]interface{}) { - opts.StaticRequestHeaders.Value[k] = v.(string) - } - } - if opt, ok := getOptByName(fields, "static_response_headers"); ok { - opts.StaticResponseHeaders = &cdn.StaticResponseHeaders{ - Enabled: opt["enabled"].(bool), - } - for _, v := range opt["value"].([]interface{}) { - itemData := v.(map[string]interface{}) - item := &cdn.StaticResponseHeadersItem{ - Name: itemData["name"].(string), - } - for _, val := range itemData["value"].(*schema.Set).List() { - item.Value = append(item.Value, val.(string)) - } - if _, ok := itemData["always"]; ok { - item.Always = itemData["always"].(bool) - } - opts.StaticResponseHeaders.Value = append(opts.StaticResponseHeaders.Value, *item) - } - } - if opt, ok := getOptByName(fields, "user_agent_acl"); ok { - opts.UserAgentACL = &cdn.UserAgentACL{ - Enabled: opt["enabled"].(bool), - PolicyType: opt["policy_type"].(string), - } - for _, v := range opt["excepted_values"].(*schema.Set).List() { - opts.UserAgentACL.ExceptedValues = append(opts.UserAgentACL.ExceptedValues, v.(string)) - } - } - if opt, ok := getOptByName(fields, "websockets"); ok { - opts.WebSockets = &cdn.WebSockets{ - Enabled: opt["enabled"].(bool), - Value: opt["value"].(bool), - } - } - - return &opts -} - -func locationOptionsToList(options *cdn.LocationOptions) []interface{} { - result := make(map[string][]interface{}) - if options.AllowedHTTPMethods != nil { - m := structToMap(options.AllowedHTTPMethods) - result["allowed_http_methods"] = []interface{}{m} - } - if options.BrotliCompression != nil { - m := structToMap(options.BrotliCompression) - result["brotli_compression"] = []interface{}{m} - } - if options.BrowserCacheSettings != nil { - m := structToMap(options.BrowserCacheSettings) - result["browser_cache_settings"] = []interface{}{m} - } - if options.CacheHttpHeaders != nil { - m := structToMap(options.CacheHttpHeaders) - result["cache_http_headers"] = []interface{}{m} - } - if options.Cors != nil { - m := structToMap(options.Cors) - result["cors"] = []interface{}{m} - } - if options.CountryACL != nil { - m := structToMap(options.CountryACL) - result["country_acl"] = []interface{}{m} - } - if options.DisableProxyForceRanges != nil { - m := structToMap(options.DisableProxyForceRanges) - result["disable_proxy_force_ranges"] = []interface{}{m} - } - if options.EdgeCacheSettings != nil { - m := structToMap(options.EdgeCacheSettings) - result["edge_cache_settings"] = []interface{}{m} - } - if options.FetchCompressed != nil { - m := structToMap(options.FetchCompressed) - result["fetch_compressed"] = []interface{}{m} - } - if options.FollowOriginRedirect != nil { - m := structToMap(options.FollowOriginRedirect) - result["follow_origin_redirect"] = []interface{}{m} - } - if options.ForceReturn != nil { - m := structToMap(options.ForceReturn) - result["force_return"] = []interface{}{m} - } - if options.ForwardHostHeader != nil { - m := structToMap(options.ForwardHostHeader) - result["forward_host_header"] = []interface{}{m} - } - if options.GzipOn != nil { - m := structToMap(options.GzipOn) - result["gzip_on"] = []interface{}{m} - } - if options.HostHeader != nil { - m := structToMap(options.HostHeader) - result["host_header"] = []interface{}{m} - } - if options.IgnoreCookie != nil { - m := structToMap(options.IgnoreCookie) - result["ignore_cookie"] = []interface{}{m} - } - if options.IgnoreQueryString != nil { - m := structToMap(options.IgnoreQueryString) - result["ignore_query_string"] = []interface{}{m} - } - if options.ImageStack != nil { - m := structToMap(options.ImageStack) - result["image_stack"] = []interface{}{m} - } - if options.IPAddressACL != nil { - m := structToMap(options.IPAddressACL) - result["ip_address_acl"] = []interface{}{m} - } - if options.LimitBandwidth != nil { - m := structToMap(options.LimitBandwidth) - result["limit_bandwidth"] = []interface{}{m} - } - if options.ProxyCacheMethodsSet != nil { - m := structToMap(options.ProxyCacheMethodsSet) - result["proxy_cache_methods_set"] = []interface{}{m} - } - if options.QueryParamsBlacklist != nil { - m := structToMap(options.QueryParamsBlacklist) - result["query_params_blacklist"] = []interface{}{m} - } - if options.QueryParamsWhitelist != nil { - m := structToMap(options.QueryParamsWhitelist) - result["query_params_whitelist"] = []interface{}{m} - } - if options.RedirectHttpsToHttp != nil { - m := structToMap(options.RedirectHttpsToHttp) - result["redirect_https_to_http"] = []interface{}{m} - } - if options.RedirectHttpToHttps != nil { - m := structToMap(options.RedirectHttpToHttps) - result["redirect_http_to_https"] = []interface{}{m} - } - if options.ReferrerACL != nil { - m := structToMap(options.ReferrerACL) - result["referrer_acl"] = []interface{}{m} - } - if options.ResponseHeadersHidingPolicy != nil { - m := structToMap(options.ResponseHeadersHidingPolicy) - result["response_headers_hiding_policy"] = []interface{}{m} - } - if options.Rewrite != nil { - m := structToMap(options.Rewrite) - result["rewrite"] = []interface{}{m} - } - if options.SecureKey != nil { - m := structToMap(options.SecureKey) - result["secure_key"] = []interface{}{m} - } - if options.Slice != nil { - m := structToMap(options.Slice) - result["slice"] = []interface{}{m} - } - if options.SNI != nil { - m := structToMap(options.SNI) - result["sni"] = []interface{}{m} - } - if options.Stale != nil { - m := structToMap(options.Stale) - result["stale"] = []interface{}{m} - } - if options.StaticHeaders != nil { - m := structToMap(options.StaticHeaders) - result["static_headers"] = []interface{}{m} - } - if options.StaticRequestHeaders != nil { - m := structToMap(options.StaticRequestHeaders) - result["static_request_headers"] = []interface{}{m} - } - if options.StaticResponseHeaders != nil { - m := structToMap(options.StaticResponseHeaders) - items := []interface{}{} - for _, v := range m["value"].([]cdn.StaticResponseHeadersItem) { - items = append(items, structToMap(v)) - } - m["value"] = items - result["static_response_headers"] = []interface{}{m} - } - if options.UserAgentACL != nil { - m := structToMap(options.UserAgentACL) - result["user_agent_acl"] = []interface{}{m} - } - if options.WebSockets != nil { - m := structToMap(options.WebSockets) - result["websockets"] = []interface{}{m} - } - - return []interface{}{result} -} diff --git a/edgecenter/resource_edgecenter_cdn_sslcerts.go b/edgecenter/resource_edgecenter_cdn_sslcerts.go deleted file mode 100644 index 9c1a6451..00000000 --- a/edgecenter/resource_edgecenter_cdn_sslcerts.go +++ /dev/null @@ -1,124 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "strconv" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercdn-go/sslcerts" -) - -func resourceCDNCert() *schema.Resource { - return &schema.Resource{ - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "Name of the SSL certificate. Must be unique.", - }, - "cert": { - Type: schema.TypeString, - Required: true, - Sensitive: true, - ForceNew: true, - Description: "The public part of the SSL certificate. All chain of the SSL certificate should be added.", - }, - "private_key": { - Type: schema.TypeString, - Required: true, - Sensitive: true, - ForceNew: true, - Description: "The private key of the SSL certificate.", - }, - "has_related_resources": { - Type: schema.TypeBool, - Computed: true, - Description: "It shows if the SSL certificate is used by a CDN resource.", - }, - "automated": { - Type: schema.TypeBool, - Computed: true, - Description: "The way SSL certificate was issued.", - }, - }, - CreateContext: resourceCDNCertCreate, - ReadContext: resourceCDNCertRead, - DeleteContext: resourceCDNCertDelete, - } -} - -func resourceCDNCertCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start CDN Cert creating") - config := m.(*Config) - client := config.CDNClient - - var req sslcerts.CreateRequest - req.Name = d.Get("name").(string) - req.Cert = d.Get("cert").(string) - req.PrivateKey = d.Get("private_key").(string) - - result, err := client.SSLCerts().Create(ctx, &req) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(fmt.Sprintf("%d", result.ID)) - resourceCDNCertRead(ctx, d, m) - - log.Printf("[DEBUG] Finish CDN Cert creating (id=%d)\n", result.ID) - - return nil -} - -func resourceCDNCertRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - certID := d.Id() - log.Printf("[DEBUG] Start CDN Cert reading (id=%s)\n", certID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(certID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - result, err := client.SSLCerts().Get(ctx, id) - if err != nil { - return diag.FromErr(err) - } - - d.Set("has_related_resources", result.HasRelatedResources) - d.Set("automated", result.Automated) - - log.Println("[DEBUG] Finish CDN Cert reading") - - return nil -} - -func resourceCDNCertDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - certID := d.Id() - log.Printf("[DEBUG] Start CDN Cert deleting (id=%s)\n", certID) - config := m.(*Config) - client := config.CDNClient - - id, err := strconv.ParseInt(certID, 10, 64) - if err != nil { - return diag.FromErr(err) - } - - if err := client.SSLCerts().Delete(ctx, id); err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Println("[DEBUG] Finish CDN Cert deleting") - - return nil -} diff --git a/edgecenter/resource_edgecenter_dns_zone.go b/edgecenter/resource_edgecenter_dns_zone.go deleted file mode 100644 index e179aa75..00000000 --- a/edgecenter/resource_edgecenter_dns_zone.go +++ /dev/null @@ -1,120 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "strings" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" -) - -const ( - DNSZoneResource = "edgecenter_dns_zone" - DNSZoneSchemaName = "name" -) - -func resourceDNSZone() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - DNSZoneSchemaName: { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - zoneName := i.(string) - if strings.TrimSpace(zoneName) == "" || len(zoneName) > 255 { - return diag.Errorf("dns name can't be empty, it also should be less than 256 symbols") - } - return nil - }, - Description: "A name of DNS Zone resource.", - }, - }, - CreateContext: checkDNSDependency(resourceDNSZoneCreate), - ReadContext: checkDNSDependency(resourceDNSZoneRead), - DeleteContext: checkDNSDependency(resourceDNSZoneDelete), - Description: "Represent DNS zone resource. https://dns.edgecenter.ru/zones", - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - } -} - -func checkDNSDependency(next func(context.Context, *schema.ResourceData, - interface{}) diag.Diagnostics, -) func(context.Context, *schema.ResourceData, interface{}) diag.Diagnostics { - return func(ctx context.Context, data *schema.ResourceData, i interface{}) diag.Diagnostics { - config := i.(*Config) - client := config.DNSClient - if client == nil { - return diag.Errorf("dns api client is null. make sure that you defined edgecenter_dns_api var in edgecenter provider section.") - } - return next(ctx, data, i) - } -} - -func resourceDNSZoneCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - name := strings.TrimSpace(d.Get(DNSZoneSchemaName).(string)) - log.Println("[DEBUG] Start DNS Zone Resource creating") - defer log.Printf("[DEBUG] Finish DNS Zone Resource creating (id=%s)\n", name) - - config := m.(*Config) - client := config.DNSClient - - _, err := client.CreateZone(ctx, name) - if err != nil { - return diag.FromErr(fmt.Errorf("create zone: %w", err)) - } - d.SetId(name) - - return resourceDNSZoneRead(ctx, d, m) -} - -func resourceDNSZoneRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - zoneName := dnsZoneResourceID(d) - log.Printf("[DEBUG] Start DNS Zone Resource reading (id=%s)\n", zoneName) - defer log.Println("[DEBUG] Finish DNS Zone Resource reading") - - config := m.(*Config) - client := config.DNSClient - - result, err := client.Zone(ctx, zoneName) - if err != nil { - return diag.FromErr(fmt.Errorf("get zone: %w", err)) - } - d.SetId(result.Name) - _ = d.Set(DNSZoneSchemaName, result.Name) - - return nil -} - -func resourceDNSZoneDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - zoneName := dnsZoneResourceID(d) - log.Printf("[DEBUG] Start DNS Zone Resource deleting (id=%s)\n", zoneName) - defer log.Println("[DEBUG] Finish DNS Zone Resource deleting") - if zoneName == "" { - return diag.Errorf("empty zone name") - } - - config := m.(*Config) - client := config.DNSClient - - err := client.DeleteZone(ctx, zoneName) - if err != nil { - return diag.FromErr(fmt.Errorf("delete zone: %w", err)) - } - d.SetId("") - - return nil -} - -func dnsZoneResourceID(d *schema.ResourceData) string { - resourceID := d.Id() - if resourceID == "" { - resourceID = d.Get(DNSZoneSchemaName).(string) - } - return resourceID -} diff --git a/edgecenter/resource_edgecenter_dns_zone_record.go b/edgecenter/resource_edgecenter_dns_zone_record.go deleted file mode 100644 index 42b1623d..00000000 --- a/edgecenter/resource_edgecenter_dns_zone_record.go +++ /dev/null @@ -1,502 +0,0 @@ -package edgecenter - -import ( - "context" - "encoding/json" - "fmt" - "log" - "net" - "strings" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - dnssdk "github.com/Edge-Center/edgecenter-dns-sdk-go" -) - -const ( - DNSZoneRecordResource = "edgecenter_dns_zone_record" - - DNSZoneRecordSchemaZone = "zone" - DNSZoneRecordSchemaDomain = "domain" - DNSZoneRecordSchemaType = "type" - DNSZoneRecordSchemaTTL = "ttl" - DNSZoneRecordSchemaFilter = "filter" - - DNSZoneRecordSchemaFilterLimit = "limit" - DNSZoneRecordSchemaFilterType = "type" - DNSZoneRecordSchemaFilterStrict = "strict" - - DNSZoneRecordSchemaResourceRecord = "resource_record" - DNSZoneRecordSchemaContent = "content" - DNSZoneRecordSchemaEnabled = "enabled" - DNSZoneRecordSchemaMeta = "meta" - - DNSZoneRecordSchemaMetaAsn = "asn" - DNSZoneRecordSchemaMetaIP = "ip" - DNSZoneRecordSchemaMetaCountries = "countries" - DNSZoneRecordSchemaMetaContinents = "continents" - DNSZoneRecordSchemaMetaLatLong = "latlong" - DNSZoneRecordSchemaMetaNotes = "notes" - DNSZoneRecordSchemaMetaDefault = "default" -) - -func resourceDNSZoneRecord() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - DNSZoneRecordSchemaZone: { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - val := i.(string) - if strings.TrimSpace(val) == "" || len(val) > 255 { - return diag.Errorf("dns record zone can't be empty, it also should be less than 256 symbols") - } - return nil - }, - Description: "A zone of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaDomain: { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - val := i.(string) - if strings.TrimSpace(val) == "" || len(val) > 255 { - return diag.Errorf("dns record domain can't be empty, it also should be less than 256 symbols") - } - return nil - }, - Description: "A domain of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaType: { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - val := strings.TrimSpace(i.(string)) - types := []string{"A", "AAAA", "MX", "CNAME", "TXT", "CAA", "NS", "SRV"} - for _, t := range types { - if strings.EqualFold(t, val) { - return nil - } - } - return diag.Errorf("dns record type should be one of %v", types) - }, - Description: "A type of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaTTL: { - Type: schema.TypeInt, - Optional: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - val := i.(int) - if val < 0 { - return diag.Errorf("dns record ttl can't be less than 0") - } - return nil - }, - Description: "A ttl of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaFilter: { - Type: schema.TypeSet, - Optional: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - DNSZoneRecordSchemaFilterLimit: { - Type: schema.TypeInt, - Optional: true, - Description: "A DNS Zone Record filter option that describe how many records will be percolated.", - }, - DNSZoneRecordSchemaFilterStrict: { - Type: schema.TypeBool, - Optional: true, - Description: "A DNS Zone Record filter option that describe possibility to return answers if no records were percolated through filter.", - }, - DNSZoneRecordSchemaFilterType: { - Type: schema.TypeString, - Required: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - names := []string{"geodns", "geodistance", "default", "first_n"} - name := i.(string) - for _, n := range names { - if n == name { - return nil - } - } - return diag.Errorf("dns record filter type should be one of %v", names) - }, - Description: "A DNS Zone Record filter option that describe a name of filter.", - }, - }, - }, - }, - DNSZoneRecordSchemaResourceRecord: { - Type: schema.TypeSet, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - DNSZoneRecordSchemaContent: { - Type: schema.TypeString, - Required: true, - Description: `A content of DNS Zone Record resource. (TXT: 'anyString', MX: '50 mail.company.io.', CAA: '0 issue "company.org; account=12345"')`, - }, - DNSZoneRecordSchemaEnabled: { - Type: schema.TypeBool, - Optional: true, - Default: true, - Description: "Manage of public appearing of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaMeta: { - Type: schema.TypeSet, - Optional: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - DNSZoneRecordSchemaMetaAsn: { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeInt, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - if i.(int) < 0 { - return diag.Errorf("asn cannot be less then 0") - } - return nil - }, - }, - Optional: true, - Description: "An asn meta (e.g. 12345) of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaMetaIP: { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeString, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - val := i.(string) - ip := net.ParseIP(val) - if ip == nil { - return diag.Errorf("dns record meta ip has wrong format: %s", val) - } - return nil - }, - }, - Optional: true, - Description: "An ip meta (e.g. 127.0.0.0) of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaMetaLatLong: { - Optional: true, - Type: schema.TypeList, - MaxItems: 2, - MinItems: 2, - Elem: &schema.Schema{ - Type: schema.TypeFloat, - }, - Description: "A latlong meta (e.g. 27.988056, 86.925278) of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaMetaNotes: { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Optional: true, - Description: "A notes meta (e.g. Miami DC) of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaMetaContinents: { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Optional: true, - Description: "Continents meta (e.g. Asia) of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaMetaCountries: { - Type: schema.TypeList, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - Optional: true, - Description: "Countries meta (e.g. USA) of DNS Zone Record resource.", - }, - DNSZoneRecordSchemaMetaDefault: { - Type: schema.TypeBool, - Optional: true, - Default: false, - Description: "Fallback meta equals true marks records which are used as a default answer (when nothing was selected by specified meta fields).", - }, - }, - }, - }, - }, - }, - Description: "An array of contents with meta of DNS Zone Record resource.", - }, - }, - CreateContext: checkDNSDependency(resourceDNSZoneRecordCreate), - UpdateContext: checkDNSDependency(resourceDNSZoneRecordUpdate), - ReadContext: checkDNSDependency(resourceDNSZoneRecordRead), - DeleteContext: checkDNSDependency(resourceDNSZoneRecordDelete), - Description: "Represent DNS Zone Record resource. https://dns.edgecenter.ru/zones", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - parts := strings.Split(d.Id(), ":") - if len(parts) != 3 { - return nil, fmt.Errorf("format must be as zone:domain:type") - } - _ = d.Set(DNSZoneRecordSchemaZone, parts[0]) - d.SetId(parts[0]) - _ = d.Set(DNSZoneRecordSchemaDomain, parts[1]) - _ = d.Set(DNSZoneRecordSchemaType, parts[2]) - - return []*schema.ResourceData{d}, nil - }, - }, - } -} - -func resourceDNSZoneRecordCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - zone := strings.TrimSpace(d.Get(DNSZoneRecordSchemaZone).(string)) - domain := strings.TrimSpace(d.Get(DNSZoneRecordSchemaDomain).(string)) - rType := strings.TrimSpace(d.Get(DNSZoneRecordSchemaType).(string)) - log.Println("[DEBUG] Start DNS Zone Record Resource creating") - defer log.Printf("[DEBUG] Finish DNS Zone Record Resource creating (id=%s %s %s)\n", zone, domain, rType) - - ttl := d.Get(DNSZoneRecordSchemaTTL).(int) - rrSet := dnssdk.RRSet{TTL: ttl, Records: make([]dnssdk.ResourceRecord, 0)} - err := fillRRSet(d, rType, &rrSet) - if err != nil { - return diag.FromErr(err) - } - - config := m.(*Config) - client := config.DNSClient - - _, err = client.Zone(ctx, zone) - if err != nil { - return diag.FromErr(fmt.Errorf("find zone: %w", err)) - } - - err = client.CreateRRSet(ctx, zone, domain, rType, rrSet) - if err != nil { - return diag.FromErr(fmt.Errorf("create zone rrset: %w", err)) - } - d.SetId(zone) - - return resourceDNSZoneRecordRead(ctx, d, m) -} - -func resourceDNSZoneRecordUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - if d.Id() == "" { - return diag.Errorf("empty id") - } - zone := strings.TrimSpace(d.Get(DNSZoneRecordSchemaZone).(string)) - domain := strings.TrimSpace(d.Get(DNSZoneRecordSchemaDomain).(string)) - rType := strings.TrimSpace(d.Get(DNSZoneRecordSchemaType).(string)) - log.Println("[DEBUG] Start DNS Zone Record Resource updating") - defer log.Printf("[DEBUG] Finish DNS Zone Record Resource updating (id=%s %s %s)\n", zone, domain, rType) - - ttl := d.Get(DNSZoneRecordSchemaTTL).(int) - rrSet := dnssdk.RRSet{TTL: ttl, Records: make([]dnssdk.ResourceRecord, 0)} - err := fillRRSet(d, rType, &rrSet) - if err != nil { - return diag.FromErr(err) - } - - config := m.(*Config) - client := config.DNSClient - - err = client.UpdateRRSet(ctx, zone, domain, rType, rrSet) - if err != nil { - return diag.FromErr(fmt.Errorf("update zone rrset: %w", err)) - } - d.SetId(zone) - - return resourceDNSZoneRecordRead(ctx, d, m) -} - -func resourceDNSZoneRecordRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - if d.Id() == "" { - return diag.Errorf("empty id") - } - zone := strings.TrimSpace(d.Get(DNSZoneRecordSchemaZone).(string)) - domain := strings.TrimSpace(d.Get(DNSZoneRecordSchemaDomain).(string)) - rType := strings.TrimSpace(d.Get(DNSZoneRecordSchemaType).(string)) - log.Println("[DEBUG] Start DNS Zone Record Resource reading") - defer log.Printf("[DEBUG] Finish DNS Zone Record Resource reading (id=%s %s %s)\n", zone, domain, rType) - - config := m.(*Config) - client := config.DNSClient - - result, err := client.RRSet(ctx, zone, domain, rType) - if err != nil { - return diag.FromErr(fmt.Errorf("get zone rrset: %w", err)) - } - id := struct{ Zone, Domain, Type string }{zone, domain, rType} //nolint: musttag - bs, err := json.Marshal(id) - if err != nil { - return diag.FromErr(err) - } - d.SetId(string(bs)) - _ = d.Set(DNSZoneRecordSchemaZone, zone) - _ = d.Set(DNSZoneRecordSchemaDomain, domain) - _ = d.Set(DNSZoneRecordSchemaType, rType) - _ = d.Set(DNSZoneRecordSchemaTTL, result.TTL) - - filters := make([]map[string]interface{}, 0) - for _, f := range result.Filters { - filters = append(filters, map[string]interface{}{ - DNSZoneRecordSchemaFilterLimit: f.Limit, - DNSZoneRecordSchemaFilterType: f.Type, - DNSZoneRecordSchemaFilterStrict: f.Strict, - }) - } - if len(filters) > 0 { - _ = d.Set(DNSZoneRecordSchemaFilter, filters) - } - - rr := make([]map[string]interface{}, 0) - for _, rec := range result.Records { - r := map[string]interface{}{} - r[DNSZoneRecordSchemaEnabled] = rec.Enabled - r[DNSZoneRecordSchemaContent] = rec.ContentToString() - meta := map[string]interface{}{} - for key, val := range rec.Meta { - meta[key] = val - } - if len(meta) > 0 { - r[DNSZoneRecordSchemaMeta] = []map[string]interface{}{meta} - } - rr = append(rr, r) - } - if len(rr) > 0 { - _ = d.Set(DNSZoneRecordSchemaResourceRecord, rr) - } - - return nil -} - -func resourceDNSZoneRecordDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - if d.Id() == "" { - return diag.Errorf("empty id") - } - zone := strings.TrimSpace(d.Get(DNSZoneRecordSchemaZone).(string)) - domain := strings.TrimSpace(d.Get(DNSZoneRecordSchemaDomain).(string)) - rType := strings.TrimSpace(d.Get(DNSZoneRecordSchemaType).(string)) - log.Println("[DEBUG] Start DNS Zone Record Resource deleting") - defer log.Printf("[DEBUG] Finish DNS Zone Record Resource deleting (id=%s %s %s)\n", zone, domain, rType) - - config := m.(*Config) - client := config.DNSClient - - err := client.DeleteRRSet(ctx, zone, domain, rType) - if err != nil { - return diag.FromErr(fmt.Errorf("delete zone rrset: %w", err)) - } - - d.SetId("") - - return nil -} - -func fillRRSet(d *schema.ResourceData, rType string, rrSet *dnssdk.RRSet) error { - // set filters - for _, resource := range d.Get(DNSZoneRecordSchemaFilter).(*schema.Set).List() { - filter := dnssdk.RecordFilter{} - filterData := resource.(map[string]interface{}) - name := filterData[DNSZoneRecordSchemaFilterType].(string) - filter.Type = name - limit, ok := filterData[DNSZoneRecordSchemaFilterLimit].(int) - if ok { - filter.Limit = uint(limit) - } - strict, ok := filterData[DNSZoneRecordSchemaFilterStrict].(bool) - if ok { - filter.Strict = strict - } - rrSet.AddFilter(filter) - } - // set meta - for _, resource := range d.Get(DNSZoneRecordSchemaResourceRecord).(*schema.Set).List() { - data := resource.(map[string]interface{}) - content := data[DNSZoneRecordSchemaContent].(string) - rr := (&dnssdk.ResourceRecord{}).SetContent(rType, content) - enabled := data[DNSZoneRecordSchemaEnabled].(bool) - rr.Enabled = enabled - metaErrs := make([]error, 0) - - for _, dataMeta := range data[DNSZoneRecordSchemaMeta].(*schema.Set).List() { - meta := dataMeta.(map[string]interface{}) - validWrap := func(rm dnssdk.ResourceMeta) dnssdk.ResourceMeta { - if rm.Valid() != nil { - metaErrs = append(metaErrs, rm.Valid()) - } - return rm - } - - val := meta[DNSZoneRecordSchemaMetaIP].([]interface{}) - ips := make([]string, len(val)) - for i, v := range val { - ips[i] = v.(string) - } - if len(ips) > 0 { - rr.AddMeta(dnssdk.NewResourceMetaIP(ips...)) - } - - val = meta[DNSZoneRecordSchemaMetaCountries].([]interface{}) - countries := make([]string, len(val)) - for i, v := range val { - countries[i] = v.(string) - } - if len(countries) > 0 { - rr.AddMeta(dnssdk.NewResourceMetaCountries(countries...)) - } - - val = meta[DNSZoneRecordSchemaMetaContinents].([]interface{}) - continents := make([]string, len(val)) - for i, v := range val { - continents[i] = v.(string) - } - if len(continents) > 0 { - rr.AddMeta(dnssdk.NewResourceMetaContinents(continents...)) - } - - val = meta[DNSZoneRecordSchemaMetaNotes].([]interface{}) - notes := make([]string, len(val)) - for i, v := range val { - notes[i] = v.(string) - } - if len(notes) > 0 { - rr.AddMeta(dnssdk.NewResourceMetaNotes(notes...)) - } - - latLongVal := meta[DNSZoneRecordSchemaMetaLatLong].([]interface{}) - if len(latLongVal) == 2 { - rr.AddMeta( - validWrap( - dnssdk.NewResourceMetaLatLong( - fmt.Sprintf("%f,%f", latLongVal[0].(float64), latLongVal[1].(float64))))) - } - - val = meta[DNSZoneRecordSchemaMetaAsn].([]interface{}) - asn := make([]uint64, len(val)) - for i, v := range val { - asn[i] = uint64(v.(int)) - } - if len(asn) > 0 { - rr.AddMeta(dnssdk.NewResourceMetaAsn(asn...)) - } - - valDefault := meta[DNSZoneRecordSchemaMetaDefault].(bool) - if valDefault { - rr.AddMeta(validWrap(dnssdk.NewResourceMetaDefault())) - } - } - - if len(metaErrs) > 0 { - return fmt.Errorf("invalid meta for zone rrset with content %s: %v", content, metaErrs) - } - rrSet.Records = append(rrSet.Records, *rr) - } - - return nil -} diff --git a/edgecenter/resource_edgecenter_floatingip.go b/edgecenter/resource_edgecenter_floatingip.go deleted file mode 100644 index 54e548c6..00000000 --- a/edgecenter/resource_edgecenter_floatingip.go +++ /dev/null @@ -1,353 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "net" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/floatingip/v1/floatingips" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" -) - -const ( - FloatingIPsPoint = "floatingips" - FloatingIPCreateTimeout = 1200 -) - -func resourceFloatingIP() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceFloatingIPCreate, - ReadContext: resourceFloatingIPRead, - UpdateContext: resourceFloatingIPUpdate, - DeleteContext: resourceFloatingIPDelete, - Description: `A floating IP is a static IP address that can be associated with one of your instances or loadbalancers, -allowing it to have a static public IP address. The floating IP can be re-associated to any other instance in the same datacenter.`, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, fipID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(fipID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "floating_ip_address": { - Type: schema.TypeString, - Computed: true, - Description: "The floating IP address assigned to the resource.", - }, - "port_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The ID (uuid) of the network port that the floating IP is associated with.", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the floating IP. Can be 'DOWN' or 'ACTIVE'.", - }, - "fixed_ip_address": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The fixed (reserved) IP address that is associated with the floating IP.", - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - ip := net.ParseIP(v) - if ip != nil { - return diag.Diagnostics{} - } - - return diag.FromErr(fmt.Errorf("%q must be a valid ip, got: %s", key, v)) - }, - }, - "router_id": { - Type: schema.TypeString, - Computed: true, - Description: "The ID (uuid) of the router that the floating IP is associated with.", - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - Description: "The timestamp when the floating IP was created.", - }, - "updated_at": { - Type: schema.TypeString, - Computed: true, - Description: "The timestamp when the floating IP was updated.", - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func resourceFloatingIPCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start FloatingIP creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, FloatingIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := floatingips.CreateOpts{ - PortID: d.Get("port_id").(string), - FixedIPAddress: net.ParseIP(d.Get("fixed_ip_address").(string)), - } - - if metadataRaw, ok := d.GetOk("metadata_map"); ok { - meta, err := utils.MapInterfaceToMapString(metadataRaw) - if err != nil { - return diag.FromErr(err) - } - opts.Metadata = meta - } - - results, err := floatingips.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - floatingIPID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, FloatingIPCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - floatingIPID, err := floatingips.ExtractFloatingIPIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve FloatingIP ID from task info: %w", err) - } - return floatingIPID, nil - }) - - log.Printf("[DEBUG] FloatingIP id (%s)", floatingIPID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(floatingIPID.(string)) - resourceFloatingIPRead(ctx, d, m) - - log.Printf("[DEBUG] Finish FloatingIP creating (%s)", floatingIPID) - - return diags -} - -func resourceFloatingIPRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start FloatingIP reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, FloatingIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - floatingIP, err := floatingips.Get(client, d.Id()).Extract() - if err != nil { - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - log.Printf("[WARN] Removing floating ip %s because resource doesn't exist anymore", d.Id()) - d.SetId("") - return nil - } - return diag.FromErr(err) - } - - if floatingIP.FixedIPAddress != nil { - d.Set("fixed_ip_address", floatingIP.FixedIPAddress.String()) - } else { - d.Set("fixed_ip_address", "") - } - - d.Set("project_id", floatingIP.ProjectID) - d.Set("region_id", floatingIP.RegionID) - d.Set("status", floatingIP.Status) - d.Set("port_id", floatingIP.PortID) - d.Set("router_id", floatingIP.RouterID) - d.Set("floating_ip_address", floatingIP.FloatingIPAddress.String()) - - metadataMap, metadataReadOnly := PrepareMetadata(floatingIP.Metadata) - - if err = d.Set("metadata_map", metadataMap); err != nil { - return diag.FromErr(err) - } - - if err = d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish FloatingIP reading") - - return diags -} - -func resourceFloatingIPUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start FloatingIP updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, FloatingIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChanges("fixed_ip_address", "port_id") { - oldFixedIP, newFixedIP := d.GetChange("fixed_ip_address") - oldPortID, newPortID := d.GetChange("port_id") - if oldPortID.(string) != "" || oldFixedIP.(string) != "" { - _, err := floatingips.UnAssign(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - } - - if newPortID.(string) != "" || newFixedIP.(string) != "" { - opts := floatingips.CreateOpts{ - PortID: d.Get("port_id").(string), - FixedIPAddress: net.ParseIP(d.Get("fixed_ip_address").(string)), - } - - _, err = floatingips.Assign(client, d.Id(), opts).Extract() - if err != nil { - return diag.FromErr(err) - } - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - } - - if d.HasChange("metadata_map") { - _, nmd := d.GetChange("metadata_map") - - meta, err := utils.MapInterfaceToMapString(nmd.(map[string]interface{})) - if err != nil { - return diag.Errorf("cannot get metadata. Error: %s", err) - } - - err = metadata.ResourceMetadataReplace(client, d.Id(), meta).Err - if err != nil { - return diag.Errorf("cannot update metadata. Error: %s", err) - } - } - - return resourceFloatingIPRead(ctx, d, m) -} - -func resourceFloatingIPDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start FloatingIP deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, FloatingIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - id := d.Id() - results, err := floatingips.Delete(client, id).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, FloatingIPCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := floatingips.Get(client, id).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete floating ip with ID: %s", id) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting FloatingIP resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of FloatingIP deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_instance.go b/edgecenter/resource_edgecenter_instance.go deleted file mode 100644 index 31142501..00000000 --- a/edgecenter/resource_edgecenter_instance.go +++ /dev/null @@ -1,1069 +0,0 @@ -package edgecenter - -import ( - "context" - "encoding/base64" - "errors" - "fmt" - "log" - "sort" - "strconv" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/instances" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - edgecloudMeta "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" -) - -const ( - InstanceDeleting int = 1200 - InstanceCreatingTimeout int = 1200 - InstancePoint = "instances" - - InstanceVMStateActive = "active" - InstanceVMStateStopped = "stopped" -) - -func resourceInstance() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceInstanceCreate, - ReadContext: resourceInstanceRead, - UpdateContext: resourceInstanceUpdate, - DeleteContext: resourceInstanceDelete, - Description: "A cloud instance is a virtual machine in a cloud environment.", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, InstanceID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(InstanceID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The name of the instance.", - }, - "flavor_id": { - Type: schema.TypeString, - Required: true, - Description: "The ID of the flavor to be used for the instance, determining its compute and memory, for example 'g1-standard-2-4'.", - }, - "name_templates": { - Type: schema.TypeList, - Optional: true, - Deprecated: "Use name_template instead.", - ConflictsWith: []string{"name_template"}, - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "name_template": { - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"name_templates"}, - Description: "A template used to generate the instance name. This field cannot be used with 'name_templates'.", - }, - "volume": { - Type: schema.TypeSet, - Required: true, - Set: volumeUniqueID, - Description: "A set defining the volumes to be attached to the instance.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Optional: true, - Description: "The name assigned to the volume. Defaults to 'system'.", - }, - "source": { - Type: schema.TypeString, - Required: true, - Description: "Currently available only 'existing-volume' value", - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - if types.VolumeSource(v) == types.ExistingVolume { - return diag.Diagnostics{} - } - return diag.Errorf("wrong source type %s, now available values is '%s'", v, types.ExistingVolume) - }, - }, - "boot_index": { - Type: schema.TypeInt, - Description: "If boot_index==0 volumes can not detached", - Optional: true, - }, - "type_name": { - Type: schema.TypeString, - Optional: true, - Description: "The type of volume to create. Valid values are 'ssd_hiiops', 'standard', 'cold', and 'ultra'. Defaults to 'standard'.", - }, - "image_id": { - Type: schema.TypeString, - Optional: true, - }, - "size": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "The size of the volume, specified in gigabytes (GB).", - }, - "volume_id": { - Type: schema.TypeString, - Optional: true, - }, - "attachment_tag": { - Type: schema.TypeString, - Optional: true, - }, - "id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "delete_on_termination": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - }, - }, - }, - "interface": { - Type: schema.TypeList, - Required: true, - Description: "A list defining the network interfaces to be attached to the instance.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Optional: true, - Description: fmt.Sprintf("Available value is '%s', '%s', '%s', '%s'", types.SubnetInterfaceType, types.AnySubnetInterfaceType, types.ExternalInterfaceType, types.ReservedFixedIPType), - }, - "order": { - Type: schema.TypeInt, - Optional: true, - Description: "Order of attaching interface", - Computed: true, - }, - "network_id": { - Type: schema.TypeString, - Description: "Required if type is 'subnet' or 'any_subnet'.", - Optional: true, - Computed: true, - }, - "subnet_id": { - Type: schema.TypeString, - Description: "Required if type is 'subnet'.", - Optional: true, - Computed: true, - }, - // nested map is not supported, in this case, you do not need to use the list for the map - "fip_source": { - Type: schema.TypeString, - Optional: true, - }, - "existing_fip_id": { - Type: schema.TypeString, - Optional: true, - }, - "port_id": { - Type: schema.TypeString, - Computed: true, - Description: "required if type is 'reserved_fixed_ip'", - Optional: true, - }, - "security_groups": { - Type: schema.TypeList, - Optional: true, - Description: "list of security group IDs", - Elem: &schema.Schema{Type: schema.TypeString}, - }, - "ip_address": { - Type: schema.TypeString, - Computed: true, - Optional: true, - }, - }, - }, - }, - "keypair_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the key pair to be associated with the instance for SSH access.", - }, - "server_group": { - Type: schema.TypeString, - Optional: true, - Description: "The ID (uuid) of the server group to which the instance should belong.", - }, - "security_group": { - Type: schema.TypeList, - Computed: true, - Description: "A list of firewall configurations applied to the instance, defined by their ID and name.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Description: "Firewall unique id (uuid)", - Required: true, - }, - "name": { - Type: schema.TypeString, - Description: "Firewall name", - Required: true, - }, - }, - }, - }, - "password": { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{"username"}, - Description: "The password to be used for accessing the instance. Required with username.", - }, - "username": { - Type: schema.TypeString, - Optional: true, - RequiredWith: []string{"password"}, - Description: "The username to be used for accessing the instance. Required with password.", - }, - "metadata": { - Type: schema.TypeList, - Optional: true, - Deprecated: "Use metadata_map instead", - ConflictsWith: []string{"metadata_map"}, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Required: true, - }, - "value": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - ConflictsWith: []string{"metadata"}, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "configuration": { - Type: schema.TypeList, - Optional: true, - Description: `A list of key-value pairs specifying configuration settings for the instance when created -from a template (marketplace), e.g. {"gitlab_external_url": "https://gitlab/..."}`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Required: true, - }, - "value": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - "userdata": { - Type: schema.TypeString, - Optional: true, - Description: "**Deprecated**", - Deprecated: "Use user_data instead", - ConflictsWith: []string{"user_data"}, - }, - "user_data": { - Type: schema.TypeString, - Optional: true, - ConflictsWith: []string{"userdata"}, - Description: "A field for specifying user data to be used for configuring the instance at launch time.", - }, - "allow_app_ports": { - Type: schema.TypeBool, - Optional: true, - Description: "A boolean indicating whether to allow application ports on the instance.", - }, - "flavor": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Description: `A map defining the flavor of the instance, for example, {"flavor_name": "g1-standard-2-4", "ram": 4096, ...}.`, - }, - "status": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The current status of the instance. This is computed automatically and can be used to track the instance's state.", - }, - "vm_state": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: fmt.Sprintf(`The current virtual machine state of the instance, -allowing you to start or stop the VM. Possible values are %s and %s.`, InstanceVMStateStopped, InstanceVMStateActive), - ValidateFunc: validation.StringInSlice([]string{InstanceVMStateActive, InstanceVMStateStopped}, true), - }, - "addresses": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Description: `A list of network addresses associated with the instance, for example "pub_net": [...]`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "net": { - Type: schema.TypeList, - Required: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "addr": { - Type: schema.TypeString, - Required: true, - Description: "The net ip address, for example '45.147.163.112'.", - }, - "type": { - Type: schema.TypeString, - Required: true, - Description: "The net type, for example 'fixed'.", - }, - }, - }, - }, - }, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceInstanceCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Instance creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - clientV1, err := CreateClient(provider, d, InstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - clientV2, err := CreateClient(provider, d, InstancePoint, VersionPointV2) - if err != nil { - return diag.FromErr(err) - } - - createOpts := instances.CreateOpts{ - Flavor: d.Get("flavor_id").(string), - SecurityGroups: []edgecloud.ItemID{}, - Keypair: d.Get("keypair_name").(string), - Password: d.Get("password").(string), - Username: d.Get("username").(string), - ServerGroupID: d.Get("server_group").(string), - AllowAppPorts: d.Get("allow_app_ports").(bool), - } - - if userData, ok := d.GetOk("user_data"); ok { - createOpts.UserData = base64.StdEncoding.EncodeToString([]byte(userData.(string))) - } else if userData, ok := d.GetOk("userdata"); ok { - createOpts.UserData = base64.StdEncoding.EncodeToString([]byte(userData.(string))) - } - - name := d.Get("name").(string) - if len(name) > 0 { - createOpts.Names = []string{name} - } - - if nameTemplatesRaw, ok := d.GetOk("name_templates"); ok { - nameTemplates := nameTemplatesRaw.([]interface{}) - if len(nameTemplates) > 0 { - NameTemp := make([]string, len(nameTemplates)) - for i, nametemp := range nameTemplates { - NameTemp[i] = nametemp.(string) - } - createOpts.NameTemplates = NameTemp - } - } else if nameTemplate, ok := d.GetOk("name_template"); ok { - createOpts.NameTemplates = []string{nameTemplate.(string)} - } - - currentVols := d.Get("volume").(*schema.Set).List() - if len(currentVols) > 0 { - vs, err := extractVolumesMap(currentVols) - if err != nil { - return diag.FromErr(err) - } - createOpts.Volumes = vs - } - - ifs := d.Get("interface").([]interface{}) - if len(ifs) > 0 { - interfacesList, err := extractInstanceInterfaceToListCreate(ifs) - if err != nil { - return diag.FromErr(err) - } - createOpts.Interfaces = interfacesList - } - - if metadata, ok := d.GetOk("metadata"); ok { - if len(metadata.([]interface{})) > 0 { - md, err := extractKeyValue(metadata.([]interface{})) - if err != nil { - return diag.FromErr(err) - } - createOpts.Metadata = &md - } - } else if metadataRaw, ok := d.GetOk("metadata_map"); ok { - md := extractMetadataMap(metadataRaw.(map[string]interface{})) - createOpts.Metadata = &md - } - - configuration := d.Get("configuration") - if len(configuration.([]interface{})) > 0 { - conf, err := extractKeyValue(configuration.([]interface{})) - if err != nil { - return diag.FromErr(err) - } - createOpts.Configuration = &conf - } - - log.Printf("[DEBUG] Instance create options: %+v", createOpts) - results, err := instances.Create(clientV2, createOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - InstanceID, err := tasks.WaitTaskAndReturnResult(clientV1, taskID, true, InstanceCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(clientV1, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - Instance, err := instances.ExtractInstanceIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve Instance ID from task info: %w", err) - } - return Instance, nil - }, - ) - log.Printf("[DEBUG] Instance id (%s)", InstanceID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(InstanceID.(string)) - resourceInstanceRead(ctx, d, m) - - log.Printf("[DEBUG] Finish Instance creating (%s)", InstanceID) - - return diags -} - -func resourceInstanceRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Instance reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - instanceID := d.Id() - log.Printf("[DEBUG] Instance id = %s", instanceID) - - client, err := CreateClient(provider, d, InstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - clientV2, err := CreateClient(provider, d, InstancePoint, VersionPointV2) - if err != nil { - return diag.FromErr(err) - } - - instance, err := instances.Get(client, instanceID).Extract() - if err != nil { - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - log.Printf("[WARN] Removing instance %s because resource doesn't exist anymore", d.Id()) - d.SetId("") - return nil - } - return diag.FromErr(err) - } - - d.Set("name", instance.Name) - d.Set("flavor_id", instance.Flavor.FlavorID) - d.Set("status", instance.Status) - d.Set("vm_state", instance.VMState) - - flavor := make(map[string]interface{}, 4) - flavor["flavor_id"] = instance.Flavor.FlavorID - flavor["flavor_name"] = instance.Flavor.FlavorName - flavor["ram"] = strconv.Itoa(instance.Flavor.RAM) - flavor["vcpus"] = strconv.Itoa(instance.Flavor.VCPUS) - d.Set("flavor", flavor) - - currentVolumes := extractVolumesIntoMap(d.Get("volume").(*schema.Set).List()) - - extVolumes := make([]interface{}, 0, len(instance.Volumes)) - for _, vol := range instance.Volumes { - v, ok := currentVolumes[vol.ID] - // todo fix it - if !ok { - v = make(map[string]interface{}) - v["volume_id"] = vol.ID - v["source"] = types.ExistingVolume.String() - } - - v["id"] = vol.ID - v["delete_on_termination"] = vol.DeleteOnTermination - extVolumes = append(extVolumes, v) - } - - if err := d.Set("volume", schema.NewSet(volumeUniqueID, extVolumes)); err != nil { - return diag.FromErr(err) - } - - instancePorts, err := instances.ListPortsAll(client, instanceID) - if err != nil { - return diag.FromErr(err) - } - secGroups := prepareSecurityGroups(instancePorts) - - if err := d.Set("security_group", secGroups); err != nil { - return diag.FromErr(err) - } - - interfacesListAPI, err := instances.ListInterfacesAll(client, instanceID) - if err != nil { - return diag.FromErr(err) - } - - ifs := d.Get("interface").([]interface{}) - sort.Sort(instanceInterfaces(ifs)) - interfacesListExtracted, err := extractInstanceInterfaceToListRead(ifs) - if err != nil { - return diag.FromErr(err) - } - - var interfacesList []interface{} - for order, iFace := range interfacesListAPI { - if len(iFace.IPAssignments) == 0 { - continue - } - - portID := iFace.PortID - for _, assignment := range iFace.IPAssignments { - subnetID := assignment.SubnetID - ipAddress := assignment.IPAddress.String() - - var interfaceOpts instances.InterfaceOpts - for _, interfaceExtracted := range interfacesListExtracted { - if interfaceExtracted.SubnetID == subnetID || interfaceExtracted.IPAddress == ipAddress || interfaceExtracted.PortID == portID { - interfaceOpts = interfaceExtracted - break - } - } - - i := make(map[string]interface{}) - i["type"] = interfaceOpts.Type.String() - i["order"] = order - i["network_id"] = iFace.NetworkID - i["subnet_id"] = subnetID - i["port_id"] = portID - if interfaceOpts.FloatingIP != nil { - i["fip_source"] = interfaceOpts.FloatingIP.Source.String() - i["existing_fip_id"] = interfaceOpts.FloatingIP.ExistingFloatingID - } - i["ip_address"] = ipAddress - - if port, err := findInstancePort(portID, instancePorts); err == nil { - sgs := make([]string, len(port.SecurityGroups)) - for i, sg := range port.SecurityGroups { - sgs[i] = sg.ID - } - i["security_groups"] = sgs - } - - interfacesList = append(interfacesList, i) - } - } - if err := d.Set("interface", interfacesList); err != nil { - return diag.FromErr(err) - } - - if metadataRaw, ok := d.GetOk("metadata"); ok { - metadata := metadataRaw.([]interface{}) - sliced := make([]map[string]string, len(metadata)) - for i, data := range metadata { - d := data.(map[string]interface{}) - mdata := make(map[string]string, 2) - md, err := instances.MetadataGet(client, instanceID, d["key"].(string)).Extract() - if err != nil { - return diag.Errorf("cannot get metadata with key: %s. Error: %s", instanceID, err) - } - mdata["key"] = md.Key - mdata["value"] = md.Value - sliced[i] = mdata - } - d.Set("metadata", sliced) - } else { - metadata := d.Get("metadata_map").(map[string]interface{}) - newMetadata := make(map[string]interface{}, len(metadata)) - for k := range metadata { - md, err := edgecloudMeta.ResourceMetadataGet(clientV2, instanceID, k).Extract() - if err != nil { - return diag.Errorf("cannot get metadata with key: %s. Error: %s", instanceID, err) - } - newMetadata[k] = md.Value - } - if err := d.Set("metadata_map", newMetadata); err != nil { - return diag.FromErr(err) - } - } - - addresses := []map[string][]map[string]string{} - for _, data := range instance.Addresses { - d := map[string][]map[string]string{} - netd := make([]map[string]string, len(data)) - for i, iaddr := range data { - ndata := make(map[string]string, 2) - ndata["type"] = iaddr.Type.String() - ndata["addr"] = iaddr.Address.String() - netd[i] = ndata - } - d["net"] = netd - addresses = append(addresses, d) - } - if err := d.Set("addresses", addresses); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish Instance reading") - - return diags -} - -func resourceInstanceUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Instance updating") - instanceID := d.Id() - log.Printf("[DEBUG] Instance id = %s", instanceID) - config := m.(*Config) - provider := config.Provider - client, err := CreateClient(provider, d, InstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("name") { - nameTemplates := d.Get("name_templates").([]interface{}) - nameTemplate := d.Get("name_template").(string) - if len(nameTemplate) == 0 && len(nameTemplates) == 0 { - opts := instances.RenameInstanceOpts{ - Name: d.Get("name").(string), - } - if _, err := instances.RenameInstance(client, instanceID, opts).Extract(); err != nil { - return diag.FromErr(err) - } - } - } - - if d.HasChange("flavor_id") { - flavorID := d.Get("flavor_id").(string) - results, err := instances.Resize(client, instanceID, instances.ChangeFlavorOpts{FlavorID: flavorID}).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - taskState, err := tasks.WaitTaskAndReturnResult(client, taskID, true, InstanceCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - return taskInfo.State, nil - }, - ) - log.Printf("[DEBUG] Task state (%s)", taskState) - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("metadata") { - omd, nmd := d.GetChange("metadata") - if len(omd.([]interface{})) > 0 { - for _, data := range omd.([]interface{}) { - d := data.(map[string]interface{}) - k := d["key"].(string) - err := instances.MetadataDelete(client, instanceID, k).Err - if err != nil { - return diag.Errorf("cannot delete metadata key: %s. Error: %s", k, err) - } - } - } - if len(nmd.([]interface{})) > 0 { - var MetaData []instances.MetadataOpts - for _, data := range nmd.([]interface{}) { - d := data.(map[string]interface{}) - var md instances.MetadataOpts - md.Key = d["key"].(string) - md.Value = d["value"].(string) - MetaData = append(MetaData, md) - } - createOpts := instances.MetadataSetOpts{ - Metadata: MetaData, - } - err := instances.MetadataCreate(client, instanceID, createOpts).Err - if err != nil { - return diag.Errorf("cannot create metadata. Error: %s", err) - } - } - } else if d.HasChange("metadata_map") { - omd, nmd := d.GetChange("metadata_map") - if len(omd.(map[string]interface{})) > 0 { - for k := range omd.(map[string]interface{}) { - err := instances.MetadataDelete(client, instanceID, k).Err - if err != nil { - return diag.Errorf("cannot delete metadata key: %s. Error: %s", k, err) - } - } - } - if len(nmd.(map[string]interface{})) > 0 { - var MetaData []instances.MetadataOpts - for k, v := range nmd.(map[string]interface{}) { - md := instances.MetadataOpts{ - Key: k, - Value: v.(string), - } - MetaData = append(MetaData, md) - } - createOpts := instances.MetadataSetOpts{ - Metadata: MetaData, - } - err := instances.MetadataCreate(client, instanceID, createOpts).Err - if err != nil { - return diag.Errorf("cannot create metadata. Error: %s", err) - } - } - } - - if d.HasChange("interface") { - iOldRaw, iNewRaw := d.GetChange("interface") - ifsOldSlice, ifsNewSlice := iOldRaw.([]interface{}), iNewRaw.([]interface{}) - sort.Sort(instanceInterfaces(ifsOldSlice)) - sort.Sort(instanceInterfaces(ifsNewSlice)) - - switch { - // the same number of interfaces - case len(ifsOldSlice) == len(ifsNewSlice): - for idx, item := range ifsOldSlice { - iOld := item.(map[string]interface{}) - iNew := ifsNewSlice[idx].(map[string]interface{}) - - sgsIDsOld := getSecurityGroupsIDs(iOld["security_groups"].([]interface{})) - sgsIDsNew := getSecurityGroupsIDs(iNew["security_groups"].([]interface{})) - if len(sgsIDsOld) > 0 || len(sgsIDsNew) > 0 { - portID := iOld["port_id"].(string) - sgClient, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - removeSGs := getSecurityGroupsDifference(sgsIDsNew, sgsIDsOld) - if err := removeSecurityGroupFromInstance(sgClient, client, instanceID, portID, removeSGs); err != nil { - return diag.FromErr(err) - } - addSGs := getSecurityGroupsDifference(sgsIDsOld, sgsIDsNew) - if err := attachSecurityGroupToInstance(sgClient, client, instanceID, portID, addSGs); err != nil { - return diag.FromErr(err) - } - } - - differentFields := getMapDifference(iOld, iNew, []string{"security_groups"}) - if len(differentFields) > 0 { - if err := detachInterfaceFromInstance(client, instanceID, iOld); err != nil { - return diag.FromErr(err) - } - if err := attachInterfaceToInstance(client, instanceID, iNew); err != nil { - return diag.FromErr(err) - } - } - } - - // new interfaces > old interfaces - need to attach new - case len(ifsOldSlice) < len(ifsNewSlice): - for idx, item := range ifsOldSlice { - iOld := item.(map[string]interface{}) - iNew := ifsNewSlice[idx].(map[string]interface{}) - - sgsIDsOld := getSecurityGroupsIDs(iOld["security_groups"].([]interface{})) - sgsIDsNew := getSecurityGroupsIDs(iNew["security_groups"].([]interface{})) - if len(sgsIDsOld) > 0 || len(sgsIDsNew) > 0 { - portID := iOld["port_id"].(string) - clientSG, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - removeSGs := getSecurityGroupsDifference(sgsIDsNew, sgsIDsOld) - if err := removeSecurityGroupFromInstance(clientSG, client, instanceID, portID, removeSGs); err != nil { - return diag.FromErr(err) - } - - addSGs := getSecurityGroupsDifference(sgsIDsOld, sgsIDsNew) - if err := attachSecurityGroupToInstance(clientSG, client, instanceID, portID, addSGs); err != nil { - return diag.FromErr(err) - } - } - - differentFields := getMapDifference(iOld, iNew, []string{"security_groups"}) - if len(differentFields) > 0 { - if err := detachInterfaceFromInstance(client, instanceID, iOld); err != nil { - return diag.FromErr(err) - } - if err := attachInterfaceToInstance(client, instanceID, iNew); err != nil { - return diag.FromErr(err) - } - } - } - - for _, item := range ifsNewSlice[len(ifsOldSlice):] { - iNew := item.(map[string]interface{}) - if err := attachInterfaceToInstance(client, instanceID, iNew); err != nil { - return diag.FromErr(err) - } - } - - // old interfaces > new interfaces - need to detach old - case len(ifsOldSlice) > len(ifsNewSlice): - for idx, item := range ifsOldSlice[:len(ifsNewSlice)] { - iOld := item.(map[string]interface{}) - iNew := ifsNewSlice[idx].(map[string]interface{}) - - sgsIDsOld := getSecurityGroupsIDs(iOld["security_groups"].([]interface{})) - sgsIDsNew := getSecurityGroupsIDs(iNew["security_groups"].([]interface{})) - if len(sgsIDsOld) > 0 || len(sgsIDsNew) > 0 { - portID := iOld["port_id"].(string) - clientSG, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - removeSGs := getSecurityGroupsDifference(sgsIDsNew, sgsIDsOld) - if err := removeSecurityGroupFromInstance(clientSG, client, instanceID, portID, removeSGs); err != nil { - return diag.FromErr(err) - } - - addSGs := getSecurityGroupsDifference(sgsIDsOld, sgsIDsNew) - if err := attachSecurityGroupToInstance(clientSG, client, instanceID, portID, addSGs); err != nil { - return diag.FromErr(err) - } - } - - differentFields := getMapDifference(iOld, iNew, []string{"security_groups"}) - if len(differentFields) > 0 { - if err := detachInterfaceFromInstance(client, instanceID, iOld); err != nil { - return diag.FromErr(err) - } - if err := attachInterfaceToInstance(client, instanceID, iNew); err != nil { - return diag.FromErr(err) - } - } - } - - for _, item := range ifsOldSlice[len(ifsNewSlice):] { - iOld := item.(map[string]interface{}) - if err := detachInterfaceFromInstance(client, instanceID, iOld); err != nil { - return diag.FromErr(err) - } - } - } - } - - if d.HasChange("server_group") { - oldSGRaw, newSGRaw := d.GetChange("server_group") - oldSGID, newSGID := oldSGRaw.(string), newSGRaw.(string) - - clientSG, err := CreateClient(provider, d, ServerGroupsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - // delete old server group - if oldSGID != "" { - err := deleteServerGroup(clientSG, client, instanceID, oldSGID) - if err != nil { - return diag.FromErr(err) - } - } - - // add new server group if needed - if newSGID != "" { - err := addServerGroup(clientSG, client, instanceID, newSGID) - if err != nil { - return diag.FromErr(err) - } - } - } - - if d.HasChange("volume") { - vClient, err := CreateClient(provider, d, VolumesPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - oldVolumesRaw, newVolumesRaw := d.GetChange("volume") - oldVolumes := extractInstanceVolumesMap(oldVolumesRaw.(*schema.Set).List()) - newVolumes := extractInstanceVolumesMap(newVolumesRaw.(*schema.Set).List()) - - vOpts := volumes.InstanceOperationOpts{InstanceID: d.Id()} - for vid := range oldVolumes { - if isAttached := newVolumes[vid]; isAttached { - // mark as already attached - newVolumes[vid] = false - continue - } - if _, err := volumes.Detach(vClient, vid, vOpts).Extract(); err != nil { - return diag.FromErr(err) - } - } - - // range over not attached volumes - for vid, ok := range newVolumes { - if ok { - if _, err := volumes.Attach(vClient, vid, vOpts).Extract(); err != nil { - return diag.FromErr(err) - } - } - } - } - - if d.HasChange("vm_state") { - state := d.Get("vm_state").(string) - switch state { - case InstanceVMStateActive: - if _, err := instances.Start(client, instanceID).Extract(); err != nil { - return diag.FromErr(err) - } - startStateConf := &retry.StateChangeConf{ - Target: []string{InstanceVMStateActive}, - Refresh: ServerV2StateRefreshFunc(client, instanceID), - Timeout: d.Timeout(schema.TimeoutCreate), - Delay: 10 * time.Second, - MinTimeout: 3 * time.Second, - } - _, err = startStateConf.WaitForStateContext(ctx) - if err != nil { - return diag.Errorf("Error waiting for instance (%s) to become active: %s", d.Id(), err) - } - case InstanceVMStateStopped: - if _, err := instances.Stop(client, instanceID).Extract(); err != nil { - return diag.FromErr(err) - } - stopStateConf := &retry.StateChangeConf{ - Target: []string{InstanceVMStateStopped}, - Refresh: ServerV2StateRefreshFunc(client, instanceID), - Timeout: d.Timeout(schema.TimeoutCreate), - Delay: 10 * time.Second, - MinTimeout: 3 * time.Second, - } - _, err = stopStateConf.WaitForStateContext(ctx) - if err != nil { - return diag.Errorf("Error waiting for instance (%s) to become inactive(stopped): %s", d.Id(), err) - } - } - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish Instance updating") - - return resourceInstanceRead(ctx, d, m) -} - -func resourceInstanceDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Instance deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - instanceID := d.Id() - log.Printf("[DEBUG] Instance id = %s", instanceID) - - client, err := CreateClient(provider, d, InstancePoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - var delOpts instances.DeleteOpts - results, err := instances.Delete(client, instanceID, delOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, InstanceDeleting, func(task tasks.TaskID) (interface{}, error) { - _, err := instances.Get(client, instanceID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete instance with ID: %s", instanceID) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Instance resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of Instance deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_k8s.go b/edgecenter/resource_edgecenter_k8s.go deleted file mode 100644 index 84705c1f..00000000 --- a/edgecenter/resource_edgecenter_k8s.go +++ /dev/null @@ -1,573 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/clusters" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/pools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/keypair/v2/keypairs" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" -) - -const ( - K8sPoint = "k8s/clusters" - K8sCreateTimeout = 3600 -) - -var k8sCreateTimeout = time.Second * time.Duration(K8sCreateTimeout) - -func resourceK8s() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceK8sCreate, - ReadContext: resourceK8sRead, - UpdateContext: resourceK8sUpdate, - DeleteContext: resourceK8sDelete, - Description: "Represent k8s cluster with one default pool.", - Timeouts: &schema.ResourceTimeout{ - Create: &k8sCreateTimeout, - Update: &k8sCreateTimeout, - }, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, k8sID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(k8sID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the Kubernetes cluster.", - }, - "fixed_network": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "Fixed network (uuid) associated with the Kubernetes cluster.", - }, - "fixed_subnet": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "Subnet (uuid) associated with the fixed network. Ensure there's a router on this subnet.", - }, - "auto_healing_enabled": { - Type: schema.TypeBool, - Optional: true, - Description: "Indicates whether auto-healing is enabled for the Kubernetes cluster. true by default.", - }, - "master_lb_floating_ip_enabled": { - Type: schema.TypeBool, - Optional: true, - Description: "Flag indicating if the master LoadBalancer should have a floating IP.", - }, - "pods_ip_pool": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "IP pool to be used for pods within the Kubernetes cluster.", - }, - "services_ip_pool": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "IP pool to be used for services within the Kubernetes cluster.", - }, - "keypair": { - Type: schema.TypeString, - Required: true, - Description: "The name of the keypair", - }, - "pool": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - MinItems: 1, - Description: "Configuration details of the node pool in the Kubernetes cluster.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - }, - "flavor_id": { - Type: schema.TypeString, - Required: true, - }, - "min_node_count": { - Type: schema.TypeInt, - Required: true, - }, - "max_node_count": { - Type: schema.TypeInt, - Required: true, - }, - "node_count": { - Type: schema.TypeInt, - Required: true, - }, - "docker_volume_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "Available value is 'standard', 'ssd_hiiops', 'cold', 'ultra'.", - }, - "docker_volume_size": { - Type: schema.TypeInt, - Optional: true, - }, - "uuid": { - Type: schema.TypeString, - Computed: true, - }, - "stack_id": { - Type: schema.TypeString, - Computed: true, - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "node_count": { - Type: schema.TypeInt, - Computed: true, - Description: "Total number of nodes in the Kubernetes cluster.", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the Kubernetes cluster.", - }, - "status_reason": { - Type: schema.TypeString, - Computed: true, - Description: "The reason for the current status of the Kubernetes cluster, if ERROR.", - }, - "master_addresses": { - Type: schema.TypeList, - Computed: true, - Description: "List of IP addresses for master nodes in the Kubernetes cluster.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "node_addresses": { - Type: schema.TypeList, - Computed: true, - Description: "List of IP addresses for worker nodes in the Kubernetes cluster.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "container_version": { - Type: schema.TypeString, - Computed: true, - Description: "The container runtime version used in the Kubernetes cluster.", - }, - "api_address": { - Type: schema.TypeString, - Computed: true, - Description: "API endpoint address for the Kubernetes cluster.", - }, - "user_id": { - Type: schema.TypeString, - Computed: true, - Description: "User identifier associated with the Kubernetes cluster.", - }, - "discovery_url": { - Type: schema.TypeString, - Computed: true, - Description: "URL used for node discovery within the Kubernetes cluster.", - }, - "health_status": { - Type: schema.TypeString, - Computed: true, - Description: "Overall health status of the Kubernetes cluster.", - }, - "health_status_reason": { - Type: schema.TypeMap, - Computed: true, - }, - "faults": { - Type: schema.TypeMap, - Computed: true, - }, - "master_flavor_id": { - Type: schema.TypeString, - Computed: true, - Description: "Identifier for the master node flavor in the Kubernetes cluster.", - }, - "cluster_template_id": { - Type: schema.TypeString, - Computed: true, - Description: "Template identifier from which the Kubernetes cluster was instantiated.", - }, - "version": { - Type: schema.TypeString, - Required: true, - Description: "The version of the Kubernetes cluster.", - }, - "updated_at": { - Type: schema.TypeString, - Computed: true, - Description: "The timestamp when the Kubernetes cluster was updated.", - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - Description: "The timestamp when the Kubernetes cluster was created.", - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := clusters.CreateOpts{ - Name: d.Get("name").(string), - Version: d.Get("version").(string), - FixedNetwork: d.Get("fixed_network").(string), - FixedSubnet: d.Get("fixed_subnet").(string), - KeyPair: d.Get("keypair").(string), - AutoHealingEnabled: d.Get("auto_healing_enabled").(bool), - MasterLBFloatingIPEnabled: d.Get("master_lb_floating_ip_enabled").(bool), - } - - if podsIP, ok := d.GetOk("pods_ip_pool"); ok { - eccidr, err := parseCIDRFromString(podsIP.(string)) - if err != nil { - return diag.FromErr(err) - } - opts.PodsIPPool = &eccidr - } - - if svcIP, ok := d.GetOk("services_ip_pool"); ok { - eccidr, err := parseCIDRFromString(svcIP.(string)) - if err != nil { - return diag.FromErr(err) - } - opts.ServicesIPPool = &eccidr - } - - poolRaw := d.Get("pool").([]interface{}) - pool := poolRaw[0].(map[string]interface{}) - - poolNodeCount := pool["node_count"].(int) - maxNodeCount := pool["max_node_count"].(int) - optPool := pools.CreateOpts{ - Name: pool["name"].(string), - FlavorID: pool["flavor_id"].(string), - NodeCount: &poolNodeCount, - MinNodeCount: pool["min_node_count"].(int), - MaxNodeCount: &maxNodeCount, - } - - dockerVolumeSize := pool["docker_volume_size"].(int) - if dockerVolumeSize != 0 { - optPool.DockerVolumeSize = &dockerVolumeSize - } - - dockerVolumeType := pool["docker_volume_type"].(string) - if dockerVolumeType != "" { - optPool.DockerVolumeType = volumes.VolumeType(dockerVolumeType) - } - - opts.Pools = []pools.CreateOpts{optPool} - results, err := clusters.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - k8sID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - k8sID, err := clusters.ExtractClusterIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve k8s ID from task info: %w", err) - } - return k8sID, nil - }, - ) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(k8sID.(string)) - resourceK8sRead(ctx, d, m) - - log.Printf("[DEBUG] Finish K8s creating (%s)", k8sID) - - return diags -} - -func resourceK8sRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - clientK8S, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - clusterID := d.Id() - cluster, err := clusters.Get(clientK8S, clusterID).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.Set("name", cluster.Name) - d.Set("fixed_network", cluster.FixedNetwork) - d.Set("fixed_subnet", cluster.FixedSubnet) - d.Set("master_lb_floating_ip_enabled", cluster.FloatingIPEnabled) - d.Set("node_count", cluster.NodeCount) - d.Set("status", cluster.Status) - d.Set("status_reason", cluster.StatusReason) - - clientKeypairs, err := CreateClient(provider, d, KeypairsPoint, VersionPointV2) - if err != nil { - return diag.FromErr(err) - } - - keypairInfo, err := keypairs.Get(clientKeypairs, cluster.KeyPair).Extract() - if err != nil { - return diag.FromErr(err) - } - d.Set("keypair", keypairInfo.Name) - - masterAddresses := make([]string, len(cluster.MasterAddresses)) - for i, addr := range cluster.MasterAddresses { - masterAddresses[i] = addr.String() - } - if err := d.Set("master_addresses", masterAddresses); err != nil { - return diag.FromErr(err) - } - - nodeAddresses := make([]string, len(cluster.NodeAddresses)) - for i, addr := range cluster.NodeAddresses { - nodeAddresses[i] = addr.String() - } - if err := d.Set("node_addresses", nodeAddresses); err != nil { - return diag.FromErr(err) - } - - d.Set("container_version", cluster.ContainerVersion) - d.Set("api_address", cluster.APIAddress.String()) - d.Set("user_id", cluster.UserID) - d.Set("discovery_url", cluster.DiscoveryURL.String()) - - d.Set("health_status", cluster.HealthStatus) - if err := d.Set("health_status_reason", cluster.HealthStatusReason); err != nil { - return diag.FromErr(err) - } - - if err := d.Set("faults", cluster.Faults); err != nil { - return diag.FromErr(err) - } - - d.Set("master_flavor_id", cluster.MasterFlavorID) - d.Set("cluster_template_id", cluster.ClusterTemplateID) - d.Set("version", cluster.Version) - d.Set("updated_at", cluster.UpdatedAt.Format(time.RFC850)) - d.Set("created_at", cluster.CreatedAt.Format(time.RFC850)) - - var pool pools.ClusterPool - for _, p := range cluster.Pools { - if p.IsDefault { - pool = p - } - } - - p := make(map[string]interface{}) - p["uuid"] = pool.UUID - p["name"] = pool.Name - p["flavor_id"] = pool.FlavorID - p["min_node_count"] = pool.MinNodeCount - p["max_node_count"] = pool.MaxNodeCount - p["node_count"] = pool.NodeCount - p["docker_volume_type"] = pool.DockerVolumeType.String() - p["docker_volume_size"] = pool.DockerVolumeSize - p["stack_id"] = pool.StackID - p["created_at"] = pool.CreatedAt.Format(time.RFC850) - - if err := d.Set("pool", []interface{}{p}); err != nil { - return diag.FromErr(err) - } - - fields := []string{"region_id", "auto_healing_enabled", "pods_ip_pool", "services_ip_pool"} - revertState(d, &fields) - - log.Println("[DEBUG] Finish K8s reading") - - return diags -} - -func resourceK8sUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("pool") { - poolRaw := d.Get("pool").([]interface{})[0] - pool := poolRaw.(map[string]interface{}) - - clusterID := d.Id() - poolID := pool["uuid"].(string) - - if d.HasChanges("pool.0.name", "pool.0.min_node_count", "pool.0.max_node_count") { - updateOpts := pools.UpdateOpts{ - Name: pool["name"].(string), - MinNodeCount: pool["min_node_count"].(int), - MaxNodeCount: pool["max_node_count"].(int), - } - results, err := pools.Update(client, clusterID, poolID, updateOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := pools.Get(client, clusterID, poolID).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get pool with ID: %s. Error: %w", poolID, err) - } - return nil, nil - }) - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("pool.0.node_count") { - resizeOpts := clusters.ResizeOpts{ - NodeCount: pool["node_count"].(*int), - } - results, err := clusters.Resize(client, clusterID, poolID, resizeOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := pools.Get(client, clusterID, poolID).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get pool with ID: %s. Error: %w", poolID, err) - } - return nil, nil - }) - if err != nil { - return diag.FromErr(err) - } - } - } - - return resourceK8sRead(ctx, d, m) -} - -func resourceK8sDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - id := d.Id() - results, err := clusters.Delete(client, id).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := clusters.Get(client, id).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete k8s cluster with ID: %s", id) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Cluster resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of K8s deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_k8s_pool.go b/edgecenter/resource_edgecenter_k8s_pool.go deleted file mode 100644 index ed7c0654..00000000 --- a/edgecenter/resource_edgecenter_k8s_pool.go +++ /dev/null @@ -1,330 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/clusters" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/pools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" -) - -func resourceK8sPool() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceK8sPoolCreate, - ReadContext: resourceK8sPoolRead, - UpdateContext: resourceK8sPoolUpdate, - DeleteContext: resourceK8sPoolDelete, - Description: "Represent k8s cluster's pool.", - Timeouts: &schema.ResourceTimeout{ - Create: &k8sCreateTimeout, - Update: &k8sCreateTimeout, - }, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, poolID, clusterID, err := ImportStringParserExtended(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.Set("cluster_id", clusterID) - d.SetId(poolID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "cluster_id": { - Type: schema.TypeString, - Required: true, - Description: "The uuid of the Kubernetes cluster this pool belongs to.", - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the Kubernetes pool.", - }, - "flavor_id": { - Type: schema.TypeString, - Required: true, - Description: "The identifier of the flavor used for nodes in this pool, e.g. g1-standard-2-4.", - }, - "min_node_count": { - Type: schema.TypeInt, - Required: true, - Description: "The minimum number of nodes in the pool.", - }, - "max_node_count": { - Type: schema.TypeInt, - Required: true, - Description: "The maximum number of nodes the pool can scale to.", - }, - "node_count": { - Type: schema.TypeInt, - Required: true, - Description: "The current number of nodes in the pool.", - }, - "docker_volume_type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The type of volume used for the Docker containers. Available values are 'standard', 'ssd_hiiops', 'cold', and 'ultra'.", - }, - "docker_volume_size": { - Type: schema.TypeInt, - Optional: true, - Description: "The size of the volume used for Docker containers, in gigabytes.", - }, - "stack_id": { - Type: schema.TypeString, - Computed: true, - Description: "The identifier of the underlying infrastructure stack used by this pool.", - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - Description: "The timestamp when the Kubernetes pool was created.", - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceK8sPoolCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s pool creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - poolNodeCount := d.Get("node_count").(int) - maxNodeCount := d.Get("max_node_count").(int) - opts := pools.CreateOpts{ - Name: d.Get("name").(string), - FlavorID: d.Get("flavor_id").(string), - NodeCount: &poolNodeCount, - MinNodeCount: d.Get("min_node_count").(int), - MaxNodeCount: &maxNodeCount, - } - - dockerVolumeSize := d.Get("docker_volume_size").(int) - if dockerVolumeSize != 0 { - opts.DockerVolumeSize = &dockerVolumeSize - } - - dockerVolumeType := d.Get("docker_volume_type").(string) - if dockerVolumeType != "" { - opts.DockerVolumeType = volumes.VolumeType(dockerVolumeType) - } - - clusterID := d.Get("cluster_id").(string) - results, err := pools.Create(client, clusterID, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - poolID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - poolID, err := pools.ExtractClusterPoolIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve k8s pool ID from task info: %w", err) - } - return poolID, nil - }, - ) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(poolID.(string)) - resourceK8sPoolRead(ctx, d, m) - - log.Printf("[DEBUG] Finish K8s pool creating (%s)", poolID) - - return diags -} - -func resourceK8sPoolRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s pool reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - clusterID := d.Get("cluster_id").(string) - poolID := d.Id() - - pool, err := pools.Get(client, clusterID, poolID).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.Set("name", pool.Name) - d.Set("cluster_id", pool.ClusterID) - d.Set("flavor_id", pool.FlavorID) - d.Set("min_node_count", pool.MinNodeCount) - d.Set("max_node_count", pool.MaxNodeCount) - d.Set("node_count", pool.NodeCount) - d.Set("docker_volume_type", pool.DockerVolumeType.String()) - d.Set("docker_volume_size", pool.DockerVolumeSize) - d.Set("stack_id", pool.StackID) - d.Set("created_at", pool.CreatedAt.Format(time.RFC850)) - - log.Println("[DEBUG] Finish K8s pool reading") - - return diags -} - -func resourceK8sPoolUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - poolID := d.Id() - clusterID := d.Get("cluster_id").(string) - - if d.HasChanges("name", "min_node_count", "max_node_count") { - updateOpts := pools.UpdateOpts{ - Name: d.Get("name").(string), - MinNodeCount: d.Get("min_node_count").(int), - MaxNodeCount: d.Get("max_node_count").(int), - } - results, err := pools.Update(client, clusterID, poolID, updateOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := pools.Get(client, clusterID, poolID).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get pool with ID: %s. Error: %w", poolID, err) - } - return nil, nil - }) - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("node_count") { - resizeOpts := clusters.ResizeOpts{ - NodeCount: d.Get("node_count").(*int), - } - results, err := clusters.Resize(client, clusterID, poolID, resizeOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := pools.Get(client, clusterID, poolID).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get pool with ID: %s. Error: %w", poolID, err) - } - return nil, nil - }) - if err != nil { - return diag.FromErr(err) - } - } - - return resourceK8sPoolRead(ctx, d, m) -} - -func resourceK8sPoolDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start K8s deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, K8sPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - id := d.Id() - clusterID := d.Get("cluster_id").(string) - results, err := pools.Delete(client, clusterID, id).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := pools.Get(client, clusterID, id).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete k8s cluster pool with ID: %s", id) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Pool resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of K8s pool deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_keypair.go b/edgecenter/resource_edgecenter_keypair.go deleted file mode 100644 index 946cc122..00000000 --- a/edgecenter/resource_edgecenter_keypair.go +++ /dev/null @@ -1,145 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/keypair/v2/keypairs" -) - -const KeypairsPoint = "keypairs" - -func resourceKeypair() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceKeypairCreate, - ReadContext: resourceKeypairRead, - DeleteContext: resourceKeypairDelete, - Description: "Represent a ssh key, do not depends on region", - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "public_key": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The public portion of the SSH key pair.", - }, - "sshkey_name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The name assigned to the SSH key pair, used for identification purposes.", - }, - "sshkey_id": { - Type: schema.TypeString, - Computed: true, - Description: "The unique identifier assigned by the provider to the SSH key pair.", - }, - "fingerprint": { - Type: schema.TypeString, - Computed: true, - Description: "A fingerprint of the SSH public key, used to verify the integrity of the key.", - }, - }, - } -} - -func resourceKeypairCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start KeyPair creating") - - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, KeypairsPoint, VersionPointV2) - if err != nil { - return diag.FromErr(err) - } - - opts := keypairs.CreateOpts{ - Name: d.Get("sshkey_name").(string), - PublicKey: d.Get("public_key").(string), - ProjectID: d.Get("project_id").(int), - } - - kp, err := keypairs.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - log.Printf("[DEBUG] KeyPair id (%s)", kp.ID) - d.SetId(kp.ID) - - resourceKeypairRead(ctx, d, m) - - log.Printf("[DEBUG] Finish KeyPair creating (%s)", kp.ID) - - return diags -} - -func resourceKeypairRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start KeyPair reading") - - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, KeypairsPoint, VersionPointV2) - if err != nil { - return diag.FromErr(err) - } - - kpID := d.Id() - kp, err := keypairs.Get(client, kpID).Extract() - if err != nil { - return diag.Errorf("cannot get keypairs with ID %s. Error: %s", kpID, err.Error()) - } - - d.Set("sshkey_name", kp.Name) - d.Set("public_key", kp.PublicKey) - d.Set("sshkey_id", kp.ID) - d.Set("fingerprint", kp.Fingerprint) - d.Set("project_id", kp.ProjectID) - - log.Println("[DEBUG] Finish KeyPair reading") - - return diags -} - -func resourceKeypairDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start KeyPair deleting") - - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, KeypairsPoint, VersionPointV2) - if err != nil { - return diag.FromErr(err) - } - - kpID := d.Id() - if err := keypairs.Delete(client, kpID).ExtractErr(); err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Println("[DEBUG] Finish of KeyPair deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_lblistener.go b/edgecenter/resource_edgecenter_lblistener.go deleted file mode 100644 index eb1a0819..00000000 --- a/edgecenter/resource_edgecenter_lblistener.go +++ /dev/null @@ -1,358 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/listeners" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -const ( - LBListenersPoint = "lblisteners" - LBListenerCreateTimeout = 2400 -) - -func resourceLbListener() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceLBListenerCreate, - ReadContext: resourceLBListenerRead, - UpdateContext: resourceLBListenerUpdate, - DeleteContext: resourceLBListenerDelete, - Description: "Represent a load balancer listener. Can not be created without a load balancer. A listener is a process that checks for connection requests using the protocol and port that you configure.", - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(5 * time.Minute), - Delete: schema.DefaultTimeout(5 * time.Minute), - }, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, listenerID, lbID, err := ImportStringParserExtended(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.Set("loadbalancer_id", lbID) - d.SetId(listenerID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the load balancer listener.", - }, - "loadbalancer_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The uuid for the load balancer.", - }, - "protocol": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "Available values are 'TCP', 'UDP', 'HTTP', 'HTTPS' and 'Terminated HTTPS'.", - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - switch types.ProtocolType(v) { - case types.ProtocolTypeTCP, types.ProtocolTypeUDP, types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS, types.ProtocolTypeTerminatedHTTPS: - return diag.Diagnostics{} - case types.ProtocolTypePROXY: - } - return diag.Errorf("wrong protocol %s, available values are 'TCP', 'UDP', 'HTTP', 'HTTPS' and 'Terminated HTTPS'.", v) - }, - }, - "protocol_port": { - Type: schema.TypeInt, - Required: true, - ForceNew: true, - Description: "The port on which the protocol is bound.", - }, - "insert_x_forwarded": { - Type: schema.TypeBool, - Optional: true, - Description: "Insert *-forwarded headers", - ForceNew: true, - }, - "pool_count": { - Type: schema.TypeInt, - Computed: true, - Description: "Number of pools associated with the load balancer.", - }, - "operating_status": { - Type: schema.TypeString, - Computed: true, - Description: "The current operational status of the load balancer.", - }, - "provisioning_status": { - Type: schema.TypeString, - Computed: true, - Description: "The current provisioning status of the load balancer.", - }, - "secret_id": { - Type: schema.TypeString, - Optional: true, - Description: "The identifier for the associated secret, typically used for SSL configurations.", - }, - "sni_secret_id": { - Type: schema.TypeList, - Elem: &schema.Schema{Type: schema.TypeString}, - Optional: true, - Description: "List of secret identifiers used for Server Name Indication (SNI).", - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceLBListenerCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBListener creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBListenersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := listeners.CreateOpts{ - Name: d.Get("name").(string), - Protocol: types.ProtocolType(d.Get("protocol").(string)), - ProtocolPort: d.Get("protocol_port").(int), - LoadBalancerID: d.Get("loadbalancer_id").(string), - InsertXForwarded: d.Get("insert_x_forwarded").(bool), - } - secretID := d.Get("secret_id").(string) - sniSecretIDRaw := d.Get("sni_secret_id").([]interface{}) - - switch opts.Protocol { //nolint: exhaustive - case types.ProtocolTypeTCP, types.ProtocolTypeUDP, types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS: - if secretID != "" { - return diag.Errorf("secret_id parameter can only be used with %s listener protocol type", types.ProtocolTypeTerminatedHTTPS) - } - - if len(sniSecretIDRaw) > 0 { - return diag.Errorf("sni_secret_id parameter can only be used with %s listener protocol type", types.ProtocolTypeTerminatedHTTPS) - } - - if opts.InsertXForwarded && (opts.Protocol == types.ProtocolTypeTCP || opts.Protocol == types.ProtocolTypeUDP || opts.Protocol == types.ProtocolTypeHTTPS) { - return diag.Errorf( - "X-Forwarded headers can only be used with %s or %s listener protocol type", - types.ProtocolTypeHTTP, types.ProtocolTypeTerminatedHTTPS, - ) - } - case types.ProtocolTypeTerminatedHTTPS: - if secretID == "" { - return diag.Errorf("secret_id parameter is required with %s listener protocol type", types.ProtocolTypeTerminatedHTTPS) - } - opts.SecretID = secretID - if len(sniSecretIDRaw) > 0 { - opts.SNISecretID = make([]string, len(sniSecretIDRaw)) - for i, s := range sniSecretIDRaw { - opts.SNISecretID[i] = s.(string) - } - } - default: - return diag.Errorf("wrong protocol") - } - - results, err := listeners.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - listenerID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, LBListenerCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - listenerID, err := listeners.ExtractListenerIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve LBListener ID from task info: %w", err) - } - return listenerID, nil - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(listenerID.(string)) - resourceLBListenerRead(ctx, d, m) - - log.Printf("[DEBUG] Finish LBListener creating (%s)", listenerID) - - return diags -} - -func resourceLBListenerRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBListener reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBListenersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - lb, err := listeners.Get(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - d.Set("name", lb.Name) - d.Set("protocol", lb.Protocol.String()) - d.Set("protocol_port", lb.ProtocolPort) - d.Set("pool_count", lb.PoolCount) - d.Set("operating_status", lb.OperationStatus.String()) - d.Set("provisioning_status", lb.ProvisioningStatus.String()) - d.Set("secret_id", lb.SecretID) - d.Set("sni_secret_id", lb.SNISecretID) - - fields := []string{"project_id", "region_id", "loadbalancer_id", "insert_x_forwarded"} - revertState(d, &fields) - - log.Println("[DEBUG] Finish LBListener reading") - - return diags -} - -func resourceLBListenerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBListener updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBListenersPoint, VersionPointV2) - if err != nil { - return diag.FromErr(err) - } - - var changed bool - opts := listeners.UpdateOpts{ - Name: d.Get("name").(string), - } - - if d.HasChange("name") { - changed = true - } - - if d.HasChange("secret_id") { - if types.ProtocolType(d.Get("protocol").(string)) != types.ProtocolTypeTerminatedHTTPS { - return diag.Errorf("secret_id parameter can only be used with %s listener protocol type", types.ProtocolTypeTerminatedHTTPS) - } - opts.SecretID = d.Get("secret_id").(string) - changed = true - } - - if d.HasChange("sni_secret_id") { - if types.ProtocolType(d.Get("protocol").(string)) != types.ProtocolTypeTerminatedHTTPS { - return diag.Errorf("sni_secret_id parameter can only be used with %s listener protocol type", types.ProtocolTypeTerminatedHTTPS) - } - sniSecretIDRaw := d.Get("sni_secret_id").([]interface{}) - sniSecretID := make([]string, len(sniSecretIDRaw)) - for i, s := range sniSecretIDRaw { - sniSecretID[i] = s.(string) - } - opts.SNISecretID = sniSecretID - changed = true - } - - if changed { - _, err = listeners.Update(client, d.Id(), opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - } - - log.Println("[DEBUG] Finish LBListener updating") - - return resourceLBListenerRead(ctx, d, m) -} - -func resourceLBListenerDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBListener deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBListenersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - id := d.Id() - results, err := listeners.Delete(client, id).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, LBListenerCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := listeners.Get(client, id).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete LBListener with ID: %s", id) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Listener resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of LBListener deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_lbmember.go b/edgecenter/resource_edgecenter_lbmember.go deleted file mode 100644 index 133da787..00000000 --- a/edgecenter/resource_edgecenter_lbmember.go +++ /dev/null @@ -1,341 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "net" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/lbpools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -const ( - minWeight = 0 - maxWeight = 256 -) - -func resourceLBMember() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceLBMemberCreate, - ReadContext: resourceLBMemberRead, - UpdateContext: resourceLBMemberUpdate, - DeleteContext: resourceLBMemberDelete, - Description: "Represent load balancer member", - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(5 * time.Minute), - Delete: schema.DefaultTimeout(5 * time.Minute), - }, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, memberID, lbPoolID, err := ImportStringParserExtended(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.Set("pool_id", lbPoolID) - d.SetId(memberID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "pool_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The uuid for the load balancer pool.", - }, - "address": { - Type: schema.TypeString, - Required: true, - Description: "The IP address of the load balancer pool member.", - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - ip := net.ParseIP(v) - if ip != nil { - return diag.Diagnostics{} - } - - return diag.FromErr(fmt.Errorf("%q must be a valid ip, got: %s", key, v)) - }, - }, - "protocol_port": { - Type: schema.TypeInt, - Required: true, - Description: "The port on which the member listens for requests.", - }, - "weight": { - Type: schema.TypeInt, - Optional: true, - Description: "A weight value between 0 and 256, determining the distribution of requests among the members of the pool.", - ValidateDiagFunc: func(val interface{}, path cty.Path) diag.Diagnostics { - v := val.(int) - if v >= minWeight && v <= maxWeight { - return nil - } - return diag.Errorf("Valid values: %d to %d got: %d", minWeight, maxWeight, v) - }, - }, - "subnet_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The uuid of the subnet in which the pool member is located.", - }, - "instance_id": { - Type: schema.TypeString, - Optional: true, - Description: "The uuid of the instance (amphora) associated with the pool member.", - }, - "operating_status": { - Type: schema.TypeString, - Computed: true, - Description: "The current operating status of the pool member.", - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceLBMemberCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBMember creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := lbpools.CreatePoolMemberOpts{ - Address: net.ParseIP(d.Get("address").(string)), - ProtocolPort: d.Get("protocol_port").(int), - Weight: d.Get("weight").(int), - SubnetID: d.Get("subnet_id").(string), - InstanceID: d.Get("instance_id").(string), - } - - results, err := lbpools.CreateMember(client, d.Get("pool_id").(string), opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - pmID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, LBPoolsCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - pmID, err := lbpools.ExtractPoolMemberIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve LBMember ID from task info: %w", err) - } - return pmID, nil - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(pmID.(string)) - resourceLBMemberRead(ctx, d, m) - - log.Printf("[DEBUG] Finish LBMember creating (%s)", pmID) - - return diags -} - -func resourceLBMemberRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBMember reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - pool, err := lbpools.Get(client, d.Get("pool_id").(string)).Extract() - if err != nil { - return diag.FromErr(err) - } - - mid := d.Id() - for _, pm := range pool.Members { - if mid == pm.ID { - d.Set("address", pm.Address.String()) - d.Set("protocol_port", pm.ProtocolPort) - d.Set("weight", pm.Weight) - d.Set("subnet_id", pm.SubnetID) - d.Set("instance_id", pm.InstanceID) - d.Set("operating_status", pm.OperatingStatus) - } - } - - fields := []string{"project_id", "region_id"} - revertState(d, &fields) - - log.Println("[DEBUG] Finish LBMember reading)") - - return diags -} - -func resourceLBMemberUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBMember updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - pool, err := lbpools.Get(client, d.Get("pool_id").(string)).Extract() - if err != nil { - return diag.FromErr(err) - } - - members := make([]lbpools.CreatePoolMemberOpts, len(pool.Members)) - for i, pm := range pool.Members { - if pm.ID != d.Id() { - members[i] = lbpools.CreatePoolMemberOpts{ - Address: *pm.Address, - ProtocolPort: pm.ProtocolPort, - Weight: pm.Weight, - SubnetID: pm.SubnetID, - InstanceID: pm.InstanceID, - ID: pm.ID, - } - continue - } - - members[i] = lbpools.CreatePoolMemberOpts{ - Address: net.ParseIP(d.Get("address").(string)), - ProtocolPort: d.Get("protocol_port").(int), - Weight: d.Get("weight").(int), - SubnetID: d.Get("subnet_id").(string), - InstanceID: d.Get("instance_id").(string), - ID: d.Id(), - } - } - - opts := lbpools.UpdateOpts{Name: pool.Name, Members: members} - results, err := lbpools.Update(client, pool.ID, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, LBPoolsCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - lbPoolID, err := lbpools.ExtractPoolMemberIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve LBPool ID from task info: %w, %+v, %+v", err, taskInfo, task) - } - return lbPoolID, nil - }) - if err != nil { - return diag.FromErr(err) - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish LBMember updating") - - return resourceLBMemberRead(ctx, d, m) -} - -func resourceLBMemberDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBMember deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - mid := d.Id() - pid := d.Get("pool_id").(string) - results, err := lbpools.DeleteMember(client, pid, mid).Extract() - if err != nil { - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - d.SetId("") - log.Printf("[DEBUG] Finish of LBMember deleting") - return diags - } - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, LBPoolsCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - pool, err := lbpools.Get(client, pid).Extract() - if err != nil { - return nil, fmt.Errorf("extracting LBPool resource error: %w", err) - } - - for _, pm := range pool.Members { - if pm.ID == mid { - return nil, fmt.Errorf("pool member %s still exist", mid) - } - } - - return nil, nil - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of LBMember deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_lbpool.go b/edgecenter/resource_edgecenter_lbpool.go deleted file mode 100644 index 2149076f..00000000 --- a/edgecenter/resource_edgecenter_lbpool.go +++ /dev/null @@ -1,441 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/lbpools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -const ( - LBPoolsPoint = "lbpools" - LBPoolsCreateTimeout = 2400 -) - -func resourceLBPool() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceLBPoolCreate, - ReadContext: resourceLBPoolRead, - UpdateContext: resourceLBPoolUpdate, - DeleteContext: resourceLBPoolDelete, - Description: "Represent load balancer listener pool. A pool is a list of virtual machines to which the listener will redirect incoming traffic", - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(5 * time.Minute), - Delete: schema.DefaultTimeout(5 * time.Minute), - }, - - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, lbPoolID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(lbPoolID) - - return []*schema.ResourceData{d}, nil - }, - }, - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the load balancer listener pool.", - }, - "lb_algorithm": { - Type: schema.TypeString, - Required: true, - Description: fmt.Sprintf("Available values is '%s', '%s', '%s', '%s'", types.LoadBalancerAlgorithmRoundRobin, types.LoadBalancerAlgorithmLeastConnections, types.LoadBalancerAlgorithmSourceIP, types.LoadBalancerAlgorithmSourceIPPort), - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - switch types.LoadBalancerAlgorithm(v) { - case types.LoadBalancerAlgorithmRoundRobin, types.LoadBalancerAlgorithmLeastConnections, types.LoadBalancerAlgorithmSourceIP, types.LoadBalancerAlgorithmSourceIPPort: - return diag.Diagnostics{} - } - return diag.Errorf("wrong type %s, available values is '%s', '%s', '%s', '%s'", v, types.LoadBalancerAlgorithmRoundRobin, types.LoadBalancerAlgorithmLeastConnections, types.LoadBalancerAlgorithmSourceIP, types.LoadBalancerAlgorithmSourceIPPort) - }, - }, - "protocol": { - Type: schema.TypeString, - Required: true, - Description: fmt.Sprintf("Available values is '%s' (currently work, other do not work on ed-8), '%s', '%s', '%s'", types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS, types.ProtocolTypeTCP, types.ProtocolTypeUDP), - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - switch types.ProtocolType(v) { - case types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS, types.ProtocolTypeTCP, types.ProtocolTypeUDP: - return diag.Diagnostics{} - case types.ProtocolTypeTerminatedHTTPS, types.ProtocolTypePROXY: - } - return diag.Errorf("wrong type %s, available values is '%s', '%s', '%s', '%s'", v, types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS, types.ProtocolTypeTCP, types.ProtocolTypeUDP) - }, - }, - "loadbalancer_id": { - Type: schema.TypeString, - Optional: true, - Description: "The uuid for the load balancer.", - }, - "listener_id": { - Type: schema.TypeString, - Optional: true, - Description: "The uuid for the load balancer listener.", - }, - "health_monitor": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Description: `Configuration for health checks to test the health and state of the backend members. -It determines how the load balancer identifies whether the backend members are healthy or unhealthy.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Required: true, - Description: fmt.Sprintf("Available values is '%s', '%s', '%s', '%s', '%s', '%s", types.HealthMonitorTypeHTTP, types.HealthMonitorTypeHTTPS, types.HealthMonitorTypePING, types.HealthMonitorTypeTCP, types.HealthMonitorTypeTLSHello, types.HealthMonitorTypeUDPConnect), - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - switch types.HealthMonitorType(v) { - case types.HealthMonitorTypeHTTP, types.HealthMonitorTypeHTTPS, types.HealthMonitorTypePING, types.HealthMonitorTypeTCP, types.HealthMonitorTypeTLSHello, types.HealthMonitorTypeUDPConnect: - return diag.Diagnostics{} - } - return diag.Errorf("wrong type %s, available values is '%s', '%s', '%s', '%s', '%s', '%s", v, types.HealthMonitorTypeHTTP, types.HealthMonitorTypeHTTPS, types.HealthMonitorTypePING, types.HealthMonitorTypeTCP, types.HealthMonitorTypeTLSHello, types.HealthMonitorTypeUDPConnect) - }, - }, - "delay": { - Type: schema.TypeInt, - Required: true, - }, - "max_retries": { - Type: schema.TypeInt, - Required: true, - }, - "timeout": { - Type: schema.TypeInt, - Required: true, - }, - "max_retries_down": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - "http_method": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "url_path": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "expected_codes": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - }, - }, - }, - "session_persistence": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Description: `Configuration that enables the load balancer to bind a user's session to a specific backend member. -This ensures that all requests from the user during the session are sent to the same member.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Required: true, - }, - "cookie_name": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "persistence_granularity": { - Type: schema.TypeString, - Optional: true, - Computed: true, - }, - "persistence_timeout": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - }, - }, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceLBPoolCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBPool creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - healthOpts := extractHealthMonitorMap(d) - sessionOpts := extractSessionPersistenceMap(d) - opts := lbpools.CreateOpts{ - Name: d.Get("name").(string), - Protocol: types.ProtocolType(d.Get("protocol").(string)), - LBPoolAlgorithm: types.LoadBalancerAlgorithm(d.Get("lb_algorithm").(string)), - LoadBalancerID: d.Get("loadbalancer_id").(string), - ListenerID: d.Get("listener_id").(string), - HealthMonitor: healthOpts, - SessionPersistence: sessionOpts, - } - - results, err := lbpools.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - lbPoolID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, LBPoolsCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - lbPoolID, err := lbpools.ExtractPoolIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve LBPool ID from task info: %w", err) - } - return lbPoolID, nil - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(lbPoolID.(string)) - resourceLBPoolRead(ctx, d, m) - - log.Printf("[DEBUG] Finish LBPool creating (%s)", lbPoolID) - - return diags -} - -func resourceLBPoolRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBPool reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - lb, err := lbpools.Get(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - d.Set("name", lb.Name) - d.Set("lb_algorithm", lb.LoadBalancerAlgorithm.String()) - d.Set("protocol", lb.Protocol.String()) - - if len(lb.LoadBalancers) > 0 { - d.Set("loadbalancer_id", lb.LoadBalancers[0].ID) - } - - if len(lb.Listeners) > 0 { - d.Set("listener_id", lb.Listeners[0].ID) - } - - if lb.HealthMonitor != nil { - healthMonitor := map[string]interface{}{ - "id": lb.HealthMonitor.ID, - "type": lb.HealthMonitor.Type.String(), - "delay": lb.HealthMonitor.Delay, - "timeout": lb.HealthMonitor.Timeout, - "max_retries": lb.HealthMonitor.MaxRetries, - "max_retries_down": lb.HealthMonitor.MaxRetriesDown, - "url_path": lb.HealthMonitor.URLPath, - "expected_codes": lb.HealthMonitor.ExpectedCodes, - } - if lb.HealthMonitor.HTTPMethod != nil { - healthMonitor["http_method"] = lb.HealthMonitor.HTTPMethod.String() - } - - if err := d.Set("health_monitor", []interface{}{healthMonitor}); err != nil { - return diag.FromErr(err) - } - } - - if lb.SessionPersistence != nil { - sessionPersistence := map[string]interface{}{ - "type": lb.SessionPersistence.Type.String(), - "cookie_name": lb.SessionPersistence.CookieName, - "persistence_granularity": lb.SessionPersistence.PersistenceGranularity, - "persistence_timeout": lb.SessionPersistence.PersistenceTimeout, - } - - if err := d.Set("session_persistence", []interface{}{sessionPersistence}); err != nil { - return diag.FromErr(err) - } - } - - fields := []string{"project_id", "region_id"} - revertState(d, &fields) - - log.Println("[DEBUG] Finish LBPool reading") - - return diags -} - -func resourceLBPoolUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBPool updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - var change bool - opts := lbpools.UpdateOpts{Name: d.Get("name").(string)} - - if d.HasChange("lb_algorithm") { - opts.LBPoolAlgorithm = types.LoadBalancerAlgorithm(d.Get("lb_algorithm").(string)) - change = true - } - - if d.HasChange("health_monitor") { - opts.HealthMonitor = extractHealthMonitorMap(d) - change = true - } - - if d.HasChange("session_persistence") { - opts.SessionPersistence = extractSessionPersistenceMap(d) - change = true - } - - if !change { - log.Println("[DEBUG] Finish LBPool updating") - return resourceLBPoolRead(ctx, d, m) - } - - results, err := lbpools.Update(client, d.Id(), opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, LBPoolsCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - return nil, nil - }) - - if err != nil { - return diag.FromErr(err) - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish LBPool updating") - - return resourceLBPoolRead(ctx, d, m) -} - -func resourceLBPoolDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LBPool deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LBPoolsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - id := d.Id() - results, err := lbpools.Delete(client, id).Extract() - if err != nil { - var errDefault404 edgecloud.Default404Error - if !errors.As(err, &errDefault404) { - return diag.FromErr(err) - } - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, LBPoolsCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := lbpools.Get(client, id).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete LBPool with ID: %s", id) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting LBPool resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of LBPool deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_lifecyclepolicy.go b/edgecenter/resource_edgecenter_lifecyclepolicy.go deleted file mode 100644 index d5cdfa56..00000000 --- a/edgecenter/resource_edgecenter_lifecyclepolicy.go +++ /dev/null @@ -1,585 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "regexp" - "strconv" - - "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" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/lifecyclepolicy/v1/lifecyclepolicy" -) - -const ( - LifecyclePolicyPoint = "lifecycle_policies" - // Maybe move to utils and use for other resources. - nameRegexString = `^[a-zA-Z0-9][a-zA-Z 0-9._\-]{1,61}[a-zA-Z0-9._]$` -) - -// Maybe move to utils and use for other resources. -var nameRegex = regexp.MustCompile(nameRegexString) - -func resourceLifecyclePolicy() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceLifecyclePolicyCreate, - ReadContext: resourceLifecyclePolicyRead, - UpdateContext: resourceLifecyclePolicyUpdate, - DeleteContext: resourceLifecyclePolicyDelete, - Description: "Represent lifecycle policy. Use to periodically take snapshots", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, lcpID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(lcpID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.StringMatch(nameRegex, ""), - }, - "status": { - Type: schema.TypeString, - Optional: true, - Default: lifecyclepolicy.PolicyStatusActive.String(), - ValidateFunc: validation.StringInSlice(lifecyclepolicy.PolicyStatus("").StringList(), false), - }, - "action": { - Type: schema.TypeString, - Optional: true, - Default: lifecyclepolicy.PolicyActionVolumeSnapshot.String(), - ForceNew: true, - ValidateFunc: validation.StringInSlice(lifecyclepolicy.PolicyAction("").StringList(), false), - }, - "volume": { - Type: schema.TypeSet, - Optional: true, - Description: "List of managed volumes", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Required: true, - ValidateFunc: validation.IsUUID, - }, - "name": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "schedule": { - Type: schema.TypeList, - Optional: true, - ForceNew: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "max_quantity": { - Type: schema.TypeInt, - Required: true, - ValidateFunc: validation.IntBetween(1, 10000), - Description: "Maximum number of stored resources", - }, - "interval": { - Type: schema.TypeList, - MinItems: 1, - MaxItems: 1, - Description: "Use for taking actions with equal time intervals between them. Exactly one of interval and cron blocks should be provided", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "weeks": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: intervalScheduleParamDescription("week"), - }, - "days": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: intervalScheduleParamDescription("day"), - }, - "hours": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: intervalScheduleParamDescription("hour"), - }, - "minutes": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: intervalScheduleParamDescription("minute"), - }, - }, - }, - Optional: true, - }, - "cron": { - Type: schema.TypeList, - MinItems: 1, - MaxItems: 1, - Description: "Use for taking actions at specified moments of time. Exactly one of interval and cron blocks should be provided", - Elem: &schema.Resource{ // TODO: validate? - Schema: map[string]*schema.Schema{ - "timezone": { - Type: schema.TypeString, - Optional: true, - Default: "UTC", - }, - "month": { - Type: schema.TypeString, - Optional: true, - Default: "*", - Description: cronScheduleParamDescription(1, 12), - }, - "week": { - Type: schema.TypeString, - Optional: true, - Default: "*", - Description: cronScheduleParamDescription(1, 53), - }, - "day": { - Type: schema.TypeString, - Optional: true, - Default: "*", - Description: cronScheduleParamDescription(1, 31), - }, - "day_of_week": { - Type: schema.TypeString, - Optional: true, - Default: "*", - Description: cronScheduleParamDescription(0, 6), - }, - "hour": { - Type: schema.TypeString, - Optional: true, - Default: "*", - Description: cronScheduleParamDescription(0, 23), - }, - "minute": { - Type: schema.TypeString, - Optional: true, - Default: "0", - Description: cronScheduleParamDescription(0, 59), - }, - }, - }, - Optional: true, - }, - "resource_name_template": { - Type: schema.TypeString, - Optional: true, - Default: "reserve snap of the volume {volume_id}", - Description: "Used to name snapshots. {volume_id} is substituted with volume.id on creation", - }, - "retention_time": { - Type: schema.TypeList, - MinItems: 1, - MaxItems: 1, - Description: "If it is set, new resource will be deleted after time", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "weeks": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: retentionTimerParamDescription("week"), - }, - "days": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: retentionTimerParamDescription("day"), - }, - "hours": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: retentionTimerParamDescription("hour"), - }, - "minutes": { - Type: schema.TypeInt, - Optional: true, - Default: 0, - Description: retentionTimerParamDescription("minute"), - }, - }, - }, - Optional: true, - }, - "id": { - Type: schema.TypeString, - Computed: true, - }, - "type": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "user_id": { - Type: schema.TypeInt, - Computed: true, - }, - }, - } -} - -func resourceLifecyclePolicyCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client, err := CreateClient(m.(*Config).Provider, d, LifecyclePolicyPoint, VersionPointV1) - if err != nil { - return diag.Errorf("Error creating client: %s", err) - } - - log.Printf("[DEBUG] Start of LifecyclePolicy creating") - opts, err := buildLifecyclePolicyCreateOpts(d) - if err != nil { - return diag.FromErr(err) - } - policy, err := lifecyclepolicy.Create(client, *opts).Extract() - if err != nil { - return diag.Errorf("Error creating lifecycle policy: %s", err) - } - d.SetId(strconv.Itoa(policy.ID)) - log.Printf("[DEBUG] Finish of LifecyclePolicy %s creating", d.Id()) - - return resourceLifecyclePolicyRead(ctx, d, m) -} - -func resourceLifecyclePolicyRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client, err := CreateClient(m.(*Config).Provider, d, LifecyclePolicyPoint, VersionPointV1) - if err != nil { - return diag.Errorf("Error creating client: %s", err) - } - id := d.Id() - integerID, err := strconv.Atoi(id) - if err != nil { - return diag.Errorf("Error converting lifecycle policy ID to integer: %s", err) - } - - log.Printf("[DEBUG] Start of LifecyclePolicy %s reading", id) - policy, err := lifecyclepolicy.Get(client, integerID, lifecyclepolicy.GetOpts{NeedVolumes: true}).Extract() - if err != nil { - return diag.Errorf("Error getting lifecycle policy: %s", err) - } - - _ = d.Set("name", policy.Name) - _ = d.Set("status", policy.Status) - _ = d.Set("action", policy.Action) - _ = d.Set("user_id", policy.UserID) - if err = d.Set("volume", flattenVolumes(policy.Volumes)); err != nil { - return diag.Errorf("error setting lifecycle policy volumes: %s", err) - } - if err = d.Set("schedule", flattenSchedules(policy.Schedules)); err != nil { - return diag.Errorf("error setting lifecycle policy schedules: %s", err) - } - - log.Printf("[DEBUG] Finish of LifecyclePolicy %s reading", id) - - return nil -} - -func resourceLifecyclePolicyUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client, err := CreateClient(m.(*Config).Provider, d, LifecyclePolicyPoint, VersionPointV1) - if err != nil { - return diag.Errorf("Error creating client: %s", err) - } - id := d.Id() - integerID, err := strconv.Atoi(id) - if err != nil { - return diag.Errorf("Error converting lifecycle policy ID to integer: %s", err) - } - - log.Printf("[DEBUG] Start of LifecyclePolicy updating") - _, err = lifecyclepolicy.Update(client, integerID, buildLifecyclePolicyUpdateOpts(d)).Extract() - if err != nil { - return diag.Errorf("Error updating lifecycle policy: %s", err) - } - - if d.HasChange("volume") { - oldVolumes, newVolumes := d.GetChange("volume") - toRemove, toAdd := volumeSymmetricDifference(oldVolumes.(*schema.Set), newVolumes.(*schema.Set)) - _, err = lifecyclepolicy.RemoveVolumes(client, integerID, lifecyclepolicy.RemoveVolumesOpts{VolumeIds: toRemove}).Extract() - if err != nil { - return diag.Errorf("Error removing volumes from lifecycle policy: %s", err) - } - _, err = lifecyclepolicy.AddVolumes(client, integerID, lifecyclepolicy.AddVolumesOpts{VolumeIds: toAdd}).Extract() - if err != nil { - return diag.Errorf("Error adding volumes to lifecycle policy: %s", err) - } - } - log.Printf("[DEBUG] Finish of LifecyclePolicy %v updating", integerID) - - return resourceLifecyclePolicyRead(ctx, d, m) -} - -func resourceLifecyclePolicyDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - client, err := CreateClient(m.(*Config).Provider, d, LifecyclePolicyPoint, VersionPointV1) - if err != nil { - return diag.Errorf("Error creating client: %s", err) - } - id := d.Id() - integerID, err := strconv.Atoi(id) - if err != nil { - return diag.Errorf("Error converting lifecycle policy ID to integer: %s", err) - } - - log.Printf("[DEBUG] Start of LifecyclePolicy %s deleting", id) - err = lifecyclepolicy.Delete(client, integerID) - if err != nil { - return diag.Errorf("Error deleting lifecycle policy: %s", err) - } - d.SetId("") - log.Printf("[DEBUG] Finish of LifecyclePolicy %s deleting", id) - - return nil -} - -func expandIntervalSchedule(flat map[string]interface{}) *lifecyclepolicy.CreateIntervalScheduleOpts { - return &lifecyclepolicy.CreateIntervalScheduleOpts{ - Weeks: flat["weeks"].(int), - Days: flat["days"].(int), - Hours: flat["hours"].(int), - Minutes: flat["minutes"].(int), - } -} - -func expandCronSchedule(flat map[string]interface{}) *lifecyclepolicy.CreateCronScheduleOpts { - return &lifecyclepolicy.CreateCronScheduleOpts{ - Timezone: flat["timezone"].(string), - Week: flat["week"].(string), - DayOfWeek: flat["day_of_week"].(string), - Month: flat["month"].(string), - Day: flat["day"].(string), - Hour: flat["hour"].(string), - Minute: flat["minute"].(string), - } -} - -func expandRetentionTimer(flat []interface{}) *lifecyclepolicy.RetentionTimer { - if len(flat) > 0 { - rawRetention := flat[0].(map[string]interface{}) - return &lifecyclepolicy.RetentionTimer{ - Weeks: rawRetention["weeks"].(int), - Days: rawRetention["days"].(int), - Hours: rawRetention["hours"].(int), - Minutes: rawRetention["minutes"].(int), - } - } - return nil -} - -func expandSchedule(flat map[string]interface{}) (lifecyclepolicy.CreateScheduleOpts, error) { - t := lifecyclepolicy.ScheduleType("") - intervalSlice := flat["interval"].([]interface{}) - cronSlice := flat["cron"].([]interface{}) - if len(intervalSlice)+len(cronSlice) != 1 { - return nil, fmt.Errorf("exactly one of interval and cron blocks should be provided") - } - var expanded lifecyclepolicy.CreateScheduleOpts - if len(intervalSlice) > 0 { - t = lifecyclepolicy.ScheduleTypeInterval - expanded = expandIntervalSchedule(intervalSlice[0].(map[string]interface{})) - } else { - t = lifecyclepolicy.ScheduleTypeCron - expanded = expandCronSchedule(cronSlice[0].(map[string]interface{})) - } - expanded.SetCommonCreateScheduleOpts(lifecyclepolicy.CommonCreateScheduleOpts{ - Type: t, - ResourceNameTemplate: flat["resource_name_template"].(string), - MaxQuantity: flat["max_quantity"].(int), - RetentionTime: expandRetentionTimer(flat["retention_time"].([]interface{})), - }) - - return expanded, nil -} - -func expandSchedules(flat []interface{}) ([]lifecyclepolicy.CreateScheduleOpts, error) { - expanded := make([]lifecyclepolicy.CreateScheduleOpts, len(flat)) - for i, x := range flat { - exp, err := expandSchedule(x.(map[string]interface{})) - if err != nil { - return nil, err - } - expanded[i] = exp - } - return expanded, nil -} - -func expandVolumeIds(flat []interface{}) []string { - expanded := make([]string, len(flat)) - for i, x := range flat { - expanded[i] = x.(map[string]interface{})["id"].(string) - } - return expanded -} - -func buildLifecyclePolicyCreateOpts(d *schema.ResourceData) (*lifecyclepolicy.CreateOpts, error) { - schedules, err := expandSchedules(d.Get("schedule").([]interface{})) - if err != nil { - return nil, err - } - opts := &lifecyclepolicy.CreateOpts{ - Name: d.Get("name").(string), - Status: lifecyclepolicy.PolicyStatus(d.Get("status").(string)), - Schedules: schedules, - VolumeIds: expandVolumeIds(d.Get("volume").(*schema.Set).List()), - } - - // Action is required field from API point of view, but optional for us - if action, ok := d.GetOk("action"); ok { - opts.Action = lifecyclepolicy.PolicyAction(action.(string)) - } else { - opts.Action = lifecyclepolicy.PolicyActionVolumeSnapshot - } - - return opts, nil -} - -func volumeSymmetricDifference(oldVolumes, newVolumes *schema.Set) ([]string, []string) { - toRemove := make([]string, 0) - for _, v := range oldVolumes.List() { - if !newVolumes.Contains(v) { - toRemove = append(toRemove, v.(map[string]interface{})["id"].(string)) - } - } - toAdd := make([]string, 0) - for _, v := range newVolumes.List() { - if !oldVolumes.Contains(v) { - toAdd = append(toAdd, v.(map[string]interface{})["id"].(string)) - } - } - - return toRemove, toAdd -} - -func buildLifecyclePolicyUpdateOpts(d *schema.ResourceData) lifecyclepolicy.UpdateOpts { - opts := lifecyclepolicy.UpdateOpts{ - Name: d.Get("name").(string), - Status: lifecyclepolicy.PolicyStatus(d.Get("status").(string)), - } - return opts -} - -func flattenIntervalSchedule(expanded lifecyclepolicy.IntervalSchedule) interface{} { - return []map[string]int{{ - "weeks": expanded.Weeks, - "days": expanded.Days, - "hours": expanded.Hours, - "minutes": expanded.Minutes, - }} -} - -func flattenCronSchedule(expanded lifecyclepolicy.CronSchedule) interface{} { - return []map[string]string{{ - "timezone": expanded.Timezone, - "week": expanded.Week, - "day_of_week": expanded.DayOfWeek, - "month": expanded.Month, - "day": expanded.Day, - "hour": expanded.Hour, - "minute": expanded.Minute, - }} -} - -func flattenRetentionTimer(expanded *lifecyclepolicy.RetentionTimer) interface{} { - if expanded != nil { - return []map[string]int{{ - "weeks": expanded.Weeks, - "days": expanded.Days, - "hours": expanded.Hours, - "minutes": expanded.Minutes, - }} - } - return []interface{}{} -} - -func flattenSchedule(expanded lifecyclepolicy.Schedule) map[string]interface{} { - common := expanded.GetCommonSchedule() - flat := map[string]interface{}{ - "max_quantity": common.MaxQuantity, - "resource_name_template": common.ResourceNameTemplate, - "retention_time": flattenRetentionTimer(common.RetentionTime), - "id": common.ID, - "type": common.Type, - } - switch common.Type { - case lifecyclepolicy.ScheduleTypeInterval: - flat["interval"] = flattenIntervalSchedule(expanded.(lifecyclepolicy.IntervalSchedule)) - case lifecyclepolicy.ScheduleTypeCron: - flat["cron"] = flattenCronSchedule(expanded.(lifecyclepolicy.CronSchedule)) - } - - return flat -} - -func flattenSchedules(expanded []lifecyclepolicy.Schedule) []map[string]interface{} { - flat := make([]map[string]interface{}, len(expanded)) - for i, x := range expanded { - flat[i] = flattenSchedule(x) - } - return flat -} - -func flattenVolumes(expanded []lifecyclepolicy.Volume) []map[string]string { - flat := make([]map[string]string, len(expanded)) - for i, volume := range expanded { - flat[i] = map[string]string{"id": volume.ID, "name": volume.Name} - } - return flat -} - -func cronScheduleParamDescription(min, max int) string { - return fmt.Sprintf("Either single asterisk or comma-separated list of integers (%v-%v)", min, max) -} - -func intervalScheduleParamDescription(unit string) string { - return fmt.Sprintf("Number of %ss to wait between actions", unit) -} - -func retentionTimerParamDescription(unit string) string { - return fmt.Sprintf("Number of %ss to wait before deleting snapshot", unit) -} diff --git a/edgecenter/resource_edgecenter_loadbalancer.go b/edgecenter/resource_edgecenter_loadbalancer.go deleted file mode 100644 index b3df2c52..00000000 --- a/edgecenter/resource_edgecenter_loadbalancer.go +++ /dev/null @@ -1,469 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/listeners" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/loadbalancers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" -) - -const ( - LoadBalancersPoint = "loadbalancers" - LoadBalancerCreateTimeout = 2400 -) - -func resourceLoadBalancer() *schema.Resource { - return &schema.Resource{ - DeprecationMessage: "!> **WARNING:** This resource is deprecated and will be removed in the next major version. Use edgecenter_loadbalancerv2 resource instead", - CreateContext: resourceLoadBalancerCreate, - ReadContext: resourceLoadBalancerRead, - UpdateContext: resourceLoadBalancerUpdate, - DeleteContext: resourceLoadBalancerDelete, - Description: "Represent load balancer", - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(5 * time.Minute), - Delete: schema.DefaultTimeout(5 * time.Minute), - }, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, lbID, listenerID, err := ImportStringParserExtended(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(lbID) - - config := m.(*Config) - provider := config.Provider - - listenersClient, err := CreateClient(provider, d, LBListenersPoint, VersionPointV1) - if err != nil { - return nil, err - } - - listener, err := listeners.Get(listenersClient, listenerID).Extract() - if err != nil { - return nil, fmt.Errorf("extracting Listener resource error: %w", err) - } - - l := extractListenerIntoMap(listener) - if err := d.Set("listener", []interface{}{l}); err != nil { - return nil, fmt.Errorf("set listener error: %w", err) - } - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the load balancer.", - }, - "flavor": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, - "vip_network_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, - "vip_subnet_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - }, - "vip_address": { - Type: schema.TypeString, - Description: "Load balancer IP address", - Computed: true, - }, - "listener": { - Type: schema.TypeList, - Required: true, - MaxItems: 1, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - }, - "name": { - Type: schema.TypeString, - Required: true, - }, - "certificate": { - Type: schema.TypeString, - Optional: true, - }, - "protocol": { - Type: schema.TypeString, - Required: true, - Description: fmt.Sprintf("Available values is '%s' (currently work, other do not work on ed-8), '%s', '%s', '%s'", types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS, types.ProtocolTypeTCP, types.ProtocolTypeUDP), - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - switch types.ProtocolType(v) { - case types.ProtocolTypeHTTP, types.ProtocolTypeHTTPS, types.ProtocolTypeTCP, types.ProtocolTypeUDP: - return diag.Diagnostics{} - case types.ProtocolTypeTerminatedHTTPS, types.ProtocolTypePROXY: - } - return diag.Errorf("wrong protocol %s, available values is 'HTTP', 'HTTPS', 'TCP', 'UDP'", v) - }, - }, - "certificate_chain": { - Type: schema.TypeString, - Optional: true, - }, - "protocol_port": { - Type: schema.TypeInt, - Required: true, - }, - "private_key": { - Type: schema.TypeString, - Optional: true, - }, - "insert_x_forwarded": { - Type: schema.TypeBool, - Optional: true, - }, - "secret_id": { - Type: schema.TypeString, - Optional: true, - }, - "sni_secret_id": { - Type: schema.TypeList, - Elem: &schema.Schema{Type: schema.TypeString}, - Optional: true, - }, - }, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func resourceLoadBalancerCreate(_ context.Context, _ *schema.ResourceData, _ interface{}) diag.Diagnostics { - return diag.FromErr(fmt.Errorf("use edgecenter_loadbalancerv2 resource instead")) -} - -func resourceLoadBalancerRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LoadBalancer reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LoadBalancersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - lb, err := loadbalancers.Get(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - d.Set("project_id", lb.ProjectID) - d.Set("region_id", lb.RegionID) - d.Set("name", lb.Name) - d.Set("flavor", lb.Flavor.FlavorName) - - if lb.VipAddress != nil { - d.Set("vip_address", lb.VipAddress.String()) - } - - fields := []string{"vip_network_id", "vip_subnet_id"} - revertState(d, &fields) - - listenersClient, err := CreateClient(provider, d, LBListenersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - var ok bool - currentL := make(map[string]interface{}) - // we need to find correct listener because after upgrade some of them could be nil - // but still in terraform.state - cls := d.Get("listener").([]interface{}) - for _, cl := range cls { - if currentL, ok = cl.(map[string]interface{}); ok { - break - } - } - - for _, l := range lb.Listeners { - listener, err := listeners.Get(listenersClient, l.ID).Extract() - if err != nil { - return diag.FromErr(err) - } - port, _ := currentL["protocol_port"].(int) - if (listener.ProtocolPort == port && listener.Protocol.String() == currentL["protocol"]) || len(cls) == 0 { - currentL = extractListenerIntoMap(listener) - break - } - } - if err := d.Set("listener", []interface{}{currentL}); err != nil { - diag.FromErr(err) - } - - metadataMap, metadataReadOnly := PrepareMetadata(lb.Metadata) - - if err = d.Set("metadata_map", metadataMap); err != nil { - return diag.FromErr(err) - } - - if err = d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish LoadBalancer reading") - - return diags -} - -func resourceLoadBalancerUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LoadBalancer updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LoadBalancersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("name") { - opts := loadbalancers.UpdateOpts{ - Name: d.Get("name").(string), - } - if _, err = loadbalancers.Update(client, d.Id(), opts).Extract(); err != nil { - return diag.FromErr(err) - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - } - - if d.HasChange("listener") { - client, err := CreateClient(provider, d, LBListenersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - oldListenerRaw, newListenerRaw := d.GetChange("listener") - oldListener := oldListenerRaw.([]interface{})[0].(map[string]interface{}) - newListener := newListenerRaw.([]interface{})[0].(map[string]interface{}) - - listenerID := oldListener["id"].(string) - if oldListener["protocol"].(string) != newListener["protocol"].(string) || - oldListener["protocol_port"].(int) != newListener["protocol_port"].(int) { - // if protocol or port changed listener need to be recreated - // delete at first - results, err := listeners.Delete(client, listenerID).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, LBListenerCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := listeners.Get(client, listenerID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete LBListener with ID: %s", listenerID) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Listener resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - opts := listeners.CreateOpts{ - Name: newListener["name"].(string), - Protocol: types.ProtocolType(newListener["protocol"].(string)), - ProtocolPort: newListener["protocol_port"].(int), - LoadBalancerID: d.Id(), - InsertXForwarded: newListener["insert_x_forwarded"].(bool), - SecretID: newListener["secret_id"].(string), - } - sniSecretIDRaw := newListener["sni_secret_id"].([]interface{}) - if len(sniSecretIDRaw) != 0 { - sniSecretID := make([]string, len(sniSecretIDRaw)) - for i, s := range sniSecretIDRaw { - sniSecretID[i] = s.(string) - } - opts.SNISecretID = sniSecretID - } - - results, err = listeners.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID = results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, LBListenerCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - listenerID, err := listeners.ExtractListenerIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve LBListener ID from task info: %w", err) - } - return listenerID, nil - }) - if err != nil { - return diag.FromErr(err) - } - } else { - opts := listeners.UpdateOpts{ - Name: newListener["name"].(string), - SecretID: newListener["secret_id"].(string), - } - sniSecretIDRaw := newListener["sni_secret_id"].([]interface{}) - sniSecretID := make([]string, len(sniSecretIDRaw)) - for i, s := range sniSecretIDRaw { - sniSecretID[i] = s.(string) - } - opts.SNISecretID = sniSecretID - if _, err := listeners.Update(client, listenerID, opts).Extract(); err != nil { - return diag.FromErr(err) - } - } - } - - if d.HasChange("metadata_map") { - _, nmd := d.GetChange("metadata_map") - - meta, err := utils.MapInterfaceToMapString(nmd.(map[string]interface{})) - if err != nil { - return diag.Errorf("cannot get metadata. Error: %s", err) - } - - err = metadata.ResourceMetadataReplace(client, d.Id(), meta).Err - if err != nil { - return diag.Errorf("cannot update metadata. Error: %s", err) - } - } - - log.Println("[DEBUG] Finish LoadBalancer updating") - - return resourceLoadBalancerRead(ctx, d, m) -} - -func resourceLoadBalancerDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LoadBalancer deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LoadBalancersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - id := d.Id() - results, err := loadbalancers.Delete(client, id).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, LoadBalancerCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := loadbalancers.Get(client, id).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete loadbalancer with ID: %s", id) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Load Balancer resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of LoadBalancer deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_loadbalancerv2.go b/edgecenter/resource_edgecenter_loadbalancerv2.go deleted file mode 100644 index e7a58306..00000000 --- a/edgecenter/resource_edgecenter_loadbalancerv2.go +++ /dev/null @@ -1,330 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/loadbalancers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/securitygroups" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" -) - -func resourceLoadBalancerV2() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceLoadBalancerV2Create, - ReadContext: resourceLoadBalancerV2Read, - UpdateContext: resourceLoadBalancerV2Update, - DeleteContext: resourceLoadBalancerDelete, - Description: "Represent load balancer without nested listener", - Timeouts: &schema.ResourceTimeout{ - Create: schema.DefaultTimeout(5 * time.Minute), - Delete: schema.DefaultTimeout(5 * time.Minute), - }, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, m interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, lbID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(lbID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the load balancer.", - }, - "flavor": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The flavor or specification of the load balancer to be created.", - }, - "vip_port_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ConflictsWith: []string{"vip_network_id"}, - Description: "Attaches the created reserved IP.", - }, - "vip_network_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - ConflictsWith: []string{"vip_port_id"}, - Description: "Attaches the created network.", - }, - "vip_subnet_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - RequiredWith: []string{"vip_network_id"}, - Description: "The ID of the subnet in which to allocate the VIP address for the load balancer.", - }, - "vip_address": { - Type: schema.TypeString, - Computed: true, - Description: "Load balancer IP address", - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - "security_group": { - Type: schema.TypeString, - Optional: true, - Description: "Creates a new security group with the specified name", - }, - "security_group_id": { - Type: schema.TypeString, - Description: "Load balancer security group ID", - Computed: true, - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func resourceLoadBalancerV2Create(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LoadBalancer creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LoadBalancersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := loadbalancers.CreateOpts{ - Name: d.Get("name").(string), - VipPortID: d.Get("vip_port_id").(string), - VipNetworkID: d.Get("vip_network_id").(string), - VipSubnetID: d.Get("vip_subnet_id").(string), - } - - if metadataRaw, ok := d.GetOk("metadata_map"); ok { - meta, err := utils.MapInterfaceToMapString(metadataRaw) - if err != nil { - return diag.FromErr(err) - } - opts.Metadata = meta - } - - lbFlavor := d.Get("flavor").(string) - if len(lbFlavor) != 0 { - opts.Flavor = &lbFlavor - } - - results, err := loadbalancers.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - lbID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, LoadBalancerCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - lbID, err := loadbalancers.ExtractLoadBalancerIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve LoadBalancer ID from task info: %w", err) - } - return lbID, nil - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(lbID.(string)) - - securityGroup := d.Get("security_group").(string) - if securityGroup != "" { - if err := loadbalancers.CreateCustomSecurityGroup(client, d.Id()).ExtractErr(); err != nil { - return diag.FromErr(err) - } - - sgInfo, err := loadbalancers.ListCustomSecurityGroup(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - - if len(sgInfo) > 0 { - sgID := sgInfo[0].ID - d.Set("security_group_id", sgID) - clientSG, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - _, err = securitygroups.Update(clientSG, sgID, securitygroups.UpdateOpts{Name: securityGroup}).Extract() - if err != nil { - return diag.FromErr(err) - } - } - } - - resourceLoadBalancerV2Read(ctx, d, m) - - log.Printf("[DEBUG] Finish LoadBalancer creating (%s)", lbID) - - return diags -} - -func resourceLoadBalancerV2Read(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LoadBalancer reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LoadBalancersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - lb, err := loadbalancers.Get(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - d.Set("project_id", lb.ProjectID) - d.Set("region_id", lb.RegionID) - d.Set("name", lb.Name) - d.Set("flavor", lb.Flavor.FlavorName) - - if lb.VipAddress != nil { - d.Set("vip_address", lb.VipAddress.String()) - } - - fields := []string{"vip_network_id", "vip_subnet_id"} - revertState(d, &fields) - - metadataList, err := metadata.ResourceMetadataListAll(client, d.Id()) - if err != nil { - return diag.FromErr(err) - } - metadataMap, metadataReadOnly := PrepareMetadata(metadataList) - - if err = d.Set("metadata_map", metadataMap); err != nil { - return diag.FromErr(err) - } - - if err = d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish LoadBalancer reading") - - return diags -} - -func resourceLoadBalancerV2Update(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start LoadBalancer updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, LoadBalancersPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("name") { - opts := loadbalancers.UpdateOpts{ - Name: d.Get("name").(string), - } - _, err = loadbalancers.Update(client, d.Id(), opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - } - - if d.HasChange("metadata_map") { - _, nmd := d.GetChange("metadata_map") - - meta, err := utils.MapInterfaceToMapString(nmd.(map[string]interface{})) - if err != nil { - return diag.Errorf("cannot get metadata. Error: %s", err) - } - - err = metadata.ResourceMetadataReplace(client, d.Id(), meta).Err - if err != nil { - return diag.Errorf("cannot update metadata. Error: %s", err) - } - } - - log.Println("[DEBUG] Finish LoadBalancer updating") - - return resourceLoadBalancerV2Read(ctx, d, m) -} diff --git a/edgecenter/resource_edgecenter_network.go b/edgecenter/resource_edgecenter_network.go deleted file mode 100644 index b34d2884..00000000 --- a/edgecenter/resource_edgecenter_network.go +++ /dev/null @@ -1,313 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" -) - -const ( - NetworkDeleting int = 1200 - NetworkCreatingTimeout int = 1200 - NetworksPoint = "networks" - SharedNetworksPoint = "availablenetworks" -) - -func resourceNetwork() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceNetworkCreate, - ReadContext: resourceNetworkRead, - UpdateContext: resourceNetworkUpdate, - DeleteContext: resourceNetworkDelete, - Description: "Represent network. A network is a software-defined network in a cloud computing infrastructure", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, NetworkID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(NetworkID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the network.", - }, - "mtu": { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "Maximum Transmission Unit (MTU) for the network. It determines the maximum packet size that can be transmitted without fragmentation.", - }, - "type": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "'vlan' or 'vxlan' network type is allowed. Default value is 'vxlan'", - }, - "create_router": { - Type: schema.TypeBool, - Optional: true, - Default: true, - Description: "Create external router to the network, default true", - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func resourceNetworkCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Network creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, NetworksPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - createOpts := networks.CreateOpts{ - Name: d.Get("name").(string), - Type: d.Get("type").(string), - CreateRouter: d.Get("create_router").(bool), - } - - if metadataRaw, ok := d.GetOk("metadata_map"); ok { - meta, err := utils.MapInterfaceToMapString(metadataRaw) - if err != nil { - return diag.FromErr(err) - } - - createOpts.Metadata = meta - } - - log.Printf("Create network ops: %+v", createOpts) - results, err := networks.Create(client, createOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - networkID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, NetworkCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - NetworkID, err := networks.ExtractNetworkIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve Network ID from task info: %w", err) - } - return NetworkID, nil - }, - ) - log.Printf("[DEBUG] Network id (%s)", networkID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(networkID.(string)) - resourceNetworkRead(ctx, d, m) - - log.Printf("[DEBUG] Finish Network creating (%s)", networkID) - - return diags -} - -func resourceNetworkRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start network reading") - log.Printf("[DEBUG] Start network reading%s", d.State()) - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - networkID := d.Id() - log.Printf("[DEBUG] Network id = %s", networkID) - - client, err := CreateClient(provider, d, NetworksPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - network, err := networks.Get(client, networkID).Extract() - if err != nil { - return diag.Errorf("cannot get network with ID: %s. Error: %s", networkID, err) - } - - d.Set("name", network.Name) - d.Set("mtu", network.MTU) - d.Set("type", network.Type) - d.Set("region_id", network.RegionID) - d.Set("project_id", network.ProjectID) - - metadataMap, metadataReadOnly := PrepareMetadata(network.Metadata) - - if err = d.Set("metadata_map", metadataMap); err != nil { - return diag.FromErr(err) - } - - if err = d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - fields := []string{"create_router"} - revertState(d, &fields) - - log.Println("[DEBUG] Finish network reading") - - return diags -} - -func resourceNetworkUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start network updating") - networkID := d.Id() - log.Printf("[DEBUG] Volume id = %s", networkID) - config := m.(*Config) - provider := config.Provider - client, err := CreateClient(provider, d, NetworksPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("name") { - newName := d.Get("name").(string) - _, err := networks.Update(client, networkID, networks.UpdateOpts{Name: newName}).Extract() - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("metadata_map") { - _, nmd := d.GetChange("metadata_map") - - meta, err := utils.MapInterfaceToMapString(nmd.(map[string]interface{})) - if err != nil { - return diag.Errorf("cannot get metadata. Error: %s", err) - } - - err = metadata.ResourceMetadataReplace(client, networkID, meta).Err - if err != nil { - return diag.Errorf("cannot update metadata. Error: %s", err) - } - } - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish network updating") - - return resourceNetworkRead(ctx, d, m) -} - -func resourceNetworkDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start network deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - networkID := d.Id() - log.Printf("[DEBUG] Network id = %s", networkID) - - client, err := CreateClient(provider, d, NetworksPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - results, err := networks.Delete(client, networkID).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, NetworkDeleting, func(task tasks.TaskID) (interface{}, error) { - _, err := networks.Get(client, networkID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete network with ID: %s", networkID) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Network resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of network deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_reservedfixedip.go b/edgecenter/resource_edgecenter_reservedfixedip.go deleted file mode 100644 index f9c61741..00000000 --- a/edgecenter/resource_edgecenter_reservedfixedip.go +++ /dev/null @@ -1,382 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "net" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/port/v1/ports" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/reservedfixedip/v1/reservedfixedips" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -const ( - ReservedFixedIPsPoint = "reserved_fixed_ips" - portsPoint = "ports" - ReservedFixedIPCreateTimeout = 1200 -) - -func resourceReservedFixedIP() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceReservedFixedIPCreate, - ReadContext: resourceReservedFixedIPRead, - UpdateContext: resourceReservedFixedIPUpdate, - DeleteContext: resourceReservedFixedIPDelete, - Description: "Represent reserved ips", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, ipID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(ipID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "type": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: fmt.Sprintf("The type of reserved fixed IP. Valid values are '%s', '%s', '%s', and '%s'", reservedfixedips.External, reservedfixedips.Subnet, reservedfixedips.AnySubnet, reservedfixedips.IPAddress), - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - switch reservedfixedips.ReservedFixedIPType(v) { - case reservedfixedips.External, reservedfixedips.Subnet, reservedfixedips.AnySubnet, reservedfixedips.IPAddress: - return diag.Diagnostics{} - } - return diag.Errorf("wrong type %s, available values is '%s', '%s', '%s', '%s'", v, reservedfixedips.External, reservedfixedips.Subnet, reservedfixedips.AnySubnet, reservedfixedips.IPAddress) - }, - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the reserved fixed IP.", - }, - "fixed_ip_address": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - Description: "The IP address that is associated with the reserved IP.", - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - ip := net.ParseIP(v) - if ip != nil { - return diag.Diagnostics{} - } - - return diag.FromErr(fmt.Errorf("%q must be a valid ip, got: %s", key, v)) - }, - }, - "subnet_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - Description: "ID of the subnet from which the fixed IP should be reserved.", - }, - "network_id": { - Type: schema.TypeString, - Optional: true, - Computed: true, - ForceNew: true, - Description: "ID of the network to which the reserved fixed IP is associated.", - }, - "is_vip": { - Type: schema.TypeBool, - Required: true, - Description: "Flag to determine if the reserved fixed IP should be treated as a Virtual IP (VIP).", - }, - "port_id": { - Type: schema.TypeString, - Description: "ID of the port_id underlying the reserved fixed IP.", - Computed: true, - }, - "allowed_address_pairs": { - Type: schema.TypeList, - Optional: true, - Description: "Group of IP addresses that share the current IP as VIP.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip_address": { - Type: schema.TypeString, - Optional: true, - }, - "mac_address": { - Type: schema.TypeString, - Optional: true, - }, - }, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceReservedFixedIPCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ReservedFixedIP creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ReservedFixedIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := reservedfixedips.CreateOpts{ - IsVip: d.Get("is_vip").(bool), - } - - portType := d.Get("type").(string) - switch reservedfixedips.ReservedFixedIPType(portType) { - case reservedfixedips.External: - case reservedfixedips.Subnet: - subnetID := d.Get("subnet_id").(string) - if subnetID == "" { - return diag.Errorf("'subnet_id' required if the type is 'subnet'") - } - - opts.SubnetID = subnetID - case reservedfixedips.AnySubnet: - networkID := d.Get("network_id").(string) - if networkID == "" { - return diag.Errorf("'network_id' required if the type is 'any_subnet'") - } - opts.NetworkID = networkID - case reservedfixedips.IPAddress: - networkID := d.Get("network_id").(string) - ipAddress := d.Get("fixed_ip_address").(string) - if networkID == "" || ipAddress == "" { - return diag.Errorf("'network_id' and 'fixed_ip_address' required if the type is 'ip_address'") - } - - opts.NetworkID = networkID - opts.IPAddress = net.ParseIP(ipAddress) - default: - return diag.Errorf("wrong type %s, available values is 'external', 'subnet', 'any_subnet', 'ip_address'", portType) - } - - opts.Type = reservedfixedips.ReservedFixedIPType(portType) - results, err := reservedfixedips.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - reservedFixedIPID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, ReservedFixedIPCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - reservedFixedIPID, err := reservedfixedips.ExtractReservedFixedIPIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve reservedFixedIP ID from task info: %w", err) - } - return reservedFixedIPID, nil - }) - - log.Printf("[DEBUG] ReservedFixedIP id (%s)", reservedFixedIPID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(reservedFixedIPID.(string)) - resourceReservedFixedIPRead(ctx, d, m) - - log.Printf("[DEBUG] Finish ReservedFixedIP creating (%s)", reservedFixedIPID) - - return diags -} - -func resourceReservedFixedIPRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ReservedFixedIP reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ReservedFixedIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - reservedFixedIP, err := reservedfixedips.Get(client, d.Id()).Extract() - if err != nil { - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - log.Printf("[WARN] Removing reserved fixed ip %s because resource doesn't exist anymore", d.Id()) - d.SetId("") - return nil - } - return diag.FromErr(err) - } - - d.Set("project_id", reservedFixedIP.ProjectID) - d.Set("region_id", reservedFixedIP.RegionID) - d.Set("status", reservedFixedIP.Status) - d.Set("fixed_ip_address", reservedFixedIP.FixedIPAddress.String()) - d.Set("subnet_id", reservedFixedIP.SubnetID) - d.Set("network_id", reservedFixedIP.NetworkID) - d.Set("is_vip", reservedFixedIP.IsVip) - d.Set("port_id", reservedFixedIP.PortID) - - allowedPairs := make([]map[string]interface{}, len(reservedFixedIP.AllowedAddressPairs)) - for i, p := range reservedFixedIP.AllowedAddressPairs { - pair := make(map[string]interface{}) - - pair["ip_address"] = p.IPAddress - pair["mac_address"] = p.MacAddress - - allowedPairs[i] = pair - } - if err := d.Set("allowed_address_pairs", allowedPairs); err != nil { - return diag.FromErr(err) - } - fields := []string{"type"} - revertState(d, &fields) - - log.Println("[DEBUG] Finish ReservedFixedIP reading") - - return diags -} - -func resourceReservedFixedIPUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ReservedFixedIP updating") - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ReservedFixedIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - id := d.Id() - if d.HasChange("is_vip") { - opts := reservedfixedips.SwitchVIPOpts{IsVip: d.Get("is_vip").(bool)} - _, err := reservedfixedips.SwitchVIP(client, id, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("allowed_address_pairs") { - aap := d.Get("allowed_address_pairs").([]interface{}) - allowedAddressPairs := make([]reservedfixedips.AllowedAddressPairs, len(aap)) - for i, p := range aap { - pair := p.(map[string]interface{}) - allowedAddressPairs[i] = reservedfixedips.AllowedAddressPairs{ - IPAddress: pair["ip_address"].(string), - MacAddress: pair["mac_address"].(string), - } - } - - clientPort, err := CreateClient(provider, d, portsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := ports.AllowAddressPairsOpts{AllowedAddressPairs: allowedAddressPairs} - if _, err := ports.AllowAddressPairs(clientPort, id, opts).Extract(); err != nil { - return diag.FromErr(err) - } - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish ReservedFixedIP updating") - - return resourceReservedFixedIPRead(ctx, d, m) -} - -func resourceReservedFixedIPDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ReservedFixedIP deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ReservedFixedIPsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - // only is_vip == false - isVip := d.Get("is_vip").(bool) - if isVip { - return diag.Errorf("could not delete reserved fixed ip with is_vip=true") - } - - id := d.Id() - results, err := reservedfixedips.Delete(client, id).Extract() - if err != nil { - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - d.SetId("") - log.Printf("[DEBUG] Finish of ReservedFixedIP deleting") - return diags - } - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, ReservedFixedIPCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - _, err := reservedfixedips.Get(client, id).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete reserved fixed ip with ID: %s", id) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting FixedIP resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of ReservedFixedIP deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_router.go b/edgecenter/resource_edgecenter_router.go deleted file mode 100644 index 917d732b..00000000 --- a/edgecenter/resource_edgecenter_router.go +++ /dev/null @@ -1,468 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/router/v1/routers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -const ( - RouterDeleting int = 1200 - RouterCreatingTimeout int = 1200 - RouterPoint = "routers" -) - -func resourceRouter() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceRouterCreate, - ReadContext: resourceRouterRead, - UpdateContext: resourceRouterUpdate, - DeleteContext: resourceRouterDelete, - Description: "Represent router. Router enables you to dynamically exchange routes between networks", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, routerID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(routerID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the router.", - }, - "external_gateway_info": { - Type: schema.TypeList, - Optional: true, - Computed: true, - MaxItems: 1, - Description: "Information related to the external gateway.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Description: "Must be 'manual' or 'default'", - Optional: true, - Computed: true, - }, - "enable_snat": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - }, - "network_id": { - Type: schema.TypeString, - Description: "Id of the external network", - Optional: true, - Computed: true, - }, - "external_fixed_ips": { - Type: schema.TypeList, - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "ip_address": { - Type: schema.TypeString, - Required: true, - }, - "subnet_id": { - Type: schema.TypeString, - Required: true, - }, - }, - }, - }, - }, - }, - }, - "interfaces": { - Type: schema.TypeSet, - Optional: true, - Set: routerInterfaceUniqueID, - Description: "Set of interfaces associated with the router.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "type": { - Type: schema.TypeString, - Description: "must be 'subnet'", - Required: true, - }, - "subnet_id": { - Type: schema.TypeString, - Description: "Subnet for router interface must have a gateway IP", - Required: true, - }, - "port_id": { - Type: schema.TypeString, - Computed: true, - }, - "network_id": { - Type: schema.TypeString, - Computed: true, - }, - "mac_address": { - Type: schema.TypeString, - Computed: true, - }, - "ip_address": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "routes": { - Type: schema.TypeList, - Optional: true, - Description: "List of static routes to be applied to the router.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "destination": { - Type: schema.TypeString, - Required: true, - }, - "nexthop": { - Type: schema.TypeString, - Required: true, - Description: "IPv4 address to forward traffic to if it's destination IP matches 'destination' CIDR", - }, - }, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceRouterCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start router creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, RouterPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - createOpts := routers.CreateOpts{} - - createOpts.Name = d.Get("name").(string) - - egi := d.Get("external_gateway_info") - if len(egi.([]interface{})) > 0 { - gws, err := extractExternalGatewayInfoMap(egi.([]interface{})) - if err != nil { - return diag.FromErr(err) - } - createOpts.ExternalGatewayInfo = gws - } - - ifs := d.Get("interfaces").(*schema.Set) - if ifs.Len() > 0 { - ifaces, err := extractInterfacesMap(ifs.List()) - if err != nil { - return diag.FromErr(err) - } - createOpts.Interfaces = ifaces - } - - rs := d.Get("routes") - if len(rs.([]interface{})) > 0 { - routes, err := extractHostRoutesMap(rs.([]interface{})) - if err != nil { - return diag.FromErr(err) - } - createOpts.Routes = routes - } - - results, err := routers.Create(client, createOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - routerID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, RouterCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - Router, err := routers.ExtractRouterIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve Router ID from task info: %w", err) - } - return Router, nil - }, - ) - log.Printf("[DEBUG] Router id (%s)", routerID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(routerID.(string)) - resourceRouterRead(ctx, d, m) - - log.Printf("[DEBUG] Finish router creating (%s)", routerID) - - return diags -} - -func resourceRouterRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start router reading") - log.Printf("[DEBUG] Start router reading%s", d.State()) - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - routerID := d.Id() - log.Printf("[DEBUG] Router id = %s", routerID) - - client, err := CreateClient(provider, d, RouterPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - router, err := routers.Get(client, routerID).Extract() - if err != nil { - return diag.Errorf("cannot get router with ID: %s. Error: %s", routerID, err) - } - - d.Set("name", router.Name) - - if len(router.ExternalGatewayInfo.ExternalFixedIPs) > 0 { - egi := make(map[string]interface{}, 4) - egilst := make([]map[string]interface{}, 1) - egi["enable_snat"] = router.ExternalGatewayInfo.EnableSNat - egi["network_id"] = router.ExternalGatewayInfo.NetworkID - - egist := d.Get("external_gateway_info") - if len(egist.([]interface{})) > 0 { - gws, err := extractExternalGatewayInfoMap(egist.([]interface{})) - if err != nil { - return diag.FromErr(err) - } - egi["type"] = gws.Type - } - - efip := make([]map[string]string, len(router.ExternalGatewayInfo.ExternalFixedIPs)) - for i, fip := range router.ExternalGatewayInfo.ExternalFixedIPs { - tmpfip := make(map[string]string, 1) - tmpfip["ip_address"] = fip.IPAddress - tmpfip["subnet_id"] = fip.SubnetID - efip[i] = tmpfip - } - egi["external_fixed_ips"] = efip - - egilst[0] = egi - d.Set("external_gateway_info", egilst) - } - - ifs := make([]interface{}, 0, len(router.Interfaces)) - for _, iface := range router.Interfaces { - for _, subnet := range iface.IPAssignments { - smap := make(map[string]interface{}, 6) - smap["port_id"] = iface.PortID - smap["network_id"] = iface.NetworkID - smap["mac_address"] = iface.MacAddress.String() - smap["type"] = "subnet" - smap["subnet_id"] = subnet.SubnetID - smap["ip_address"] = subnet.IPAddress.String() - ifs = append(ifs, smap) - } - } - if err := d.Set("interfaces", schema.NewSet(routerInterfaceUniqueID, ifs)); err != nil { - return diag.FromErr(err) - } - - rs := make([]map[string]string, len(router.Routes)) - for i, r := range router.Routes { - rmap := make(map[string]string, 2) - rmap["destination"] = r.Destination.String() - rmap["nexthop"] = r.NextHop.String() - rs[i] = rmap - } - d.Set("routes", rs) - - log.Println("[DEBUG] Finish router reading") - - return diags -} - -func resourceRouterUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start router updating") - routerID := d.Id() - log.Printf("[DEBUG] Router id = %s", routerID) - config := m.(*Config) - provider := config.Provider - client, err := CreateClient(provider, d, RouterPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - updateOpts := routers.UpdateOpts{} - - if d.HasChange("name") { - updateOpts.Name = d.Get("name").(string) - } - - // Only one kind of update is supported when external manual gateway is set. - if d.HasChange("external_gateway_info") { - egi := d.Get("external_gateway_info") - if len(egi.([]interface{})) > 0 { - gws, err := extractExternalGatewayInfoMap(egi.([]interface{})) - if err != nil { - return diag.FromErr(err) - } - if gws.Type == "manual" { - updateOpts.ExternalGatewayInfo = gws - } - } - } - - if d.HasChange("interfaces") { - oldValue, newValue := d.GetChange("interfaces") - oifs, err := extractInterfacesMap(oldValue.(*schema.Set).List()) - if err != nil { - return diag.FromErr(err) - } - nifs, err := extractInterfacesMap(newValue.(*schema.Set).List()) - if err != nil { - return diag.FromErr(err) - } - - omap := make(map[string]int, len(oifs)) - - for index, iface := range oifs { - omap[iface.SubnetID] = index - } - - for _, niface := range nifs { - _, ok := omap[niface.SubnetID] - if ok { - delete(omap, niface.SubnetID) - } else { - _, err = routers.Attach(client, routerID, niface.SubnetID).Extract() - if err != nil { - return diag.FromErr(err) - } - } - } - - for _, v := range omap { - oiface := oifs[v] - _, err = routers.Detach(client, routerID, oiface.SubnetID).Extract() - if err != nil { - return diag.FromErr(err) - } - } - } - - if d.HasChange("routes") { - rs := d.Get("routes") - updateOpts.Routes = make([]subnets.HostRoute, 0) - if len(rs.([]interface{})) > 0 { - routes, err := extractHostRoutesMap(rs.([]interface{})) - if err != nil { - return diag.FromErr(err) - } - updateOpts.Routes = routes - } - } - - _, err = routers.Update(client, routerID, updateOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish router updating") - - return resourceRouterRead(ctx, d, m) -} - -func resourceRouterDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start router deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - routerID := d.Id() - log.Printf("[DEBUG] Router id = %s", routerID) - - client, err := CreateClient(provider, d, RouterPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - results, err := routers.Delete(client, routerID).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, RouterDeleting, func(task tasks.TaskID) (interface{}, error) { - _, err := routers.Get(client, routerID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete router with ID: %s", routerID) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Router resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of router deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_secret.go b/edgecenter/resource_edgecenter_secret.go deleted file mode 100644 index f4cf9c01..00000000 --- a/edgecenter/resource_edgecenter_secret.go +++ /dev/null @@ -1,285 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/secret/v1/secrets" - secretsV2 "github.com/Edge-Center/edgecentercloud-go/edgecenter/secret/v2/secrets" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -const ( - SecretDeleting int = 1200 - SecretCreatingTimeout int = 1200 - SecretPoint = "secrets" -) - -func resourceSecret() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceSecretCreate, - ReadContext: resourceSecretRead, - DeleteContext: resourceSecretDelete, - Description: "Represent secret", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, secretID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(secretID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The name of the secret.", - }, - "private_key": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "SSL private key in PEM format", - }, - "certificate_chain": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "SSL certificate chain of intermediates and root certificates in PEM format", - }, - "certificate": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "SSL certificate in PEM format", - }, - "algorithm": { - Type: schema.TypeString, - Computed: true, - Description: "The encryption algorithm used for the secret.", - }, - "bit_length": { - Type: schema.TypeInt, - Computed: true, - Description: "The bit length of the encryption algorithm.", - }, - "mode": { - Type: schema.TypeString, - Computed: true, - Description: "The mode of the encryption algorithm.", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the secret.", - }, - "content_types": { - Type: schema.TypeMap, - Computed: true, - Description: "The content types associated with the secret's payload.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "expiration": { - Type: schema.TypeString, - Description: "Datetime when the secret will expire. The format is 2025-12-28T19:14:44", - Optional: true, - Computed: true, - StateFunc: func(val interface{}) string { - expTime, _ := time.Parse(edgecloud.RFC3339NoZ, val.(string)) - return expTime.Format(edgecloud.RFC3339NoZ) - }, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - rawTime := i.(string) - _, err := time.Parse(edgecloud.RFC3339NoZ, rawTime) - if err != nil { - return diag.FromErr(err) - } - return nil - }, - }, - "created": { - Type: schema.TypeString, - Description: "Datetime when the secret was created. The format is 2025-12-28T19:14:44.180394", - Computed: true, - }, - }, - } -} - -func resourceSecretCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Secret creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, SecretPoint, VersionPointV2) - if err != nil { - return diag.FromErr(err) - } - - opts := secretsV2.CreateOpts{ - Name: d.Get("name").(string), - Payload: secretsV2.PayloadOpts{ - CertificateChain: d.Get("certificate_chain").(string), - Certificate: d.Get("certificate").(string), - PrivateKey: d.Get("private_key").(string), - }, - } - if rawTime := d.Get("expiration").(string); rawTime != "" { - expiration, err := time.Parse(edgecloud.RFC3339NoZ, rawTime) - if err != nil { - return diag.FromErr(err) - } - opts.Expiration = &expiration - } - - results, err := secretsV2.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - - clientV1, err := CreateClient(provider, d, SecretPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - secretID, err := tasks.WaitTaskAndReturnResult(clientV1, taskID, true, SecretCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(clientV1, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - Secret, err := secrets.ExtractSecretIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve Secret ID from task info: %w", err) - } - return Secret, nil - }, - ) - if err != nil { - return diag.FromErr(err) - } - log.Printf("[DEBUG] Secret id (%s)", secretID) - - d.SetId(secretID.(string)) - - resourceSecretRead(ctx, d, m) - - log.Printf("[DEBUG] Finish Secret creating (%s)", secretID) - - return diags -} - -func resourceSecretRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start secret reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - secretID := d.Id() - log.Printf("[DEBUG] Secret id = %s", secretID) - - client, err := CreateClient(provider, d, SecretPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - secret, err := secrets.Get(client, secretID).Extract() - if err != nil { - return diag.Errorf("cannot get secret with ID: %s. Error: %s", secretID, err.Error()) - } - d.Set("name", secret.Name) - d.Set("algorithm", secret.Algorithm) - d.Set("bit_length", secret.BitLength) - d.Set("mode", secret.Mode) - d.Set("status", secret.Status) - d.Set("expiration", secret.Expiration.Format(edgecloud.RFC3339NoZ)) - d.Set("created", secret.CreatedAt.Format(edgecloud.RFC3339MilliNoZ)) - if err := d.Set("content_types", secret.ContentTypes); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish secret reading") - - return diags -} - -func resourceSecretDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start secret deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - secretID := d.Id() - log.Printf("[DEBUG] Secret id = %s", secretID) - - client, err := CreateClient(provider, d, SecretPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - results, err := secrets.Delete(client, secretID).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, SecretDeleting, func(task tasks.TaskID) (interface{}, error) { - _, err := secrets.Get(client, secretID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete secret with ID: %s", secretID) - } - return nil, nil - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of secret deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_securitygroup.go b/edgecenter/resource_edgecenter_securitygroup.go deleted file mode 100644 index 6c73156e..00000000 --- a/edgecenter/resource_edgecenter_securitygroup.go +++ /dev/null @@ -1,482 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "strings" - "time" - - "github.com/hashicorp/go-cty/cty" - "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" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/securitygrouprules" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/securitygroups" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/types" -) - -const ( - SecurityGroupPoint = "securitygroups" - securityGroupRulesPoint = "securitygrouprules" -) - -func resourceSecurityGroup() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceSecurityGroupCreate, - ReadContext: resourceSecurityGroupRead, - UpdateContext: resourceSecurityGroupUpdate, - DeleteContext: resourceSecurityGroupDelete, - Description: "Represent SecurityGroups(Firewall)", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, sgID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(sgID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the security group.", - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: "A detailed description of the security group.", - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - "security_group_rules": { - Type: schema.TypeSet, - Required: true, - Description: "Firewall rules control what inbound(ingress) and outbound(egress) traffic is allowed to enter or leave a Instance. At least one 'egress' rule should be set", - Set: secGroupUniqueID, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "id": { - Type: schema.TypeString, - Computed: true, - }, - "direction": { - Type: schema.TypeString, - Required: true, - Description: fmt.Sprintf("Available value is '%s', '%s'", types.RuleDirectionIngress, types.RuleDirectionEgress), - ValidateDiagFunc: func(v interface{}, path cty.Path) diag.Diagnostics { - val := v.(string) - switch types.RuleDirection(val) { - case types.RuleDirectionIngress, types.RuleDirectionEgress: - return nil - } - return diag.Errorf("wrong direction '%s', available value is '%s', '%s'", val, types.RuleDirectionIngress, types.RuleDirectionEgress) - }, - }, - "ethertype": { - Type: schema.TypeString, - Required: true, - Description: fmt.Sprintf("Available value is '%s', '%s'", types.EtherTypeIPv4, types.EtherTypeIPv6), - ValidateDiagFunc: func(v interface{}, path cty.Path) diag.Diagnostics { - val := v.(string) - switch types.EtherType(val) { - case types.EtherTypeIPv4, types.EtherTypeIPv6: - return nil - } - return diag.Errorf("wrong ethertype '%s', available value is '%s', '%s'", val, types.EtherTypeIPv4, types.EtherTypeIPv6) - }, - }, - "protocol": { - Type: schema.TypeString, - Required: true, - Description: fmt.Sprintf("Available value is %s", strings.Join(types.Protocol("").StringList(), ",")), - }, - "port_range_min": { - Type: schema.TypeInt, - Optional: true, - Default: 1, - ValidateFunc: validation.IntBetween(1, 65535), - }, - "port_range_max": { - Type: schema.TypeInt, - Optional: true, - Default: 65535, - ValidateFunc: validation.IntBetween(1, 65535), - }, - "description": { - Type: schema.TypeString, - Optional: true, - Default: "", - }, - "remote_ip_prefix": { - Type: schema.TypeString, - Optional: true, - Default: "", - }, - "updated_at": { - Type: schema.TypeString, - Computed: true, - }, - "created_at": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceSecurityGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start SecurityGroup creating") - - var valid bool - vals := d.Get("security_group_rules").(*schema.Set).List() - for _, val := range vals { - rule := val.(map[string]interface{}) - if types.RuleDirection(rule["direction"].(string)) == types.RuleDirectionEgress { - valid = true - break - } - } - if !valid { - return diag.Errorf("at least one 'egress' rule should be set") - } - - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - rawRules := d.Get("security_group_rules").(*schema.Set).List() - rules := make([]securitygroups.CreateSecurityGroupRuleOpts, len(rawRules)) - for i, r := range rawRules { - rule := r.(map[string]interface{}) - - descr := rule["description"].(string) - remoteIPPrefix := rule["remote_ip_prefix"].(string) - - sgrOpts := securitygroups.CreateSecurityGroupRuleOpts{ - Direction: types.RuleDirection(rule["direction"].(string)), - EtherType: types.EtherType(rule["ethertype"].(string)), - Protocol: types.Protocol(rule["protocol"].(string)), - Description: &descr, - } - - if remoteIPPrefix != "" { - sgrOpts.RemoteIPPrefix = &remoteIPPrefix - } - - portRangeMin := rule["port_range_min"].(int) - portRangeMax := rule["port_range_max"].(int) - - if portRangeMin > portRangeMax { - return diag.FromErr(fmt.Errorf("value of the port_range_min cannot be greater than port_range_max")) - } - - sgrOpts.PortRangeMax = &portRangeMax - sgrOpts.PortRangeMin = &portRangeMin - - rules[i] = sgrOpts - } - - createSecurityGroupOpts := &securitygroups.CreateSecurityGroupOpts{} - createSecurityGroupOpts.Name = d.Get("name").(string) - createSecurityGroupOpts.SecurityGroupRules = rules - - if metadataRaw, ok := d.GetOk("metadata_map"); ok { - createSecurityGroupOpts.Metadata = metadataRaw.(map[string]interface{}) - } - - opts := securitygroups.CreateOpts{ - SecurityGroup: *createSecurityGroupOpts, - } - descr := d.Get("description").(string) - if descr != "" { - opts.SecurityGroup.Description = &descr - } - - sg, err := securitygroups.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.SetId(sg.ID) - - resourceSecurityGroupRead(ctx, d, m) - log.Printf("[DEBUG] Finish SecurityGroup creating (%s)", sg.ID) - - return diags -} - -func resourceSecurityGroupRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start SecurityGroup reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - sg, err := securitygroups.Get(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.Set("project_id", sg.ProjectID) - d.Set("region_id", sg.RegionID) - d.Set("name", sg.Name) - d.Set("description", sg.Description) - - metadataMap := make(map[string]string) - metadataReadOnly := make([]map[string]interface{}, 0, len(sg.Metadata)) - - if len(sg.Metadata) > 0 { - for _, metadataItem := range sg.Metadata { - metadataMap[metadataItem.Key] = metadataItem.Value - metadataReadOnly = append(metadataReadOnly, map[string]interface{}{ - "key": metadataItem.Key, - "value": metadataItem.Value, - "read_only": metadataItem.ReadOnly, - }) - } - } - - if err := d.Set("metadata_map", metadataMap); err != nil { - return diag.FromErr(err) - } - if err := d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - newSgRules := make([]interface{}, len(sg.SecurityGroupRules)) - for i, sgr := range sg.SecurityGroupRules { - log.Printf("rules: %+v", sgr) - r := make(map[string]interface{}) - r["id"] = sgr.ID - r["direction"] = sgr.Direction.String() - - if sgr.EtherType != nil { - r["ethertype"] = sgr.EtherType.String() - } - - r["protocol"] = types.ProtocolAny - if sgr.Protocol != nil { - r["protocol"] = sgr.Protocol.String() - } - - r["port_range_max"] = 65535 - if sgr.PortRangeMax != nil { - r["port_range_max"] = *sgr.PortRangeMax - } - r["port_range_min"] = 1 - if sgr.PortRangeMin != nil { - r["port_range_min"] = *sgr.PortRangeMin - } - - r["description"] = "" - if sgr.Description != nil { - r["description"] = *sgr.Description - } - - r["remote_ip_prefix"] = "" - if sgr.RemoteIPPrefix != nil { - r["remote_ip_prefix"] = *sgr.RemoteIPPrefix - } - - r["updated_at"] = sgr.UpdatedAt.String() - r["created_at"] = sgr.CreatedAt.String() - - newSgRules[i] = r - } - - if err := d.Set("security_group_rules", schema.NewSet(secGroupUniqueID, newSgRules)); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish SecurityGroup reading") - - return diags -} - -func resourceSecurityGroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start SecurityGroup updating") - var valid bool - vals := d.Get("security_group_rules").(*schema.Set).List() - for _, val := range vals { - rule := val.(map[string]interface{}) - if types.RuleDirection(rule["direction"].(string)) == types.RuleDirectionEgress { - valid = true - break - } - } - if !valid { - return diag.Errorf("at least one 'egress' rule should be set") - } - - config := m.(*Config) - provider := config.Provider - clientCreate, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - clientUpdateDelete, err := CreateClient(provider, d, securityGroupRulesPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - gid := d.Id() - - if d.HasChange("security_group_rules") { - oldRulesRaw, newRulesRaw := d.GetChange("security_group_rules") - oldRules := oldRulesRaw.(*schema.Set) - newRules := newRulesRaw.(*schema.Set) - - changedRule := make(map[string]bool) - for _, r := range newRules.List() { - rule := r.(map[string]interface{}) - rid := rule["id"].(string) - if !oldRules.Contains(r) && rid == "" { - opts := extractSecurityGroupRuleMap(r, gid) - _, err := securitygroups.AddRule(clientCreate, gid, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - continue - } - if rid != "" && !oldRules.Contains(r) { - changedRule[rid] = true - opts := extractSecurityGroupRuleMap(r, gid) - _, err := securitygrouprules.Replace(clientUpdateDelete, rid, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - } - } - - for _, r := range oldRules.List() { - rule := r.(map[string]interface{}) - rid := rule["id"].(string) - if !newRules.Contains(r) && !changedRule[rid] { - // todo patch lib, should be task instead of DeleteResult - err := securitygrouprules.Delete(clientUpdateDelete, rid).ExtractErr() - if err != nil { - return diag.FromErr(err) - } - // todo remove after patch lib - time.Sleep(time.Second * 2) - continue - } - } - } - - if d.HasChange("metadata_map") { - _, nmd := d.GetChange("metadata_map") - - err := securitygroups.MetadataReplace(clientCreate, gid, nmd.(map[string]interface{})).Err - if err != nil { - return diag.Errorf("cannot update metadata. Error: %s", err) - } - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish SecurityGroup updating") - - return resourceSecurityGroupRead(ctx, d, m) -} - -func resourceSecurityGroupDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start SecurityGroup deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - sgID := d.Id() - - client, err := CreateClient(provider, d, SecurityGroupPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - err = securitygroups.Delete(client, sgID).Err - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of SecurityGroup deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_servergroup.go b/edgecenter/resource_edgecenter_servergroup.go deleted file mode 100644 index 36d2b667..00000000 --- a/edgecenter/resource_edgecenter_servergroup.go +++ /dev/null @@ -1,184 +0,0 @@ -package edgecenter - -import ( - "context" - "log" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/servergroup/v1/servergroups" -) - -const ( - ServerGroupsPoint = "servergroups" -) - -func resourceServerGroup() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceServerGroupCreate, - ReadContext: resourceServerGroupRead, - DeleteContext: resourceServerGroupDelete, - Description: "Represent server group resource", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, sgID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(sgID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - ForceNew: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Description: "Displayed server group name", - Required: true, - ForceNew: true, - }, - "policy": { - Type: schema.TypeString, - Description: "Server group policy. Available value is 'affinity', 'anti-affinity'", - Required: true, - ForceNew: true, - }, - "instances": { - Type: schema.TypeList, - Description: "Instances in this server group", - Computed: true, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "instance_id": { - Type: schema.TypeString, - Computed: true, - }, - "instance_name": { - Type: schema.TypeString, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func resourceServerGroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ServerGroup creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ServerGroupsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := servergroups.CreateOpts{ - Name: d.Get("name").(string), - Policy: servergroups.ServerGroupPolicy(d.Get("policy").(string)), - } - - serverGroup, err := servergroups.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.SetId(serverGroup.ServerGroupID) - resourceServerGroupRead(ctx, d, m) - log.Println("[DEBUG] Finish ServerGroup creating") - - return diags -} - -func resourceServerGroupRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ServerGroup reading") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ServerGroupsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - serverGroup, err := servergroups.Get(client, d.Id()).Extract() - if err != nil { - return diag.FromErr(err) - } - - d.Set("name", serverGroup.Name) - d.Set("project_id", serverGroup.ProjectID) - d.Set("region_id", serverGroup.RegionID) - d.Set("policy", serverGroup.Policy.String()) - - instances := make([]map[string]string, len(serverGroup.Instances)) - for i, instance := range serverGroup.Instances { - rawInstance := make(map[string]string) - rawInstance["instance_id"] = instance.InstanceID - rawInstance["instance_name"] = instance.InstanceName - instances[i] = rawInstance - } - if err := d.Set("instances", instances); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish ServerGroup reading") - - return diags -} - -func resourceServerGroupDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start ServerGroup deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, ServerGroupsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - err = servergroups.Delete(client, d.Id()).ExtractErr() - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Println("[DEBUG] Finish ServerGroup deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_snapshot.go b/edgecenter/resource_edgecenter_snapshot.go deleted file mode 100644 index c3274b6d..00000000 --- a/edgecenter/resource_edgecenter_snapshot.go +++ /dev/null @@ -1,279 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/snapshot/v1/snapshots" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -const ( - snapshotDeleting int = 1200 - snapshotCreatingTimeout int = 1200 - SnapshotsPoint = "snapshots" -) - -func resourceSnapshot() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceSnapshotCreate, - ReadContext: resourceSnapshotRead, - UpdateContext: resourceSnapshotUpdate, - DeleteContext: resourceSnapshotDelete, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, snapshotID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(snapshotID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The name of the snapshot.", - }, - "size": { - Type: schema.TypeInt, - Computed: true, - Description: "The size of the snapshot in GB.", - }, - "status": { - Type: schema.TypeString, - Computed: true, - Description: "The current status of the snapshot.", - }, - "description": { - Type: schema.TypeString, - Optional: true, - Description: "A detailed description of the snapshot.", - }, - "volume_id": { - Type: schema.TypeString, - Required: true, - ForceNew: true, - Description: "The ID of the volume from which the snapshot was created.", - }, - "metadata": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceSnapshotCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start snapshot creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, SnapshotsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := getSnapshotData(d) - results, err := snapshots.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - SnapshotID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, snapshotCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - snapshotID, err := snapshots.ExtractSnapshotIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve snapshot ID from task info: %w", err) - } - return snapshotID, nil - }, - ) - log.Printf("[DEBUG] Snapshot id (%s)", SnapshotID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(SnapshotID.(string)) - resourceSnapshotRead(ctx, d, m) - - log.Printf("[DEBUG] Finish snapshot creating (%s)", SnapshotID) - - return diags -} - -func resourceSnapshotRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start snapshot reading") - log.Printf("[DEBUG] Start snapshot reading %s", d.State()) - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - snapshotID := d.Id() - log.Printf("[DEBUG] Snapshot id = %s", snapshotID) - - client, err := CreateClient(provider, d, SnapshotsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - snapshot, err := snapshots.Get(client, snapshotID).Extract() - if err != nil { - return diag.Errorf("cannot get snapshot with ID: %s. Error: %s", snapshotID, err) - } - - d.Set("name", snapshot.Name) - d.Set("description", snapshot.Description) - d.Set("status", snapshot.Status) - d.Set("size", snapshot.Size) - d.Set("volume_id", snapshot.VolumeID) - d.Set("region_id", snapshot.RegionID) - d.Set("project_id", snapshot.ProjectID) - if err := d.Set("metadata", snapshot.Metadata); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish snapshot reading") - - return diags -} - -func resourceSnapshotUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start snapshot updating") - snapshotID := d.Id() - if d.HasChange("metadata") { - config := m.(*Config) - provider := config.Provider - client, err := CreateClient(provider, d, SnapshotsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - newMeta := prepareRawMetadata(d.Get("metadata").(map[string]interface{})) - metadata := make([]snapshots.MetadataOpts, 0, len(newMeta)) - for k, v := range newMeta { - metadata = append(metadata, snapshots.MetadataOpts{Key: k, Value: v}) - } - opts := snapshots.MetadataSetOpts{Metadata: metadata} - if _, err := snapshots.MetadataReplace(client, snapshotID, opts).Extract(); err != nil { - return diag.FromErr(err) - } - } - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish snapshot updating") - - return resourceSnapshotRead(ctx, d, m) -} - -func resourceSnapshotDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start snapshot deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - snapshotID := d.Id() - log.Printf("[DEBUG] Snapshot id = %s", snapshotID) - - client, err := CreateClient(provider, d, SnapshotsPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - results, err := snapshots.Delete(client, snapshotID).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, snapshotDeleting, func(task tasks.TaskID) (interface{}, error) { - _, err := snapshots.Get(client, snapshotID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete snapshot with ID: %s", snapshotID) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Shapshot resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of snapshot deleting") - - return diags -} - -func getSnapshotData(d *schema.ResourceData) *snapshots.CreateOpts { - snapshotData := snapshots.CreateOpts{} - snapshotData.Name = d.Get("name").(string) - snapshotData.VolumeID = d.Get("volume_id").(string) - snapshotData.Description = d.Get("description").(string) - metadataRaw := d.Get("metadata").(map[string]interface{}) - if len(metadataRaw) > 0 { - snapshotData.Metadata = prepareRawMetadata(metadataRaw) - } - - return &snapshotData -} - -func prepareRawMetadata(raw map[string]interface{}) map[string]string { - meta := make(map[string]string, len(raw)) - for k, v := range raw { - meta[k] = v.(string) - } - return meta -} diff --git a/edgecenter/resource_edgecenter_storage_s3.go b/edgecenter/resource_edgecenter_storage_s3.go deleted file mode 100644 index cf9de633..00000000 --- a/edgecenter/resource_edgecenter_storage_s3.go +++ /dev/null @@ -1,242 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "regexp" - "strconv" - "strings" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecenter-storage-sdk-go/swagger/client/storages" -) - -const ( - StorageS3SchemaGenerateAccessKey = "generated_access_key" - StorageS3SchemaGenerateSecretKey = "generated_secret_key" - StorageSchemaGenerateHTTPEndpoint = "generated_http_endpoint" - StorageSchemaGenerateS3Endpoint = "generated_s3_endpoint" - StorageSchemaGenerateEndpoint = "generated_endpoint" - - StorageSchemaLocation = "location" - StorageSchemaName = "name" - StorageSchemaID = "storage_id" - StorageSchemaClientID = "client_id" -) - -func resourceStorageS3() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - StorageSchemaID: { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "An id of new storage resource.", - }, - StorageSchemaClientID: { - Type: schema.TypeInt, - Optional: true, - Computed: true, - Description: "An client id of new storage resource.", - }, - StorageSchemaName: { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - storageName := i.(string) - if !regexp.MustCompile(`^[\w\-]+$`).MatchString(storageName) || len(storageName) > 255 { - return diag.Errorf("storage name can't be empty and can have only letters, numbers, dashes and underscores, it also should be less than 256 symbols") - } - return nil - }, - Description: "A name of new storage resource.", - }, - StorageSchemaLocation: { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: func(v interface{}, path cty.Path) diag.Diagnostics { - val := v.(string) - allowed := []string{"s-ed1", "s-darz1", "s-ws1", "s-dt2", "s-drc2"} - for _, el := range allowed { - if el == val { - return nil - } - } - return diag.Errorf(`must be one of %+v`, allowed) - }, - Description: "A location of new storage resource. One of (s-ed1, s-darz1, s-ws1, s-dt2, s-drc2)", - }, - StorageS3SchemaGenerateAccessKey: { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "A s3 access key for new storage resource.", - }, - StorageS3SchemaGenerateSecretKey: { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "A s3 secret key for new storage resource.", - }, - StorageSchemaGenerateHTTPEndpoint: { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "A http s3 entry point for new storage resource.", - }, - StorageSchemaGenerateS3Endpoint: { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "A s3 endpoint for new storage resource.", - }, - StorageSchemaGenerateEndpoint: { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "A s3 entry point for new storage resource.", - }, - }, - CreateContext: resourceStorageS3Create, - ReadContext: resourceStorageS3Read, - DeleteContext: resourceStorageS3Delete, - Description: "Represent s3 storage resource. https://storage.edgecenter.ru/storage/list", - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - } -} - -func resourceStorageS3Create(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - id := new(int) - log.Println("[DEBUG] Start S3 Storage Resource creating") - defer log.Printf("[DEBUG] Finish S3 Storage Resource creating (id=%d)\n", *id) - config := m.(*Config) - client := config.StorageClient - - opts := []func(opt *storages.StorageCreateHTTPParams){ - func(opt *storages.StorageCreateHTTPParams) { opt.Context = ctx }, - func(opt *storages.StorageCreateHTTPParams) { opt.Body.Type = "s3" }, - } - location := strings.TrimSpace(d.Get(StorageSchemaLocation).(string)) - if location != "" { - opts = append(opts, func(opt *storages.StorageCreateHTTPParams) { opt.Body.Location = location }) - } - name := strings.TrimSpace(d.Get(StorageSchemaName).(string)) - if name != "" { - opts = append(opts, func(opt *storages.StorageCreateHTTPParams) { opt.Body.Name = name }) - } - - result, err := client.CreateStorage(opts...) - if err != nil { - return diag.FromErr(fmt.Errorf("create storage: %w", err)) - } - d.SetId(fmt.Sprintf("%d", result.ID)) - *id = int(result.ID) - if result.Credentials.S3.AccessKey != "" { - _ = d.Set(StorageS3SchemaGenerateAccessKey, result.Credentials.S3.AccessKey) - } - if result.Credentials.S3.SecretKey != "" { - _ = d.Set(StorageS3SchemaGenerateSecretKey, result.Credentials.S3.SecretKey) - } - - return resourceStorageS3Read(ctx, d, m) -} - -func resourceStorageS3Read(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - resourceID := storageResourceID(d) - log.Printf("[DEBUG] Start S3 Storage Resource reading (id=%s)\n", resourceID) - defer log.Println("[DEBUG] Finish S3 Storage Resource reading") - - config := m.(*Config) - client := config.StorageClient - - opts := []func(opt *storages.StorageListHTTPV2Params){ - func(opt *storages.StorageListHTTPV2Params) { opt.Context = ctx }, - func(opt *storages.StorageListHTTPV2Params) { opt.ShowDeleted = new(bool) }, - } - if resourceID != "" { - opts = append(opts, func(opt *storages.StorageListHTTPV2Params) { opt.ID = &resourceID }) - } - name := d.Get(StorageSchemaName).(string) - if name != "" { - opts = append(opts, func(opt *storages.StorageListHTTPV2Params) { opt.Name = &name }) - } - if resourceID == "" && name == "" { - return diag.Errorf("get storage: empty storage id/name") - } - - result, err := client.StoragesList(opts...) - if err != nil { - return diag.FromErr(fmt.Errorf("storages list: %w", err)) - } - - if (len(result) == 0) || (name == "" && len(result) != 1) { - return diag.Errorf("get storage: wrong length of search result (%d), want 1", len(result)) - } - st := result[0] - - d.SetId(fmt.Sprint(st.ID)) - nameParts := strings.Split(st.Name, "-") - if len(nameParts) > 1 { - clientID, _ := strconv.ParseInt(nameParts[0], 10, 64) - _ = d.Set(StorageSchemaClientID, int(clientID)) - _ = d.Set(StorageSchemaName, strings.Join(nameParts[1:], "-")) - } else { - _ = d.Set(StorageSchemaName, st.Name) - } - _ = d.Set(StorageSchemaID, st.ID) - _ = d.Set(StorageSchemaLocation, st.Location) - _ = d.Set(StorageSchemaGenerateEndpoint, fmt.Sprintf("%s.cloud.edgecenter.ru/%s", st.Location, st.Name)) - _ = d.Set(StorageSchemaGenerateHTTPEndpoint, fmt.Sprintf("https://%s.cloud.edgecenter.ru/{bucket_name}", st.Location)) - _ = d.Set(StorageSchemaGenerateS3Endpoint, fmt.Sprintf("https://%s.cloud.edgecenter.ru", st.Location)) - - return nil -} - -func resourceStorageS3Delete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - resourceID := storageResourceID(d) - log.Printf("[DEBUG] Start S3 Storage Resource deleting (id=%s)\n", resourceID) - defer log.Println("[DEBUG] Finish S3 Storage Resource deleting") - if resourceID == "" { - return diag.Errorf("empty storage id") - } - - config := m.(*Config) - client := config.StorageClient - - id, err := strconv.ParseInt(resourceID, 10, 64) - if err != nil { - return diag.FromErr(fmt.Errorf("get resource id: %w", err)) - } - - opts := []func(opt *storages.StorageDeleteHTTPParams){ - func(opt *storages.StorageDeleteHTTPParams) { opt.Context = ctx }, - func(opt *storages.StorageDeleteHTTPParams) { opt.ID = id }, - } - err = client.DeleteStorage(opts...) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - - return nil -} - -func storageResourceID(d *schema.ResourceData) string { - resourceID := d.Id() - if resourceID == "" { - id := d.Get(StorageSchemaID).(int) - if id > 0 { - resourceID = fmt.Sprint(id) - } - } - return resourceID -} diff --git a/edgecenter/resource_edgecenter_storage_s3_bucket.go b/edgecenter/resource_edgecenter_storage_s3_bucket.go deleted file mode 100644 index fdca2f7d..00000000 --- a/edgecenter/resource_edgecenter_storage_s3_bucket.go +++ /dev/null @@ -1,161 +0,0 @@ -package edgecenter - -import ( - "context" - "fmt" - "log" - "regexp" - "strconv" - "strings" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecenter-storage-sdk-go/swagger/client/buckets" -) - -const ( - StorageS3BucketSchemaName = "name" - StorageS3BucketSchemaStorageID = "storage_id" -) - -func resourceStorageS3Bucket() *schema.Resource { - return &schema.Resource{ - Schema: map[string]*schema.Schema{ - StorageS3BucketSchemaStorageID: { - Type: schema.TypeInt, - Required: true, - ForceNew: true, - Description: "An id of existing storage resource.", - }, - StorageS3BucketSchemaName: { - Type: schema.TypeString, - Required: true, - ForceNew: true, - ValidateDiagFunc: func(i interface{}, path cty.Path) diag.Diagnostics { - storageName := i.(string) - if !regexp.MustCompile(`^[\w\-]+$`).MatchString(storageName) || - len(storageName) > 63 || - len(storageName) < 3 { - return diag.Errorf("bucket name can't be empty and can have only letters & numbers. it also should be less than 63 symbols") - } - return nil - }, - Description: "A name of new storage bucket resource.", - }, - }, - CreateContext: resourceStorageS3BucketCreate, - ReadContext: resourceStorageS3BucketRead, - DeleteContext: resourceStorageS3BucketDelete, - Description: "Represent s3 storage bucket resource. https://storage.edgecenter.ru/storage/list", - Importer: &schema.ResourceImporter{ - StateContext: schema.ImportStatePassthroughContext, - }, - } -} - -func resourceStorageS3BucketCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - id := d.Get(StorageSchemaID).(int) - log.Println("[DEBUG] Start S3 Storage Bucket Resource creating") - defer log.Printf("[DEBUG] Finish S3 Storage Bucket Resource creating (id=%d)\n", id) - config := m.(*Config) - client := config.StorageClient - - opts := []func(opt *buckets.StorageBucketCreateHTTPParams){ - func(opt *buckets.StorageBucketCreateHTTPParams) { - opt.Context = ctx - opt.ID = int64(id) - }, - } - name := strings.TrimSpace(d.Get(StorageS3BucketSchemaName).(string)) - if name != "" { - opts = append(opts, func(opt *buckets.StorageBucketCreateHTTPParams) { opt.Name = name }) - } - - err := client.CreateBucket(opts...) - if err != nil { - return diag.FromErr(fmt.Errorf("create storage bucket: %w", err)) - } - d.SetId(fmt.Sprintf("%d:%s", id, name)) - - return resourceStorageS3BucketRead(ctx, d, m) -} - -func resourceStorageS3BucketRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - storageID, bucketName := storageBucketResourceID(d) - log.Printf("[DEBUG] Start S3 Storage Bucket Resource reading (id=%d, name=%s)\n", storageID, bucketName) - defer log.Println("[DEBUG] Finish S3 Storage Bucket Resource reading") - - config := m.(*Config) - client := config.StorageClient - - opts := []func(opt *buckets.StorageListBucketsHTTPParams){ - func(opt *buckets.StorageListBucketsHTTPParams) { opt.Context = ctx }, - func(opt *buckets.StorageListBucketsHTTPParams) { opt.ID = int64(storageID) }, - } - - result, err := client.BucketsList(opts...) - if err != nil { - return diag.FromErr(fmt.Errorf("storage buckets list: %w", err)) - } - if len(result) == 0 { - return diag.Errorf("get buckets: wrong length of search result (%d), want more", len(result)) - } - for _, bucket := range result { - if bucket.Name == bucketName { - d.SetId(fmt.Sprintf("%d:%s", storageID, bucketName)) - _ = d.Set(StorageS3BucketSchemaStorageID, storageID) - _ = d.Set(StorageS3BucketSchemaName, bucketName) - return nil - } - } - - return diag.FromErr(fmt.Errorf("storage buckets list has not this bucket")) -} - -func resourceStorageS3BucketDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - storageID, bucketName := storageBucketResourceID(d) - log.Printf("[DEBUG] Start S3 Storage Bucket Resource deleting (id=%d,name=%s)\n", storageID, bucketName) - defer log.Println("[DEBUG] Finish S3 Storage Bucket Resource deleting") - if bucketName == "" { - return diag.Errorf("empty bucket") - } - - config := m.(*Config) - client := config.StorageClient - - opts := []func(opt *buckets.StorageBucketRemoveHTTPParams){ - func(opt *buckets.StorageBucketRemoveHTTPParams) { opt.Context = ctx }, - func(opt *buckets.StorageBucketRemoveHTTPParams) { opt.ID = int64(storageID) }, - func(opt *buckets.StorageBucketRemoveHTTPParams) { opt.Name = bucketName }, - } - err := client.DeleteBucket(opts...) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - - return nil -} - -func storageBucketResourceID(d *schema.ResourceData) (int, string) { - var storageID int - var bucketName string - resourceID := d.Id() - if resourceID == "" { - storageID = d.Get(StorageS3BucketSchemaStorageID).(int) - bucketName = strings.TrimSpace(d.Get(StorageS3BucketSchemaName).(string)) - return storageID, bucketName - } - parts := strings.Split(resourceID, ":") - if len(parts) != 2 { - return storageID, bucketName - } - id, _ := strconv.ParseInt(parts[0], 10, 64) - storageID = int(id) - bucketName = parts[1] - - return storageID, bucketName -} diff --git a/edgecenter/resource_edgecenter_subnet.go b/edgecenter/resource_edgecenter_subnet.go deleted file mode 100644 index 4c0c6b30..00000000 --- a/edgecenter/resource_edgecenter_subnet.go +++ /dev/null @@ -1,455 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "net" - "regexp" - "time" - - "github.com/hashicorp/go-cty/cty" - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" -) - -const ( - SubnetDeleting int = 1200 - SubnetCreatingTimeout int = 1200 - SubnetPoint = "subnets" - disable = "disable" -) - -func resourceSubnet() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceSubnetCreate, - ReadContext: resourceSubnetRead, - UpdateContext: resourceSubnetUpdate, - DeleteContext: resourceSubnetDelete, - Description: "Represent subnets. Subnetwork is a range of IP addresses in a cloud network. Addresses from this range will be assigned to machines in the cloud", - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, subnetID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(subnetID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the subnet.", - }, - "enable_dhcp": { - Type: schema.TypeBool, - Optional: true, - Computed: true, - Description: "Enable DHCP for this subnet. If true, DHCP will be used to assign IP addresses to instances within this subnet.", - }, - "cidr": { - Type: schema.TypeString, - Required: true, - Description: "Represents the IP address range of the subnet.", - }, - "network_id": { - Type: schema.TypeString, - Required: true, - Description: "The ID of the network to which this subnet belongs.", - }, - "connect_to_network_router": { - Type: schema.TypeBool, - Description: "True if the network's router should get a gateway in this subnet. Must be explicitly 'false' when gateway_ip is null. Default true.", - Optional: true, - Default: true, - }, - "dns_nameservers": { - Type: schema.TypeList, - Optional: true, - Computed: true, - Description: "List of DNS name servers for the subnet.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "host_routes": { - Type: schema.TypeList, - Optional: true, - Description: "List of additional routes to be added to instances that are part of this subnet.", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "destination": { - Type: schema.TypeString, - Required: true, - }, - "nexthop": { - Type: schema.TypeString, - Required: true, - Description: "IPv4 address to forward traffic to if it's destination IP matches 'destination' CIDR", - }, - }, - }, - }, - "gateway_ip": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The IP address of the gateway for this subnet.", - ValidateDiagFunc: func(val interface{}, key cty.Path) diag.Diagnostics { - v := val.(string) - IP := regexp.MustCompile(`(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}`) - if v == disable || IP.MatchString(v) { - return nil - } - return diag.FromErr(fmt.Errorf("%q must be a valid ip, got: %s", key, v)) - }, - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - }, - } -} - -func resourceSubnetCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start Subnet creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, SubnetPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - createOpts := subnets.CreateOpts{} - - var eccidr edgecloud.CIDR - cidr := d.Get("cidr").(string) - if cidr != "" { - _, netIPNet, err := net.ParseCIDR(cidr) - if err != nil { - return diag.FromErr(err) - } - eccidr.IP = netIPNet.IP - eccidr.Mask = netIPNet.Mask - createOpts.CIDR = eccidr - } - - dnsNameservers := d.Get("dns_nameservers").([]interface{}) - createOpts.DNSNameservers = make([]net.IP, 0) - if len(dnsNameservers) > 0 { - ns := dnsNameservers - dns := make([]net.IP, len(ns)) - for i, s := range ns { - dns[i] = net.ParseIP(s.(string)) - } - createOpts.DNSNameservers = dns - } - - hostRoutes := d.Get("host_routes").([]interface{}) - createOpts.HostRoutes = make([]subnets.HostRoute, 0) - if len(hostRoutes) > 0 { - createOpts.HostRoutes, err = extractHostRoutesMap(hostRoutes) - if err != nil { - return diag.FromErr(err) - } - } - - createOpts.Name = d.Get("name").(string) - createOpts.EnableDHCP = d.Get("enable_dhcp").(bool) - createOpts.NetworkID = d.Get("network_id").(string) - createOpts.ConnectToNetworkRouter = d.Get("connect_to_network_router").(bool) - gatewayIP := d.Get("gateway_ip").(string) - gw := net.ParseIP(gatewayIP) - if gatewayIP == disable { - createOpts.ConnectToNetworkRouter = false - } else { - createOpts.GatewayIP = &gw - } - - if metadataRaw, ok := d.GetOk("metadata_map"); ok { - meta, err := utils.MapInterfaceToMapString(metadataRaw) - if err != nil { - return diag.FromErr(err) - } - createOpts.Metadata = meta - } - - log.Printf("Create subnet ops: %+v", createOpts) - results, err := subnets.Create(client, createOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - subnetID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, SubnetCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - Subnet, err := subnets.ExtractSubnetIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve Subnet ID from task info: %w", err) - } - return Subnet, nil - }, - ) - log.Printf("[DEBUG] Subnet id (%s)", subnetID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(subnetID.(string)) - resourceSubnetRead(ctx, d, m) - - log.Printf("[DEBUG] Finish Subnet creating (%s)", subnetID) - - return diags -} - -func resourceSubnetRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start subnet reading") - log.Printf("[DEBUG] Start subnet reading%s", d.State()) - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - subnetID := d.Id() - log.Printf("[DEBUG] Subnet id = %s", subnetID) - - client, err := CreateClient(provider, d, SubnetPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - subnet, err := subnets.Get(client, subnetID).Extract() - if err != nil { - return diag.Errorf("cannot get subnet with ID: %s. Error: %s", subnetID, err) - } - - d.Set("name", subnet.Name) - d.Set("enable_dhcp", subnet.EnableDHCP) - d.Set("cidr", subnet.CIDR.String()) - d.Set("network_id", subnet.NetworkID) - - dns := make([]string, len(subnet.DNSNameservers)) - for i, ns := range subnet.DNSNameservers { - dns[i] = ns.String() - } - d.Set("dns_nameservers", dns) - - hrs := make([]map[string]string, len(subnet.HostRoutes)) - for i, hr := range subnet.HostRoutes { - hR := map[string]string{"destination": "", "nexthop": ""} - hR["destination"] = hr.Destination.String() - hR["nexthop"] = hr.NextHop.String() - hrs[i] = hR - } - d.Set("host_routes", hrs) - d.Set("region_id", subnet.RegionID) - d.Set("project_id", subnet.ProjectID) - d.Set("gateway_ip", subnet.GatewayIP.String()) - - fields := []string{"connect_to_network_router"} - revertState(d, &fields) - - if subnet.GatewayIP == nil { - d.Set("connect_to_network_router", false) - d.Set("gateway_ip", disable) - } - - metadataMap, metadataReadOnly := PrepareMetadata(subnet.Metadata) - - if err = d.Set("metadata_map", metadataMap); err != nil { - return diag.FromErr(err) - } - - if err = d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - log.Println("[DEBUG] Finish subnet reading") - - return diags -} - -func resourceSubnetUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start subnet updating") - subnetID := d.Id() - log.Printf("[DEBUG] Subnet id = %s", subnetID) - config := m.(*Config) - provider := config.Provider - client, err := CreateClient(provider, d, SubnetPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - updateOpts := subnets.UpdateOpts{} - - if d.HasChange("name") { - updateOpts.Name = d.Get("name").(string) - } - updateOpts.EnableDHCP = d.Get("enable_dhcp").(bool) - - // In the structure, the field is mandatory for the ability to transfer the absence of data, - // if you do not initialize it with a empty list, marshalling will send null and receive a validation error. - dnsNameservers := d.Get("dns_nameservers").([]interface{}) - updateOpts.DNSNameservers = make([]net.IP, 0) - if len(dnsNameservers) > 0 { - ns := dnsNameservers - dns := make([]net.IP, len(ns)) - for i, s := range ns { - dns[i] = net.ParseIP(s.(string)) - } - updateOpts.DNSNameservers = dns - } - - hostRoutes := d.Get("host_routes").([]interface{}) - updateOpts.HostRoutes = make([]subnets.HostRoute, 0) - if len(hostRoutes) > 0 { - updateOpts.HostRoutes, err = extractHostRoutesMap(hostRoutes) - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("gateway_ip") { - _, newValue := d.GetChange("gateway_ip") - if newValue.(string) != disable { - gatewayIP := net.ParseIP(newValue.(string)) - updateOpts.GatewayIP = &gatewayIP - } - } - - _, err = subnets.Update(client, subnetID, updateOpts).Extract() - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("metadata_map") { - _, nmd := d.GetChange("metadata_map") - meta, err := utils.MapInterfaceToMapString(nmd) - if err != nil { - return diag.Errorf("metadata wrong fmt. Error: %s", err) - } - err = metadata.ResourceMetadataReplace(client, subnetID, meta).Err - if err != nil { - return diag.Errorf("cannot update metadata. Error: %s", err) - } - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish subnet updating") - - return resourceSubnetRead(ctx, d, m) -} - -func resourceSubnetDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start subnet deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - subnetID := d.Id() - log.Printf("[DEBUG] Subnet id = %s", subnetID) - - client, err := CreateClient(provider, d, SubnetPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - results, err := subnets.Delete(client, subnetID).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, SubnetDeleting, func(task tasks.TaskID) (interface{}, error) { - _, err := subnets.Get(client, subnetID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete subnet with ID: %s", subnetID) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Subnet resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of subnet deleting") - - return diags -} diff --git a/edgecenter/resource_edgecenter_volume.go b/edgecenter/resource_edgecenter_volume.go deleted file mode 100644 index 7c589456..00000000 --- a/edgecenter/resource_edgecenter_volume.go +++ /dev/null @@ -1,430 +0,0 @@ -package edgecenter - -import ( - "context" - "errors" - "fmt" - "log" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/diag" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/utils/metadata" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" -) - -const ( - volumeDeleting int = 1200 - VolumeCreatingTimeout int = 1200 - volumeExtending int = 1200 - VolumesPoint = "volumes" -) - -func resourceVolume() *schema.Resource { - return &schema.Resource{ - CreateContext: resourceVolumeCreate, - ReadContext: resourceVolumeRead, - UpdateContext: resourceVolumeUpdate, - DeleteContext: resourceVolumeDelete, - Description: `A volume is a detachable block storage device akin to a USB hard drive or SSD, but located remotely in the cloud. -Volumes can be attached to a virtual machine and manipulated like a physical hard drive.`, - Importer: &schema.ResourceImporter{ - StateContext: func(ctx context.Context, d *schema.ResourceData, meta interface{}) ([]*schema.ResourceData, error) { - projectID, regionID, volumeID, err := ImportStringParser(d.Id()) - if err != nil { - return nil, err - } - d.Set("project_id", projectID) - d.Set("region_id", regionID) - d.SetId(volumeID) - - config := meta.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, VolumesPoint, VersionPointV1) - if err != nil { - return nil, err - } - - volume, err := volumes.Get(client, volumeID).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get volume with ID: %s. Error: %w", volumeID, err) - } - d.Set("image_id", volume.VolumeImageMetadata.ImageID) - - return []*schema.ResourceData{d}, nil - }, - }, - - Schema: map[string]*schema.Schema{ - "project_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "project_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the project. Either 'project_id' or 'project_name' must be specified.", - ExactlyOneOf: []string{"project_id", "project_name"}, - }, - "region_id": { - Type: schema.TypeInt, - Optional: true, - Description: "The uuid of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "region_name": { - Type: schema.TypeString, - Optional: true, - Description: "The name of the region. Either 'region_id' or 'region_name' must be specified.", - ExactlyOneOf: []string{"region_id", "region_name"}, - }, - "name": { - Type: schema.TypeString, - Required: true, - Description: "The name of the volume.", - }, - "size": { - Type: schema.TypeInt, - Required: true, - Description: "The size of the volume, specified in gigabytes (GB).", - }, - "type_name": { - Type: schema.TypeString, - Optional: true, - Description: "The type of volume to create. Valid values are 'ssd_hiiops', 'standard', 'cold', and 'ultra'. Defaults to 'standard'.", - }, - "image_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "(ForceNew) The ID of the image to create the volume from. This field is mandatory if creating a volume from an image.", - }, - "snapshot_id": { - Type: schema.TypeString, - Optional: true, - ForceNew: true, - Description: "(ForceNew) The ID of the snapshot to create the volume from. This field is mandatory if creating a volume from a snapshot.", - }, - "last_updated": { - Type: schema.TypeString, - Optional: true, - Computed: true, - Description: "The timestamp of the last update (use with update context).", - }, - "metadata_map": { - Type: schema.TypeMap, - Optional: true, - Computed: true, - Description: "A map containing metadata, for example tags.", - Elem: &schema.Schema{ - Type: schema.TypeString, - }, - }, - "metadata_read_only": { - Type: schema.TypeList, - Computed: true, - Description: `A list of read-only metadata items, e.g. tags.`, - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "key": { - Type: schema.TypeString, - Computed: true, - }, - "value": { - Type: schema.TypeString, - Computed: true, - }, - "read_only": { - Type: schema.TypeBool, - Computed: true, - }, - }, - }, - }, - }, - } -} - -func resourceVolumeCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start volume creating") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - - client, err := CreateClient(provider, d, VolumesPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts, err := getVolumeData(d) - if err != nil { - return diag.FromErr(err) - } - results, err := volumes.Create(client, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - VolumeID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, VolumeCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - volumeID, err := volumes.ExtractVolumeIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve volume ID from task info: %w", err) - } - return volumeID, nil - }, - ) - log.Printf("[DEBUG] Volume id (%s)", VolumeID) - if err != nil { - return diag.FromErr(err) - } - - d.SetId(VolumeID.(string)) - resourceVolumeRead(ctx, d, m) - - log.Printf("[DEBUG] Finish volume creating (%s)", VolumeID) - - return diags -} - -func resourceVolumeRead(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start volume reading") - log.Printf("[DEBUG] Start volume reading%s", d.State()) - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - volumeID := d.Id() - log.Printf("[DEBUG] Volume id = %s", volumeID) - - client, err := CreateClient(provider, d, VolumesPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - volume, err := volumes.Get(client, volumeID).Extract() - if err != nil { - return diag.Errorf("cannot get volume with ID: %s. Error: %s", volumeID, err) - } - - d.Set("name", volume.Name) - d.Set("size", volume.Size) - d.Set("type_name", volume.VolumeType) - d.Set("region_id", volume.RegionID) - d.Set("project_id", volume.ProjectID) - - metadataMap, metadataReadOnly := PrepareMetadata(volume.Metadata) - - if err = d.Set("metadata_map", metadataMap); err != nil { - return diag.FromErr(err) - } - - if err = d.Set("metadata_read_only", metadataReadOnly); err != nil { - return diag.FromErr(err) - } - - fields := []string{"image_id", "snapshot_id"} - revertState(d, &fields) - - log.Println("[DEBUG] Finish volume reading") - - return diags -} - -func resourceVolumeUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start volume updating") - volumeID := d.Id() - log.Printf("[DEBUG] Volume id = %s", volumeID) - config := m.(*Config) - provider := config.Provider - client, err := CreateClient(provider, d, VolumesPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - volume, err := volumes.Get(client, volumeID).Extract() - if err != nil { - return diag.FromErr(err) - } - - if d.HasChange("name") { - name := d.Get("name").(string) - _, err := volumes.Update(client, volumeID, volumes.UpdateOpts{Name: name}).Extract() - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("size") { - newValue := d.Get("size") - newSize := newValue.(int) - if newSize != 0 { - if volume.Size < newSize { - err = ExtendVolume(client, volumeID, newSize) - if err != nil { - return diag.FromErr(err) - } - } else { - return diag.Errorf("Validation error: unable to update size field because new volume size must be greater than current size") - } - } - } - - if d.HasChange("type_name") { - newTN := d.Get("type_name") - newVolumeType, err := volumes.VolumeType(newTN.(string)).ValidOrNil() - if err != nil { - return diag.FromErr(err) - } - - opts := volumes.VolumeTypePropertyOperationOpts{ - VolumeType: *newVolumeType, - } - _, err = volumes.Retype(client, volumeID, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - } - - if d.HasChange("metadata_map") { - _, nmd := d.GetChange("metadata_map") - - meta, err := utils.MapInterfaceToMapString(nmd.(map[string]interface{})) - if err != nil { - return diag.Errorf("cannot get metadata. Error: %s", err) - } - - err = metadata.ResourceMetadataReplace(client, d.Id(), meta).Err - if err != nil { - return diag.Errorf("cannot update metadata. Error: %s", err) - } - } - - d.Set("last_updated", time.Now().Format(time.RFC850)) - log.Println("[DEBUG] Finish volume updating") - - return resourceVolumeRead(ctx, d, m) -} - -func resourceVolumeDelete(_ context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { - log.Println("[DEBUG] Start volume deleting") - var diags diag.Diagnostics - config := m.(*Config) - provider := config.Provider - volumeID := d.Id() - log.Printf("[DEBUG] Volume id = %s", volumeID) - - client, err := CreateClient(provider, d, VolumesPoint, VersionPointV1) - if err != nil { - return diag.FromErr(err) - } - - opts := volumes.DeleteOpts{ - Snapshots: [](string){d.Get("snapshot_id").(string)}, - } - results, err := volumes.Delete(client, volumeID, opts).Extract() - if err != nil { - return diag.FromErr(err) - } - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, volumeDeleting, func(task tasks.TaskID) (interface{}, error) { - _, err := volumes.Get(client, volumeID).Extract() - if err == nil { - return nil, fmt.Errorf("cannot delete volume with ID: %s", volumeID) - } - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil, nil - } - return nil, fmt.Errorf("extracting Volume resource error: %w", err) - }) - if err != nil { - return diag.FromErr(err) - } - - d.SetId("") - log.Printf("[DEBUG] Finish of volume deleting") - - return diags -} - -func getVolumeData(d *schema.ResourceData) (*volumes.CreateOpts, error) { - volumeData := volumes.CreateOpts{} - volumeData.Source = volumes.NewVolume - volumeData.Name = d.Get("name").(string) - volumeData.Size = d.Get("size").(int) - - imageID := d.Get("image_id").(string) - if imageID != "" { - volumeData.Source = volumes.Image - volumeData.ImageID = imageID - } - - snapshotID := d.Get("snapshot_id").(string) - if snapshotID != "" { - volumeData.Source = volumes.Snapshot - volumeData.SnapshotID = snapshotID - if volumeData.Size != 0 { - log.Println("[DEBUG] Size must be equal or larger to respective snapshot size") - } - } - - typeName := d.Get("type_name").(string) - if typeName != "" { - modifiedTypeName, err := volumes.VolumeType(typeName).ValidOrNil() - if err != nil { - return nil, fmt.Errorf("checking Volume validation error: %w", err) - } - volumeData.TypeName = *modifiedTypeName - } - - if metadataRaw, ok := d.GetOk("metadata_map"); ok { - meta, err := utils.MapInterfaceToMapString(metadataRaw) - if err != nil { - return nil, fmt.Errorf("volume metadata error: %w", err) - } - - volumeData.Metadata = meta - } - - return &volumeData, nil -} - -func ExtendVolume(client *edgecloud.ServiceClient, volumeID string, newSize int) error { - opts := volumes.SizePropertyOperationOpts{ - Size: newSize, - } - results, err := volumes.Extend(client, volumeID, opts).Extract() - if err != nil { - return fmt.Errorf("extracting Volume resource error: %w", err) - } - - taskID := results.Tasks[0] - log.Printf("[DEBUG] Task id (%s)", taskID) - _, err = tasks.WaitTaskAndReturnResult(client, taskID, true, volumeExtending, func(task tasks.TaskID) (interface{}, error) { - _, err := volumes.Get(client, volumeID).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get volume with ID: %s. Error: %w", volumeID, err) - } - return nil, nil - }) - - if err != nil { - return fmt.Errorf("checking Volume state error: %w", err) - } - log.Printf("[DEBUG] Finish waiting.") - - return nil -} diff --git a/edgecenter/test/.env b/edgecenter/test/.env deleted file mode 100644 index fb0a07e5..00000000 --- a/edgecenter/test/.env +++ /dev/null @@ -1,11 +0,0 @@ -VAULT_ADDR=https://vault.p.ecnl.ru/ -EC_API=https://api.edgecenter.online/cloud -EC_CDN_URL=https://cdn.edgecenter.online -EC_DNS_API=https://api.edgecenter.online/dns -EC_PASSWORD=Test-1234 -EC_PLATFORM=https://api.edgecenter.online/iam -EC_STORAGE_API=https://api.edgecenter.online/storage -EC_USERNAME=test-cloud-common@edgecenter.ru -TEST_PROJECT_ID=31203 -TEST_REGION_ID=8 - diff --git a/edgecenter/test/data_source_edgecenter_floatingip_test.go b/edgecenter/test/data_source_edgecenter_floatingip_test.go deleted file mode 100644 index f78b884f..00000000 --- a/edgecenter/test/data_source_edgecenter_floatingip_test.go +++ /dev/null @@ -1,83 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/floatingip/v1/floatingips" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccFloatingIPDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.FloatingIPsPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := floatingips.CreateOpts{} - - res, err := floatingips.Create(client, opts).Extract() - if err != nil { - t.Fatal(err) - } - - taskID := res.Tasks[0] - floatingIPID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.FloatingIPCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - floatingIPID, err := floatingips.ExtractFloatingIPIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve FloatingIP ID from task info: %w", err) - } - return floatingIPID, nil - }) - if err != nil { - t.Fatal(err) - } - - defer floatingips.Delete(client, floatingIPID.(string)) - - fip, err := floatingips.Get(client, floatingIPID.(string)).Extract() - if err != nil { - t.Fatal(err) - } - - resourceName := "data.edgecenter_floatingip.acctest" - tpl := func(ip string) string { - return fmt.Sprintf(` - data "edgecenter_floatingip" "acctest" { - %s - %s - floating_ip_address = "%s" - } - `, projectInfo(), regionInfo(), ip) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(fip.FloatingIPAddress.String()), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "id", floatingIPID.(string)), - resource.TestCheckResourceAttr(resourceName, "floating_ip_address", fip.FloatingIPAddress.String()), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_image_test.go b/edgecenter/test/data_source_edgecenter_image_test.go deleted file mode 100644 index bbc58911..00000000 --- a/edgecenter/test/data_source_edgecenter_image_test.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/image/v1/images" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccImageDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.ImagesPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - imgs, err := images.ListAll(client, images.ListOpts{}) - if err != nil { - t.Fatal(err) - } - - if len(imgs) == 0 { - t.Fatal("images not found") - } - - img := imgs[0] - - resourceName := "data.edgecenter_image.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_image" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(img.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", img.Name), - resource.TestCheckResourceAttr(resourceName, "id", img.ID), - resource.TestCheckResourceAttr(resourceName, "min_disk", strconv.Itoa(img.MinDisk)), - resource.TestCheckResourceAttr(resourceName, "min_ram", strconv.Itoa(img.MinRAM)), - resource.TestCheckResourceAttr(resourceName, "os_distro", img.OsDistro), - resource.TestCheckResourceAttr(resourceName, "os_version", img.OsVersion), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_instance_test.go b/edgecenter/test/data_source_edgecenter_instance_test.go deleted file mode 100644 index 541a3eb8..00000000 --- a/edgecenter/test/data_source_edgecenter_instance_test.go +++ /dev/null @@ -1,140 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/image/v1/images" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/instances" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccInstanceDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - clientVolume, err := createTestClient(cfg.Provider, edgecenter.VolumesPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - clientImage, err := createTestClient(cfg.Provider, edgecenter.ImagesPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - imgs, err := images.ListAll(clientImage, nil) - if err != nil { - t.Fatal(err) - } - - var img images.Image - for _, i := range imgs { - if i.OsDistro == osDistroTest { - img = i - break - } - } - if img.ID == "" { - t.Fatalf("images with os_distro='%s' does not exist", osDistroTest) - } - - optsV := volumes.CreateOpts{ - Name: volumeTestName, - Size: volumeSizeTest * 5, - Source: volumes.Image, - TypeName: volumes.Standard, - ImageID: img.ID, - } - volumeID, err := createTestVolume(clientVolume, optsV) - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.InstancePoint, edgecenter.VersionPointV2) - if err != nil { - t.Fatal(err) - } - - clientV1, err := createTestClient(cfg.Provider, edgecenter.InstancePoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := instances.CreateOpts{ - Names: []string{instanceTestName}, - Flavor: flavorTest, - Volumes: []instances.CreateVolumeOpts{{ - Source: types.ExistingVolume, - BootIndex: 0, - VolumeID: volumeID, - }}, - Interfaces: []instances.InterfaceInstanceCreateOpts{ - { - InterfaceOpts: instances.InterfaceOpts{Type: types.ExternalInterfaceType}, - SecurityGroups: []edgecloud.ItemID{}, - }, - }, - } - - res, err := instances.Create(client, opts).Extract() - if err != nil { - t.Fatal(err) - } - - taskID := res.Tasks[0] - instanceID, err := tasks.WaitTaskAndReturnResult(clientVolume, taskID, true, edgecenter.InstanceCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(clientVolume, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - id, err := instances.ExtractInstanceIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve instance ID from task info: %w", err) - } - return id, nil - }, - ) - if err != nil { - t.Fatal(err) - } - - defer instances.Delete(clientV1, instanceID.(string), instances.DeleteOpts{Volumes: []string{volumeID}}) - - resourceName := "data.edgecenter_instance.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_instance" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(instanceTestName), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", instanceTestName), - resource.TestCheckResourceAttr(resourceName, "id", instanceID.(string)), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_k8s_pool_test.go b/edgecenter/test/data_source_edgecenter_k8s_pool_test.go deleted file mode 100644 index 1c0268b1..00000000 --- a/edgecenter/test/data_source_edgecenter_k8s_pool_test.go +++ /dev/null @@ -1,153 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "net" - "os" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/clusters" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/pools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/keypair/v2/keypairs" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccK8sPoolDataSource(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode") - } - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - k8sClient, err := createTestClient(cfg.Provider, edgecenter.K8sPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - netClient, err := createTestClient(cfg.Provider, edgecenter.NetworksPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - subnetClient, err := createTestClient(cfg.Provider, edgecenter.SubnetPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - kpClient, err := createTestClient(cfg.Provider, edgecenter.KeypairsPoint, edgecenter.VersionPointV2) - if err != nil { - t.Fatal(err) - } - - netOpts := networks.CreateOpts{ - Name: networkTestName, - CreateRouter: true, - } - networkID, err := createTestNetwork(netClient, netOpts) - if err != nil { - t.Fatal(err) - } - defer deleteTestNetwork(netClient, networkID) - - gw := net.ParseIP("") - subnetOpts := subnets.CreateOpts{ - Name: subnetTestName, - NetworkID: networkID, - ConnectToNetworkRouter: true, - EnableDHCP: true, - GatewayIP: &gw, - } - - subnetID, err := createTestSubnet(subnetClient, subnetOpts) - if err != nil { - t.Fatal(err) - } - - // update our new network router so that the k8s nodes will have access to the Nexus - // registry to download images - if err := patchRouterForK8S(cfg.Provider, networkID); err != nil { - t.Fatal(err) - } - - pid, err := strconv.Atoi(os.Getenv("TEST_PROJECT_ID")) - if err != nil { - t.Fatal(err) - } - - kpOpts := keypairs.CreateOpts{ - Name: kpTestName, - PublicKey: pkTest, - ProjectID: pid, - } - keyPair, err := keypairs.Create(kpClient, kpOpts).Extract() - if err != nil { - t.Fatal(err) - } - defer keypairs.Delete(kpClient, keyPair.ID) - - nodeCountTestPtr := nodeCountTest - dockerVolumeSizeTestPtr := dockerVolumeSizeTest - maxNodeCountTestPtr := maxNodeCountTest - k8sOpts := clusters.CreateOpts{ - Name: clusterTestName, - FixedNetwork: networkID, - FixedSubnet: subnetID, - AutoHealingEnabled: true, - KeyPair: keyPair.ID, - Version: clusterVersionTest, - Pools: []pools.CreateOpts{{ - Name: poolTestName, - FlavorID: flavorTest, - NodeCount: &nodeCountTestPtr, - DockerVolumeSize: &dockerVolumeSizeTestPtr, - DockerVolumeType: ockerVolumeTypeTest, - MinNodeCount: minNodeCountTest, - MaxNodeCount: &maxNodeCountTestPtr, - }}, - } - clusterID, err := createTestCluster(k8sClient, k8sOpts) - if err != nil { - t.Fatal(err) - } - defer deleteTestCluster(k8sClient, clusterID) - - cluster, err := clusters.Get(k8sClient, clusterID).Extract() - if err != nil { - t.Fatal(err) - } - pool := cluster.Pools[0] - - resourceName := "data.edgecenter_k8s_pool.acctest" - ipTemplate := fmt.Sprintf(` - data "edgecenter_k8s_pool" "acctest" { - %s - %s - cluster_id = "%s" - pool_id = "%s" - } - `, projectInfo(), regionInfo(), clusterID, pool.UUID) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: ipTemplate, - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "cluster_id", clusterID), - resource.TestCheckResourceAttr(resourceName, "pool_id", pool.UUID), - resource.TestCheckResourceAttr(resourceName, "name", pool.Name), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_k8s_test.go b/edgecenter/test/data_source_edgecenter_k8s_test.go deleted file mode 100644 index a694ad52..00000000 --- a/edgecenter/test/data_source_edgecenter_k8s_test.go +++ /dev/null @@ -1,146 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "net" - "os" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/clusters" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/pools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/keypair/v2/keypairs" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccK8sDataSource(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode") - } - resourceName := "data.edgecenter_k8s.acctest" - - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - k8sClient, err := createTestClient(cfg.Provider, edgecenter.K8sPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - netClient, err := createTestClient(cfg.Provider, edgecenter.NetworksPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - subnetClient, err := createTestClient(cfg.Provider, edgecenter.SubnetPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - kpClient, err := createTestClient(cfg.Provider, edgecenter.KeypairsPoint, edgecenter.VersionPointV2) - if err != nil { - t.Fatal(err) - } - - netOpts := networks.CreateOpts{ - Name: networkTestName, - CreateRouter: true, - } - networkID, err := createTestNetwork(netClient, netOpts) - if err != nil { - t.Fatal(err) - } - defer deleteTestNetwork(netClient, networkID) - - gw := net.ParseIP("") - subnetOpts := subnets.CreateOpts{ - Name: subnetTestName, - NetworkID: networkID, - ConnectToNetworkRouter: true, - EnableDHCP: true, - GatewayIP: &gw, - } - - subnetID, err := createTestSubnet(subnetClient, subnetOpts) - if err != nil { - t.Fatal(err) - } - - // update our new network router so that the k8s nodes will have access to the Nexus - // registry to download images - if err := patchRouterForK8S(cfg.Provider, networkID); err != nil { - t.Fatal(err) - } - - pid, err := strconv.Atoi(os.Getenv("TEST_PROJECT_ID")) - if err != nil { - t.Fatal(err) - } - - kpOpts := keypairs.CreateOpts{ - Name: kpTestName, - PublicKey: pkTest, - ProjectID: pid, - } - keyPair, err := keypairs.Create(kpClient, kpOpts).Extract() - if err != nil { - t.Fatal(err) - } - defer keypairs.Delete(kpClient, keyPair.ID) - - nodeCountTestPtr := nodeCountTest - dockerVolumeSizeTestPtr := dockerVolumeSizeTest - maxNodeCountTestPtr := maxNodeCountTest - k8sOpts := clusters.CreateOpts{ - Name: clusterTestName, - FixedNetwork: networkID, - FixedSubnet: subnetID, - AutoHealingEnabled: true, - KeyPair: keyPair.ID, - Version: clusterVersionTest, - Pools: []pools.CreateOpts{{ - Name: poolTestName, - FlavorID: flavorTest, - NodeCount: &nodeCountTestPtr, - DockerVolumeSize: &dockerVolumeSizeTestPtr, - DockerVolumeType: ockerVolumeTypeTest, - MinNodeCount: minNodeCountTest, - MaxNodeCount: &maxNodeCountTestPtr, - }}, - } - clusterID, err := createTestCluster(k8sClient, k8sOpts) - if err != nil { - t.Fatal(err) - } - defer deleteTestCluster(k8sClient, clusterID) - - ipTemplate := fmt.Sprintf(` - data "edgecenter_k8s" "acctest" { - %s - %s - cluster_id = "%s" - } - `, projectInfo(), regionInfo(), clusterID) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: ipTemplate, - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "cluster_id", clusterID), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_lblistener_test.go b/edgecenter/test/data_source_edgecenter_lblistener_test.go deleted file mode 100644 index 90a2ec3a..00000000 --- a/edgecenter/test/data_source_edgecenter_lblistener_test.go +++ /dev/null @@ -1,79 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/listeners" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/loadbalancers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccLBListenerDataSource(t *testing.T) { - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.LoadBalancersPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - clientListener, err := createTestClient(cfg.Provider, edgecenter.LBListenersPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := loadbalancers.CreateOpts{ - Name: lbTestName, - Listeners: []loadbalancers.CreateListenerOpts{{ - Name: lbListenerTestName, - ProtocolPort: 80, - Protocol: types.ProtocolTypeHTTP, - }}, - } - - lbID, err := createTestLoadBalancerWithListener(client, opts) - if err != nil { - t.Fatal(err) - } - defer loadbalancers.Delete(client, lbID) - - ls, err := listeners.ListAll(clientListener, listeners.ListOpts{LoadBalancerID: &lbID}) - if err != nil { - t.Fatal(err) - } - listener := ls[0] - - resourceName := "data.edgecenter_lblistener.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_lblistener" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(lbListenerTestName), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", lbListenerTestName), - resource.TestCheckResourceAttr(resourceName, "id", listener.ID), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_lbpool_test.go b/edgecenter/test/data_source_edgecenter_lbpool_test.go deleted file mode 100644 index 8226a7ac..00000000 --- a/edgecenter/test/data_source_edgecenter_lbpool_test.go +++ /dev/null @@ -1,132 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/lbpools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/listeners" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/loadbalancers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccLBPoolDataSource(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode") - } - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.LoadBalancersPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - clientListener, err := createTestClient(cfg.Provider, edgecenter.LBListenersPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - clientPools, err := createTestClient(cfg.Provider, edgecenter.LBPoolsPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := loadbalancers.CreateOpts{ - Name: lbTestName, - Listeners: []loadbalancers.CreateListenerOpts{{ - Name: lbListenerTestName, - ProtocolPort: 80, - Protocol: types.ProtocolTypeHTTP, - }}, - } - - lbID, err := createTestLoadBalancerWithListener(client, opts) - if err != nil { - t.Fatal(err) - } - defer loadbalancers.Delete(client, lbID) - - ls, err := listeners.ListAll(clientListener, listeners.ListOpts{LoadBalancerID: &lbID}) - if err != nil { - t.Fatal(err) - } - listener := ls[0] - - optsPool := lbpools.CreateOpts{ - Name: poolTestName, - Protocol: types.ProtocolTypeHTTP, - LoadBalancerID: lbID, - ListenerID: listener.ID, - LBPoolAlgorithm: types.LoadBalancerAlgorithmRoundRobin, - HealthMonitor: &lbpools.CreateHealthMonitorOpts{ - Type: types.HealthMonitorTypeHTTP, - Delay: 5, - MaxRetries: 10, - Timeout: 10, - MaxRetriesDown: 10, - HTTPMethod: types.HTTPMethodPointer(types.HTTPMethodGET), - URLPath: "/", - ExpectedCodes: "123,321", - }, - } - res, err := lbpools.Create(clientPools, optsPool).Extract() - if err != nil { - t.Fatal(err) - } - - taskID := res.Tasks[0] - lbPoolID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.LBPoolsCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - lbPoolID, err := lbpools.ExtractPoolIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve LBPool ID from task info: %w", err) - } - return lbPoolID, nil - }) - if err != nil { - t.Fatal(err) - } - - pool, err := lbpools.Get(clientPools, lbPoolID.(string)).Extract() - if err != nil { - t.Fatal(err) - } - - resourceName := "data.edgecenter_lbpool.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_lbpool" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(poolTestName), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", poolTestName), - resource.TestCheckResourceAttr(resourceName, "id", pool.ID), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_loadbalancer_test.go b/edgecenter/test/data_source_edgecenter_loadbalancer_test.go deleted file mode 100644 index ef6d3f5f..00000000 --- a/edgecenter/test/data_source_edgecenter_loadbalancer_test.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/loadbalancers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccLoadBalancerDataSource(t *testing.T) { - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.LoadBalancersPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := loadbalancers.CreateOpts{ - Name: lbTestName, - Listeners: []loadbalancers.CreateListenerOpts{{ - Name: lbListenerTestName, - ProtocolPort: 80, - Protocol: types.ProtocolTypeHTTP, - }}, - } - - lbID, err := createTestLoadBalancerWithListener(client, opts) - if err != nil { - t.Fatal(err) - } - - defer loadbalancers.Delete(client, lbID) - - resourceName := "data.edgecenter_loadbalancer.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_loadbalancer" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(opts.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", opts.Name), - resource.TestCheckResourceAttr(resourceName, "id", lbID), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_network_test.go b/edgecenter/test/data_source_edgecenter_network_test.go deleted file mode 100644 index 873d5238..00000000 --- a/edgecenter/test/data_source_edgecenter_network_test.go +++ /dev/null @@ -1,100 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccNetworkDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.NetworksPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts1 := networks.CreateOpts{ - Name: "test-network1", - Metadata: map[string]string{"key1": "val1", "key2": "val2"}, - } - - network1ID, err := createTestNetwork(client, opts1) - if err != nil { - t.Fatal(err) - } - opts2 := networks.CreateOpts{ - Name: "test-network2", - Metadata: map[string]string{"key1": "val1", "key3": "val3"}, - } - - network2ID, err := createTestNetwork(client, opts2) - if err != nil { - t.Fatal(err) - } - - defer deleteTestNetwork(client, network1ID) - defer deleteTestNetwork(client, network2ID) - - resourceName := "data.edgecenter_network.acctest" - tpl1 := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_network" "acctest" { - %s - %s - name = "%s" - metadata_k="key1" - } - `, projectInfo(), regionInfo(), name) - } - tpl2 := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_network" "acctest" { - %s - %s - name = "%s" - metadata_kv={ - key3 = "val3" - } - } - `, projectInfo(), regionInfo(), name) - } - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl1(opts1.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", opts1.Name), - resource.TestCheckResourceAttr(resourceName, "id", network1ID), - testAccCheckMetadata(t, resourceName, true, map[string]string{ - "key1": "val1", "key2": "val2", - }), - ), - }, - { - Config: tpl2(opts2.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", opts2.Name), - resource.TestCheckResourceAttr(resourceName, "id", network2ID), - testAccCheckMetadata(t, resourceName, true, map[string]string{ - "key3": "val3", - }), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_project_test.go b/edgecenter/test/data_source_edgecenter_project_test.go deleted file mode 100644 index 11c58cca..00000000 --- a/edgecenter/test/data_source_edgecenter_project_test.go +++ /dev/null @@ -1,62 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/project/v1/projects" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccProjectDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.ProjectPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - prjs, err := projects.ListAll(client) - if err != nil { - t.Fatal(err) - } - - if len(prjs) == 0 { - t.Fatal("projects not found") - } - - project := prjs[0] - - resourceName := "data.edgecenter_project.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_project" "acctest" { - name = "%s" - } - `, name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(project.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", project.Name), - resource.TestCheckResourceAttr(resourceName, "id", strconv.Itoa(project.ID)), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_region_test.go b/edgecenter/test/data_source_edgecenter_region_test.go deleted file mode 100644 index 8c69923c..00000000 --- a/edgecenter/test/data_source_edgecenter_region_test.go +++ /dev/null @@ -1,62 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/region/v1/regions" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccRegionDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.RegionPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - rs, err := regions.ListAll(client) - if err != nil { - t.Fatal(err) - } - - if len(rs) == 0 { - t.Fatal("regions not found") - } - - region := rs[0] - - resourceName := "data.edgecenter_region.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_region" "acctest" { - name = "%s" - } - `, name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(region.DisplayName), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", region.DisplayName), - resource.TestCheckResourceAttr(resourceName, "id", strconv.Itoa(region.ID)), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_reservedfixedip_test.go b/edgecenter/test/data_source_edgecenter_reservedfixedip_test.go deleted file mode 100644 index 8db0b88b..00000000 --- a/edgecenter/test/data_source_edgecenter_reservedfixedip_test.go +++ /dev/null @@ -1,85 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/reservedfixedip/v1/reservedfixedips" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccReservedFixedIPDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.ReservedFixedIPsPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := reservedfixedips.CreateOpts{ - Type: reservedfixedips.External, - } - - res, err := reservedfixedips.Create(client, opts).Extract() - if err != nil { - t.Fatal(err) - } - - taskID := res.Tasks[0] - reservedFixedIPID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.ReservedFixedIPCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - reservedFixedIPID, err := reservedfixedips.ExtractReservedFixedIPIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve reservedFixedIP ID from task info: %w", err) - } - return reservedFixedIPID, nil - }) - if err != nil { - t.Fatal(err) - } - - defer reservedfixedips.Delete(client, reservedFixedIPID.(string)) - - fip, err := reservedfixedips.Get(client, reservedFixedIPID.(string)).Extract() - if err != nil { - t.Fatal(err) - } - - resourceName := "data.edgecenter_reservedfixedip.acctest" - tpl := func(ip string) string { - return fmt.Sprintf(` - data "edgecenter_reservedfixedip" "acctest" { - %s - %s - fixed_ip_address = "%s" - } - `, projectInfo(), regionInfo(), ip) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(fip.FixedIPAddress.String()), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "id", reservedFixedIPID.(string)), - resource.TestCheckResourceAttr(resourceName, "fixed_ip_address", fip.FixedIPAddress.String()), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_router_test.go b/edgecenter/test/data_source_edgecenter_router_test.go deleted file mode 100644 index c03de8b9..00000000 --- a/edgecenter/test/data_source_edgecenter_router_test.go +++ /dev/null @@ -1,75 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/router/v1/routers" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccRouterDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - clientNet, err := createTestClient(cfg.Provider, edgecenter.NetworksPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - clientRouter, err := createTestClient(cfg.Provider, edgecenter.RouterPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := networks.CreateOpts{ - Name: networkTestName, - CreateRouter: true, - } - - networkID, err := createTestNetwork(clientNet, opts) - if err != nil { - t.Fatal(err) - } - defer networks.Delete(clientNet, networkID) - - rs, err := routers.ListAll(clientRouter, routers.ListOpts{}) - if err != nil { - t.Fatal(err) - } - router := rs[0] - - resourceName := "data.edgecenter_router.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_router" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(router.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", router.Name), - resource.TestCheckResourceAttr(resourceName, "id", router.ID), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_secret_test.go b/edgecenter/test/data_source_edgecenter_secret_test.go deleted file mode 100644 index 6c71ded1..00000000 --- a/edgecenter/test/data_source_edgecenter_secret_test.go +++ /dev/null @@ -1,86 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/secret/v1/secrets" - secretsV2 "github.com/Edge-Center/edgecentercloud-go/edgecenter/secret/v2/secrets" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccSecretDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.SecretPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - clientV2, err := createTestClient(cfg.Provider, edgecenter.SecretPoint, edgecenter.VersionPointV2) - if err != nil { - t.Fatal(err) - } - - opts := secretsV2.CreateOpts{ - Name: secretTestName, - Payload: secretsV2.PayloadOpts{ - CertificateChain: certificateChain, - Certificate: certificate, - PrivateKey: privateKey, - }, - } - results, err := secretsV2.Create(clientV2, opts).Extract() - if err != nil { - t.Fatal(err) - } - - taskID := results.Tasks[0] - secretID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.SecretCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - Secret, err := secrets.ExtractSecretIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve Secret ID from task info: %w", err) - } - return Secret, nil - }, - ) - if err != nil { - t.Fatal(err) - } - defer secrets.Delete(client, secretID.(string)) - - resourceName := "data.edgecenter_secret.acctest" - kpTemplate := fmt.Sprintf(` - data "edgecenter_secret" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), secretTestName) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: kpTemplate, - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", secretTestName), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_securitygroup_test.go b/edgecenter/test/data_source_edgecenter_securitygroup_test.go deleted file mode 100644 index 13f4cebe..00000000 --- a/edgecenter/test/data_source_edgecenter_securitygroup_test.go +++ /dev/null @@ -1,108 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/securitygroups" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccSecurityGroupDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.SecurityGroupPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts1 := securitygroups.CreateOpts{ - SecurityGroup: securitygroups.CreateSecurityGroupOpts{ - Name: "test-sg1", - SecurityGroupRules: []securitygroups.CreateSecurityGroupRuleOpts{}, - Metadata: map[string]interface{}{"key1": "val1", "key2": "val2"}, - }, - } - - sg1, err := securitygroups.Create(client, opts1).Extract() - if err != nil { - t.Fatal(err) - } - - opts2 := securitygroups.CreateOpts{ - SecurityGroup: securitygroups.CreateSecurityGroupOpts{ - Name: "test-sg2", - SecurityGroupRules: []securitygroups.CreateSecurityGroupRuleOpts{}, - Metadata: map[string]interface{}{"key1": "val1", "key3": "val3"}, - }, - } - - sg2, err := securitygroups.Create(client, opts2).Extract() - if err != nil { - t.Fatal(err) - } - defer securitygroups.Delete(client, sg1.ID) - defer securitygroups.Delete(client, sg2.ID) - - resourceName := "data.edgecenter_securitygroup.acctest" - - tpl1 := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_securitygroup" "acctest" { - %s - %s - name = "%s" - metadata_k="key1" - } - `, projectInfo(), regionInfo(), name) - } - - tpl2 := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_securitygroup" "acctest" { - %s - %s - name = "%s" - metadata_kv={ - key3 = "val3" - } - } - `, projectInfo(), regionInfo(), name) - } - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl1(sg1.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", sg1.Name), - resource.TestCheckResourceAttr(resourceName, "id", sg1.ID), - testAccCheckMetadata(t, resourceName, true, map[string]interface{}{ - "key1": "val1", "key2": "val2", - }), - ), - }, - { - Config: tpl2(sg2.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", sg2.Name), - resource.TestCheckResourceAttr(resourceName, "id", sg2.ID), - testAccCheckMetadata(t, resourceName, true, map[string]interface{}{ - "key3": "val3", - }), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_servergroup_test.go b/edgecenter/test/data_source_edgecenter_servergroup_test.go deleted file mode 100644 index e3605cfc..00000000 --- a/edgecenter/test/data_source_edgecenter_servergroup_test.go +++ /dev/null @@ -1,61 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/servergroup/v1/servergroups" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccServerGroupDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.ServerGroupsPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := servergroups.CreateOpts{Name: "name", Policy: servergroups.AntiAffinityPolicy} - serverGroup, err := servergroups.Create(client, opts).Extract() - if err != nil { - t.Fatal(err) - } - - resourceName := "data.edgecenter_servergroup.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_servergroup" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), name) - } - - defer servergroups.Delete(client, serverGroup.ServerGroupID) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(opts.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", serverGroup.Name), - resource.TestCheckResourceAttr(resourceName, "id", serverGroup.ServerGroupID), - resource.TestCheckResourceAttr(resourceName, "policy", serverGroup.Policy.String()), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_storage_s3_test.go b/edgecenter/test/data_source_edgecenter_storage_s3_test.go deleted file mode 100644 index f56606fb..00000000 --- a/edgecenter/test/data_source_edgecenter_storage_s3_test.go +++ /dev/null @@ -1,94 +0,0 @@ -//go:build storage - -package edgecenter_test - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecenter-storage-sdk-go/swagger/client/storages" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -const ( - s3Storage = "edgecenter_storage_s3" -) - -func TestStorageS3DataSource(t *testing.T) { - t.Parallel() - random := time.Now().Nanosecond() - resourceName := fmt.Sprintf("edgecenter_storage_s3.terraformtest%d_s3", random) - dataSourceName := fmt.Sprintf("data.edgecenter_storage_s3.terraformtest%d_s3_data", random) - - templateCreate := func() string { - return fmt.Sprintf(` -resource "%s" "terraformtest%d_s3" { - name = "terraformtest%d" - location = "s-ed1" -} - `, s3Storage, random, random) - } - - templateRead := func() string { - return fmt.Sprintf(` -data "%s" "terraformtest%d_s3_data" { - name = "terraformtest%d" -} - `, s3Storage, random, random) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheckVars(t, EC_USERNAME_VAR, EC_PASSWORD_VAR, EC_STORAGE_URL_VAR) - }, - CheckDestroy: func(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - for _, rs := range s.RootModule().Resources { - if rs.Type != s3Storage { - continue - } - opts := []func(opt *storages.StorageListHTTPV2Params){ - func(opt *storages.StorageListHTTPV2Params) { opt.Context = ctx }, - func(opt *storages.StorageListHTTPV2Params) { opt.ID = &rs.Primary.ID }, - } - storages, err := config.StorageClient.StoragesList(opts...) - if err != nil { - return fmt.Errorf("find storage: %w", err) - } - if len(storages) == 0 { - return nil - } - if storages[0].ProvisioningStatus == "ok" { - return fmt.Errorf("storage #%s wasn't deleted correctrly", rs.Primary.ID) - } - } - - return nil - }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: templateCreate(), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, edgecenter.StorageSchemaLocation, "s-ed1"), - ), - }, - { - Config: templateRead(), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(dataSourceName), - resource.TestCheckResourceAttr(dataSourceName, edgecenter.StorageSchemaLocation, "s-ed1"), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_subnet_test.go b/edgecenter/test/data_source_edgecenter_subnet_test.go deleted file mode 100644 index 3794828c..00000000 --- a/edgecenter/test/data_source_edgecenter_subnet_test.go +++ /dev/null @@ -1,120 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccSubnetDataSource(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - clientNet, err := createTestClient(cfg.Provider, edgecenter.NetworksPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - clientSubnet, err := createTestClient(cfg.Provider, edgecenter.SubnetPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := networks.CreateOpts{ - Name: networkTestName, - } - - networkID, err := createTestNetwork(clientNet, opts) - if err != nil { - t.Fatal(err) - } - - defer deleteTestNetwork(clientNet, networkID) - - optsSubnet1 := subnets.CreateOpts{ - Name: "test-subnet1", - NetworkID: networkID, - Metadata: map[string]string{"key1": "val1", "key2": "val2"}, - } - - subnet1ID, err := createTestSubnet(clientSubnet, optsSubnet1, "192.168.41.0/24") - if err != nil { - t.Fatal(err) - } - - optsSubnet2 := subnets.CreateOpts{ - Name: "test-subnet2", - NetworkID: networkID, - Metadata: map[string]string{"key1": "val1", "key3": "val3"}, - } - - subnet2ID, err := createTestSubnet(clientSubnet, optsSubnet2, "192.168.43.0/24") - if err != nil { - t.Fatal(err) - } - - resourceName := "data.edgecenter_subnet.acctest" - tpl1 := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_subnet" "acctest" { - %s - %s - name = "%s" - metadata_k="key1" - } - `, projectInfo(), regionInfo(), name) - } - - tpl2 := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_subnet" "acctest" { - %s - %s - name = "%s" - metadata_kv={ - key3 = "val3" - } - } - `, projectInfo(), regionInfo(), name) - } - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl1(optsSubnet1.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", optsSubnet1.Name), - resource.TestCheckResourceAttr(resourceName, "id", subnet1ID), - resource.TestCheckResourceAttr(resourceName, "network_id", networkID), - testAccCheckMetadata(t, resourceName, true, map[string]string{ - "key1": "val1", "key2": "val2", - }), - ), - }, - { - Config: tpl2(optsSubnet2.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", optsSubnet2.Name), - resource.TestCheckResourceAttr(resourceName, "id", subnet2ID), - // resource.TestCheckResourceAttr(resourceName, "network_id", networkID), - testAccCheckMetadata(t, resourceName, true, map[string]string{ - "key3": "val3", - }), - ), - }, - }, - }) -} diff --git a/edgecenter/test/data_source_edgecenter_volume_test.go b/edgecenter/test/data_source_edgecenter_volume_test.go deleted file mode 100644 index 97d3c07f..00000000 --- a/edgecenter/test/data_source_edgecenter_volume_test.go +++ /dev/null @@ -1,67 +0,0 @@ -//go:build cloud_data_source - -package edgecenter_test - -import ( - "fmt" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccVolumeDataSource(t *testing.T) { - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.VolumesPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := volumes.CreateOpts{ - Name: volumeTestName, - Size: volumeSizeTest, - Source: volumes.NewVolume, - TypeName: volumes.Standard, - } - - volumeID, err := createTestVolume(client, opts) - if err != nil { - t.Fatal(err) - } - - defer volumes.Delete(client, volumeID, volumes.DeleteOpts{}) - - resourceName := "data.edgecenter_volume.acctest" - tpl := func(name string) string { - return fmt.Sprintf(` - data "edgecenter_volume" "acctest" { - %s - %s - name = "%s" - } - `, projectInfo(), regionInfo(), name) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: tpl(opts.Name), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", opts.Name), - resource.TestCheckResourceAttr(resourceName, "id", volumeID), - resource.TestCheckResourceAttr(resourceName, "size", strconv.Itoa(opts.Size)), - ), - }, - }, - }) -} diff --git a/edgecenter/test/helper_test.go b/edgecenter/test/helper_test.go deleted file mode 100644 index aa7249e4..00000000 --- a/edgecenter/test/helper_test.go +++ /dev/null @@ -1,250 +0,0 @@ -//go:build cloud_data_source || cloud_resource - -package edgecenter_test - -import ( - "errors" - "fmt" - "net" - "strings" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/k8s/v1/clusters" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/loadbalancers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/availablenetworks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/router/v1/routers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func createTestNetwork(client *edgecloud.ServiceClient, opts networks.CreateOpts) (string, error) { - result, err := networks.Create(client, opts).Extract() - if err != nil { - return "", err - } - - taskID := result.Tasks[0] - networkID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.NetworkCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - networkID, err := networks.ExtractNetworkIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve network ID from task info: %w", err) - } - return networkID, nil - }) - - if err != nil { - return "", err - } - - return networkID.(string), nil -} - -func deleteTestNetwork(client *edgecloud.ServiceClient, networkID string) error { - result, err := networks.Delete(client, networkID).Extract() - if err != nil { - return err - } - - taskID := result.Tasks[0] - err = tasks.WaitTaskAndProcessResult(client, taskID, true, edgecenter.NetworkDeleting, func(task tasks.TaskID) error { - _, err := networks.Get(client, networkID).Extract() - if err == nil { - return fmt.Errorf("cannot delete network with ID: %s", networkID) - } - - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil - } - return fmt.Errorf("extracting Network resource error: %w", err) - }) - - return err -} - -func createTestSubnet(client *edgecloud.ServiceClient, opts subnets.CreateOpts, extra ...string) (string, error) { - subCidr := cidrTest - if extra != nil { - subCidr = extra[0] - } - - var eccidr edgecloud.CIDR - _, netIPNet, err := net.ParseCIDR(subCidr) - if err != nil { - return "", err - } - eccidr.IP = netIPNet.IP - eccidr.Mask = netIPNet.Mask - opts.CIDR = eccidr - - result, err := subnets.Create(client, opts).Extract() - if err != nil { - return "", err - } - - taskID := result.Tasks[0] - subnetID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.SubnetCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - subnet, err := subnets.ExtractSubnetIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve Subnet ID from task info: %w", err) - } - return subnet, nil - }) - - return subnetID.(string), err -} - -func patchRouterForK8S(provider *edgecloud.ProviderClient, networkID string) error { - routersClient, err := createTestClient(provider, edgecenter.RouterPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - - aNetClient, err := createTestClient(provider, edgecenter.SharedNetworksPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - - availableNetworks, err := availablenetworks.ListAll(aNetClient, nil) - if err != nil { - return err - } - var extNet availablenetworks.Network - for _, an := range availableNetworks { - if an.External { - extNet = an - break - } - } - - rs, err := routers.ListAll(routersClient, nil) - if err != nil { - return err - } - - var router routers.Router - for _, r := range rs { - if strings.Contains(r.Name, networkID) { - router = r - break - } - } - - extSubnet := extNet.Subnets[0] - routerOpts := routers.UpdateOpts{Routes: extSubnet.HostRoutes} - if _, err = routers.Update(routersClient, router.ID, routerOpts).Extract(); err != nil { - return err - } - - return nil -} - -func createTestCluster(client *edgecloud.ServiceClient, opts clusters.CreateOpts) (string, error) { - result, err := clusters.Create(client, opts).Extract() - if err != nil { - return "", err - } - - taskID := result.Tasks[0] - clusterID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.K8sCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - clusterID, err := clusters.ExtractClusterIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve cluster ID from task info: %w", err) - } - return clusterID, nil - }) - - if err != nil { - return "", err - } - - return clusterID.(string), nil -} - -func deleteTestCluster(client *edgecloud.ServiceClient, clusterID string) error { - result, err := clusters.Delete(client, clusterID).Extract() - if err != nil { - return err - } - - taskID := result.Tasks[0] - err = tasks.WaitTaskAndProcessResult(client, taskID, true, edgecenter.K8sCreateTimeout, func(task tasks.TaskID) error { - _, err := clusters.Get(client, clusterID).Extract() - if err == nil { - return fmt.Errorf("cannot delete k8s cluster with ID: %s", clusterID) - } - - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return nil - } - return fmt.Errorf("extracting k8s cluster resource error: %w", err) - }) - - return err -} - -func createTestLoadBalancerWithListener(client *edgecloud.ServiceClient, opts loadbalancers.CreateOpts) (string, error) { - result, err := loadbalancers.Create(client, opts).Extract() - if err != nil { - return "", err - } - - taskID := result.Tasks[0] - lbID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.LoadBalancerCreateTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - lbID, err := loadbalancers.ExtractLoadBalancerIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve LoadBalancer ID from task info: %w", err) - } - return lbID, nil - }) - if err != nil { - return "", err - } - - return lbID.(string), nil -} - -func createTestVolume(client *edgecloud.ServiceClient, opts volumes.CreateOpts) (string, error) { - result, err := volumes.Create(client, opts).Extract() - if err != nil { - return "", err - } - - taskID := result.Tasks[0] - volumeID, err := tasks.WaitTaskAndReturnResult(client, taskID, true, edgecenter.VolumeCreatingTimeout, func(task tasks.TaskID) (interface{}, error) { - taskInfo, err := tasks.Get(client, string(task)).Extract() - if err != nil { - return nil, fmt.Errorf("cannot get task with ID: %s. Error: %w", task, err) - } - volumeID, err := volumes.ExtractVolumeIDFromTask(taskInfo) - if err != nil { - return nil, fmt.Errorf("cannot retrieve volume ID from task info: %w", err) - } - return volumeID, nil - }) - if err != nil { - return "", err - } - - return volumeID.(string), nil -} diff --git a/edgecenter/test/main_test.go b/edgecenter/test/main_test.go deleted file mode 100644 index 7fabe06b..00000000 --- a/edgecenter/test/main_test.go +++ /dev/null @@ -1,304 +0,0 @@ -//go:build cloud_data_source || cloud_resource || dns || storage || cdn - -package edgecenter_test - -import ( - "fmt" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" - "net/http" - "net/url" - "os" - "strconv" - "strings" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - dnssdk "github.com/Edge-Center/edgecenter-dns-sdk-go" - storageSDK "github.com/Edge-Center/edgecenter-storage-sdk-go" - cdn "github.com/Edge-Center/edgecentercdn-go" - eccdnProvider "github.com/Edge-Center/edgecentercdn-go/edgecenter/provider" - edgecloud "github.com/Edge-Center/edgecentercloud-go" - ec "github.com/Edge-Center/edgecentercloud-go/edgecenter" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -const ( - instanceTestName = "test-vm" - clusterTestName = "test-cluster" - poolTestName = "test-pool" - lbTestName = "test-lb" - lbListenerTestName = "test-listener" - networkTestName = "test-network" - subnetTestName = "test-subnet" - volumeTestName = "test-volume" - secretTestName = "test-secret" - kpTestName = "test-kp" - - flavorTest = "g1-standard-1-2" - osDistroTest = "ubuntu" - clusterVersionTest = "1.20.15" - cidrTest = "192.168.42.0/24" - nodeCountTest = 1 - dockerVolumeSizeTest = 10 - ockerVolumeTypeTest = volumes.Standard - minNodeCountTest = 1 - maxNodeCountTest = 1 - volumeSizeTest = 1 - - pkTest = `ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQC1bdbQYquD/swsZpFPXagY9KvhlNUTKYMdhRNtlGglAMgRxJS3Q0V74BNElJtP+UU/AbZD4H2ZAwW3PLLD/maclnLlrA48xg/ez9IhppBop0WADZ/nB4EcvQfR/Db7nHDTZERW6EiiGhV6CkHVasK2sY/WNRXqPveeWUlwCqtSnU90l/s9kQCoEfkM2auO6ppJkVrXbs26vcRclS8KL7Cff4HwdVpV7b+edT5seZdtrFUCbkEof9D9nGpahNvg8mYWf0ofx4ona4kaXm1NdPID+ljvE/dbYUX8WZRmyLjMvVQS+VxDJtsiDQIVtwbC4w+recqwDvHhLWwoeczsbEsp ondi@ds` - privateKey = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQ4E6U0vql4EST\n8o41TlHRz6MKmMhddVUjM2juTKjxv4WuB4T3z/wokznEjQg4H7gfYEKeCJqelrfq\ntdOtbPsznSceMOXB5uA2Sc9WVKwk7owoRJxPd4LQeOcarVOFdIzudzkgSK/oV7Za\nL8Y2hylsB4SX2cfbULtmW/WDePp3YZAL6zYV1fXJSnK+hL2iUSqikiViEGRta+47\nnaTKZnnmSgojdshzsw0wlF/PgRJ/Anf9j9J8ratdJP81yAG5daU3L2NdJ3qx9UbV\ntKnSq2z2u4yx6xdb4t4WFQBKNjC6+YZN/gI5lp96p3FNTNS4PKYxAAUrnCwf0EE3\n7dOR4eWlAgMBAAECggEBALPm3ge0h4li1e4PVYh4AmSRT74KxVgpfMCqwM+uWzyM\nVpkDhPTjwC06UOEHD3M3bqAninkOtA2vhoyzOrP+T4Wu70hDmUAemDJp9BhJKVNN\n2o28Olz/dD4WRAZoDq29Kr0hFqTFtiyJj1eyGihQ1c5j00HuowI0UJPi1Fz+T8uN\nPwukUtTPYwEds6SApii3v9VKjmvbRDmsbHU3KkUoaeqpRnRagyp1vtoLXigezUcK\nrQcoh6wlKtvj0YLR2lxq9Wmj1nn6m3F5Bom54X8o18tcOmFSRudRb+Fxjb0jnqSK\nAsyVlZg4alTBQUmx9gIKv0oSJAIh2nXdclECkGjs8WkCgYEA9xvdDWephsbv+X3k\nndnDG9JTxfrR6HMHPrUrTaZ8/VD+Qw4zuReoNGkcQbV3Cb26egprWQWfYc9+l6mU\nAWgOjFgeGie1uwOwkhv6CfhE/iVvotJ3hOOsC5pLEhz4vRpO75C9wSehjfTYkP1m\nXEAhRTRbgMnvzChWyh5CEjosX5sCgYEA2GRHrG0JVxsYSCugLPKf9fSK4CQDm0bK\nywBwZtAWX0xhiHO/BW6PeK1Mqx2nbiWl1hXNpZKJNS9bnrZWym/yUqOvg2XJKjb6\nhHBvwAD1MOQ8Ysby4JHGCrMBEwlcDpI2wpMpXkKhU3X0XWjkqrhqCH/TETFKkqLt\nfJX/c9PTQ78CgYAEPek0grQJST7zVHLpNsS/pIOloWGbEOZt8CQ3KAV7P7mtov/G\nTJ6pj6hZhGjvtN8Pm0Aufgc3YZ11swaEY6nkRNr3bfkTpcORLoPDSgy9JB1feSdu\nE45vgI2LWQ34CQyT1jM7rpd6XVqeWos4SC2KB5UOh+ji40piG9TchT0fwwKBgA/M\nmpMTTvhGKSqzzLkbaeR6W11sI7tFmu7hdFN9Y/THTeO5l7vcy6ri9FMWEjBvnUEZ\nTG+HWG9CquzWoVWcgNPZ0anFV7+2Teo3j2E0cLKGJ4aKwhb1bcFAOpbaOxdxQ4BH\nYGDaeo7ucM4VJ4TzfAJs2stJjwlPzgknpoQddjJfAoGBAIFfnU8x/SrNhAqZrG9d\n3kpJ5LmbVswOYtj01KHM+KpEwOQVF+s2NOeHqyC7QUIWrue00+1MT88F9cNHDeWk\n0dEOJNWCfzcV85l8A+0p6/4qAW7h7RNiFqeA8GyVKCT8f7fu/7WpYw8D0aq8w5X/\nKZl+AjB+MzYFs71+SC4ohTlI\n-----END PRIVATE KEY-----" - certificate = "-----BEGIN CERTIFICATE-----\nMIIDpDCCAoygAwIBAgIJAIUvym0uaBHbMA0GCSqGSIb3DQEBCwUAMD0xCzAJBgNV\nBAYTAlJVMQ8wDQYDVQQIDAZNT1NDT1cxCzAJBgNVBAoMAkNBMRAwDgYDVQQDDAdS\nT09UIENBMB4XDTIxMDczMDE1MTU0NVoXDTMxMDcyODE1MTU0NVowTDELMAkGA1UE\nBhMCQ0ExDTALBgNVBAgMBE5vbmUxCzAJBgNVBAcMAk5CMQ0wCwYDVQQKDAROb25l\nMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQDQ4E6U0vql4EST8o41TlHRz6MKmMhddVUjM2juTKjxv4WuB4T3z/wokznE\njQg4H7gfYEKeCJqelrfqtdOtbPsznSceMOXB5uA2Sc9WVKwk7owoRJxPd4LQeOca\nrVOFdIzudzkgSK/oV7ZaL8Y2hylsB4SX2cfbULtmW/WDePp3YZAL6zYV1fXJSnK+\nhL2iUSqikiViEGRta+47naTKZnnmSgojdshzsw0wlF/PgRJ/Anf9j9J8ratdJP81\nyAG5daU3L2NdJ3qx9UbVtKnSq2z2u4yx6xdb4t4WFQBKNjC6+YZN/gI5lp96p3FN\nTNS4PKYxAAUrnCwf0EE37dOR4eWlAgMBAAGjgZcwgZQwVwYDVR0jBFAwTqFBpD8w\nPTELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1PU0NPVzELMAkGA1UECgwCQ0ExEDAO\nBgNVBAMMB1JPT1QgQ0GCCQCectJTETy4lTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE\n8DAhBgNVHREEGjAYgglsb2NhbGhvc3SCCyoubG9jYWxob3N0MA0GCSqGSIb3DQEB\nCwUAA4IBAQBqzJcwygLsVCTPlReUpcKVn84aFqzfZA0m7hYvH+7PDH/FM8SbX3zg\nteBL/PgQAZw1amO8xjeMc2Pe2kvi9VrpfTeGqNia/9axhGu3q/NEP0tyDFXAE2bR\njBdGhd5gCmg+X4WdHigCgn51cz5r2k3fSOIWP+TQWHqc8Yt+vZXnkwnQkRA1Ki7N\nWOiJjj/ae5RWwma/kJNmShTZn754gbQn06bAjNbPjclsHRLkawmLqikd1rYUhIdk\nOr1Nrl+CWMx3CXg0TVVdJ6rH3dO31uyvb+3qEY7WnL+HhZyr08ay8gJsEKPuPFA2\nxvveXqt9ceU5qh+8T7mHwGALEUw96QcP\n-----END CERTIFICATE-----" - certificateChain = "-----BEGIN CERTIFICATE-----\nMIIC9jCCAd4CCQCectJTETy4lTANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQGEwJS\nVTEPMA0GA1UECAwGTU9TQ09XMQswCQYDVQQKDAJDQTEQMA4GA1UEAwwHUk9PVCBD\nQTAeFw0yMTA3MzAxNTExMzVaFw0yNDA1MTkxNTExMzVaMD0xCzAJBgNVBAYTAlJV\nMQ8wDQYDVQQIDAZNT1NDT1cxCzAJBgNVBAoMAkNBMRAwDgYDVQQDDAdST09UIENB\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo6tZ0NV6QIR/mvsqtAII\nzTTuBMrZR5OTwKvcGnhe4GVDwzJ/OgEWkghLAzOojcJvkfzJOtWwOXqwgphksc+7\n+vwIPTPt3iWjbQUzXK8pFLkjxrO8px/QxPuUrp+U6DTVvvgQesjMZ9jQRUFKOiCc\nu0st1N5Q/CJR4VOJxtYoLy1ZUlsABhwJ+6trkoOFTLRPlMUX1EIG57jYAotHvQFo\nc8UNx3KzvJsJJ56SniXCIkeu61IOt8aOXHU+3TLYhZnPiP311cMbXA0J3vGPRZwz\n25BZjF3IF/ShXlfzz76FjWUTAThc0+HA8lzx53xD4/n8HN+sGubGx9TvLyZimG/U\nGwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAnK8Wzw33fR6R6pqV05XI9Yu8J+BwC\nCn2bKxxYwwQWZyX1as+UIlGuvyBRJba9W2UGMj95FQfWVdDyFC98spUur+O/5yL+\nNHH+dxGnkxIRc6RMIy+GXJwPrLiB/t70hSvwgVa249zNJVcwYN/5SGX5wLaJKnim\neY99xm75nr03O/RJK/DR8HvWysH7zxvrMWs0ppfwxkxrwOcg0Cb9xODVkg/wyClw\nLiHWlmH/eyC8nkiLYJKmV7566VWCV+gy+hC/DRstVVjIMG6LsqaPq6ycm7N8EV8s\nBb5uXIVHW6w5a20c40+W9G4EDYiQjdgEaf0FoMAWGDnOEaPsvjQk2/z5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIDPDCCAiQCCQDxA75ydLHVoTANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJS\nVTEPMA0GA1UECAwGTU9TQ09XMQ8wDQYDVQQHDAZNT1NDT1cxFTATBgNVBAoMDElO\nVEVSTUVESUFURTEYMBYGA1UEAwwPSU5URVJNRURJQVRFIENBMB4XDTIxMDczMDE1\nMTIyMloXDTI0MDUxOTE1MTIyMlowYDELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1P\nU0NPVzEPMA0GA1UEBwwGTU9TQ09XMRUwEwYDVQQKDAxJTlRFUk1FRElBVEUxGDAW\nBgNVBAMMD0lOVEVSTUVESUFURSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAKOrWdDVekCEf5r7KrQCCM007gTK2UeTk8Cr3Bp4XuBlQ8MyfzoBFpII\nSwMzqI3Cb5H8yTrVsDl6sIKYZLHPu/r8CD0z7d4lo20FM1yvKRS5I8azvKcf0MT7\nlK6flOg01b74EHrIzGfY0EVBSjognLtLLdTeUPwiUeFTicbWKC8tWVJbAAYcCfur\na5KDhUy0T5TFF9RCBue42AKLR70BaHPFDcdys7ybCSeekp4lwiJHrutSDrfGjlx1\nPt0y2IWZz4j99dXDG1wNCd7xj0WcM9uQWYxdyBf0oV5X88++hY1lEwE4XNPhwPJc\n8ed8Q+P5/BzfrBrmxsfU7y8mYphv1BsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA\ngOHvrh66+bQoG3Lo8bfp7D1Xvm/Md3gJq2nMotl2BH1TvNzMV93fCXygRX8J8rTL\n7xjUC2SbOrFDWFq2hNJQagdecAeuG+U55BY6Wi8SsHw+fhgxQyl9wtXWwotQPmsD\nuRhR1rL3vEphgPLbxNBzA7Lvj+P89Ar988Qy+o5AiUzHMUuqZbGOqs8UcKCQP7e/\nIX+zqqFwqyI8f90SVySGgs574jo8jQFy3l5fnp6yK0MPWg2cBCjpa5H1A+5DADF+\nnryV6Ie/m/wfxmitZZN+YCJu+8Bmmdl/FCwbmiH+HCLhrO8gonH3K21cQujMyFF5\nc7OFj86hvhqbr4kzz1J8lg==\n-----END CERTIFICATE-----" -) - -type VarName string - -const ( - EC_USERNAME_VAR VarName = "EC_USERNAME" - EC_PASSWORD_VAR VarName = "EC_PASSWORD" - EC_CDN_URL_VAR VarName = "EC_CDN_URL" - EC_STORAGE_URL_VAR VarName = "EC_STORAGE_API" - EC_DNS_URL_VAR VarName = "EC_DNS_API" - EC_IMAGE_VAR VarName = "EC_IMAGE" - EC_SECGROUP_VAR VarName = "EC_SECGROUP" - EC_EXT_NET_VAR VarName = "EC_EXT_NET" - EC_PRIV_NET_VAR VarName = "EC_PRIV_NET" - EC_PRIV_SUBNET_VAR VarName = "EC_PRIV_SUBNET" - EC_LB_ID_VAR VarName = "EC_LB_ID" - EC_LBLISTENER_ID_VAR VarName = "EC_LBLISTENER_ID" - EC_LBPOOL_ID_VAR VarName = "EC_LBPOOL_ID" - EC_VOLUME_ID_VAR VarName = "EC_VOLUME_ID" - EC_CDN_ORIGINGROUP_ID_VAR VarName = "EC_CDN_ORIGINGROUP_ID" - EC_CDN_RESOURCE_ID_VAR VarName = "EC_CDN_RESOURCE_ID" - EC_NETWORK_ID_VAR VarName = "EC_NETWORK_ID" - EC_SUBNET_ID_VAR VarName = "EC_SUBNET_ID" - EC_CLUSTER_ID_VAR VarName = "EC_CLUSTER_ID" - EC_CLUSTER_POOL_ID_VAR VarName = "EC_CLUSTER_POOL_ID" -) - -func getEnv(name VarName) string { - return os.Getenv(string(name)) -} - -var ( - EC_USERNAME = getEnv(EC_USERNAME_VAR) - EC_PASSWORD = getEnv(EC_PASSWORD_VAR) - EC_CDN_URL = getEnv(EC_CDN_URL_VAR) - EC_IMAGE = getEnv(EC_IMAGE_VAR) - EC_SECGROUP = getEnv(EC_SECGROUP_VAR) - EC_EXT_NET = getEnv(EC_EXT_NET_VAR) - EC_PRIV_NET = getEnv(EC_PRIV_NET_VAR) - EC_PRIV_SUBNET = getEnv(EC_PRIV_SUBNET_VAR) - EC_LB_ID = getEnv(EC_LB_ID_VAR) - EC_LBLISTENER_ID = getEnv(EC_LBLISTENER_ID_VAR) - EC_LBPOOL_ID = getEnv(EC_LBPOOL_ID_VAR) - EC_VOLUME_ID = getEnv(EC_VOLUME_ID_VAR) - EC_CDN_ORIGINGROUP_ID = getEnv(EC_CDN_ORIGINGROUP_ID_VAR) - EC_CDN_RESOURCE_ID = getEnv(EC_CDN_RESOURCE_ID_VAR) - EC_STORAGE_API = getEnv(EC_STORAGE_URL_VAR) - EC_DNS_API = getEnv(EC_DNS_URL_VAR) - EC_NETWORK_ID = getEnv(EC_NETWORK_ID_VAR) - EC_SUBNET_ID = getEnv(EC_SUBNET_ID_VAR) - EC_CLUSTER_ID = getEnv(EC_CLUSTER_ID_VAR) - EC_CLUSTER_POOL_ID = getEnv(EC_CLUSTER_POOL_ID_VAR) -) - -var varsMap = map[VarName]string{ - EC_USERNAME_VAR: EC_USERNAME, - EC_PASSWORD_VAR: EC_PASSWORD, - EC_CDN_URL_VAR: EC_CDN_URL, - EC_IMAGE_VAR: EC_IMAGE, - EC_SECGROUP_VAR: EC_SECGROUP, - EC_EXT_NET_VAR: EC_EXT_NET, - EC_PRIV_NET_VAR: EC_PRIV_NET, - EC_PRIV_SUBNET_VAR: EC_PRIV_SUBNET, - EC_LB_ID_VAR: EC_LB_ID, - EC_LBLISTENER_ID_VAR: EC_LBLISTENER_ID, - EC_LBPOOL_ID_VAR: EC_LBPOOL_ID, - EC_VOLUME_ID_VAR: EC_VOLUME_ID, - EC_CDN_ORIGINGROUP_ID_VAR: EC_CDN_ORIGINGROUP_ID, - EC_CDN_RESOURCE_ID_VAR: EC_CDN_RESOURCE_ID, - EC_STORAGE_URL_VAR: EC_STORAGE_API, - EC_DNS_URL_VAR: EC_DNS_API, - EC_NETWORK_ID_VAR: EC_NETWORK_ID, - EC_SUBNET_ID_VAR: EC_SUBNET_ID, - EC_CLUSTER_ID_VAR: EC_CLUSTER_ID, - EC_CLUSTER_POOL_ID_VAR: EC_CLUSTER_POOL_ID, -} - -func testAccPreCheckVars(t *testing.T, vars ...VarName) { - t.Helper() - for _, name := range vars { - if val := varsMap[name]; val == "" { - t.Fatalf("'%s' must be set for acceptance test", name) - } - } -} - -func testAccPreCheck(t *testing.T) { - t.Helper() - vars := map[string]interface{}{ - "EC_USERNAME": EC_USERNAME, - "EC_PASSWORD": EC_PASSWORD, - } - for k, v := range vars { - if v == "" { - t.Fatalf("'%s' must be set for acceptance test", k) - } - } - checkNameAndID(t, "PROJECT") - checkNameAndID(t, "REGION") -} - -func checkNameAndID(t *testing.T, resourceType string) { - // resourceType is a word in capital letters - t.Helper() - keyID := fmt.Sprintf("TEST_%s_ID", resourceType) - keyName := fmt.Sprintf("TEST_%s_NAME", resourceType) - _, haveID := os.LookupEnv(keyID) - _, haveName := os.LookupEnv(keyName) - if !haveID && !haveName { - t.Fatalf("%s or %s must be set for acceptance tests", keyID, keyName) - } - if haveID && haveName { - t.Fatalf("Use only one from environment variables: %s or %s", keyID, keyName) - } -} - -func regionInfo() string { - return objectInfo("REGION") -} - -func projectInfo() string { - return objectInfo("PROJECT") -} - -func objectInfo(resourceType string) string { - // resourceType is a word in capital letters - keyID := fmt.Sprintf("TEST_%s_ID", resourceType) - keyName := fmt.Sprintf("TEST_%s_NAME", resourceType) - if objectID, exists := os.LookupEnv(keyID); exists { - return fmt.Sprintf(`%s_id = %s`, strings.ToLower(resourceType), objectID) - } - return fmt.Sprintf(`%s_name = "%s"`, strings.ToLower(resourceType), os.Getenv(keyName)) -} - -func createTestClient(provider *edgecloud.ProviderClient, endpoint, version string) (*edgecloud.ServiceClient, error) { - projectID := 0 - var err error - if strProjectID, exists := os.LookupEnv("TEST_PROJECT_ID"); exists { - projectID, err = strconv.Atoi(strProjectID) - if err != nil { - return nil, err - } - } else { - projectID, err = edgecenter.GetProject(provider, 0, os.Getenv("TEST_PROJECT_NAME")) - if err != nil { - return nil, err - } - } - regionID := 0 - if strRegionID, exists := os.LookupEnv("TEST_REGION_ID"); exists { - regionID, err = strconv.Atoi(strRegionID) - if err != nil { - return nil, err - } - } else { - regionID, err = edgecenter.GetProject(provider, 0, os.Getenv("TEST_REGION_NAME")) - if err != nil { - return nil, err - } - } - - client, err := ec.ClientServiceFromProvider(provider, edgecloud.EndpointOpts{ - Name: endpoint, - Region: regionID, - Project: projectID, - Version: version, - }) - if err != nil { - return nil, err - } - - return client, nil -} - -func createTestConfig() (*edgecenter.Config, error) { - provider, err := ec.AuthenticatedClient(edgecloud.AuthOptions{ - APIURL: os.Getenv("EC_API"), - AuthURL: os.Getenv("EC_PLATFORM"), - Username: os.Getenv("EC_USERNAME"), - Password: os.Getenv("EC_PASSWORD"), - AllowReauth: true, - }) - if err != nil { - return nil, err - } - - cdnProvider := eccdnProvider.NewClient(EC_CDN_URL, eccdnProvider.WithSignerFunc(func(req *http.Request) error { - req.Header.Set("Authorization", "Bearer "+provider.AccessToken()) - return nil - })) - cdnService := cdn.NewService(cdnProvider) - - storageAPI := EC_STORAGE_API - stHost, stPath, err := edgecenter.ExtractHostAndPath(storageAPI) - var storageClient *storageSDK.SDK - if err == nil { - storageClient = storageSDK.NewSDK(stHost, stPath, storageSDK.WithBearerAuth(provider.AccessToken)) - } - - var dnsClient *dnssdk.Client - if EC_DNS_API != "" { - baseURL, err := url.Parse(EC_DNS_API) - if err == nil { - authorizer := dnssdk.BearerAuth(provider.AccessToken()) - dnsClient = dnssdk.NewClient(authorizer, func(client *dnssdk.Client) { - client.BaseURL = baseURL - }) - } - } - - config := edgecenter.Config{ - Provider: provider, - CDNClient: cdnService, - StorageClient: storageClient, - DNSClient: dnsClient, - } - - return &config, nil -} - -func testAccCheckResourceExists(resourceName string) resource.TestCheckFunc { - return func(s *terraform.State) error { - // retrieve the resource by name from state - rs, ok := s.RootModule().Resources[resourceName] - if !ok { - return fmt.Errorf("not found: %s", resourceName) - } - - if rs.Primary.ID == "" { - return fmt.Errorf("widget ID is not set") - } - return nil - } -} - -var ( - testAccProvider *schema.Provider - testAccProviders map[string]func() (*schema.Provider, error) -) - -func TestMain(m *testing.M) { - testAccProvider = edgecenter.Provider() - testAccProviders = map[string]func() (*schema.Provider, error){ - "edgecenter": func() (*schema.Provider, error) { - return testAccProvider, nil - }, - } - exitCode := m.Run() - os.Exit(exitCode) -} diff --git a/edgecenter/test/provider_test.go b/edgecenter/test/provider_test.go deleted file mode 100644 index f2af548e..00000000 --- a/edgecenter/test/provider_test.go +++ /dev/null @@ -1,14 +0,0 @@ -package edgecenter_test - -import ( - "testing" - - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestProvider(t *testing.T) { - t.Parallel() - if err := edgecenter.Provider().InternalValidate(); err != nil { - t.Fatalf("err: %s", err) - } -} diff --git a/edgecenter/test/resource_edgecenter_baremetal_test.go b/edgecenter/test/resource_edgecenter_baremetal_test.go deleted file mode 100644 index b3b4cda6..00000000 --- a/edgecenter/test/resource_edgecenter_baremetal_test.go +++ /dev/null @@ -1,68 +0,0 @@ -//go:build cloud_resource - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/instances" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccBaremetal(t *testing.T) { - if testing.Short() { - t.Skip("skipping test in short mode") - } - - resourceName := "edgecenter_baremetal.acctest" - - ipTemplate := fmt.Sprintf(` - resource "edgecenter_baremetal" "acctest" { - %s - %s - name = "test sg" - flavor_id = "bm1-infrastructure-small" - image_id = "1ee7ccee-5003-48c9-8ae0-d96063af75b2" - } - `, projectInfo(), regionInfo()) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - CheckDestroy: testAccBaremetalDestroy, - Steps: []resource.TestStep{ - { - Config: ipTemplate, - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", "test_sg"), - resource.TestCheckResourceAttr(resourceName, "flavor_id", "bm1-infrastructure-small"), - ), - }, - }, - }) -} - -func testAccBaremetalDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - client, err := createTestClient(config.Provider, edgecenter.InstancePoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_baremetal" { - continue - } - - _, err := instances.Get(client, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("baremetal instance %s still exists", rs.Primary.ID) - } - } - - return nil -} diff --git a/edgecenter/test/resource_edgecenter_cdn_origin_group_test.go b/edgecenter/test/resource_edgecenter_cdn_origin_group_test.go deleted file mode 100644 index fe473ed2..00000000 --- a/edgecenter/test/resource_edgecenter_cdn_origin_group_test.go +++ /dev/null @@ -1,100 +0,0 @@ -//go:build cdn - -package edgecenter_test - -import ( - "errors" - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func TestAccOriginGroup(t *testing.T) { - t.Parallel() - resourceName := "edgecenter_cdn_origingroup.acctest" - - type Params struct { - Source string - Enabled string - } - - create := Params{"google.com", "true"} - update := Params{"tut.by", "false"} - - template := func(params *Params) string { - return fmt.Sprintf(` - resource "edgecenter_cdn_origingroup" "acctest" { - name = "terraform_acctest_group" - use_next = true - - origin { - source = "%s" - enabled = %s - } - - origin { - source = "yandex.ru" - enabled = true - } - } - `, params.Source, params.Enabled) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheckVars(t, EC_USERNAME_VAR, EC_PASSWORD_VAR, EC_CDN_URL_VAR) - }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: template(&create), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", "terraform_acctest_group"), - or( - resource.TestCheckResourceAttr(resourceName, "origin.0.source", create.Source), - resource.TestCheckResourceAttr(resourceName, "origin.1.source", create.Source), - ), - or( - resource.TestCheckResourceAttr(resourceName, "origin.0.enabled", create.Enabled), - resource.TestCheckResourceAttr(resourceName, "origin.1.enabled", create.Enabled), - ), - ), - }, - { - Config: template(&update), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", "terraform_acctest_group"), - or( - resource.TestCheckResourceAttr(resourceName, "origin.0.source", update.Source), - resource.TestCheckResourceAttr(resourceName, "origin.1.source", update.Source), - ), - or( - resource.TestCheckResourceAttr(resourceName, "origin.0.enabled", update.Enabled), - resource.TestCheckResourceAttr(resourceName, "origin.1.enabled", update.Enabled), - ), - ), - }, - }, - }) -} - -func or(checks ...resource.TestCheckFunc) resource.TestCheckFunc { - return func(t *terraform.State) error { - var composed string - - for _, check := range checks { - err := check(t) - if err == nil { - return nil - } - - composed += err.Error() + "; " - } - - return errors.New(composed) - } -} diff --git a/edgecenter/test/resource_edgecenter_cdn_resource_test.go b/edgecenter/test/resource_edgecenter_cdn_resource_test.go deleted file mode 100644 index 39d0cbf3..00000000 --- a/edgecenter/test/resource_edgecenter_cdn_resource_test.go +++ /dev/null @@ -1,62 +0,0 @@ -//go:build cdn - -package edgecenter_test - -import ( - "fmt" - "testing" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" -) - -func TestAccCDNResource(t *testing.T) { - t.Parallel() - resourceName := "edgecenter_cdn_resource.acctest" - - type Params struct { - Proto string - } - - cname := fmt.Sprintf("cdn.terraform-%d.acctest", time.Now().Nanosecond()) - secondaryHostname := "secondary-" + cname - - create := Params{"HTTP"} - update := Params{"MATCH"} - - template := func(params *Params) string { - return fmt.Sprintf(` -resource "edgecenter_cdn_resource" "acctest" { - cname = "%s" - origin_group = %s - origin_protocol = "%s" - secondary_hostnames = ["%s"] -} - `, cname, EC_CDN_ORIGINGROUP_ID, params.Proto, secondaryHostname) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheckVars(t, EC_USERNAME_VAR, EC_PASSWORD_VAR, EC_CDN_URL_VAR, EC_CDN_ORIGINGROUP_ID_VAR) - }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: template(&create), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "cname", cname), - resource.TestCheckResourceAttr(resourceName, "origin_protocol", create.Proto), - ), - }, - { - Config: template(&update), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "cname", cname), - resource.TestCheckResourceAttr(resourceName, "origin_protocol", update.Proto), - ), - }, - }, - }) -} diff --git a/edgecenter/test/resource_edgecenter_cdn_rule_test.go b/edgecenter/test/resource_edgecenter_cdn_rule_test.go deleted file mode 100644 index 51afad1c..00000000 --- a/edgecenter/test/resource_edgecenter_cdn_rule_test.go +++ /dev/null @@ -1,75 +0,0 @@ -//go:build cdn - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" -) - -func TestAccCDNRule(t *testing.T) { - t.Parallel() - resourceName := "edgecenter_cdn_rule.acctest" - - type Params struct { - Name string - Pattern string - RawPart string - } - - create := Params{ - Name: "All images", - Pattern: "/folder/images/*.png", - } - update := Params{ - Name: "All scripts", - Pattern: "/folder/scripts/*.js", - RawPart: ` - options { - host_header { - enabled = true - value = "rule-host.com" - } - } - `, - } - - template := func(params *Params) string { - return fmt.Sprintf(` -resource "edgecenter_cdn_rule" "acctest" { - resource_id = %s - name = "%s" - rule = "%s" - %s -} - `, EC_CDN_RESOURCE_ID, params.Name, params.Pattern, params.RawPart) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheckVars(t, EC_USERNAME_VAR, EC_PASSWORD_VAR, EC_CDN_URL_VAR, EC_CDN_RESOURCE_ID_VAR) - }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: template(&create), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", create.Name), - resource.TestCheckResourceAttr(resourceName, "rule", create.Pattern), - ), - }, - { - Config: template(&update), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", update.Name), - resource.TestCheckResourceAttr(resourceName, "rule", update.Pattern), - resource.TestCheckResourceAttr(resourceName, "options.0.host_header.0.value", "rule-host.com"), - ), - }, - }, - }) -} diff --git a/edgecenter/test/resource_edgecenter_cdn_sslcerts_test.go b/edgecenter/test/resource_edgecenter_cdn_sslcerts_test.go deleted file mode 100644 index fbe1a06f..00000000 --- a/edgecenter/test/resource_edgecenter_cdn_sslcerts_test.go +++ /dev/null @@ -1,127 +0,0 @@ -//go:build cdn - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" -) - -func TestAccCDNCert(t *testing.T) { - t.Parallel() - resourceName := "edgecenter_cdn_sslcert.acctest" - template := fmt.Sprintf(` -resource "edgecenter_cdn_sslcert" "acctest" { - name = "Terraform acctest cert" - cert = < 0 { - for i, iface := range opts.Interfaces { - checksStore = append(checksStore, - resource.TestCheckResourceAttr(resourceName, fmt.Sprintf(`interfaces.%d.type`, i), iface.Type.String()), - resource.TestCheckResourceAttr(resourceName, fmt.Sprintf(`interfaces.%d.subnet_id`, i), iface.SubnetID), - ) - } - } - - for i, r := range opts.Routes { - checksStore = append(checksStore, - resource.TestCheckResourceAttr(resourceName, fmt.Sprintf(`routes.%d.destination`, i), r.Destination.String()), - resource.TestCheckResourceAttr(resourceName, fmt.Sprintf(`routes.%d.nexthop`, i), r.NextHop.String()), - ) - } - - return resource.ComposeTestCheckFunc(checksStore...)(s) - } -} - -func testAccRouterDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - client, err := createTestClient(config.Provider, edgecenter.RouterPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_router" { - continue - } - - _, err := routers.Get(client, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("router still exists") - } - } - - return nil -} diff --git a/edgecenter/test/resource_edgecenter_secret_test.go b/edgecenter/test/resource_edgecenter_secret_test.go deleted file mode 100644 index 00a5bfdf..00000000 --- a/edgecenter/test/resource_edgecenter_secret_test.go +++ /dev/null @@ -1,65 +0,0 @@ -//go:build cloud_resource - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/secret/v1/secrets" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccSecret(t *testing.T) { - t.Parallel() - resourceName := "edgecenter_secret.acctest" - kpTemplate := fmt.Sprintf(` - resource "edgecenter_secret" "acctest" { - %s - %s - name = "%s" - private_key = %q - certificate = %q - certificate_chain = %q - expiration = "2025-12-28T19:14:44.213" - } - `, projectInfo(), regionInfo(), secretTestName, privateKey, certificate, certificateChain) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - CheckDestroy: testAccSecretDestroy, - Steps: []resource.TestStep{ - { - Config: kpTemplate, - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", secretTestName), - ), - }, - }, - }) -} - -func testAccSecretDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - client, err := createTestClient(config.Provider, edgecenter.SecretPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_secret" { - continue - } - - _, err := secrets.Get(client, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("secret still exists") - } - } - - return nil -} diff --git a/edgecenter/test/resource_edgecenter_securitygroup_test.go b/edgecenter/test/resource_edgecenter_securitygroup_test.go deleted file mode 100644 index dd8ff9f1..00000000 --- a/edgecenter/test/resource_edgecenter_securitygroup_test.go +++ /dev/null @@ -1,108 +0,0 @@ -//go:build cloud_resource - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/securitygroups" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccSecurityGroup(t *testing.T) { - t.Parallel() - resourceName := "edgecenter_securitygroup.acctest" - - ipTemplate1 := fmt.Sprintf(` - resource "edgecenter_securitygroup" "acctest" { - %s - %s - name = "test" - metadata_map = { - key1 = "val1" - key2 = "val2" - } - security_group_rules { - direction = "egress" - ethertype = "IPv4" - protocol = "vrrp" - } - } - `, projectInfo(), regionInfo()) - - ipTemplate2 := fmt.Sprintf(` - resource "edgecenter_securitygroup" "acctest" { - %s - %s - name = "test" - metadata_map = { - key3 = "val3" - } - security_group_rules { - direction = "egress" - ethertype = "IPv4" - protocol = "vrrp" - } - } - `, projectInfo(), regionInfo()) - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - CheckDestroy: testAccSecurityGroupDestroy, - Steps: []resource.TestStep{ - { - Config: ipTemplate1, - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "metadata_map.key1", "val1"), - resource.TestCheckResourceAttr(resourceName, "metadata_map.key2", "val2"), - testAccCheckMetadata(t, resourceName, true, map[string]interface{}{ - "key1": "val1", - "key2": "val2", - }), - ), - }, - { - Config: ipTemplate2, - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "metadata_map.key3", "val3"), - testAccCheckMetadata(t, resourceName, true, map[string]interface{}{ - "key3": "val3", - }), - testAccCheckMetadata(t, resourceName, false, map[string]interface{}{ - "key1": "val1", - }), - testAccCheckMetadata(t, resourceName, false, map[string]interface{}{ - "key2": "val2", - }), - ), - }, - }, - }) -} - -func testAccSecurityGroupDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - client, err := createTestClient(config.Provider, edgecenter.SecurityGroupPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_securitygroup" { - continue - } - - _, err := securitygroups.Get(client, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("SecurityGroup still exists") - } - } - - return nil -} diff --git a/edgecenter/test/resource_edgecenter_servergroup_test.go b/edgecenter/test/resource_edgecenter_servergroup_test.go deleted file mode 100644 index e26dca83..00000000 --- a/edgecenter/test/resource_edgecenter_servergroup_test.go +++ /dev/null @@ -1,76 +0,0 @@ -//go:build cloud_resource - -package edgecenter_test - -import ( - "fmt" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/servergroup/v1/servergroups" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccServerGroupResource(t *testing.T) { - t.Parallel() - type Params struct { - Name string - Policy string - } - - create := Params{ - Name: "test", - Policy: servergroups.AntiAffinityPolicy.String(), - } - - resourceName := "edgecenter_servergroup.acctest" - - kpTemplate := func(params *Params) string { - return fmt.Sprintf(` - resource "edgecenter_servergroup" "acctest" { - %s - %s - name = "%s" - policy = "%s" - } - `, projectInfo(), regionInfo(), params.Name, params.Policy) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - CheckDestroy: testAccServerGroupDestroy, - Steps: []resource.TestStep{ - { - Config: kpTemplate(&create), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "name", create.Name), - resource.TestCheckResourceAttr(resourceName, "policy", create.Policy), - ), - }, - }, - }) -} - -func testAccServerGroupDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - client, err := createTestClient(config.Provider, edgecenter.ServerGroupsPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_servergroup" { - continue - } - - _, err := servergroups.Get(client, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("ServerGroup %s still exists", rs.Primary.ID) - } - } - - return nil -} diff --git a/edgecenter/test/resource_edgecenter_snapshot_test.go b/edgecenter/test/resource_edgecenter_snapshot_test.go deleted file mode 100644 index 860eaa2a..00000000 --- a/edgecenter/test/resource_edgecenter_snapshot_test.go +++ /dev/null @@ -1,124 +0,0 @@ -//go:build cloud_resource - -package edgecenter_test - -import ( - "fmt" - "os" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/volume/v1/volumes" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccSnapshot(t *testing.T) { - t.Parallel() - cfg, err := createTestConfig() - if err != nil { - t.Fatal(err) - } - - client, err := createTestClient(cfg.Provider, edgecenter.VolumesPoint, edgecenter.VersionPointV1) - if err != nil { - t.Fatal(err) - } - - opts := volumes.CreateOpts{ - Name: volumeTestName, - Size: volumeSizeTest, - Source: volumes.NewVolume, - TypeName: volumes.Standard, - } - - volumeID, err := createTestVolume(client, opts) - if err != nil { - t.Fatal(err) - } - - defer volumes.Delete(client, volumeID, volumes.DeleteOpts{}) - - type Params struct { - Name string - Description string - Status string - Size int - VolumeID string - } - - create := Params{ - Name: "test", - VolumeID: volumeID, - } - - update := Params{ - Name: "test", - VolumeID: volumeID, - } - - resourceName := "edgecenter_snapshot.acctest" - importStateIDPrefix := fmt.Sprintf("%s:%s:", os.Getenv("TEST_PROJECT_ID"), os.Getenv("TEST_REGION_ID")) - - SnapshotTemplate := func(params *Params) string { - additional := fmt.Sprintf("%s\n %s", regionInfo(), projectInfo()) - - template := fmt.Sprintf(` - resource "edgecenter_snapshot" "acctest" { - name = "%s" - volume_id = "%s" - %s - `, params.Name, params.VolumeID, additional) - - return template + "\n}" - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - CheckDestroy: testAccSnapshotDestroy, - Steps: []resource.TestStep{ - { - Config: SnapshotTemplate(&create), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "volume_id", create.VolumeID), - ), - }, - { - Config: SnapshotTemplate(&update), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "volume_id", update.VolumeID), - ), - }, - { - ImportStateIdPrefix: importStateIDPrefix, - ResourceName: resourceName, - ImportState: true, - }, - }, - }) -} - -func testAccSnapshotDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - client, err := createTestClient(config.Provider, edgecenter.SnapshotsPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_snapshot" { - continue - } - - _, err := networks.Get(client, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("snapshot still exists") - } - } - - return nil -} diff --git a/edgecenter/test/resource_edgecenter_storage_s3_bucket_test.go b/edgecenter/test/resource_edgecenter_storage_s3_bucket_test.go deleted file mode 100644 index fa81d738..00000000 --- a/edgecenter/test/resource_edgecenter_storage_s3_bucket_test.go +++ /dev/null @@ -1,81 +0,0 @@ -//go:build storage - -package edgecenter_test - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecenter-storage-sdk-go/swagger/client/storages" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccStorageS3Bucket(t *testing.T) { - t.Parallel() - random := time.Now().Nanosecond() - storageResourceName := fmt.Sprintf("edgecenter_storage_s3.terraform_test_%d_s3", random) - bucketResourceName := fmt.Sprintf("edgecenter_storage_s3_bucket.terraform_test_%d_s3_bucket", random) - name := fmt.Sprintf("terraform_test_%d", random) - - templateCreateBucket := func() string { - return fmt.Sprintf(` -resource "edgecenter_storage_s3" "terraform_test_%d_s3" { - name = "terraform_test_%d" - location = "s-ed1" -} - -resource "edgecenter_storage_s3_bucket" "terraform_test_%d_s3_bucket" { - name = "terraform_test_%d" - storage_id = %s.id -} - `, random, random, random, random, storageResourceName) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheckVars(t, EC_USERNAME_VAR, EC_PASSWORD_VAR, EC_STORAGE_URL_VAR) - }, - CheckDestroy: func(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_storage_s3" { - continue - } - opts := []func(opt *storages.StorageListHTTPV2Params){ - func(opt *storages.StorageListHTTPV2Params) { opt.Context = ctx }, - func(opt *storages.StorageListHTTPV2Params) { opt.ID = &rs.Primary.ID }, - } - storages, err := config.StorageClient.StoragesList(opts...) - if err != nil { - return fmt.Errorf("find storage: %w", err) - } - if len(storages) == 0 { - return nil - } - if storages[0].ProvisioningStatus == "ok" { - return fmt.Errorf("storage #%s wasn't deleted correctrly", rs.Primary.ID) - } - } - - return nil - }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: templateCreateBucket(), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(bucketResourceName), - resource.TestCheckResourceAttr(bucketResourceName, edgecenter.StorageS3BucketSchemaName, name), - ), - }, - }, - }) -} diff --git a/edgecenter/test/resource_edgecenter_storage_s3_test.go b/edgecenter/test/resource_edgecenter_storage_s3_test.go deleted file mode 100644 index 30a5f8a4..00000000 --- a/edgecenter/test/resource_edgecenter_storage_s3_test.go +++ /dev/null @@ -1,74 +0,0 @@ -//go:build storage - -package edgecenter_test - -import ( - "context" - "fmt" - "testing" - "time" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecenter-storage-sdk-go/swagger/client/storages" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccStorageS3(t *testing.T) { - t.Parallel() - random := time.Now().Nanosecond() - resourceName := fmt.Sprintf("edgecenter_storage_s3.terraform_test_%d_s3", random) - - templateCreate := func() string { - return fmt.Sprintf(` -resource "edgecenter_storage_s3" "terraform_test_%d_s3" { - name = "terraform_test_%d" - location = "s-ed1" -} - `, random, random) - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { - testAccPreCheckVars(t, EC_USERNAME_VAR, EC_PASSWORD_VAR, EC_STORAGE_URL_VAR) - }, - CheckDestroy: func(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) - defer cancel() - - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_storage_s3" { - continue - } - opts := []func(opt *storages.StorageListHTTPV2Params){ - func(opt *storages.StorageListHTTPV2Params) { opt.Context = ctx }, - func(opt *storages.StorageListHTTPV2Params) { opt.ID = &rs.Primary.ID }, - } - storages, err := config.StorageClient.StoragesList(opts...) - if err != nil { - return fmt.Errorf("find storage: %w", err) - } - if len(storages) == 0 { - return nil - } - if storages[0].ProvisioningStatus == "ok" { - return fmt.Errorf("storage #%s wasn't deleted correctrly", rs.Primary.ID) - } - } - - return nil - }, - ProviderFactories: testAccProviders, - Steps: []resource.TestStep{ - { - Config: templateCreate(), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, edgecenter.StorageSchemaLocation, "s-ed1"), - ), - }, - }, - }) -} diff --git a/edgecenter/test/resource_edgecenter_subnet_test.go b/edgecenter/test/resource_edgecenter_subnet_test.go deleted file mode 100644 index 2e519450..00000000 --- a/edgecenter/test/resource_edgecenter_subnet_test.go +++ /dev/null @@ -1,238 +0,0 @@ -//go:build cloud_resource - -package edgecenter_test - -import ( - "fmt" - "net" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccSubnet(t *testing.T) { - t.Parallel() - var dst1, dst2, cidr edgecloud.CIDR - - _, netIPNet, _ := net.ParseCIDR("10.0.3.0/24") - dst1.IP = netIPNet.IP - dst1.Mask = netIPNet.Mask - - _, netIPNet, _ = net.ParseCIDR("10.0.4.0/24") - dst2.IP = netIPNet.IP - dst2.Mask = netIPNet.Mask - - _, netIPNet, _ = net.ParseCIDR("192.168.10.0/24") - cidr.IP = netIPNet.IP - cidr.Mask = netIPNet.Mask - - createFixt := subnets.CreateOpts{ - Name: "create_subnet", - CIDR: cidr, - DNSNameservers: []net.IP{net.ParseIP("8.8.4.4"), net.ParseIP("1.1.1.1")}, - EnableDHCP: true, - HostRoutes: []subnets.HostRoute{ - { - Destination: dst1, - NextHop: net.ParseIP("192.168.10.1"), - }, - { - Destination: dst2, - NextHop: net.ParseIP("192.168.10.1"), - }, - }, - } - - gateway := net.ParseIP("disable") - - updateFixt := subnets.CreateOpts{ - Name: "update_subnet", - CIDR: cidr, - DNSNameservers: make([]net.IP, 0), - EnableDHCP: false, - HostRoutes: make([]subnets.HostRoute, 0), - GatewayIP: &gateway, - } - - type Params struct { - Name string - CIDR string - DNS []string - HRoutes []map[string]string - DHCP string - Gateway string - MetadataMap string - } - - create := Params{ - Name: "create_subnet", - CIDR: "192.168.10.0/24", - DNS: []string{"8.8.4.4", "1.1.1.1"}, - HRoutes: []map[string]string{ - {"destination": "10.0.3.0/24", "nexthop": "192.168.10.1"}, - {"destination": "10.0.4.0/24", "nexthop": "192.168.10.1"}, - }, - MetadataMap: `{ - key1 = "val1" - key2 = "val2" - }`, - } - - update := Params{ - Name: "update_subnet", - CIDR: "192.168.10.0/24", - DHCP: "false", - DNS: []string{}, - HRoutes: []map[string]string{}, - Gateway: "disable", - MetadataMap: `{ - key3 = "val3" - }`, - } - - SubnetTemplate := func(params *Params) string { - template := ` - locals { - dns_nameservers = [` - - for i := range params.DNS { - template += fmt.Sprintf(`"%s",`, params.DNS[i]) - } - - template += fmt.Sprint(`] - host_routes = [`) - - for i := range params.HRoutes { - template += fmt.Sprintf(` - { - destination = "%s" - nexthop = "%s" - },`, params.HRoutes[i]["destination"], params.HRoutes[i]["nexthop"]) - } - - template += fmt.Sprintf(`] - } - - resource "edgecenter_network" "acctest" { - name = "create_network" - type = "vxlan" - create_router = false - %[1]s - %[2]s - } - - resource "edgecenter_subnet" "acctest" { - name = "%s" - cidr = "%s" - network_id = edgecenter_network.acctest.id - dns_nameservers = local.dns_nameservers - connect_to_network_router = false - dynamic host_routes { - iterator = hr - for_each = local.host_routes - content { - destination = hr.value.destination - nexthop = hr.value.nexthop - } - } - metadata_map = %s - %[1]s - %[2]s - - - `, regionInfo(), projectInfo(), params.Name, params.CIDR, params.MetadataMap) - - if params.DHCP != "" { - template += fmt.Sprintf("enable_dhcp = %s\n", params.DHCP) - } - - if params.Gateway != "" { - template += fmt.Sprintf(`gateway_ip = "%s"`, params.Gateway) - } - - return template + "\n}" - } - - resourceName := "edgecenter_subnet.acctest" - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - CheckDestroy: testAccSubnetDestroy, - Steps: []resource.TestStep{ - { - Config: SubnetTemplate(&create), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - checkSubnetAttrs(resourceName, &createFixt), - testAccCheckMetadata(t, resourceName, true, map[string]interface{}{ - "key1": "val1", - "key2": "val2", - }), - ), - }, - { - Config: SubnetTemplate(&update), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - checkSubnetAttrs(resourceName, &updateFixt), - ), - }, - }, - }) -} - -func checkSubnetAttrs(resourceName string, opts *subnets.CreateOpts) resource.TestCheckFunc { - return func(s *terraform.State) error { - if s.Empty() == true { - return fmt.Errorf("State not updated") - } - - checksStore := []resource.TestCheckFunc{ - resource.TestCheckResourceAttr(resourceName, "name", opts.Name), - resource.TestCheckResourceAttr(resourceName, "cidr", opts.CIDR.String()), - resource.TestCheckResourceAttr(resourceName, "enable_dhcp", strconv.FormatBool(opts.EnableDHCP)), - resource.TestCheckResourceAttr(resourceName, "dns_nameservers.#", strconv.Itoa(len(opts.DNSNameservers))), - resource.TestCheckResourceAttr(resourceName, "host_routes.#", strconv.Itoa(len(opts.HostRoutes))), - } - - if opts.GatewayIP == nil && !opts.EnableDHCP { - checksStore = append(checksStore, resource.TestCheckResourceAttr(resourceName, "gateway_ip", "disable")) - } - - for i, hr := range opts.HostRoutes { - checksStore = append(checksStore, - resource.TestCheckResourceAttr(resourceName, fmt.Sprintf(`host_routes.%d.destination`, i), hr.Destination.String()), - resource.TestCheckResourceAttr(resourceName, fmt.Sprintf(`host_routes.%d.nexthop`, i), hr.NextHop.String()), - ) - } - - return resource.ComposeTestCheckFunc(checksStore...)(s) - } -} - -func testAccSubnetDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - client, err := createTestClient(config.Provider, edgecenter.SubnetPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_subnet" { - continue - } - - _, err := subnets.Get(client, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("subnet still exists") - } - } - - return nil -} diff --git a/edgecenter/test/resource_edgecenter_volume_test.go b/edgecenter/test/resource_edgecenter_volume_test.go deleted file mode 100644 index bedcda72..00000000 --- a/edgecenter/test/resource_edgecenter_volume_test.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build cloud_resource - -package edgecenter_test - -import ( - "fmt" - "os" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestAccVolume(t *testing.T) { - t.Parallel() - type Params struct { - Name string - Size int - Type string - Source string - SnapshotID string - ImageID string - } - - create := Params{ - Name: "test", - Size: 1, - Type: "standard", - } - - update := Params{ - Name: "test2", - Size: 2, - Type: "ssd_hiiops", - } - - resourceName := "edgecenter_volume.acctest" - importStateIDPrefix := fmt.Sprintf("%s:%s:", os.Getenv("TEST_PROJECT_ID"), os.Getenv("TEST_REGION_ID")) - - VolumeTemplate := func(params *Params) string { - additional := fmt.Sprintf("%s\n %s", regionInfo(), projectInfo()) - if params.SnapshotID != "" { - additional += fmt.Sprintf(`%s snapshot_id = "%s"`, "\n", params.SnapshotID) - } - if params.ImageID != "" { - additional += fmt.Sprintf(`%s image_id = "%s"`, "\n", params.ImageID) - } - - template := fmt.Sprintf(` - resource "edgecenter_volume" "acctest" { - name = "%s" - size = %d - type_name = "%s" - %s - `, params.Name, params.Size, params.Type, additional) - - return template + "\n}" - } - - resource.Test(t, resource.TestCase{ - PreCheck: func() { testAccPreCheck(t) }, - ProviderFactories: testAccProviders, - CheckDestroy: testAccVolumeDestroy, - Steps: []resource.TestStep{ - { - Config: VolumeTemplate(&create), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "size", strconv.Itoa(create.Size)), - resource.TestCheckResourceAttr(resourceName, "type_name", create.Type), - resource.TestCheckResourceAttr(resourceName, "name", create.Name), - ), - }, - { - Config: VolumeTemplate(&update), - Check: resource.ComposeTestCheckFunc( - testAccCheckResourceExists(resourceName), - resource.TestCheckResourceAttr(resourceName, "size", strconv.Itoa(update.Size)), - resource.TestCheckResourceAttr(resourceName, "type_name", update.Type), - resource.TestCheckResourceAttr(resourceName, "name", update.Name), - ), - }, - { - ImportStateIdPrefix: importStateIDPrefix, - ResourceName: resourceName, - ImportState: true, - }, - }, - }) -} - -func testAccVolumeDestroy(s *terraform.State) error { - config := testAccProvider.Meta().(*edgecenter.Config) - client, err := createTestClient(config.Provider, edgecenter.VolumesPoint, edgecenter.VersionPointV1) - if err != nil { - return err - } - for _, rs := range s.RootModule().Resources { - if rs.Type != "edgecenter_volume" { - continue - } - - _, err := networks.Get(client, rs.Primary.ID).Extract() - if err == nil { - return fmt.Errorf("volume still exists") - } - } - - return nil -} diff --git a/edgecenter/test/utils_metadata_test.go b/edgecenter/test/utils_metadata_test.go deleted file mode 100644 index f44f7193..00000000 --- a/edgecenter/test/utils_metadata_test.go +++ /dev/null @@ -1,141 +0,0 @@ -//go:build cloud_data_source || cloud_resource - -package edgecenter_test - -import ( - "fmt" - "reflect" - "strconv" - "testing" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource" - "github.com/hashicorp/terraform-plugin-sdk/v2/terraform" -) - -func normalizeMetadata(metadata interface{}, defaults ...bool) (map[string]interface{}, error) { - normalizedMetadata := map[string]interface{}{} - readOnly := false - - if len(defaults) > 0 { - readOnly = defaults[0] - } - - switch metadata := metadata.(type) { - default: - return nil, fmt.Errorf("unexpected type %T", metadata) - case []map[string]interface{}: - for _, v := range metadata { - normalizedMetadata[v["key"].(string)] = v - } - case map[string]interface{}: - for k, v := range metadata { - normalizedMetadata[k] = map[string]interface{}{ - "key": k, - "value": v, - "read_only": readOnly, - } - } - case map[string]string: - for k, v := range metadata { - normalizedMetadata[k] = map[string]interface{}{ - "key": k, - "value": v, - "read_only": readOnly, - } - } - } - - return normalizedMetadata, nil -} - -func modulePrimaryInstanceState(ms *terraform.ModuleState, name string) (*terraform.InstanceState, error) { - rs, ok := ms.Resources[name] - if !ok { - return nil, fmt.Errorf("not found: %s in %s", name, ms.Path) - } - - is := rs.Primary - if is == nil { - return nil, fmt.Errorf("no primary instance: %s in %s", name, ms.Path) - } - - return is, nil -} - -func getMetadataFromResourceAttributes(prefix string, attributes *map[string]string) ([]map[string]interface{}, error) { - metadataLength, err := strconv.Atoi((*attributes)[prefix+".#"]) - if err != nil { - return nil, err - } - metadata := make([]map[string]interface{}, metadataLength) - buildKey := func(idx int, name string) string { - return fmt.Sprintf("%v.%v.%v", prefix, idx, name) - } - - for i := 0; i < metadataLength; i++ { - readOnly, err := strconv.ParseBool((*attributes)[buildKey(i, "read_only")]) - if err != nil { - return nil, err - } - metadata[i] = map[string]interface{}{ - "key": (*attributes)[buildKey(i, "key")], - "value": (*attributes)[buildKey(i, "value")], - "read_only": readOnly, - } - } - - return metadata, nil -} - -func checkMapInMap(srcMap map[string]interface{}, dstMap map[string]interface{}) bool { - if len(srcMap) > len(dstMap) { - return false - } - if len(srcMap) == len(dstMap) { - return reflect.DeepEqual(srcMap, dstMap) - } - slicedMap := make(map[string]interface{}, len(srcMap)) - - for k := range srcMap { - if val, ok := dstMap[k]; ok { - slicedMap[k] = val - } else { - return false - } - } - - return reflect.DeepEqual(srcMap, slicedMap) -} - -func testAccCheckMetadata(t *testing.T, name string, isMetaExists bool, metadataForCheck interface{}) resource.TestCheckFunc { - t.Helper() - return func(s *terraform.State) error { - // retrieve the resource by name from state - ms := s.RootModule() - is, err := modulePrimaryInstanceState(ms, name) - if err != nil { - return err - } - - instanceMetadata, err := getMetadataFromResourceAttributes("metadata_read_only", &is.Attributes) - if err != nil { - return err - } - - mt1, err := normalizeMetadata(metadataForCheck) - if err != nil { - return err - } - - mt2, err := normalizeMetadata(instanceMetadata) - if err != nil { - return err - } - - if !(checkMapInMap(mt1, mt2) == isMetaExists) { - return fmt.Errorf("metadata not exist") - } - - return nil - } -} diff --git a/edgecenter/test/utils_test.go b/edgecenter/test/utils_test.go deleted file mode 100644 index acb35537..00000000 --- a/edgecenter/test/utils_test.go +++ /dev/null @@ -1,67 +0,0 @@ -package edgecenter_test - -import ( - "testing" - - "github.com/Edge-Center/terraform-provider-edgecenter/edgecenter" -) - -func TestExtractHostAndPath(t *testing.T) { - t.Parallel() - - type args struct { - uri string - } - tests := []struct { - name string - args args - wantHost string - wantPath string - wantErr bool - }{ - { - name: "long url success", - args: args{ - uri: "https://test.url/with/path", - }, - wantHost: "https://test.url", - wantPath: "/with/path", - wantErr: false, - }, - { - name: "short url success", - args: args{ - uri: "https://test.url", - }, - wantHost: "https://test.url", - wantPath: "", - wantErr: false, - }, - { - name: "error on empty", - args: args{ - uri: "", - }, - wantHost: "", - wantPath: "", - wantErr: true, - }, - } - for _, tt := range tests { - tt := tt - t.Run(tt.name, func(t *testing.T) { - t.Parallel() - gotHost, gotPath, err := edgecenter.ExtractHostAndPath(tt.args.uri) - if (err != nil) != tt.wantErr { - t.Errorf("ExtractHostAndPath() error = %v, wantErr %v", err, tt.wantErr) - return - } - if gotHost != tt.wantHost { - t.Errorf("ExtractHostAndPath() gotHost = %v, want %v", gotHost, tt.wantHost) - } - if gotPath != tt.wantPath { - t.Errorf("ExtractHostAndPath() gotPath = %v, want %v", gotPath, tt.wantPath) - } - }) - } -} diff --git a/edgecenter/utils.go b/edgecenter/utils.go deleted file mode 100644 index 0a667a25..00000000 --- a/edgecenter/utils.go +++ /dev/null @@ -1,137 +0,0 @@ -package edgecenter - -import ( - "fmt" - "log" - "net/url" - "strconv" - "strings" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/mitchellh/mapstructure" - - dnsSDK "github.com/Edge-Center/edgecenter-dns-sdk-go" - storageSDK "github.com/Edge-Center/edgecenter-storage-sdk-go" - cdn "github.com/Edge-Center/edgecentercdn-go" - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter" -) - -const ( - VersionPointV1 = "v1" - VersionPointV2 = "v2" - - ProjectPoint = "projects" - RegionPoint = "regions" -) - -type Config struct { - Provider *edgecloud.ProviderClient - CDNClient cdn.ClientService - StorageClient *storageSDK.SDK - DNSClient *dnsSDK.Client -} - -// MapStructureDecoder decodes the given map into the provided structure using the specified decoder configuration. -func MapStructureDecoder(strct interface{}, v *map[string]interface{}, config *mapstructure.DecoderConfig) error { - config.Result = strct - decoder, err := mapstructure.NewDecoder(config) - if err != nil { - return fmt.Errorf("failed to create decoder: %w", err) - } - - return decoder.Decode(*v) -} - -// ImportStringParser parses a string containing project ID, region ID, and another field, -// and returns them as separate values along with any error encountered. -func ImportStringParser(infoStr string) (projectID int, regionID int, id3 string, err error) { //nolint: nonamedreturns - log.Printf("[DEBUG] Input id string: %s", infoStr) - infoStrings := strings.Split(infoStr, ":") - if len(infoStrings) != 3 { - err = fmt.Errorf("failed import: wrong input id: %s", infoStr) - return - } - - id1, id2, id3 := infoStrings[0], infoStrings[1], infoStrings[2] - - projectID, err = strconv.Atoi(id1) - if err != nil { - return - } - regionID, err = strconv.Atoi(id2) - if err != nil { - return - } - - return -} - -// CreateClient creates a new edgecloud.ServiceClient. -func CreateClient(provider *edgecloud.ProviderClient, d *schema.ResourceData, endpoint string, version string) (*edgecloud.ServiceClient, error) { - projectID, err := GetProject(provider, d.Get("project_id").(int), d.Get("project_name").(string)) - if err != nil { - return nil, err - } - - regionID := 0 - - rawRegionID := d.Get("region_id") - rawRegionName := d.Get("region_name") - if rawRegionID != nil && rawRegionName != nil { - regionID, err = GetRegion(provider, rawRegionID.(int), rawRegionName.(string)) - if err != nil { - return nil, fmt.Errorf("failed to get region: %w", err) - } - } - - client, err := edgecenter.ClientServiceFromProvider(provider, edgecloud.EndpointOpts{ - Name: endpoint, - Region: regionID, - Project: projectID, - Version: version, - }) - if err != nil { - return nil, fmt.Errorf("failed to create client: %w", err) - } - - return client, nil -} - -// revertState reverts the state of the specified fields in the given schema.ResourceData if "last_updated" is not empty. -// It takes a schema.ResourceData and a slice of strings containing the field names to be reverted as input arguments. -func revertState(d *schema.ResourceData, fields *[]string) { - if d.Get("last_updated").(string) != "" { - for _, field := range *fields { - if d.HasChange(field) { - oldValue, _ := d.GetChange(field) - switch v := oldValue.(type) { - case int: - d.Set(field, v) - case string: - d.Set(field, v) - case map[string]interface{}: - d.Set(field, v) - } - } - log.Printf("[DEBUG] Revert (%s) '%s' field", d.Id(), field) - } - } -} - -// ExtractHostAndPath splits a given URI into the host and path components. -func ExtractHostAndPath(uri string) (string, string, error) { - var host, path string - if uri == "" { - return host, path, fmt.Errorf("empty uri") - } - - pURL, err := url.Parse(uri) - if err != nil { - return host, path, fmt.Errorf("url parse: %w", err) - } - host = pURL.Scheme + "://" + pURL.Host - path = pURL.Path - - return host, path, nil -} diff --git a/edgecenter/utils_instance.go b/edgecenter/utils_instance.go deleted file mode 100644 index 9d9a6ca3..00000000 --- a/edgecenter/utils_instance.go +++ /dev/null @@ -1,527 +0,0 @@ -package edgecenter - -import ( - "crypto/md5" - "encoding/binary" - "errors" - "fmt" - "io" - "log" - "reflect" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/retry" - "github.com/mitchellh/mapstructure" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/instances" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/instance/v1/types" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/securitygroups" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/servergroup/v1/servergroups" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/task/v1/tasks" -) - -var instanceDecoderConfig = &mapstructure.DecoderConfig{ - TagName: "json", -} - -type instanceInterfaces []interface{} - -func (s instanceInterfaces) Len() int { - return len(s) -} - -func (s instanceInterfaces) Less(i, j int) bool { - ifLeft := s[i].(map[string]interface{}) - ifRight := s[j].(map[string]interface{}) - - // only bm instance has a parent interface, and it should be attached first - isTrunkLeft, okLeft := ifLeft["is_parent"] - isTrunkRight, okRight := ifRight["is_parent"] - if okLeft && okRight { - left, _ := isTrunkLeft.(bool) - right, _ := isTrunkRight.(bool) - switch { - case left && !right: - return true - case right && !left: - return false - } - } - - lOrder, _ := ifLeft["order"].(int) - rOrder, _ := ifRight["order"].(int) - - return lOrder < rOrder -} - -func (s instanceInterfaces) Swap(i, j int) { - s[i], s[j] = s[j], s[i] -} - -type OrderedInterfaceOpts struct { - instances.InterfaceOpts - Order int -} - -// decodeInstanceInterfaceOpts decodes the interface and returns InterfaceOpts with FloatingIP. -func decodeInstanceInterfaceOpts(iFaceMap map[string]interface{}) (instances.InterfaceOpts, error) { - var interfaceOpts instances.InterfaceOpts - err := MapStructureDecoder(&interfaceOpts, &iFaceMap, instanceDecoderConfig) - if err != nil { - return interfaceOpts, err - } - - if fipSource := iFaceMap["fip_source"].(string); fipSource != "" { - var fip instances.CreateNewInterfaceFloatingIPOpts - if existingFipID := iFaceMap["existing_fip_id"].(string); existingFipID != "" { - fip.Source = types.ExistingFloatingIP - fip.ExistingFloatingID = existingFipID - } else { - fip.Source = types.NewFloatingIP - } - interfaceOpts.FloatingIP = &fip - } - - return interfaceOpts, nil -} - -// extractInstanceInterfaceToListCreate creates a list of InterfaceInstanceCreateOpts objects from a list of interfaces. -func extractInstanceInterfaceToListCreate(interfaces []interface{}) ([]instances.InterfaceInstanceCreateOpts, error) { - interfaceInstanceCreateOptsList := make([]instances.InterfaceInstanceCreateOpts, 0) - for _, iFace := range interfaces { - iFaceMap := iFace.(map[string]interface{}) - - interfaceOpts, err := decodeInstanceInterfaceOpts(iFaceMap) - if err != nil { - return nil, err - } - - rawSgsID := iFaceMap["security_groups"].([]interface{}) - sgs := make([]edgecloud.ItemID, len(rawSgsID)) - for i, sgID := range rawSgsID { - sgs[i] = edgecloud.ItemID{ID: sgID.(string)} - } - - interfaceInstanceCreateOpts := instances.InterfaceInstanceCreateOpts{ - InterfaceOpts: interfaceOpts, - SecurityGroups: sgs, - } - interfaceInstanceCreateOptsList = append(interfaceInstanceCreateOptsList, interfaceInstanceCreateOpts) - } - - return interfaceInstanceCreateOptsList, nil -} - -// extractInstanceInterfaceToListRead creates a list of InterfaceOpts objects from a list of interfaces. -func extractInstanceInterfaceToListRead(interfaces []interface{}) ([]instances.InterfaceOpts, error) { - interfaceOptsList := make([]instances.InterfaceOpts, 0) - for _, iFace := range interfaces { - if iFace == nil { - continue - } - - iFaceMap := iFace.(map[string]interface{}) - interfaceOpts, err := decodeInstanceInterfaceOpts(iFaceMap) - if err != nil { - return nil, err - } - interfaceOptsList = append(interfaceOptsList, interfaceOpts) - } - - return interfaceOptsList, nil -} - -// extractMetadataMap converts a map of metadata into a metadata set options structure. -func extractMetadataMap(metadata map[string]interface{}) instances.MetadataSetOpts { - result := make([]instances.MetadataOpts, 0, len(metadata)) - for k, v := range metadata { - result = append(result, instances.MetadataOpts{Key: k, Value: v.(string)}) - } - return instances.MetadataSetOpts{Metadata: result} -} - -// extractInstanceVolumesMap converts a slice of instance volumes into a map of volume IDs to boolean values. -func extractInstanceVolumesMap(volumes []interface{}) map[string]bool { - result := make(map[string]bool) - for _, volume := range volumes { - v := volume.(map[string]interface{}) - result[v["volume_id"].(string)] = true - } - return result -} - -// extractVolumesIntoMap converts a slice of volumes into a map with volume_id as the key. -func extractVolumesIntoMap(volumes []interface{}) map[string]map[string]interface{} { - result := make(map[string]map[string]interface{}, len(volumes)) - for _, volume := range volumes { - vol := volume.(map[string]interface{}) - result[vol["volume_id"].(string)] = vol - } - return result -} - -// extractKeyValue takes a slice of metadata interfaces and converts it into an instances.MetadataSetOpts structure. -func extractKeyValue(metadata []interface{}) (instances.MetadataSetOpts, error) { - metaData := make([]instances.MetadataOpts, len(metadata)) - var metadataSetOpts instances.MetadataSetOpts - for i, meta := range metadata { - md := meta.(map[string]interface{}) - var MD instances.MetadataOpts - err := MapStructureDecoder(&MD, &md, instanceDecoderConfig) - if err != nil { - return metadataSetOpts, err - } - metaData[i] = MD - } - metadataSetOpts.Metadata = metaData - - return metadataSetOpts, nil -} - -// volumeUniqueID generates a unique ID for a volume based on its volume_id attribute. -func volumeUniqueID(i interface{}) int { - e := i.(map[string]interface{}) - h := md5.New() - io.WriteString(h, e["volume_id"].(string)) - return int(binary.BigEndian.Uint64(h.Sum(nil))) -} - -// isInterfaceAttached checks if an interface is attached to a list of instances.Interface objects based on the subnet ID or external interface type. -func isInterfaceAttached(ifs []instances.Interface, ifs2 map[string]interface{}) bool { - subnetID, _ := ifs2["subnet_id"].(string) - iType := types.InterfaceType(ifs2["type"].(string)) - for _, i := range ifs { - if iType == types.ExternalInterfaceType && i.NetworkDetails.External { - return true - } - for _, assignment := range i.IPAssignments { - if assignment.SubnetID == subnetID { - return true - } - } - for _, subPort := range i.SubPorts { - if iType == types.ExternalInterfaceType && subPort.NetworkDetails.External { - return true - } - for _, assignment := range subPort.IPAssignments { - if assignment.SubnetID == subnetID { - return true - } - } - } - } - - return false -} - -// extractVolumesMap takes a slice of volume interfaces and converts it into a slice of instances.CreateVolumeOpts. -func extractVolumesMap(volumes []interface{}) ([]instances.CreateVolumeOpts, error) { - vols := make([]instances.CreateVolumeOpts, len(volumes)) - for i, volume := range volumes { - vol := volume.(map[string]interface{}) - var V instances.CreateVolumeOpts - err := MapStructureDecoder(&V, &vol, instanceDecoderConfig) - if err != nil { - return nil, err - } - vols[i] = V - } - - return vols, nil -} - -// isInterfaceContains checks if a given verifiable interface is present in the provided set of interfaces (ifsSet). -func isInterfaceContains(verifiable map[string]interface{}, ifsSet []interface{}) bool { - verifiableType := verifiable["type"].(string) - verifiableSubnetID, _ := verifiable["subnet_id"].(string) - for _, e := range ifsSet { - i := e.(map[string]interface{}) - iType := i["type"].(string) - subnetID, _ := i["subnet_id"].(string) - if iType == types.ExternalInterfaceType.String() && verifiableType == types.ExternalInterfaceType.String() { - return true - } - - if iType == verifiableType && subnetID == verifiableSubnetID { - return true - } - } - - return false -} - -// ServerV2StateRefreshFunc returns a StateRefreshFunc to track the state of an instance using its instanceID. -func ServerV2StateRefreshFunc(client *edgecloud.ServiceClient, instanceID string) retry.StateRefreshFunc { - return func() (interface{}, string, error) { - s, err := instances.Get(client, instanceID).Extract() - if err != nil { - var errDefault404 edgecloud.Default404Error - if errors.As(err, &errDefault404) { - return s, "DELETED", nil - } - return nil, "", err - } - - return s, s.VMState, nil - } -} - -// findInstancePort searches for the instance port with the specified portID in the given list of instance ports. -func findInstancePort(portID string, ports []instances.InstancePorts) (instances.InstancePorts, error) { - for _, port := range ports { - if port.ID == portID { - return port, nil - } - } - - return instances.InstancePorts{}, fmt.Errorf("port not found") -} - -// contains check if slice contains the element. -func contains[K comparable](slice []K, elm K) bool { - for _, s := range slice { - if s == elm { - return true - } - } - return false -} - -// getMapDifference compares two maps and returns a map of only different values. -// uncheckedKeys - list of keys to skip when comparing. -func getMapDifference(iMapOld, iMapNew map[string]interface{}, uncheckedKeys []string) map[string]interface{} { - differentFields := make(map[string]interface{}) - - for oldMapK, oldMapV := range iMapOld { - if contains(uncheckedKeys, oldMapK) { - continue - } - - if newMapV, ok := iMapNew[oldMapK]; !ok || !reflect.DeepEqual(newMapV, oldMapV) { - differentFields[oldMapK] = oldMapV - } - } - - for newMapK, newMapV := range iMapNew { - if contains(uncheckedKeys, newMapK) { - continue - } - - if _, ok := iMapOld[newMapK]; !ok { - differentFields[newMapK] = newMapV - } - } - - return differentFields -} - -// detachInterfaceFromInstance detaches interface from an instance. -func detachInterfaceFromInstance(client *edgecloud.ServiceClient, instanceID string, iface map[string]interface{}) error { - var opts instances.InterfaceOpts - opts.PortID = iface["port_id"].(string) - opts.IPAddress = iface["ip_address"].(string) - - log.Printf("[DEBUG] detach interface: %+v", opts) - results, err := instances.DetachInterface(client, instanceID, opts).Extract() - if err != nil { - return err - } - - err = tasks.WaitTaskAndProcessResult(client, results.Tasks[0], true, InstanceCreatingTimeout, func(task tasks.TaskID) error { - if taskInfo, err := tasks.Get(client, string(task)).Extract(); err != nil { - return fmt.Errorf("cannot get task with ID: %s. Error: %w, task: %+v", task, err, taskInfo) - } - return nil - }) - if err != nil { - return err - } - - return nil -} - -// attachInterfaceToInstance attach interface to instance. -func attachInterfaceToInstance(instanceClient *edgecloud.ServiceClient, instanceID string, iface map[string]interface{}) error { - iType := types.InterfaceType(iface["type"].(string)) - opts := instances.InterfaceInstanceCreateOpts{ - InterfaceOpts: instances.InterfaceOpts{Type: iType}, - } - - switch iType { //nolint: exhaustive - case types.SubnetInterfaceType: - opts.SubnetID = iface["subnet_id"].(string) - case types.AnySubnetInterfaceType: - opts.NetworkID = iface["network_id"].(string) - case types.ReservedFixedIPType: - opts.PortID = iface["port_id"].(string) - } - opts.SecurityGroups = getSecurityGroupsIDs(iface["security_groups"].([]interface{})) - - log.Printf("[DEBUG] attach interface: %+v", opts) - results, err := instances.AttachInterface(instanceClient, instanceID, opts).Extract() - if err != nil { - return fmt.Errorf("cannot attach interface: %s. Error: %w", iType, err) - } - - err = tasks.WaitTaskAndProcessResult(instanceClient, results.Tasks[0], true, InstanceCreatingTimeout, func(task tasks.TaskID) error { - taskInfo, err := tasks.Get(instanceClient, string(task)).Extract() - if err != nil { - return fmt.Errorf("cannot get task with ID: %s. Error: %w, task: %+v", task, err, taskInfo) - } - - if _, err := instances.ExtractInstancePortIDFromTask(taskInfo); err != nil { - reservedFixedIPID, ok := (*taskInfo.Data)["reserved_fixed_ip_id"] - if !ok || reservedFixedIPID.(string) == "" { - return fmt.Errorf("cannot retrieve instance port ID from task info: %w", err) - } - } - - return nil - }) - if err != nil { - return err - } - - return nil -} - -// deleteServerGroup removes a server group from an instance. -func deleteServerGroup(sgClient, instanceClient *edgecloud.ServiceClient, instanceID, sgID string) error { - log.Printf("[DEBUG] remove server group from instance: %s", instanceID) - results, err := instances.RemoveServerGroup(instanceClient, instanceID).Extract() - if err != nil { - return fmt.Errorf("failed to remove server group %s from instance %s: %w", sgID, instanceID, err) - } - - err = tasks.WaitTaskAndProcessResult(sgClient, results.Tasks[0], true, InstanceCreatingTimeout, func(task tasks.TaskID) error { - sgInfo, err := servergroups.Get(sgClient, sgID).Extract() - if err != nil { - return fmt.Errorf("failed to get server group %s: %w", sgID, err) - } - for _, instanceInfo := range sgInfo.Instances { - if instanceInfo.InstanceID == instanceID { - return fmt.Errorf("server group %s was not removed from instance %s", sgID, instanceID) - } - } - return nil - }) - - if err != nil { - return err - } - - return nil -} - -// addServerGroup adds a server group to an instance. -func addServerGroup(sgClient, instanceClient *edgecloud.ServiceClient, instanceID, sgID string) error { - log.Printf("[DEBUG] add server group to instance: %s", instanceID) - results, err := instances.AddServerGroup(instanceClient, instanceID, instances.ServerGroupOpts{ServerGroupID: sgID}).Extract() - if err != nil { - return fmt.Errorf("failed to add server group %s to instance %s: %w", sgID, instanceID, err) - } - - err = tasks.WaitTaskAndProcessResult(sgClient, results.Tasks[0], true, InstanceCreatingTimeout, func(task tasks.TaskID) error { - sgInfo, err := servergroups.Get(sgClient, sgID).Extract() - if err != nil { - return fmt.Errorf("cannot get server group with ID: %s. Error: %w", sgID, err) - } - for _, instanceInfo := range sgInfo.Instances { - if instanceInfo.InstanceID == instanceID { - return nil - } - } - return fmt.Errorf("the server group: %s was not added to the instance: %s. Error: %w", sgID, instanceID, err) - }) - - if err != nil { - return err - } - - return nil -} - -// removeSecurityGroupFromInstance removes one or more security groups from a specific instance port. -func removeSecurityGroupFromInstance(sgClient, instanceClient *edgecloud.ServiceClient, instanceID, portID string, removeSGs []edgecloud.ItemID) error { - for _, sg := range removeSGs { - sgInfo, err := securitygroups.Get(sgClient, sg.ID).Extract() - if err != nil { - return err - } - - portSGNames := instances.PortSecurityGroupNames{PortID: &portID, SecurityGroupNames: []string{sgInfo.Name}} - sgOpts := instances.SecurityGroupOpts{PortsSecurityGroupNames: []instances.PortSecurityGroupNames{portSGNames}} - - log.Printf("[DEBUG] remove security group opts: %+v", sgOpts) - if err := instances.UnAssignSecurityGroup(instanceClient, instanceID, sgOpts).Err; err != nil { - return fmt.Errorf("cannot remove security group. Error: %w", err) - } - } - - return nil -} - -// attachSecurityGroupToInstance attaches one or more security groups to a specific instance port. -func attachSecurityGroupToInstance(sgClient, instanceClient *edgecloud.ServiceClient, instanceID, portID string, addSGs []edgecloud.ItemID) error { - for _, sg := range addSGs { - sgInfo, err := securitygroups.Get(sgClient, sg.ID).Extract() - if err != nil { - return err - } - - portSGNames := instances.PortSecurityGroupNames{PortID: &portID, SecurityGroupNames: []string{sgInfo.Name}} - sgOpts := instances.SecurityGroupOpts{PortsSecurityGroupNames: []instances.PortSecurityGroupNames{portSGNames}} - - log.Printf("[DEBUG] attach security group opts: %+v", sgOpts) - if err := instances.AssignSecurityGroup(instanceClient, instanceID, sgOpts).Err; err != nil { - return fmt.Errorf("cannot attach security group. Error: %w", err) - } - } - - return nil -} - -// prepareSecurityGroups prepares a list of unique security groups assigned to all instance ports. -func prepareSecurityGroups(ports []instances.InstancePorts) []interface{} { - securityGroups := make(map[string]bool) - for _, port := range ports { - for _, sg := range port.SecurityGroups { - securityGroups[sg.ID] = true - } - } - - result := make([]interface{}, 0, len(securityGroups)) - for sgID := range securityGroups { - result = append(result, map[string]interface{}{ - "id": sgID, - "name": "", - }) - } - - return result -} - -// getSecurityGroupsIDs converts a slice of raw security group IDs to a slice of edgecloud.ItemID. -func getSecurityGroupsIDs(sgsRaw []interface{}) []edgecloud.ItemID { - sgs := make([]edgecloud.ItemID, len(sgsRaw)) - for i, sgID := range sgsRaw { - sgs[i] = edgecloud.ItemID{ID: sgID.(string)} - } - return sgs -} - -// getSecurityGroupsDifference finds the difference between two slices of edgecloud.ItemID. -func getSecurityGroupsDifference(sl1, sl2 []edgecloud.ItemID) (diff []edgecloud.ItemID) { //nolint: nonamedreturns - set := make(map[string]bool) - for _, item := range sl1 { - set[item.ID] = true - } - - for _, item := range sl2 { - if !set[item.ID] { - diff = append(diff, item) - } - } - - return diff -} diff --git a/edgecenter/utils_k8s.go b/edgecenter/utils_k8s.go deleted file mode 100644 index f53d77bd..00000000 --- a/edgecenter/utils_k8s.go +++ /dev/null @@ -1,61 +0,0 @@ -package edgecenter - -import ( - "net" - - "gopkg.in/yaml.v3" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" -) - -func parseCIDRFromString(cidr string) (edgecloud.CIDR, error) { - var ecCIDR edgecloud.CIDR - _, netIPNet, err := net.ParseCIDR(cidr) - if err != nil { - return ecCIDR, err - } - ecCIDR.IP = netIPNet.IP - ecCIDR.Mask = netIPNet.Mask - - return ecCIDR, nil -} - -type K8sConfig struct { - APIVersion string `yaml:"apiVersion"` - Kind string `yaml:"kind"` - CurrentContext string `yaml:"current-context"` // nolint: tagliatelle - Preferences struct{} `yaml:"preferences"` - - Clusters []struct { - Name string `yaml:"name"` - Cluster struct { - CertificateAuthorityData string `yaml:"certificate-authority-data"` // nolint: tagliatelle - Server string `yaml:"server"` - } `yaml:"cluster"` - } `yaml:"clusters"` - - Contexts []struct { - Name string `yaml:"name"` - Context struct { - Cluster string `yaml:"cluster"` - User string `yaml:"user"` - } `yaml:"context"` - } `yaml:"contexts"` - - Users []struct { - Name string `yaml:"name"` - User struct { - ClientCertificateData string `yaml:"client-certificate-data"` // nolint: tagliatelle - ClientKeyData string `yaml:"client-key-data"` // nolint: tagliatelle - } `yaml:"user"` - } `yaml:"users"` -} - -func parseK8sConfig(data string) (*K8sConfig, error) { - var config K8sConfig - err := yaml.Unmarshal([]byte(data), &config) - if err != nil { - return nil, err - } - return &config, nil -} diff --git a/edgecenter/utils_loadbalancer.go b/edgecenter/utils_loadbalancer.go deleted file mode 100644 index ce46da07..00000000 --- a/edgecenter/utils_loadbalancer.go +++ /dev/null @@ -1,121 +0,0 @@ -package edgecenter - -import ( - "fmt" - "log" - "strconv" - "strings" - - "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/lbpools" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/listeners" - typesLb "github.com/Edge-Center/edgecentercloud-go/edgecenter/loadbalancer/v1/types" -) - -// ImportStringParserExtended parses a string containing project ID, region ID, and two other fields, -// and returns them as separate values along with any error encountered. -func ImportStringParserExtended(infoStr string) (projectID int, regionID int, id3 string, id4 string, err error) { //nolint: nonamedreturns - log.Printf("[DEBUG] Input id string: %s", infoStr) - infoStrings := strings.Split(infoStr, ":") - if len(infoStrings) != 4 { - err = fmt.Errorf("failed import: wrong input id: %s", infoStr) - return - } - - id1, id2, id3, id4 := infoStrings[0], infoStrings[1], infoStrings[2], infoStrings[3] - - projectID, err = strconv.Atoi(id1) - if err != nil { - return - } - regionID, err = strconv.Atoi(id2) - if err != nil { - return - } - - return -} - -// extractSessionPersistenceMap creates a session persistence options struct from the data in the given ResourceData. -func extractSessionPersistenceMap(d *schema.ResourceData) *lbpools.CreateSessionPersistenceOpts { - var sessionOpts *lbpools.CreateSessionPersistenceOpts - sessionPersistence := d.Get("session_persistence").([]interface{}) - if len(sessionPersistence) > 0 { - sm := sessionPersistence[0].(map[string]interface{}) - sessionOpts = &lbpools.CreateSessionPersistenceOpts{ - Type: typesLb.PersistenceType(sm["type"].(string)), - } - - granularity, ok := sm["persistence_granularity"].(string) - if ok { - sessionOpts.PersistenceGranularity = granularity - } - - timeout, ok := sm["persistence_timeout"].(int) - if ok { - sessionOpts.PersistenceTimeout = timeout - } - - cookieName, ok := sm["cookie_name"].(string) - if ok { - sessionOpts.CookieName = cookieName - } - } - - return sessionOpts -} - -// extractHealthMonitorMap creates a health monitor options struct from the data in the given ResourceData. -func extractHealthMonitorMap(d *schema.ResourceData) *lbpools.CreateHealthMonitorOpts { - var healthOpts *lbpools.CreateHealthMonitorOpts - monitors := d.Get("health_monitor").([]interface{}) - if len(monitors) > 0 { - hm := monitors[0].(map[string]interface{}) - healthOpts = &lbpools.CreateHealthMonitorOpts{ - Type: typesLb.HealthMonitorType(hm["type"].(string)), - Delay: hm["delay"].(int), - MaxRetries: hm["max_retries"].(int), - Timeout: hm["timeout"].(int), - } - - maxRetriesDown := hm["max_retries_down"].(int) - if maxRetriesDown != 0 { - healthOpts.MaxRetriesDown = maxRetriesDown - } - - httpMethod := hm["http_method"].(string) - if httpMethod != "" { - healthOpts.HTTPMethod = typesLb.HTTPMethodPointer(typesLb.HTTPMethod(httpMethod)) - } - - urlPath := hm["url_path"].(string) - if urlPath != "" { - healthOpts.URLPath = urlPath - } - - expectedCodes := hm["expected_codes"].(string) - if expectedCodes != "" { - healthOpts.ExpectedCodes = expectedCodes - } - - id := hm["id"].(string) - if id != "" { - healthOpts.ID = id - } - } - - return healthOpts -} - -// extractListenerIntoMap converts a listener object into a map. -func extractListenerIntoMap(listener *listeners.Listener) map[string]interface{} { - l := make(map[string]interface{}) - l["id"] = listener.ID - l["name"] = listener.Name - l["protocol"] = listener.Protocol.String() - l["protocol_port"] = listener.ProtocolPort - l["secret_id"] = listener.SecretID - l["sni_secret_id"] = listener.SNISecretID - return l -} diff --git a/edgecenter/utils_network.go b/edgecenter/utils_network.go deleted file mode 100644 index e89c2219..00000000 --- a/edgecenter/utils_network.go +++ /dev/null @@ -1,90 +0,0 @@ -package edgecenter - -import ( - "encoding/json" - "net" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/availablenetworks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/network/v1/networks" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" -) - -// findNetworkByName searches for a network with the given name among the given networks. -// Returns the found network and a flag indicating the success of the search. -func findNetworkByName(name string, nets []networks.Network) (networks.Network, bool) { - for _, n := range nets { - if n.Name == name { - return n, true - } - } - return networks.Network{}, false -} - -// findSharedNetworkByName searches for a shared network with the given name among the given networks. -// Returns the found network and a flag indicating the success of the search. -func findSharedNetworkByName(name string, nets []availablenetworks.Network) (availablenetworks.Network, bool) { - for _, n := range nets { - if n.Name == name { - return n, true - } - } - return availablenetworks.Network{}, false -} - -// StructToMap converts the struct to map[string]interface{}. -// Returns an error if the conversion fails. -func StructToMap(obj interface{}) (map[string]interface{}, error) { - data, err := json.Marshal(obj) - if err != nil { - return nil, err - } - - var newMap map[string]interface{} - err = json.Unmarshal(data, &newMap) - if err != nil { - return nil, err - } - - return newMap, nil -} - -func dnsNameserversToStringList(dnsNameservers []net.IP) []string { - dns := make([]string, len(dnsNameservers)) - for i, ns := range dnsNameservers { - dns[i] = ns.String() - } - - return dns -} - -func hostRoutesToListOfMaps(hostRoutes []subnets.HostRoute) []map[string]string { - hrs := make([]map[string]string, len(hostRoutes)) - for i, hr := range hostRoutes { - hR := map[string]string{"destination": "", "nexthop": ""} - hR["destination"] = hr.Destination.String() - hR["nexthop"] = hr.NextHop.String() - hrs[i] = hR - } - - return hrs -} - -func prepareSubnets(subs []subnets.Subnet) []map[string]interface{} { - subnetList := make([]map[string]interface{}, 0, len(subs)) - for _, s := range subs { - subnetList = append(subnetList, map[string]interface{}{ - "id": s.ID, - "name": s.Name, - "enable_dhcp": s.EnableDHCP, - "cidr": s.CIDR.String(), - "available_ips": s.AvailableIps, - "total_ips": s.TotalIps, - "has_router": s.HasRouter, - "dns_nameservers": dnsNameserversToStringList(s.DNSNameservers), - "host_routes": hostRoutesToListOfMaps(s.HostRoutes), - "gateway_ip": s.GatewayIP.String(), - }) - } - - return subnetList -} diff --git a/edgecenter/utils_project.go b/edgecenter/utils_project.go deleted file mode 100644 index ec243c83..00000000 --- a/edgecenter/utils_project.go +++ /dev/null @@ -1,53 +0,0 @@ -package edgecenter - -import ( - "fmt" - "log" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/project/v1/projects" -) - -// findProjectByName searches for a project with the specified name in the provided project slice. -// Returns the project ID if found, otherwise returns an error. -func findProjectByName(arr []projects.Project, name string) (int, error) { - for _, el := range arr { - if el.Name == name { - return el.ID, nil - } - } - return 0, fmt.Errorf("project with name %s not found", name) -} - -// GetProject returns a valid project ID for a resource. -// If the projectID is provided, it will be returned directly. -// If projectName is provided instead, the function will search for the project by name and return its ID. -// Returns an error if the project is not found or there is an issue with the client. -func GetProject(provider *edgecloud.ProviderClient, projectID int, projectName string) (int, error) { - log.Println("[DEBUG] Try to get project ID") - if projectID != 0 { - return projectID, nil - } - client, err := edgecenter.ClientServiceFromProvider(provider, edgecloud.EndpointOpts{ - Name: ProjectPoint, - Region: 0, - Project: 0, - Version: VersionPointV1, - }) - if err != nil { - return 0, err - } - projectsList, err := projects.ListAll(client) - if err != nil { - return 0, err - } - log.Printf("[DEBUG] Projects: %v", projectsList) - projectID, err = findProjectByName(projectsList, projectName) - if err != nil { - return 0, err - } - log.Printf("[DEBUG] The attempt to get the project is successful: projectID=%d", projectID) - - return projectID, nil -} diff --git a/edgecenter/utils_region.go b/edgecenter/utils_region.go deleted file mode 100644 index c7af5aca..00000000 --- a/edgecenter/utils_region.go +++ /dev/null @@ -1,53 +0,0 @@ -package edgecenter - -import ( - "fmt" - "log" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/region/v1/regions" -) - -// findRegionByName searches for a region with the specified name in the provided region slice. -// Returns the region ID if found, otherwise returns an error. -func findRegionByName(arr []regions.Region, name string) (int, error) { - for _, el := range arr { - if el.DisplayName == name { - return el.ID, nil - } - } - return 0, fmt.Errorf("region with name %s not found", name) -} - -// GetRegion returns a valid region ID for a resource. -// If the regionID is provided, it will be returned directly. -// If regionName is provided instead, the function will search for the region by name and return its ID. -// Returns an error if the region is not found or there is an issue with the client. -func GetRegion(provider *edgecloud.ProviderClient, regionID int, regionName string) (int, error) { - if regionID != 0 { - return regionID, nil - } - client, err := edgecenter.ClientServiceFromProvider(provider, edgecloud.EndpointOpts{ - Name: RegionPoint, - Region: 0, - Project: 0, - Version: VersionPointV1, - }) - if err != nil { - return 0, err - } - - rs, err := regions.ListAll(client) - if err != nil { - return 0, err - } - log.Printf("[DEBUG] Regions: %v", rs) - regionID, err = findRegionByName(rs, regionName) - if err != nil { - return 0, err - } - log.Printf("[DEBUG] The attempt to get the region is successful: regionID=%d", regionID) - - return regionID, nil -} diff --git a/edgecenter/utils_router.go b/edgecenter/utils_router.go deleted file mode 100644 index eb951082..00000000 --- a/edgecenter/utils_router.go +++ /dev/null @@ -1,127 +0,0 @@ -package edgecenter - -import ( - "crypto/md5" - "encoding/binary" - "fmt" - "io" - "net" - "reflect" - - "github.com/mitchellh/mapstructure" - - edgecloud "github.com/Edge-Center/edgecentercloud-go" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/router/v1/routers" - "github.com/Edge-Center/edgecentercloud-go/edgecenter/subnet/v1/subnets" -) - -var routerDecoderConfig = &mapstructure.DecoderConfig{ - TagName: "json", -} - -// StringToNetHookFunc returns a DecodeHookFunc for the mapstructure package to handle the custom -// conversion of string values to net.IP and edgecloud.CIDR types. -func StringToNetHookFunc() mapstructure.DecodeHookFuncType { - return func(f reflect.Type, t reflect.Type, data interface{}) (interface{}, error) { - // Only process strings as source type. - if f.Kind() != reflect.String { - return data, nil - } - - // Process the target types. - switch t { - case reflect.TypeOf(edgecloud.CIDR{}): - var ecCIDR edgecloud.CIDR - _, ipNet, err := net.ParseCIDR(data.(string)) - if err != nil { - return nil, err - } - ecCIDR.IP = ipNet.IP - ecCIDR.Mask = ipNet.Mask - return ecCIDR, nil - case reflect.TypeOf(net.IP{}): - ip := net.ParseIP(data.(string)) - if ip == nil { - return nil, fmt.Errorf("failed parsing ip %v", data) - } - return ip, nil - default: - // If the target type is not supported, return the data as is. - return data, nil - } - } -} - -// extractHostRoutesMap converts a slice of interface{} representing host routes into a slice of subnets.HostRoute. -func extractHostRoutesMap(v []interface{}) ([]subnets.HostRoute, error) { - decoderConfig := &mapstructure.DecoderConfig{ - DecodeHook: StringToNetHookFunc(), - } - - hostRoutes := make([]subnets.HostRoute, len(v)) - for i, hostRoute := range v { - hs, ok := hostRoute.(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("failed to assert host route as map[string]interface{}") - } - var H subnets.HostRoute - err := MapStructureDecoder(&H, &hs, decoderConfig) - if err != nil { - return nil, err - } - hostRoutes[i] = H - } - - return hostRoutes, nil -} - -// routerInterfaceUniqueID generates a unique ID for a router interface using its subnet ID. -func routerInterfaceUniqueID(i interface{}) int { - e := i.(map[string]interface{}) - - subnetID := e["subnet_id"].(string) - - h := md5.New() - io.WriteString(h, subnetID) - - return int(binary.BigEndian.Uint64(h.Sum(nil))) -} - -// extractExternalGatewayInfoMap converts the first element of a gateway slice -// into a routers.GatewayInfo struct using the provided mapstructure decoder configuration. -func extractExternalGatewayInfoMap(gw []interface{}) (routers.GatewayInfo, error) { - gateway, ok := gw[0].(map[string]interface{}) - if !ok { - return routers.GatewayInfo{}, fmt.Errorf("failed to assert gateway as map[string]interface{}") - } - - var gwInfo routers.GatewayInfo - err := MapStructureDecoder(&gwInfo, &gateway, routerDecoderConfig) - if err != nil { - return routers.GatewayInfo{}, err - } - - return gwInfo, nil -} - -// extractInterfacesMap converts a slice of interface{} representing router interfaces -// into a slice of routers.Interface using the provided mapstructure decoder configuration. -func extractInterfacesMap(interfaces []interface{}) ([]routers.Interface, error) { - ifaceList := make([]routers.Interface, len(interfaces)) - for i, iface := range interfaces { - inter, ok := iface.(map[string]interface{}) - if !ok { - return nil, fmt.Errorf("failed to assert interface as map[string]interface{}") - } - - var ifaceInfo routers.Interface - err := MapStructureDecoder(&ifaceInfo, &inter, routerDecoderConfig) - if err != nil { - return nil, err - } - - ifaceList[i] = ifaceInfo - } - - return ifaceList, nil -} diff --git a/edgecenter/utils_securitygroup.go b/edgecenter/utils_securitygroup.go deleted file mode 100644 index 9530acd3..00000000 --- a/edgecenter/utils_securitygroup.go +++ /dev/null @@ -1,56 +0,0 @@ -package edgecenter - -import ( - "crypto/md5" - "encoding/binary" - "io" - "strconv" - - "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/securitygroups" - typesSG "github.com/Edge-Center/edgecentercloud-go/edgecenter/securitygroup/v1/types" -) - -// secGroupUniqueID generates a unique ID for a security group rule using its properties. -func secGroupUniqueID(i interface{}) int { - e := i.(map[string]interface{}) - - h := md5.New() - proto, _ := e["protocol"].(string) - io.WriteString(h, e["direction"].(string)) - io.WriteString(h, e["ethertype"].(string)) - io.WriteString(h, proto) - io.WriteString(h, strconv.Itoa(e["port_range_min"].(int))) - io.WriteString(h, strconv.Itoa(e["port_range_max"].(int))) - io.WriteString(h, e["description"].(string)) - io.WriteString(h, e["remote_ip_prefix"].(string)) - - return int(binary.BigEndian.Uint64(h.Sum(nil))) -} - -// extractSecurityGroupRuleMap creates a security group rule from the provided map and security group ID. -func extractSecurityGroupRuleMap(r interface{}, gid string) securitygroups.CreateSecurityGroupRuleOpts { - rule := r.(map[string]interface{}) - - opts := securitygroups.CreateSecurityGroupRuleOpts{ - Direction: typesSG.RuleDirection(rule["direction"].(string)), - EtherType: typesSG.EtherType(rule["ethertype"].(string)), - Protocol: typesSG.Protocol(rule["protocol"].(string)), - SecurityGroupID: &gid, - } - - minP, maxP := rule["port_range_min"].(int), rule["port_range_max"].(int) - if minP != 0 && maxP != 0 { - opts.PortRangeMin = &minP - opts.PortRangeMax = &maxP - } - - description, _ := rule["description"].(string) - opts.Description = &description - - remoteIPPrefix := rule["remote_ip_prefix"].(string) - if remoteIPPrefix != "" { - opts.RemoteIPPrefix = &remoteIPPrefix - } - - return opts -} diff --git a/examples/data-sources/edgecenter_floatingip/data-source.tf b/examples/data-sources/edgecenter_floatingip/data-source.tf deleted file mode 100644 index 3edaeeef..00000000 --- a/examples/data-sources/edgecenter_floatingip/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_floatingip" "ip" { - floating_ip_address = "10.100.179.172" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_floatingip.ip -} - diff --git a/examples/data-sources/edgecenter_image/data-source.tf b/examples/data-sources/edgecenter_image/data-source.tf deleted file mode 100644 index 9aa22b43..00000000 --- a/examples/data-sources/edgecenter_image/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_image" "ubuntu" { - name = "ubuntu-20.04" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_image.ubuntu -} - diff --git a/examples/data-sources/edgecenter_instance/data-source.tf b/examples/data-sources/edgecenter_instance/data-source.tf deleted file mode 100644 index 47e7d675..00000000 --- a/examples/data-sources/edgecenter_instance/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_instance" "vm" { - name = "test-vm" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_instance.vm -} - diff --git a/examples/data-sources/edgecenter_k8s/data-source.tf b/examples/data-sources/edgecenter_k8s/data-source.tf deleted file mode 100644 index a8f3721f..00000000 --- a/examples/data-sources/edgecenter_k8s/data-source.tf +++ /dev/null @@ -1,10 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_k8s" "cluster" { - project_id = 1 - region_id = 1 - cluster_id = "dc3a3ea9-86ae-47ad-a8e8-79df0ce04839" -} - diff --git a/examples/data-sources/edgecenter_k8s_client_config/data-source.tf b/examples/data-sources/edgecenter_k8s_client_config/data-source.tf deleted file mode 100644 index 061ee4ed..00000000 --- a/examples/data-sources/edgecenter_k8s_client_config/data-source.tf +++ /dev/null @@ -1,10 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_k8s_client_config" "cfg" { - project_id = 1 - region_id = 1 - cluster_id = "dc3a3ea9-86ae-47ad-a8e8-79df0ce04839" -} - diff --git a/examples/data-sources/edgecenter_k8s_pool/data-source.tf b/examples/data-sources/edgecenter_k8s_pool/data-source.tf deleted file mode 100644 index b3751d59..00000000 --- a/examples/data-sources/edgecenter_k8s_pool/data-source.tf +++ /dev/null @@ -1,11 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_k8s_pool" "pool" { - project_id = 1 - region_id = 1 - cluster_id = "6bf878c1-1ce4-47c3-a39b-6b5f1d79bf25" - pool_id = "dc3a3ea9-86ae-47ad-a8e8-79df0ce04839" -} - diff --git a/examples/data-sources/edgecenter_laas_hosts/data-source.tf b/examples/data-sources/edgecenter_laas_hosts/data-source.tf deleted file mode 100644 index 4a8e056b..00000000 --- a/examples/data-sources/edgecenter_laas_hosts/data-source.tf +++ /dev/null @@ -1,20 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_laas_hosts" "hosts" { - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_laas_hosts.hosts -} diff --git a/examples/data-sources/edgecenter_laas_status/data-source.tf b/examples/data-sources/edgecenter_laas_status/data-source.tf deleted file mode 100644 index dd671dc4..00000000 --- a/examples/data-sources/edgecenter_laas_status/data-source.tf +++ /dev/null @@ -1,20 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_laas_status" "status" { - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_laas_status.status -} diff --git a/examples/data-sources/edgecenter_lblistener/data-source.tf b/examples/data-sources/edgecenter_lblistener/data-source.tf deleted file mode 100644 index 1a8a6c09..00000000 --- a/examples/data-sources/edgecenter_lblistener/data-source.tf +++ /dev/null @@ -1,23 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_lblistener" "l" { - name = "test-listener" - loadbalancer_id = "59b2eabc-c0a8-4545-8081-979bd963c6ab" //optional - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_lblistener.l -} - diff --git a/examples/data-sources/edgecenter_lbpool/data-source.tf b/examples/data-sources/edgecenter_lbpool/data-source.tf deleted file mode 100644 index 088f84de..00000000 --- a/examples/data-sources/edgecenter_lbpool/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_lbpool" "pool" { - name = "test-pool" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_lbpool.pool -} - diff --git a/examples/data-sources/edgecenter_loadbalancer/data-source.tf b/examples/data-sources/edgecenter_loadbalancer/data-source.tf deleted file mode 100644 index e9239765..00000000 --- a/examples/data-sources/edgecenter_loadbalancer/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_loadbalancer" "lb" { - name = "test-lb" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_loadbalancer.lb -} - diff --git a/examples/data-sources/edgecenter_loadbalancerv2/data-source.tf b/examples/data-sources/edgecenter_loadbalancerv2/data-source.tf deleted file mode 100644 index 24411132..00000000 --- a/examples/data-sources/edgecenter_loadbalancerv2/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_loadbalancerv2" "lb" { - name = "test-lb" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_loadbalancerv2.lb -} - diff --git a/examples/data-sources/edgecenter_network/data-source.tf b/examples/data-sources/edgecenter_network/data-source.tf deleted file mode 100644 index fe361fa3..00000000 --- a/examples/data-sources/edgecenter_network/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_network" "tnw" { - name = "example" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_network.tnw -} - diff --git a/examples/data-sources/edgecenter_project/data-source.tf b/examples/data-sources/edgecenter_project/data-source.tf deleted file mode 100644 index a5abad3d..00000000 --- a/examples/data-sources/edgecenter_project/data-source.tf +++ /dev/null @@ -1,7 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} diff --git a/examples/data-sources/edgecenter_region/data-source.tf b/examples/data-sources/edgecenter_region/data-source.tf deleted file mode 100644 index 97e1e1c6..00000000 --- a/examples/data-sources/edgecenter_region/data-source.tf +++ /dev/null @@ -1,7 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} diff --git a/examples/data-sources/edgecenter_reservedfixedip/data-source.tf b/examples/data-sources/edgecenter_reservedfixedip/data-source.tf deleted file mode 100644 index 8c4f0f65..00000000 --- a/examples/data-sources/edgecenter_reservedfixedip/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_reservedfixedip" "ip" { - fixed_ip_address = "192.168.0.66" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_reservedfixedip.ip -} - diff --git a/examples/data-sources/edgecenter_router/data-source.tf b/examples/data-sources/edgecenter_router/data-source.tf deleted file mode 100644 index 92eaa953..00000000 --- a/examples/data-sources/edgecenter_router/data-source.tf +++ /dev/null @@ -1,23 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_router" "tr" { - name = "test_router" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_router.tr -} - - diff --git a/examples/data-sources/edgecenter_secret/data-source.tf b/examples/data-sources/edgecenter_secret/data-source.tf deleted file mode 100644 index 19025670..00000000 --- a/examples/data-sources/edgecenter_secret/data-source.tf +++ /dev/null @@ -1,21 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_secret" "lb_https" { - name = "lb_https" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_secret.lb_https -} diff --git a/examples/data-sources/edgecenter_securitygroup/data-source.tf b/examples/data-sources/edgecenter_securitygroup/data-source.tf deleted file mode 100644 index b1f5d47e..00000000 --- a/examples/data-sources/edgecenter_securitygroup/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_securitygroup" "default" { - name = "default" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_securitygroup.default -} - diff --git a/examples/data-sources/edgecenter_servergroup/data-source.tf b/examples/data-sources/edgecenter_servergroup/data-source.tf deleted file mode 100644 index 92a34ad8..00000000 --- a/examples/data-sources/edgecenter_servergroup/data-source.tf +++ /dev/null @@ -1,21 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_servergroup" "default" { - name = "default" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_servergroup.default -} diff --git a/examples/data-sources/edgecenter_storage_s3/data-source.tf b/examples/data-sources/edgecenter_storage_s3/data-source.tf deleted file mode 100644 index 8fe76b99..00000000 --- a/examples/data-sources/edgecenter_storage_s3/data-source.tf +++ /dev/null @@ -1,7 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_storage_s3" "example_s3" { - name = "example" -} diff --git a/examples/data-sources/edgecenter_storage_s3_bucket/data-source.tf b/examples/data-sources/edgecenter_storage_s3_bucket/data-source.tf deleted file mode 100644 index 3f09e3c5..00000000 --- a/examples/data-sources/edgecenter_storage_s3_bucket/data-source.tf +++ /dev/null @@ -1,8 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_storage_s3_bucket" "example_s3_bucket" { - storage_id = 1 - name = "example1bucket2name" -} diff --git a/examples/data-sources/edgecenter_subnet/data-source.tf b/examples/data-sources/edgecenter_subnet/data-source.tf deleted file mode 100644 index ad5b739d..00000000 --- a/examples/data-sources/edgecenter_subnet/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_subnet" "tsn" { - name = "subtest" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_subnet.tsn -} - diff --git a/examples/data-sources/edgecenter_volume/data-source.tf b/examples/data-sources/edgecenter_volume/data-source.tf deleted file mode 100644 index 00b23dc6..00000000 --- a/examples/data-sources/edgecenter_volume/data-source.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -data "edgecenter_project" "pr" { - name = "test" -} - -data "edgecenter_region" "rg" { - name = "ED-10 Preprod" -} - -data "edgecenter_volume" "tv" { - name = "test-hd" - region_id = data.edgecenter_region.rg.id - project_id = data.edgecenter_project.pr.id -} - -output "view" { - value = data.edgecenter_volume.tv -} - diff --git a/examples/provider/provider.tf b/examples/provider/provider.tf deleted file mode 100644 index 95ccf259..00000000 --- a/examples/provider/provider.tf +++ /dev/null @@ -1,220 +0,0 @@ -terraform { - required_providers { - edgecenter = { - source = "Edge-Center/edgecenter" - version = ">= 0.1.12" - } - } -} - -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_keypair" "kp" { - project_id = 1 - public_key = "your oub key" - sshkey_name = "testkey" -} - -resource "edgecenter_network" "network" { - name = "network_example" - mtu = 1450 - type = "vxlan" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_subnet" "subnet" { - name = "subnet_example" - cidr = "192.168.10.0/24" - network_id = edgecenter_network.network.id - dns_nameservers = ["8.8.4.4", "1.1.1.1"] - - host_routes { - destination = "10.0.3.0/24" - nexthop = "10.0.0.13" - } - - gateway_ip = "192.168.10.1" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_subnet" "subnet2" { - name = "subnet2_example" - cidr = "192.168.20.0/24" - network_id = edgecenter_network.network.id - dns_nameservers = ["8.8.4.4", "1.1.1.1"] - - host_routes { - destination = "10.0.3.0/24" - nexthop = "10.0.0.13" - } - - gateway_ip = "192.168.20.1" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "first_volume" { - name = "boot volume" - type_name = "ssd_hiiops" - size = 6 - image_id = "f4ce3d30-e29c-4cfd-811f-46f383b6081f" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "second_volume" { - name = "second volume" - type_name = "ssd_hiiops" - image_id = "f4ce3d30-e29c-4cfd-811f-46f383b6081f" - size = 6 - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "third_volume" { - name = "third volume" - type_name = "ssd_hiiops" - size = 6 - region_id = 1 - project_id = 1 -} - -resource "edgecenter_instance" "instance" { - flavor_id = "g1-standard-2-4" - name = "test" - keypair_name = edgecenter_keypair.kp.sshkey_name - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.first_volume.id - boot_index = 0 - } - - interface { - type = "subnet" - network_id = edgecenter_network.network.id - subnet_id = edgecenter_subnet.subnet.id - } - - interface { - type = "subnet" - network_id = edgecenter_network.network.id - subnet_id = edgecenter_subnet.subnet2.id - } - - security_group { - id = "66988147-f1b9-43b2-aaef-dee6d009b5b7" - name = "default" - } - - metadata { - key = "some_key" - value = "some_data" - } - - configuration { - key = "some_key" - value = "some_data" - } - - region_id = 1 - project_id = 1 -} - -resource "edgecenter_loadbalancer" "lb" { - project_id = 1 - region_id = 1 - name = "test1" - flavor = "lb1-1-2" - listener { - name = "test" - protocol = "HTTP" - protocol_port = 80 - } -} - -resource "edgecenter_lbpool" "pl" { - project_id = 1 - region_id = 1 - name = "test_pool1" - protocol = "HTTP" - lb_algorithm = "LEAST_CONNECTIONS" - loadbalancer_id = edgecenter_loadbalancer.lb.id - listener_id = edgecenter_loadbalancer.lb.listener.0.id - health_monitor { - type = "PING" - delay = 60 - max_retries = 5 - timeout = 10 - } - session_persistence { - type = "APP_COOKIE" - cookie_name = "test_new_cookie" - } -} - -resource "edgecenter_lbmember" "lbm" { - project_id = 1 - region_id = 1 - pool_id = edgecenter_lbpool.pl.id - instance_id = edgecenter_instance.instance.id - address = tolist(edgecenter_instance.instance.interface).0.ip_address - protocol_port = 8081 - weight = 5 -} - -resource "edgecenter_instance" "instance2" { - flavor_id = "g1-standard-2-4" - name = "test2" - keypair_name = edgecenter_keypair.kp.sshkey_name - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.second_volume.id - boot_index = 0 - } - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.third_volume.id - boot_index = 1 - } - - interface { - type = "subnet" - network_id = edgecenter_network.network.id - subnet_id = edgecenter_subnet.subnet.id - } - - security_group { - id = "66988147-f1b9-43b2-aaef-dee6d009b5b7" - name = "default" - } - - metadata { - key = "some_key" - value = "some_data" - } - - configuration { - key = "some_key" - value = "some_data" - } - - region_id = 1 - project_id = 1 -} - -resource "edgecenter_lbmember" "lbm2" { - project_id = 1 - region_id = 1 - pool_id = edgecenter_lbpool.pl.id - instance_id = edgecenter_instance.instance2.id - address = tolist(edgecenter_instance.instance2.interface).0.ip_address - protocol_port = 8081 - weight = 5 -} diff --git a/examples/resources/edgecenter_baremetal/import.sh b/examples/resources/edgecenter_baremetal/import.sh deleted file mode 100644 index e7e6cfb5..00000000 --- a/examples/resources/edgecenter_baremetal/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_baremetal.instance1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_baremetal/resource.tf b/examples/resources/edgecenter_baremetal/resource.tf deleted file mode 100644 index 049e62b2..00000000 --- a/examples/resources/edgecenter_baremetal/resource.tf +++ /dev/null @@ -1,25 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_baremetal" "bm" { - name = "test bm instance" - region_id = 1 - project_id = 1 - flavor_id = "bm1-infrastructure-small" - image_id = "1ee7ccee-5003-48c9-8ae0-d96063af75b2" // your image id - - //additional interface, available type is 'subnet' or 'external' - // interface { - // type = "subnet" - // network_id = "9c7867fb-f404-4a2d-8bb5-24acf2fccaf1" //your network_id - // subnet_id = "b68ea6e2-c2b6-4a8d-95eb-7194d12a2156" // your subnet_id - // } - - // interface { - // type = "external" - // is_parent = "true" // if is_parent = true interface cant be detached, and always connected first - // } - - keypair_name = "test" // your keypair name -} \ No newline at end of file diff --git a/examples/resources/edgecenter_cdn_origingroup/resource.tf b/examples/resources/edgecenter_cdn_origingroup/resource.tf deleted file mode 100644 index a111ff16..00000000 --- a/examples/resources/edgecenter_cdn_origingroup/resource.tf +++ /dev/null @@ -1,17 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_cdn_origingroup" "origin_group_1" { - name = "origin_group_1" - use_next = true - origin { - source = "example.com" - enabled = true - } - origin { - source = "mirror.example.com" - enabled = true - backup = true - } -} diff --git a/examples/resources/edgecenter_cdn_resource/resource.tf b/examples/resources/edgecenter_cdn_resource/resource.tf deleted file mode 100644 index c320503a..00000000 --- a/examples/resources/edgecenter_cdn_resource/resource.tf +++ /dev/null @@ -1,45 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - - -resource "edgecenter_cdn_resource" "cdn_example_com" { - cname = "cdn.example.com" - origin_group = edgecenter_cdn_origingroup.origin_group_1.id - origin_protocol = "MATCH" - secondary_hostnames = ["cdn2.example.com"] - - options { - edge_cache_settings { - default = "8d" - } - browser_cache_settings { - value = "1d" - } - redirect_http_to_https { - value = true - } - gzip_on { - value = true - } - cors { - value = [ - "*" - ] - } - rewrite { - body = "/(.*) /$1" - } - webp { - jpg_quality = 55 - png_quality = 66 - } - - tls_versions { - enabled = true - value = [ - "TLSv1.2", - ] - } - } -} diff --git a/examples/resources/edgecenter_cdn_rule/resource.tf b/examples/resources/edgecenter_cdn_rule/resource.tf deleted file mode 100644 index 735493bd..00000000 --- a/examples/resources/edgecenter_cdn_rule/resource.tf +++ /dev/null @@ -1,78 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_cdn_rule" "cdn_example_com_rule_1" { - resource_id = edgecenter_cdn_resource.cdn_example_com.id - name = "All PNG images" - rule = "/folder/images/*.png" - - options { - edge_cache_settings { - default = "14d" - } - browser_cache_settings { - value = "14d" - } - redirect_http_to_https { - value = true - } - gzip_on { - value = true - } - cors { - value = [ - "*" - ] - } - rewrite { - body = "/(.*) /$1" - } - webp { - jpg_quality = 55 - png_quality = 66 - } - ignore_query_string { - value = true - } - } -} - -resource "edgecenter_cdn_rule" "cdn_example_com_rule_2" { - resource_id = edgecenter_cdn_resource.cdn_example_com.id - name = "All JS scripts" - rule = "/folder/images/*.js" - origin_protocol = "HTTP" - - options { - redirect_http_to_https { - enabled = false - value = true - } - gzip_on { - enabled = false - value = true - } - query_params_whitelist { - value = [ - "abc", - ] - } - } -} - -resource "edgecenter_cdn_origingroup" "origin_group_1" { - name = "origin_group_1" - use_next = true - origin { - source = "example.com" - enabled = true - } -} - -resource "edgecenter_cdn_resource" "cdn_example_com" { - cname = "cdn.example.com" - origin_group = edgecenter_cdn_origingroup.origin_group_1.id - origin_protocol = "MATCH" - secondary_hostnames = ["cdn2.example.com"] -} diff --git a/examples/resources/edgecenter_cdn_sslcert/resource.tf b/examples/resources/edgecenter_cdn_sslcert/resource.tf deleted file mode 100644 index 7c4a9180..00000000 --- a/examples/resources/edgecenter_cdn_sslcert/resource.tf +++ /dev/null @@ -1,20 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -variable "cert" { - type = string - sensitive = true -} - -variable "private_key" { - type = string - sensitive = true -} - -resource "edgecenter_cdn_sslcert" "cdnopt_cert" { - name = "Test cert for cdnopt_bookatest_by" - cert = var.cert - private_key = var.private_key -} - diff --git a/examples/resources/edgecenter_dns_zone/import.sh b/examples/resources/edgecenter_dns_zone/import.sh deleted file mode 100644 index 42bdb88a..00000000 --- a/examples/resources/edgecenter_dns_zone/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using zone name format -terraform import edgecenter_dns_zone.example_zone example_zone.com \ No newline at end of file diff --git a/examples/resources/edgecenter_dns_zone/resource.tf b/examples/resources/edgecenter_dns_zone/resource.tf deleted file mode 100644 index 6f14fba0..00000000 --- a/examples/resources/edgecenter_dns_zone/resource.tf +++ /dev/null @@ -1,7 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_dns_zone" "example_zone" { - name = "example_zone.com" -} diff --git a/examples/resources/edgecenter_dns_zone_record/import.sh b/examples/resources/edgecenter_dns_zone_record/import.sh deleted file mode 100644 index 4fbe3c98..00000000 --- a/examples/resources/edgecenter_dns_zone_record/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using zone:domain:type format -terraform import edgecenter_dns_zone_record.example_rrset0 example.com:domain.example.com:A \ No newline at end of file diff --git a/examples/resources/edgecenter_dns_zone_record/resource.tf b/examples/resources/edgecenter_dns_zone_record/resource.tf deleted file mode 100644 index 4a641283..00000000 --- a/examples/resources/edgecenter_dns_zone_record/resource.tf +++ /dev/null @@ -1,85 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -// -// example0: managing zone and records by TF using variables -// -variable "example_domain0" { - type = string - default = "examplezone.com" -} - -resource "edgecenter_dns_zone" "examplezone0" { - name = var.example_domain0 -} - -resource "edgecenter_dns_zone_record" "example_rrset0" { - zone = edgecenter_dns_zone.examplezone0.name - domain = edgecenter_dns_zone.examplezone0.name - type = "A" - ttl = 100 - - resource_record { - content = "127.0.0.100" - } - resource_record { - content = "127.0.0.200" - // enabled = false - } -} - -// -// example1: managing zone outside of TF -// -resource "edgecenter_dns_zone_record" "subdomain_examplezone" { - zone = "examplezone.com" - domain = "subdomain.examplezone.com" - type = "TXT" - ttl = 10 - - filter { - type = "geodistance" - limit = 1 - strict = true - } - - resource_record { - content = "1234" - enabled = true - - meta { - latlong = [52.367, 4.9041] - asn = [12345] - ip = ["1.1.1.1"] - notes = ["notes"] - continents = ["asia"] - countries = ["russia"] - default = true - } - } -} - -resource "edgecenter_dns_zone_record" "subdomain_examplezone_mx" { - zone = "examplezone.com" - domain = "subdomain.examplezone.com" - type = "MX" - ttl = 10 - - resource_record { - content = "10 mail.my.com." - enabled = true - } -} - -resource "edgecenter_dns_zone_record" "subdomain_examplezone_caa" { - zone = "examplezone.com" - domain = "subdomain.examplezone.com" - type = "CAA" - ttl = 10 - - resource_record { - content = "0 issue \"company.org; account=12345\"" - enabled = true - } -} diff --git a/examples/resources/edgecenter_faas_function/import.sh b/examples/resources/edgecenter_faas_function/import.sh deleted file mode 100644 index d76f19f7..00000000 --- a/examples/resources/edgecenter_faas_function/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_faas_function.test 1:6:ns:test_func \ No newline at end of file diff --git a/examples/resources/edgecenter_faas_function/resource.tf b/examples/resources/edgecenter_faas_function/resource.tf deleted file mode 100644 index 85fc827a..00000000 --- a/examples/resources/edgecenter_faas_function/resource.tf +++ /dev/null @@ -1,31 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_faas_function" "func" { - project_id = 1 - region_id = 1 - name = "testf" - namespace = "ns4test" - description = "function description" - envs = { - BIG = "EXAMPLE2" - } - runtime = "go1.16.6" - code_text = <:: format -terraform import edgecenter_faas_namespace.test 1:6:ns \ No newline at end of file diff --git a/examples/resources/edgecenter_faas_namespace/resource.tf b/examples/resources/edgecenter_faas_namespace/resource.tf deleted file mode 100644 index 332e5624..00000000 --- a/examples/resources/edgecenter_faas_namespace/resource.tf +++ /dev/null @@ -1,14 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_faas_namespace" "ns" { - project_id = 1 - region_id = 1 - name = "testns" - description = "test description" - envs = { - BIG_ENV = "EXAMPLE" - } -} - diff --git a/examples/resources/edgecenter_floatingip/import.sh b/examples/resources/edgecenter_floatingip/import.sh deleted file mode 100644 index fa8bac21..00000000 --- a/examples/resources/edgecenter_floatingip/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_floatingip.fip1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_floatingip/resource.tf b/examples/resources/edgecenter_floatingip/resource.tf deleted file mode 100644 index 21e311cd..00000000 --- a/examples/resources/edgecenter_floatingip/resource.tf +++ /dev/null @@ -1,15 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_floatingip" "floating_ip" { - project_id = 1 - region_id = 1 - metadata_map = { - tag1 = "tag1_value" - } - // fixed_ip_address = "192.168.10.39" // instance`s interface ip - // port_id = "5c992875-f653-4b7b-af5b-1dc3019e5ffa" //instance`s interface port_id -} - - diff --git a/examples/resources/edgecenter_instance/import.sh b/examples/resources/edgecenter_instance/import.sh deleted file mode 100644 index 3730cef3..00000000 --- a/examples/resources/edgecenter_instance/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_instance.instance1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_instance/resource.tf b/examples/resources/edgecenter_instance/resource.tf deleted file mode 100644 index 651632a3..00000000 --- a/examples/resources/edgecenter_instance/resource.tf +++ /dev/null @@ -1,135 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_network" "network" { - name = "network_example" - mtu = 1450 - type = "vxlan" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_subnet" "subnet" { - name = "subnet_example" - cidr = "192.168.10.0/24" - network_id = edgecenter_network.network.id - dns_nameservers = ["8.8.4.4", "1.1.1.1"] - - host_routes { - destination = "10.0.3.0/24" - nexthop = "10.0.0.13" - } - - gateway_ip = "192.168.10.1" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "first_volume" { - name = "boot volume" - type_name = "ssd_hiiops" - size = 5 - image_id = "f4ce3d30-e29c-4cfd-811f-46f383b6081f" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_volume" "second_volume" { - name = "second volume" - type_name = "ssd_hiiops" - size = 5 - region_id = 1 - project_id = 1 -} - -resource "edgecenter_instance" "instance" { - flavor_id = "g1-standard-2-4" - name = "test" - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.first_volume.id - boot_index = 0 - } - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.second_volume.id - boot_index = 1 - } - - interface { - type = "subnet" - network_id = edgecenter_network.network.id - subnet_id = edgecenter_subnet.subnet.id - security_groups = ["d75db0b2-58f1-4a11-88c6-a932bb897310"] - } - - metadata_map = { - some_key = "some_value" - stage = "dev" - } - - configuration { - key = "some_key" - value = "some_data" - } - - region_id = 1 - project_id = 1 -} - -//*** -// another one example with one interface to private network and fip to internet -//*** - -resource "edgecenter_reservedfixedip" "fixed_ip" { - project_id = 1 - region_id = 1 - type = "ip_address" - network_id = "faf6507b-1ff1-4ebf-b540-befd5c09fe06" - fixed_ip_address = "192.168.13.6" - is_vip = false -} - -resource "edgecenter_volume" "first_volume" { - name = "boot volume" - type_name = "ssd_hiiops" - size = 10 - image_id = "6dc4e061-6fab-41f3-91a3-0ba848fb32d9" - project_id = 1 - region_id = 1 -} - -resource "edgecenter_floatingip" "fip" { - project_id = 1 - region_id = 1 - fixed_ip_address = edgecenter_reservedfixedip.fixed_ip.fixed_ip_address - port_id = edgecenter_reservedfixedip.fixed_ip.port_id -} - - -resource "edgecenter_instance" "v" { - project_id = 1 - region_id = 1 - name = "hello" - flavor_id = "g1-standard-1-2" - - volume { - source = "existing-volume" - volume_id = edgecenter_volume.first_volume.id - boot_index = 0 - } - - interface { - type = "reserved_fixed_ip" - port_id = edgecenter_reservedfixedip.fixed_ip.port_id - fip_source = "existing" - existing_fip_id = edgecenter_floatingip.fip.id - security_groups = ["ada84751-fcca-4491-9249-2dfceb321616"] - } -} - - - diff --git a/examples/resources/edgecenter_k8s/import.sh b/examples/resources/edgecenter_k8s/import.sh deleted file mode 100644 index e0cac597..00000000 --- a/examples/resources/edgecenter_k8s/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_k8s.cluster1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_k8s/resource.tf b/examples/resources/edgecenter_k8s/resource.tf deleted file mode 100644 index 550426a3..00000000 --- a/examples/resources/edgecenter_k8s/resource.tf +++ /dev/null @@ -1,22 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_k8s" "v" { - project_id = 1 - region_id = 1 - version = "1.25.11" - name = "tf-k8s" - fixed_network = "6bf878c1-1ce4-47c3-a39b-6b5f1d79bf25" - fixed_subnet = "dc3a3ea9-86ae-47ad-a8e8-79df0ce04839" - keypair = "tf-keypair" - pool { - name = "tf-pool" - flavor_id = "g1-standard-1-2" - min_node_count = 1 - max_node_count = 2 - node_count = 1 - docker_volume_size = 2 - } -} - diff --git a/examples/resources/edgecenter_k8s_pool/import.sh b/examples/resources/edgecenter_k8s_pool/import.sh deleted file mode 100644 index 79754270..00000000 --- a/examples/resources/edgecenter_k8s_pool/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using ::: format -terraform import edgecenter_k8s_pool.k8s_pool1 1:6:a775dd94-4e9c-4da7-9f0e-ffc9ae34446b:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_k8s_pool/resource.tf b/examples/resources/edgecenter_k8s_pool/resource.tf deleted file mode 100644 index 7f26096c..00000000 --- a/examples/resources/edgecenter_k8s_pool/resource.tf +++ /dev/null @@ -1,16 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_k8s_pool" "v" { - project_id = 1 - region_id = 1 - cluster_id = "6bf878c1-1ce4-47c3-a39b-6b5f1d79bf25" - name = "tf-pool" - flavor_id = "g1-standard-1-2" - min_node_count = 1 - max_node_count = 2 - node_count = 1 - docker_volume_size = 2 -} - diff --git a/examples/resources/edgecenter_keypair/resource.tf b/examples/resources/edgecenter_keypair/resource.tf deleted file mode 100644 index 56b2eda2..00000000 --- a/examples/resources/edgecenter_keypair/resource.tf +++ /dev/null @@ -1,13 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_keypair" "kp" { - project_id = 1 - public_key = "your public key here" - sshkey_name = "test" -} - -output "kp" { - value = edgecenter_keypair.kp -} diff --git a/examples/resources/edgecenter_laas_topic/import.sh b/examples/resources/edgecenter_laas_topic/import.sh deleted file mode 100644 index 6d2ca5ca..00000000 --- a/examples/resources/edgecenter_laas_topic/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_laas_topic.test 1:6:test_topic \ No newline at end of file diff --git a/examples/resources/edgecenter_laas_topic/resource.tf b/examples/resources/edgecenter_laas_topic/resource.tf deleted file mode 100644 index 59889161..00000000 --- a/examples/resources/edgecenter_laas_topic/resource.tf +++ /dev/null @@ -1,10 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_laas_topic" "test" { - region_id = 1 - project_id = 1 - - name = "test" -} diff --git a/examples/resources/edgecenter_lblistener/import.sh b/examples/resources/edgecenter_lblistener/import.sh deleted file mode 100644 index 0a375438..00000000 --- a/examples/resources/edgecenter_lblistener/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using ::: format -terraform import edgecenter_lblistener.lblistener1 1:6:a775dd94-4e9c-4da7-9f0e-ffc9ae34446b:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_lblistener/resource.tf b/examples/resources/edgecenter_lblistener/resource.tf deleted file mode 100644 index 7d456474..00000000 --- a/examples/resources/edgecenter_lblistener/resource.tf +++ /dev/null @@ -1,19 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancerv2" "lb" { - project_id = 1 - region_id = 1 - name = "test" - flavor = "lb1-1-2" -} - -resource "edgecenter_lblistener" "listener" { - project_id = 1 - region_id = 1 - name = "test" - protocol = "TCP" - protocol_port = 36621 - loadbalancer_id = edgecenter_loadbalancerv2.lb.id -} \ No newline at end of file diff --git a/examples/resources/edgecenter_lbmember/import.sh b/examples/resources/edgecenter_lbmember/import.sh deleted file mode 100644 index 496322e4..00000000 --- a/examples/resources/edgecenter_lbmember/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using ::: format -terraform import edgecenter_lbmember.lbmember1 1:6:a775dd94-4e9c-4da7-9f0e-ffc9ae34446b:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_lbmember/resource.tf b/examples/resources/edgecenter_lbmember/resource.tf deleted file mode 100644 index f99eaff7..00000000 --- a/examples/resources/edgecenter_lbmember/resource.tf +++ /dev/null @@ -1,46 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancer" "lb" { - project_id = 1 - region_id = 1 - name = "test1" - flavor = "lb1-1-2" - listeners { - name = "test" - protocol = "HTTP" - protocol_port = 80 - } -} - -resource "edgecenter_lbpool" "pl" { - project_id = 1 - region_id = 1 - name = "test_pool1" - protocol = "HTTP" - lb_algorithm = "LEAST_CONNECTIONS" - loadbalancer_id = edgecenter_loadbalancer.lb.id - listener_id = edgecenter_loadbalancer.lb.listeners.0.id - health_monitor { - type = "PING" - delay = 60 - max_retries = 5 - timeout = 10 - } - session_persistence { - type = "APP_COOKIE" - cookie_name = "test_new_cookie" - } -} - -resource "edgecenter_lbmember" "lbm" { - project_id = 1 - region_id = 1 - pool_id = edgecenter_lbpool.pl.id - address = "10.10.2.15" - protocol_port = 8081 - weight = 5 -} - - diff --git a/examples/resources/edgecenter_lbpool/import.sh b/examples/resources/edgecenter_lbpool/import.sh deleted file mode 100644 index 25214f16..00000000 --- a/examples/resources/edgecenter_lbpool/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_lbpool.lbpool1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_lbpool/resource.tf b/examples/resources/edgecenter_lbpool/resource.tf deleted file mode 100644 index a9d4c4c0..00000000 --- a/examples/resources/edgecenter_lbpool/resource.tf +++ /dev/null @@ -1,35 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancer" "lb" { - project_id = 1 - region_id = 1 - name = "test1" - flavor = "lb1-1-2" - listener { - name = "test" - protocol = "HTTP" - protocol_port = 80 - } -} - -resource "edgecenter_lbpool" "pl" { - project_id = 1 - region_id = 1 - name = "test_pool1" - protocol = "HTTP" - lb_algorithm = "LEAST_CONNECTIONS" - loadbalancer_id = edgecenter_loadbalancer.lb.id - listener_id = edgecenter_loadbalancer.lb.listener.0.id - health_monitor { - type = "PING" - delay = 60 - max_retries = 5 - timeout = 10 - } - session_persistence { - type = "APP_COOKIE" - cookie_name = "test_new_cookie" - } -} diff --git a/examples/resources/edgecenter_lifecyclepolicy/import.sh b/examples/resources/edgecenter_lifecyclepolicy/import.sh deleted file mode 100644 index 33f6aaf0..00000000 --- a/examples/resources/edgecenter_lifecyclepolicy/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_lifecyclepolicy.lifecyclepolicy1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_lifecyclepolicy/resource.tf b/examples/resources/edgecenter_lifecyclepolicy/resource.tf deleted file mode 100644 index 488b684f..00000000 --- a/examples/resources/edgecenter_lifecyclepolicy/resource.tf +++ /dev/null @@ -1,30 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_lifecyclepolicy" "lp" { - project_id = 1 - region_id = 1 - name = "test" - status = "active" - action = "volume_snapshot" - volume { - id = "fe93bfdd-4ce3-4041-b89b-4f10d0d49498" - } - schedule { - max_quantity = 4 - interval { - weeks = 1 - days = 2 - hours = 3 - minutes = 4 - } - resource_name_template = "reserve snap of the volume {volume_id}" - retention_time { - weeks = 4 - days = 3 - hours = 2 - minutes = 1 - } - } -} \ No newline at end of file diff --git a/examples/resources/edgecenter_loadbalancer/import.sh b/examples/resources/edgecenter_loadbalancer/import.sh deleted file mode 100644 index f23cc6d0..00000000 --- a/examples/resources/edgecenter_loadbalancer/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using ::: format, listener_id - nested listener id -terraform import edgecenter_loadbalancer.loadbalancer1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7:a336f28c-fbb0-4256-9545-e905bed9f48f \ No newline at end of file diff --git a/examples/resources/edgecenter_loadbalancer/resource.tf b/examples/resources/edgecenter_loadbalancer/resource.tf deleted file mode 100644 index e594889c..00000000 --- a/examples/resources/edgecenter_loadbalancer/resource.tf +++ /dev/null @@ -1,19 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancer" "lb" { - project_id = 1 - region_id = 1 - name = "test" - flavor = "lb1-1-2" - //when upgrading to version 0.2.28 nested listener max length reduced to 1 - //that mean, if you had more than one nested listener and removed them from - //schema they not delete in the cloud. User has to delete it manually and - //recreate as edgecenter_lblistener resource - listener { - name = "test" - protocol = "HTTP" - protocol_port = 80 - } -} \ No newline at end of file diff --git a/examples/resources/edgecenter_loadbalancerv2/import.sh b/examples/resources/edgecenter_loadbalancerv2/import.sh deleted file mode 100644 index 312eb5e5..00000000 --- a/examples/resources/edgecenter_loadbalancerv2/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_loadbalancer.loadbalancer1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_loadbalancerv2/resource.tf b/examples/resources/edgecenter_loadbalancerv2/resource.tf deleted file mode 100644 index 5d165eff..00000000 --- a/examples/resources/edgecenter_loadbalancerv2/resource.tf +++ /dev/null @@ -1,13 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_loadbalancerv2" "lb" { - project_id = 1 - region_id = 1 - name = "test" - flavor = "lb1-1-2" - metadata_map = { - tag1 = "tag1_value" - } -} diff --git a/examples/resources/edgecenter_network/import.sh b/examples/resources/edgecenter_network/import.sh deleted file mode 100644 index 14253f00..00000000 --- a/examples/resources/edgecenter_network/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_network.metwork1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_network/resource.tf b/examples/resources/edgecenter_network/resource.tf deleted file mode 100644 index 8f1dc511..00000000 --- a/examples/resources/edgecenter_network/resource.tf +++ /dev/null @@ -1,10 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_network" "network" { - name = "network_example" - type = "vxlan" - region_id = 1 - project_id = 1 -} diff --git a/examples/resources/edgecenter_reservedfixedip/import.sh b/examples/resources/edgecenter_reservedfixedip/import.sh deleted file mode 100644 index ba5463ec..00000000 --- a/examples/resources/edgecenter_reservedfixedip/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_reservedfixedip.reservedfixedip1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_reservedfixedip/resource.tf b/examples/resources/edgecenter_reservedfixedip/resource.tf deleted file mode 100644 index dcbd90e4..00000000 --- a/examples/resources/edgecenter_reservedfixedip/resource.tf +++ /dev/null @@ -1,10 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_reservedfixedip" "fixed_ip" { - project_id = 1 - region_id = 1 - type = "external" - is_vip = false -} \ No newline at end of file diff --git a/examples/resources/edgecenter_router/import.sh b/examples/resources/edgecenter_router/import.sh deleted file mode 100644 index 855098ee..00000000 --- a/examples/resources/edgecenter_router/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_router.router1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_router/resource.tf b/examples/resources/edgecenter_router/resource.tf deleted file mode 100644 index a4ed1ed0..00000000 --- a/examples/resources/edgecenter_router/resource.tf +++ /dev/null @@ -1,38 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_router" "router" { - name = "router_example" - - dynamic "external_gateway_info" { - iterator = egi - for_each = var.external_gateway_info - content { - type = egi.value.type - enable_snat = egi.value.enable_snat - network_id = egi.value.network_id - } - } - - dynamic "interfaces" { - iterator = ifaces - for_each = var.interfaces - content { - type = ifaces.value.type - subnet_id = ifaces.value.subnet_id - } - } - - dynamic "routes" { - iterator = rs - for_each = var.routes - content { - destination = rs.value.destination - nexthop = rs.value.nexthop - } - } - - region_id = 1 - project_id = 1 -} \ No newline at end of file diff --git a/examples/resources/edgecenter_router/vars.tf b/examples/resources/edgecenter_router/vars.tf deleted file mode 100755 index d54db8ce..00000000 --- a/examples/resources/edgecenter_router/vars.tf +++ /dev/null @@ -1,48 +0,0 @@ -variable "external_gateway_info" { - type = list(object({ - type = string - enable_snat = bool - network_id = string - })) - default = [ - { - type = "manual" - enable_snat = false - network_id = "" //set external network id - }, - ] -} - -variable "interfaces" { - type = list(object({ - type = string - subnet_id = string - })) - default = [ - { - type = "subnet" - subnet_id = "9bc36cf6-407c-4a74-bc83-ce3aa3854c3d" - }, - { - type = "subnet" - subnet_id = "f3f6a294-a319-4db4-84b6-6016a3481924" - }, - ] -} - -variable "routes" { - type = list(object({ - destination = string - nexthop = string - })) - default = [ - { - destination = "192.168.101.0/24" - nexthop = "192.168.100.2" - }, - { - destination = "192.168.102.0/24" - nexthop = "192.168.100.3" - }, - ] -} \ No newline at end of file diff --git a/examples/resources/edgecenter_secret/import.sh b/examples/resources/edgecenter_secret/import.sh deleted file mode 100644 index aa50112e..00000000 --- a/examples/resources/edgecenter_secret/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_secret.secret_id 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_secret/resource.tf b/examples/resources/edgecenter_secret/resource.tf deleted file mode 100644 index 4af57a18..00000000 --- a/examples/resources/edgecenter_secret/resource.tf +++ /dev/null @@ -1,14 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_secret" "lb_https" { - region_id = 1 - project_id = 1 - - name = "test" - private_key = "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDQ4E6U0vql4EST\n8o41TlHRz6MKmMhddVUjM2juTKjxv4WuB4T3z/wokznEjQg4H7gfYEKeCJqelrfq\ntdOtbPsznSceMOXB5uA2Sc9WVKwk7owoRJxPd4LQeOcarVOFdIzudzkgSK/oV7Za\nL8Y2hylsB4SX2cfbULtmW/WDePp3YZAL6zYV1fXJSnK+hL2iUSqikiViEGRta+47\nnaTKZnnmSgojdshzsw0wlF/PgRJ/Anf9j9J8ratdJP81yAG5daU3L2NdJ3qx9UbV\ntKnSq2z2u4yx6xdb4t4WFQBKNjC6+YZN/gI5lp96p3FNTNS4PKYxAAUrnCwf0EE3\n7dOR4eWlAgMBAAECggEBALPm3ge0h4li1e4PVYh4AmSRT74KxVgpfMCqwM+uWzyM\nVpkDhPTjwC06UOEHD3M3bqAninkOtA2vhoyzOrP+T4Wu70hDmUAemDJp9BhJKVNN\n2o28Olz/dD4WRAZoDq29Kr0hFqTFtiyJj1eyGihQ1c5j00HuowI0UJPi1Fz+T8uN\nPwukUtTPYwEds6SApii3v9VKjmvbRDmsbHU3KkUoaeqpRnRagyp1vtoLXigezUcK\nrQcoh6wlKtvj0YLR2lxq9Wmj1nn6m3F5Bom54X8o18tcOmFSRudRb+Fxjb0jnqSK\nAsyVlZg4alTBQUmx9gIKv0oSJAIh2nXdclECkGjs8WkCgYEA9xvdDWephsbv+X3k\nndnDG9JTxfrR6HMHPrUrTaZ8/VD+Qw4zuReoNGkcQbV3Cb26egprWQWfYc9+l6mU\nAWgOjFgeGie1uwOwkhv6CfhE/iVvotJ3hOOsC5pLEhz4vRpO75C9wSehjfTYkP1m\nXEAhRTRbgMnvzChWyh5CEjosX5sCgYEA2GRHrG0JVxsYSCugLPKf9fSK4CQDm0bK\nywBwZtAWX0xhiHO/BW6PeK1Mqx2nbiWl1hXNpZKJNS9bnrZWym/yUqOvg2XJKjb6\nhHBvwAD1MOQ8Ysby4JHGCrMBEwlcDpI2wpMpXkKhU3X0XWjkqrhqCH/TETFKkqLt\nfJX/c9PTQ78CgYAEPek0grQJST7zVHLpNsS/pIOloWGbEOZt8CQ3KAV7P7mtov/G\nTJ6pj6hZhGjvtN8Pm0Aufgc3YZ11swaEY6nkRNr3bfkTpcORLoPDSgy9JB1feSdu\nE45vgI2LWQ34CQyT1jM7rpd6XVqeWos4SC2KB5UOh+ji40piG9TchT0fwwKBgA/M\nmpMTTvhGKSqzzLkbaeR6W11sI7tFmu7hdFN9Y/THTeO5l7vcy6ri9FMWEjBvnUEZ\nTG+HWG9CquzWoVWcgNPZ0anFV7+2Teo3j2E0cLKGJ4aKwhb1bcFAOpbaOxdxQ4BH\nYGDaeo7ucM4VJ4TzfAJs2stJjwlPzgknpoQddjJfAoGBAIFfnU8x/SrNhAqZrG9d\n3kpJ5LmbVswOYtj01KHM+KpEwOQVF+s2NOeHqyC7QUIWrue00+1MT88F9cNHDeWk\n0dEOJNWCfzcV85l8A+0p6/4qAW7h7RNiFqeA8GyVKCT8f7fu/7WpYw8D0aq8w5X/\nKZl+AjB+MzYFs71+SC4ohTlI\n-----END PRIVATE KEY-----" - certificate = "-----BEGIN CERTIFICATE-----\nMIIDpDCCAoygAwIBAgIJAIUvym0uaBHbMA0GCSqGSIb3DQEBCwUAMD0xCzAJBgNV\nBAYTAlJVMQ8wDQYDVQQIDAZNT1NDT1cxCzAJBgNVBAoMAkNBMRAwDgYDVQQDDAdS\nT09UIENBMB4XDTIxMDczMDE1MTU0NVoXDTMxMDcyODE1MTU0NVowTDELMAkGA1UE\nBhMCQ0ExDTALBgNVBAgMBE5vbmUxCzAJBgNVBAcMAk5CMQ0wCwYDVQQKDAROb25l\nMRIwEAYDVQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK\nAoIBAQDQ4E6U0vql4EST8o41TlHRz6MKmMhddVUjM2juTKjxv4WuB4T3z/wokznE\njQg4H7gfYEKeCJqelrfqtdOtbPsznSceMOXB5uA2Sc9WVKwk7owoRJxPd4LQeOca\nrVOFdIzudzkgSK/oV7ZaL8Y2hylsB4SX2cfbULtmW/WDePp3YZAL6zYV1fXJSnK+\nhL2iUSqikiViEGRta+47naTKZnnmSgojdshzsw0wlF/PgRJ/Anf9j9J8ratdJP81\nyAG5daU3L2NdJ3qx9UbVtKnSq2z2u4yx6xdb4t4WFQBKNjC6+YZN/gI5lp96p3FN\nTNS4PKYxAAUrnCwf0EE37dOR4eWlAgMBAAGjgZcwgZQwVwYDVR0jBFAwTqFBpD8w\nPTELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1PU0NPVzELMAkGA1UECgwCQ0ExEDAO\nBgNVBAMMB1JPT1QgQ0GCCQCectJTETy4lTAJBgNVHRMEAjAAMAsGA1UdDwQEAwIE\n8DAhBgNVHREEGjAYgglsb2NhbGhvc3SCCyoubG9jYWxob3N0MA0GCSqGSIb3DQEB\nCwUAA4IBAQBqzJcwygLsVCTPlReUpcKVn84aFqzfZA0m7hYvH+7PDH/FM8SbX3zg\nteBL/PgQAZw1amO8xjeMc2Pe2kvi9VrpfTeGqNia/9axhGu3q/NEP0tyDFXAE2bR\njBdGhd5gCmg+X4WdHigCgn51cz5r2k3fSOIWP+TQWHqc8Yt+vZXnkwnQkRA1Ki7N\nWOiJjj/ae5RWwma/kJNmShTZn754gbQn06bAjNbPjclsHRLkawmLqikd1rYUhIdk\nOr1Nrl+CWMx3CXg0TVVdJ6rH3dO31uyvb+3qEY7WnL+HhZyr08ay8gJsEKPuPFA2\nxvveXqt9ceU5qh+8T7mHwGALEUw96QcP\n-----END CERTIFICATE-----" - certificate_chain = "-----BEGIN CERTIFICATE-----\nMIIC9jCCAd4CCQCectJTETy4lTANBgkqhkiG9w0BAQsFADA9MQswCQYDVQQGEwJS\nVTEPMA0GA1UECAwGTU9TQ09XMQswCQYDVQQKDAJDQTEQMA4GA1UEAwwHUk9PVCBD\nQTAeFw0yMTA3MzAxNTExMzVaFw0yNDA1MTkxNTExMzVaMD0xCzAJBgNVBAYTAlJV\nMQ8wDQYDVQQIDAZNT1NDT1cxCzAJBgNVBAoMAkNBMRAwDgYDVQQDDAdST09UIENB\nMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAo6tZ0NV6QIR/mvsqtAII\nzTTuBMrZR5OTwKvcGnhe4GVDwzJ/OgEWkghLAzOojcJvkfzJOtWwOXqwgphksc+7\n+vwIPTPt3iWjbQUzXK8pFLkjxrO8px/QxPuUrp+U6DTVvvgQesjMZ9jQRUFKOiCc\nu0st1N5Q/CJR4VOJxtYoLy1ZUlsABhwJ+6trkoOFTLRPlMUX1EIG57jYAotHvQFo\nc8UNx3KzvJsJJ56SniXCIkeu61IOt8aOXHU+3TLYhZnPiP311cMbXA0J3vGPRZwz\n25BZjF3IF/ShXlfzz76FjWUTAThc0+HA8lzx53xD4/n8HN+sGubGx9TvLyZimG/U\nGwIDAQABMA0GCSqGSIb3DQEBCwUAA4IBAQAnK8Wzw33fR6R6pqV05XI9Yu8J+BwC\nCn2bKxxYwwQWZyX1as+UIlGuvyBRJba9W2UGMj95FQfWVdDyFC98spUur+O/5yL+\nNHH+dxGnkxIRc6RMIy+GXJwPrLiB/t70hSvwgVa249zNJVcwYN/5SGX5wLaJKnim\neY99xm75nr03O/RJK/DR8HvWysH7zxvrMWs0ppfwxkxrwOcg0Cb9xODVkg/wyClw\nLiHWlmH/eyC8nkiLYJKmV7566VWCV+gy+hC/DRstVVjIMG6LsqaPq6ycm7N8EV8s\nBb5uXIVHW6w5a20c40+W9G4EDYiQjdgEaf0FoMAWGDnOEaPsvjQk2/z5\n-----END CERTIFICATE-----\n-----BEGIN CERTIFICATE-----\nMIIDPDCCAiQCCQDxA75ydLHVoTANBgkqhkiG9w0BAQsFADBgMQswCQYDVQQGEwJS\nVTEPMA0GA1UECAwGTU9TQ09XMQ8wDQYDVQQHDAZNT1NDT1cxFTATBgNVBAoMDElO\nVEVSTUVESUFURTEYMBYGA1UEAwwPSU5URVJNRURJQVRFIENBMB4XDTIxMDczMDE1\nMTIyMloXDTI0MDUxOTE1MTIyMlowYDELMAkGA1UEBhMCUlUxDzANBgNVBAgMBk1P\nU0NPVzEPMA0GA1UEBwwGTU9TQ09XMRUwEwYDVQQKDAxJTlRFUk1FRElBVEUxGDAW\nBgNVBAMMD0lOVEVSTUVESUFURSBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCC\nAQoCggEBAKOrWdDVekCEf5r7KrQCCM007gTK2UeTk8Cr3Bp4XuBlQ8MyfzoBFpII\nSwMzqI3Cb5H8yTrVsDl6sIKYZLHPu/r8CD0z7d4lo20FM1yvKRS5I8azvKcf0MT7\nlK6flOg01b74EHrIzGfY0EVBSjognLtLLdTeUPwiUeFTicbWKC8tWVJbAAYcCfur\na5KDhUy0T5TFF9RCBue42AKLR70BaHPFDcdys7ybCSeekp4lwiJHrutSDrfGjlx1\nPt0y2IWZz4j99dXDG1wNCd7xj0WcM9uQWYxdyBf0oV5X88++hY1lEwE4XNPhwPJc\n8ed8Q+P5/BzfrBrmxsfU7y8mYphv1BsCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEA\ngOHvrh66+bQoG3Lo8bfp7D1Xvm/Md3gJq2nMotl2BH1TvNzMV93fCXygRX8J8rTL\n7xjUC2SbOrFDWFq2hNJQagdecAeuG+U55BY6Wi8SsHw+fhgxQyl9wtXWwotQPmsD\nuRhR1rL3vEphgPLbxNBzA7Lvj+P89Ar988Qy+o5AiUzHMUuqZbGOqs8UcKCQP7e/\nIX+zqqFwqyI8f90SVySGgs574jo8jQFy3l5fnp6yK0MPWg2cBCjpa5H1A+5DADF+\nnryV6Ie/m/wfxmitZZN+YCJu+8Bmmdl/FCwbmiH+HCLhrO8gonH3K21cQujMyFF5\nc7OFj86hvhqbr4kzz1J8lg==\n-----END CERTIFICATE-----" - expiration = "2025-12-28T19:14:44.213" -} diff --git a/examples/resources/edgecenter_securitygroup/import.sh b/examples/resources/edgecenter_securitygroup/import.sh deleted file mode 100644 index 9889ec13..00000000 --- a/examples/resources/edgecenter_securitygroup/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_securitygroup.securitygroup1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_securitygroup/resource.tf b/examples/resources/edgecenter_securitygroup/resource.tf deleted file mode 100644 index 66b85a8e..00000000 --- a/examples/resources/edgecenter_securitygroup/resource.tf +++ /dev/null @@ -1,31 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_securitygroup" "sg" { - name = "test sg" - region_id = 1 - project_id = 1 - - security_group_rules { - direction = "egress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 19990 - port_range_max = 19990 - } - - security_group_rules { - direction = "ingress" - ethertype = "IPv4" - protocol = "tcp" - port_range_min = 19990 - port_range_max = 19990 - } - - security_group_rules { - direction = "egress" - ethertype = "IPv4" - protocol = "vrrp" - } -} diff --git a/examples/resources/edgecenter_servergroup/import.sh b/examples/resources/edgecenter_servergroup/import.sh deleted file mode 100644 index 4f4c4446..00000000 --- a/examples/resources/edgecenter_servergroup/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_servergroup.servergroup1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_servergroup/resource.tf b/examples/resources/edgecenter_servergroup/resource.tf deleted file mode 100644 index d2ba2251..00000000 --- a/examples/resources/edgecenter_servergroup/resource.tf +++ /dev/null @@ -1,10 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_servergroup" "default" { - name = "default" - policy = "affinity" - region_id = 1 - project_id = 1 -} diff --git a/examples/resources/edgecenter_snapshot/import.sh b/examples/resources/edgecenter_snapshot/import.sh deleted file mode 100644 index 49b39669..00000000 --- a/examples/resources/edgecenter_snapshot/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_snapshot.snapshot1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_snapshot/resource.tf b/examples/resources/edgecenter_snapshot/resource.tf deleted file mode 100644 index 177a127d..00000000 --- a/examples/resources/edgecenter_snapshot/resource.tf +++ /dev/null @@ -1,16 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_snapshot" "snapshot" { - project_id = 1 - region_id = 1 - name = "snapshot example" - volume_id = "28e9edcb-1593-41fe-971b-da729c6ec301" - description = "snapshot example description" - metadata = { - env = "test" - } -} - - diff --git a/examples/resources/edgecenter_storage_s3/resource.tf b/examples/resources/edgecenter_storage_s3/resource.tf deleted file mode 100644 index 1f60a513..00000000 --- a/examples/resources/edgecenter_storage_s3/resource.tf +++ /dev/null @@ -1,8 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_storage_s3" "example_s3" { - name = "example" - location = "s-ed1" -} diff --git a/examples/resources/edgecenter_storage_s3_bucket/resource.tf b/examples/resources/edgecenter_storage_s3_bucket/resource.tf deleted file mode 100644 index 1b02e463..00000000 --- a/examples/resources/edgecenter_storage_s3_bucket/resource.tf +++ /dev/null @@ -1,8 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_storage_s3_bucket" "example_s3_bucket" { - name = "example1bucket2name" - storage_id = 1 -} diff --git a/examples/resources/edgecenter_storage_sftp/resource.tf b/examples/resources/edgecenter_storage_sftp/resource.tf deleted file mode 100644 index 1921c167..00000000 --- a/examples/resources/edgecenter_storage_sftp/resource.tf +++ /dev/null @@ -1,9 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_storage_sftp" "example_sftp" { - name = "example" - location = "mia" - ssh_key_id = [199] -} diff --git a/examples/resources/edgecenter_storage_sftp_key/resource.tf b/examples/resources/edgecenter_storage_sftp_key/resource.tf deleted file mode 100644 index 2ef1afbe..00000000 --- a/examples/resources/edgecenter_storage_sftp_key/resource.tf +++ /dev/null @@ -1,8 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_storage_sftp_key" "terraform_test_key" { - name = "terraform_test_key" - key = "ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAklOUpkDHrfHY17SbrmTIpNLTGK9Tjom/BWDSUGPl+nafzlHDTYW7hdI4yZ5ew18JH4JW9jbhUFrviQzM7xlELEVf4h9lFX5QVkbPppSwg0cda3Pbv7kOdJ/MTyBlWXFCR+HAo3FXRitBqxiX1nKhXpHAZsMciLq8V6RjsNAQwdsdMFvSlVK/7XAt3FaoJoAsncM1Q9x5+3V0Ww68/eIFmb1zuUFljQJKprrX88XypNDvjYNby6vw/Pb0rwert/EnmZ+AW4OZPnTPI89ZPmVMLuayrD2cE86Z/il8b+gw3r3+1nKatmIkjn2so1d01QraTlMqVSsbxNrRFi9wrf+M7Q== schacon@mylaptop.local" -} diff --git a/examples/resources/edgecenter_subnet/import.sh b/examples/resources/edgecenter_subnet/import.sh deleted file mode 100644 index 040bc793..00000000 --- a/examples/resources/edgecenter_subnet/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_subnet.subnet1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_subnet/resource.tf b/examples/resources/edgecenter_subnet/resource.tf deleted file mode 100644 index fd88e396..00000000 --- a/examples/resources/edgecenter_subnet/resource.tf +++ /dev/null @@ -1,31 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_network" "network" { - name = "network_example" - mtu = 1450 - type = "vxlan" - region_id = 1 - project_id = 1 -} - -resource "edgecenter_subnet" "subnet" { - name = "subnet_example" - cidr = "192.168.10.0/24" - network_id = edgecenter_network.network.id - dns_nameservers = var.dns_nameservers - - dynamic "host_routes" { - iterator = hr - for_each = var.host_routes - content { - destination = hr.value.destination - nexthop = hr.value.nexthop - } - } - - gateway_ip = "192.168.10.1" - region_id = 1 - project_id = 1 -} \ No newline at end of file diff --git a/examples/resources/edgecenter_subnet/vars.tf b/examples/resources/edgecenter_subnet/vars.tf deleted file mode 100755 index 93e173e9..00000000 --- a/examples/resources/edgecenter_subnet/vars.tf +++ /dev/null @@ -1,21 +0,0 @@ -variable "dns_nameservers" { - type = list(any) - default = ["8.8.4.4", "1.1.1.1"] -} - -variable "host_routes" { - type = list(object({ - destination = string - nexthop = string - })) - default = [ - { - destination = "10.0.3.0/24" - nexthop = "10.0.0.13" - }, - { - destination = "10.0.4.0/24" - nexthop = "10.0.0.14" - }, - ] -} \ No newline at end of file diff --git a/examples/resources/edgecenter_volume/import.sh b/examples/resources/edgecenter_volume/import.sh deleted file mode 100644 index 0ce183fc..00000000 --- a/examples/resources/edgecenter_volume/import.sh +++ /dev/null @@ -1,2 +0,0 @@ -# import using :: format -terraform import edgecenter_volume.volume1 1:6:447d2959-8ae0-4ca0-8d47-9f050a3637d7 \ No newline at end of file diff --git a/examples/resources/edgecenter_volume/resource.tf b/examples/resources/edgecenter_volume/resource.tf deleted file mode 100644 index 1a88bbfa..00000000 --- a/examples/resources/edgecenter_volume/resource.tf +++ /dev/null @@ -1,14 +0,0 @@ -provider "edgecenter" { - permanent_api_token = "251$d3361.............1b35f26d8" -} - -resource "edgecenter_volume" "volume" { - name = "volume_example" - type_name = "standard" - size = 1 - region_id = 1 - project_id = 1 - metadata_map = { - tag1 = "tag1_value" - } -} diff --git a/go.mod b/go.mod index fe83cfcb..388ebb9b 100644 --- a/go.mod +++ b/go.mod @@ -1,93 +1,55 @@ module github.com/Edge-Center/terraform-provider-edgecenter -go 1.20 +go 1.21 require ( - github.com/AlekSi/pointer v1.2.0 - github.com/Edge-Center/edgecenter-dns-sdk-go v0.1.0 - github.com/Edge-Center/edgecenter-storage-sdk-go v0.2.0 - github.com/Edge-Center/edgecentercdn-go v0.1.4 - github.com/Edge-Center/edgecentercloud-go v0.1.10 - github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637 - github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 - github.com/mitchellh/mapstructure v1.5.0 - gopkg.in/yaml.v3 v3.0.1 + github.com/Edge-Center/edgecentercloud-go v0.2.2-0.20231122130207-80bd1dc9310b + github.com/hashicorp/go-cty v1.4.1-0.20200414143053-d3edf31b6320 + github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 ) require ( - github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 // indirect github.com/agext/levenshtein v1.2.2 // indirect github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect - github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 // indirect - github.com/cloudflare/circl v1.3.3 // indirect + github.com/avast/retry-go/v4 v4.5.1 // indirect github.com/fatih/color v1.13.0 // indirect - github.com/go-logr/logr v1.2.3 // indirect - github.com/go-logr/stdr v1.2.2 // indirect - github.com/go-openapi/analysis v0.21.4 // indirect - github.com/go-openapi/errors v0.20.4 // indirect - github.com/go-openapi/jsonpointer v0.19.6 // indirect - github.com/go-openapi/jsonreference v0.20.2 // indirect - github.com/go-openapi/loads v0.21.2 // indirect - github.com/go-openapi/runtime v0.26.0 // indirect - github.com/go-openapi/spec v0.20.9 // indirect - github.com/go-openapi/strfmt v0.21.7 // indirect - github.com/go-openapi/swag v0.22.4 // indirect - github.com/go-openapi/validate v0.22.1 // indirect - github.com/go-playground/locales v0.14.1 // indirect - github.com/go-playground/universal-translator v0.18.1 // indirect - github.com/go-playground/validator/v10 v10.12.0 // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/go-cmp v0.5.9 // indirect - github.com/hashicorp/errwrap v1.1.0 // indirect - github.com/hashicorp/go-checkpoint v0.5.0 // indirect + github.com/google/go-cmp v0.6.0 // indirect + github.com/google/go-querystring v1.1.0 // indirect + github.com/google/uuid v1.3.1 // indirect github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-hclog v1.5.0 // indirect - github.com/hashicorp/go-multierror v1.1.1 // indirect github.com/hashicorp/go-plugin v1.5.1 // indirect + github.com/hashicorp/go-retryablehttp v0.7.4 // indirect github.com/hashicorp/go-uuid v1.0.3 // indirect github.com/hashicorp/go-version v1.6.0 // indirect - github.com/hashicorp/hc-install v0.6.0 // indirect - github.com/hashicorp/hcl/v2 v2.18.0 // indirect + github.com/hashicorp/hcl/v2 v2.19.1 // indirect github.com/hashicorp/logutils v1.0.0 // indirect - github.com/hashicorp/terraform-exec v0.19.0 // indirect - github.com/hashicorp/terraform-json v0.17.1 // indirect github.com/hashicorp/terraform-plugin-go v0.19.0 // indirect github.com/hashicorp/terraform-plugin-log v0.9.0 // indirect github.com/hashicorp/terraform-registry-address v0.2.2 // indirect github.com/hashicorp/terraform-svchost v0.1.1 // indirect github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d // indirect - github.com/josharian/intern v1.0.0 // indirect - github.com/ladydascalie/currency v1.6.0 // indirect - github.com/leodido/go-urn v1.2.2 // indirect - github.com/mailru/easyjson v0.7.7 // indirect - github.com/mattn/go-colorable v0.1.13 // indirect - github.com/mattn/go-isatty v0.0.16 // indirect + github.com/kr/pretty v0.2.1 // indirect + github.com/kr/text v0.2.0 // indirect + github.com/mattn/go-colorable v0.1.12 // indirect + github.com/mattn/go-isatty v0.0.14 // indirect github.com/mitchellh/copystructure v1.2.0 // indirect github.com/mitchellh/go-testing-interface v1.14.1 // indirect github.com/mitchellh/go-wordwrap v1.0.0 // indirect + github.com/mitchellh/mapstructure v1.5.0 // indirect github.com/mitchellh/reflectwalk v1.0.2 // indirect github.com/oklog/run v1.0.0 // indirect - github.com/oklog/ulid v1.3.1 // indirect - github.com/opentracing/opentracing-go v1.2.0 // indirect - github.com/rogpeppe/go-internal v1.11.0 // indirect - github.com/shopspring/decimal v1.3.1 // indirect - github.com/sirupsen/logrus v1.8.2 // indirect github.com/vmihailenco/msgpack v4.0.4+incompatible // indirect github.com/vmihailenco/msgpack/v5 v5.3.5 // indirect github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect - github.com/zclconf/go-cty v1.14.0 // indirect - go.mongodb.org/mongo-driver v1.11.3 // indirect - go.opentelemetry.io/otel v1.14.0 // indirect - go.opentelemetry.io/otel/trace v1.14.0 // indirect - golang.org/x/crypto v0.13.0 // indirect - golang.org/x/mod v0.12.0 // indirect - golang.org/x/net v0.15.0 // indirect - golang.org/x/sync v0.3.0 // indirect - golang.org/x/sys v0.12.0 // indirect - golang.org/x/text v0.13.0 // indirect + github.com/zclconf/go-cty v1.14.1 // indirect + golang.org/x/net v0.17.0 // indirect + golang.org/x/sys v0.14.0 // indirect + golang.org/x/text v0.14.0 // indirect google.golang.org/appengine v1.6.7 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 // indirect - google.golang.org/grpc v1.57.0 // indirect + google.golang.org/grpc v1.57.1 // indirect google.golang.org/protobuf v1.31.0 // indirect - gopkg.in/yaml.v2 v2.4.0 // indirect + gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c // indirect ) diff --git a/go.sum b/go.sum index 9031f562..0decadc0 100644 --- a/go.sum +++ b/go.sum @@ -1,275 +1,104 @@ -dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= -github.com/AlekSi/pointer v1.2.0 h1:glcy/gc4h8HnG2Z3ZECSzZ1IX1x2JxRVuDzaJwQE0+w= -github.com/AlekSi/pointer v1.2.0/go.mod h1:gZGfd3dpW4vEc/UlyfKKi1roIqcCgwOIvb0tSNSBle0= -github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/Edge-Center/edgecenter-dns-sdk-go v0.1.0 h1:MDQr/60IhD1x7f5Bs20ljTQXGXFp0Uwx2+VaxtFRaDk= -github.com/Edge-Center/edgecenter-dns-sdk-go v0.1.0/go.mod h1:xWN2LYVokamADMRz1cPhOrYX/NlxiDJp9tjBumHU5G8= -github.com/Edge-Center/edgecenter-storage-sdk-go v0.2.0 h1:1aPDpywWbaF7VEjP/GjVoSgcipxWTTzEPPZv5kOWE8A= -github.com/Edge-Center/edgecenter-storage-sdk-go v0.2.0/go.mod h1:TcWO0BPvDsE6AGlPBqpKCZhoQ70rRlqmm85J32qcL8I= -github.com/Edge-Center/edgecentercdn-go v0.1.4 h1:Jt8f+CSriwVQ/KAb+a+v1dDNChtHjlpilgJOX8mOSx0= -github.com/Edge-Center/edgecentercdn-go v0.1.4/go.mod h1:RwEyxwPAmxor1mZKUTa2bIU2p5qM6kcAofUkaE4O1V4= -github.com/Edge-Center/edgecentercloud-go v0.1.10 h1:+mtt9/n4RBTKZwF0N5xlvCNTE74R+Qk29Na+zZgy/Vk= -github.com/Edge-Center/edgecentercloud-go v0.1.10/go.mod h1:kmXGtx0lL1ib+SPfJe/uIAyDHamquAvqiftoLSyhxF8= -github.com/Microsoft/go-winio v0.6.1 h1:9/kr64B9VUZrLm5YYwbGtUJnMgqWVOdUAXu6Migciow= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95 h1:KLq8BE0KwCL+mmXnjLWEAOYO+2l2AE4YMmqG1ZpZHBs= -github.com/ProtonMail/go-crypto v0.0.0-20230717121422-5aa5874ade95/go.mod h1:EjAoLdwvbIOoOQr3ihjnSoLZRtE8azugULFRteWMNc0= -github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= -github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= -github.com/acomagu/bufpipe v1.0.4 h1:e3H4WUzM3npvo5uv95QuJM3cQspFNtFBzvJ2oNjKIDQ= +github.com/Edge-Center/edgecentercloud-go v0.2.2-0.20231122130207-80bd1dc9310b h1:gKnGj0ZY1uOOs8R/P6OZnnKuk9QiHp5UJGeuTxQGq9E= +github.com/Edge-Center/edgecentercloud-go v0.2.2-0.20231122130207-80bd1dc9310b/go.mod h1:zfzX+BWQ1yHMMsDerql6dSUD5bjPp4POg6B7ptr8YHQ= github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE= github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558= github.com/apparentlymart/go-textseg/v12 v12.0.0/go.mod h1:S/4uRK2UtaQttw1GenVJEynmyUenKwP++x/+DdGV/Ec= github.com/apparentlymart/go-textseg/v15 v15.0.0 h1:uYvfpb3DyLSCGWnctWKGj857c6ew1u1fNQOlOtuGxQY= github.com/apparentlymart/go-textseg/v15 v15.0.0/go.mod h1:K8XmNZdhEBkdlyDdvbmmsvpAG721bKi0joRfFdHIWJ4= -github.com/asaskevich/govalidator v0.0.0-20200907205600-7a23bdc65eef/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2 h1:DklsrG3dyBCFEj5IhUbnKptjxatkF07cF2ak3yi77so= -github.com/asaskevich/govalidator v0.0.0-20230301143203-a9d515a09cc2/go.mod h1:WaHUgvxTVq04UNunO+XhnAqY/wQc+bxr74GqbsZ/Jqw= +github.com/avast/retry-go/v4 v4.5.1 h1:AxIx0HGi4VZ3I02jr78j5lZ3M6x1E0Ivxa6b0pUUh7o= +github.com/avast/retry-go/v4 v4.5.1/go.mod h1:/sipNsvNB3RRuT5iNcb6h73nw3IBmXJ/H3XrCQYSOpc= github.com/bufbuild/protocompile v0.4.0 h1:LbFKd2XowZvQ/kajzguUp2DC9UEIQhIq77fZZlaQsNA= -github.com/bwesterb/go-ristretto v1.2.3/go.mod h1:fUIoIZaG73pV5biE2Blr2xEzDoMj7NFEuV9ekS419A0= -github.com/cloudflare/circl v1.3.3 h1:fE/Qz0QdIGqeWfnwq0RE0R7MI51s0M2E4Ga9kq5AEMs= -github.com/cloudflare/circl v1.3.3/go.mod h1:5XYMA4rFBvNIrhs50XuiBJ15vF2pZn4nnUKZrLbUZFA= +github.com/bufbuild/protocompile v0.4.0/go.mod h1:3v93+mbWn/v3xzN+31nwkJfrEpAUwp+BagBSZWx+TP8= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/emirpasic/gods v1.18.1 h1:FXtiHYKDGKCW2KzwZKx0iC0PQmdlorYgdFG9jPXJ1Bc= github.com/fatih/color v1.13.0 h1:8LOYc1KYPPmyKMuN8QV2DNRWNbLo6LZ0iLs8+mlH53w= github.com/fatih/color v1.13.0/go.mod h1:kLAiJbzzSOZDVNGyDpeOxJ47H46qBXwg5ILebYFFOfk= -github.com/go-git/gcfg v1.5.1-0.20230307220236-3a3c6141e376 h1:+zs/tPmkDkHx3U66DAb0lQFJrpS6731Oaa12ikc+DiI= -github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4= -github.com/go-git/go-git/v5 v5.8.1 h1:Zo79E4p7TRk0xoRgMq0RShiTHGKcKI4+DI6BfJc/Q+A= -github.com/go-logr/logr v1.2.2/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -github.com/go-logr/logr v1.2.3 h1:2DntVwHkVopvECVRSlL5PSo9eG+cAkDCuckLubN+rq0= -github.com/go-logr/logr v1.2.3/go.mod h1:jdQByPbusPIv2/zmleS9BjJVeZ6kBagPoEUsqbVz/1A= -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-openapi/analysis v0.21.2/go.mod h1:HZwRk4RRisyG8vx2Oe6aqeSQcoxRp47Xkp3+K6q+LdY= -github.com/go-openapi/analysis v0.21.4 h1:ZDFLvSNxpDaomuCueM0BlSXxpANBlFYiBvr+GXrvIHc= -github.com/go-openapi/analysis v0.21.4/go.mod h1:4zQ35W4neeZTqh3ol0rv/O8JBbka9QyAgQRPp9y3pfo= -github.com/go-openapi/errors v0.19.8/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.19.9/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.2/go.mod h1:cM//ZKUKyO06HSwqAelJ5NsEMMcpa6VpXe8DOa1Mi1M= -github.com/go-openapi/errors v0.20.4 h1:unTcVm6PispJsMECE3zWgvG4xTiKda1LIR5rCRWLG6M= -github.com/go-openapi/errors v0.20.4/go.mod h1:Z3FlZ4I8jEGxjUK+bugx3on2mIAk4txuAOhlsB1FSgk= -github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= -github.com/go-openapi/jsonpointer v0.19.6 h1:eCs3fxoIi3Wh6vtgmLTOjdhSpiqphQ+DaPn38N2ZdrE= -github.com/go-openapi/jsonpointer v0.19.6/go.mod h1:osyAmYz/mB/C3I+WsTTSgw1ONzaLJoLCyoi6/zppojs= -github.com/go-openapi/jsonreference v0.19.6/go.mod h1:diGHMEHg2IqXZGKxqyvWdfWU/aim5Dprw5bqpKkTvns= -github.com/go-openapi/jsonreference v0.20.0/go.mod h1:Ag74Ico3lPc+zR+qjn4XBUmXymS4zJbYVCZmcgkasdo= -github.com/go-openapi/jsonreference v0.20.2 h1:3sVjiK66+uXK/6oQ8xgcRKcFgQ5KXa2KvnJRumpMGbE= -github.com/go-openapi/jsonreference v0.20.2/go.mod h1:Bl1zwGIM8/wsvqjsOQLJ/SH+En5Ap4rVB5KVcIDZG2k= -github.com/go-openapi/loads v0.21.1/go.mod h1:/DtAMXXneXFjbQMGEtbamCZb+4x7eGwkvZCvBmwUG+g= -github.com/go-openapi/loads v0.21.2 h1:r2a/xFIYeZ4Qd2TnGpWDIQNcP80dIaZgf704za8enro= -github.com/go-openapi/loads v0.21.2/go.mod h1:Jq58Os6SSGz0rzh62ptiu8Z31I+OTHqmULx5e/gJbNw= -github.com/go-openapi/runtime v0.26.0 h1:HYOFtG00FM1UvqrcxbEJg/SwvDRvYLQKGhw2zaQjTcc= -github.com/go-openapi/runtime v0.26.0/go.mod h1:QgRGeZwrUcSHdeh4Ka9Glvo0ug1LC5WyE+EV88plZrQ= -github.com/go-openapi/spec v0.20.4/go.mod h1:faYFR1CvsJZ0mNsmsphTMSoRrNV3TEDoAM7FOEWeq8I= -github.com/go-openapi/spec v0.20.6/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/spec v0.20.9 h1:xnlYNQAwKd2VQRRfwTEI0DcK+2cbuvI/0c7jx3gA8/8= -github.com/go-openapi/spec v0.20.9/go.mod h1:2OpW+JddWPrpXSCIX8eOx7lZ5iyuWj3RYR6VaaBKcWA= -github.com/go-openapi/strfmt v0.21.0/go.mod h1:ZRQ409bWMj+SOgXofQAGTIo2Ebu72Gs+WaRADcS5iNg= -github.com/go-openapi/strfmt v0.21.1/go.mod h1:I/XVKeLc5+MM5oPNN7P6urMOpuLXEcNrCX/rPGuWb0k= -github.com/go-openapi/strfmt v0.21.3/go.mod h1:k+RzNO0Da+k3FrrynSNN8F7n/peCmQQqbbXjtDfvmGg= -github.com/go-openapi/strfmt v0.21.7 h1:rspiXgNWgeUzhjo1YU01do6qsahtJNByjLVbPLNHb8k= -github.com/go-openapi/strfmt v0.21.7/go.mod h1:adeGTkxE44sPyLk0JV235VQAO/ZXUr8KAzYjclFs3ew= -github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= -github.com/go-openapi/swag v0.19.15/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.21.1/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= -github.com/go-openapi/swag v0.22.3/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/swag v0.22.4 h1:QLMzNJnMGPRNDCbySlcj1x01tzU8/9LTTL9hZZZogBU= -github.com/go-openapi/swag v0.22.4/go.mod h1:UzaqsxGiab7freDnrUUra0MwWfN/q7tE4j+VcZ0yl14= -github.com/go-openapi/validate v0.22.1 h1:G+c2ub6q47kfX1sOBLwIQwzBVt8qmOAARyo/9Fqs9NU= -github.com/go-openapi/validate v0.22.1/go.mod h1:rjnrwK57VJ7A8xqfpAOEKRH8yQSGUriMu5/zuPSQ1hg= -github.com/go-playground/assert/v2 v2.2.0 h1:JvknZsQTYeFEAhQwI4qEt9cyV5ONwRHC+lYKSsYSR8s= -github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/oXslEjJA= -github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY= -github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY= -github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY= -github.com/go-playground/validator/v10 v10.12.0 h1:E4gtWgxWxp8YSxExrQFv5BpCahla0PVF2oTTEYaWQGI= -github.com/go-playground/validator/v10 v10.12.0/go.mod h1:hCAPuzYvKdP33pxWa+2+6AIKXEKqjIUyqsNCtbsSJrA= -github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68= -github.com/gobuffalo/attrs v0.0.0-20190224210810-a9411de4debd/go.mod h1:4duuawTqi2wkkpB4ePgWMaai6/Kc6WEz83bhFwpHzj0= -github.com/gobuffalo/depgen v0.0.0-20190329151759-d478694a28d3/go.mod h1:3STtPUQYuzV0gBVOY3vy6CfMm/ljR4pABfrTeHNLHUY= -github.com/gobuffalo/depgen v0.1.0/go.mod h1:+ifsuy7fhi15RWncXQQKjWS9JPkdah5sZvtHc2RXGlg= -github.com/gobuffalo/envy v1.6.15/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI= -github.com/gobuffalo/flect v0.1.0/go.mod h1:d2ehjJqGOH/Kjqcoz+F7jHTBbmDb38yXA598Hb50EGs= -github.com/gobuffalo/flect v0.1.1/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/flect v0.1.3/go.mod h1:8JCgGVbRjJhVgD6399mQr4fx5rRfGKVzFjbj6RE/9UI= -github.com/gobuffalo/genny v0.0.0-20190329151137-27723ad26ef9/go.mod h1:rWs4Z12d1Zbf19rlsn0nurr75KqhYp52EAGGxTbBhNk= -github.com/gobuffalo/genny v0.0.0-20190403191548-3ca520ef0d9e/go.mod h1:80lIj3kVJWwOrXWWMRzzdhW3DsrdjILVil/SFKBzF28= -github.com/gobuffalo/genny v0.1.0/go.mod h1:XidbUqzak3lHdS//TPu2OgiFB+51Ur5f7CSnXZ/JDvo= -github.com/gobuffalo/genny v0.1.1/go.mod h1:5TExbEyY48pfunL4QSXxlDOmdsD44RRq4mVZ0Ex28Xk= -github.com/gobuffalo/gitgen v0.0.0-20190315122116-cc086187d211/go.mod h1:vEHJk/E9DmhejeLeNt7UVvlSGv3ziL+djtTr3yyzcOw= -github.com/gobuffalo/gogen v0.0.0-20190315121717-8f38393713f5/go.mod h1:V9QVDIxsgKNZs6L2IYiGR8datgMhB577vzTDqypH360= -github.com/gobuffalo/gogen v0.1.0/go.mod h1:8NTelM5qd8RZ15VjQTFkAW6qOMx5wBbW4dSCS3BY8gg= -github.com/gobuffalo/gogen v0.1.1/go.mod h1:y8iBtmHmGc4qa3urIyo1shvOD8JftTtfcKi+71xfDNE= -github.com/gobuffalo/logger v0.0.0-20190315122211-86e12af44bc2/go.mod h1:QdxcLw541hSGtBnhUc4gaNIXRjiDppFGaDqzbrBd3v8= -github.com/gobuffalo/mapi v1.0.1/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/mapi v1.0.2/go.mod h1:4VAGh89y6rVOvm5A8fKFxYG+wIW6LO1FMTG9hnKStFc= -github.com/gobuffalo/packd v0.0.0-20190315124812-a385830c7fc0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packd v0.1.0/go.mod h1:M2Juc+hhDXf/PnmBANFCqx4DM3wRbgDvnVWeG2RIxq4= -github.com/gobuffalo/packr/v2 v2.0.9/go.mod h1:emmyGweYTm6Kdper+iywB6YK5YzuKchGtJQZ0Odn4pQ= -github.com/gobuffalo/packr/v2 v2.2.0/go.mod h1:CaAwI0GPIAv+5wKLtv8Afwl+Cm78K/I/VCm/3ptBN+0= -github.com/gobuffalo/syncx v0.0.0-20190224160051-33c29581e754/go.mod h1:HhnNqWY95UYwwW3uSASeV7vtgYkT2t16hJgV3AEPUpw= -github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE= +github.com/go-test/deep v1.0.3/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= github.com/golang/protobuf v1.1.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.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/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.5.2/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= 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/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= -github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= -github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= -github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= -github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU= -github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg= -github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +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-querystring v1.1.0 h1:AnCroh3fv4ZBgVIf1Iwtovgjaw/GiKJo8M8yD/fhyJ8= +github.com/google/go-querystring v1.1.0/go.mod h1:Kcdr2DB4koayq7X8pmAG4sNG59So17icRSOU623lUBU= +github.com/google/uuid v1.3.1 h1:KjJaJ9iWZ3jOFZIf1Lqf4laDRCasjl0BCmnEGxkdLb4= +github.com/google/uuid v1.3.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637 h1:Ud/6/AdmJ1R7ibdS0Wo5MWPj0T1R0fkpaD087bBaW8I= -github.com/hashicorp/go-cty v1.4.1-0.20200723130312-85980079f637/go.mod h1:EiZBMaudVLy8fmjf9Npq1dq9RalhveqZG5w/yz3mHWs= +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.5.0 h1:bI2ocEMgcVlz55Oj1xZNBsVi900c7II+fWDyV9o+13c= github.com/hashicorp/go-hclog v1.5.0/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= -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.5.1 h1:oGm7cWBaYIp3lJpx1RUEfLWophprE2EV/KUeqBYo+6k= github.com/hashicorp/go-plugin v1.5.1/go.mod h1:w1sAEES3g3PuV/RzUrgow20W2uErMly84hhD3um1WL4= -github.com/hashicorp/go-uuid v1.0.0/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= +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-uuid v1.0.3 h1:2gKiV6YVmrJ1i2CKKa9obLvRieoRGviZFL26PcT/Co8= github.com/hashicorp/go-uuid v1.0.3/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro= github.com/hashicorp/go-version v1.6.0 h1:feTTfFNnjP967rlCxM/I9g701jU+RN74YKx2mOkIeek= github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= -github.com/hashicorp/hc-install v0.6.0 h1:fDHnU7JNFNSQebVKYhHZ0va1bC6SrPQ8fpebsvNr2w4= -github.com/hashicorp/hc-install v0.6.0/go.mod h1:10I912u3nntx9Umo1VAeYPUUuehk0aRQJYpMwbX5wQA= -github.com/hashicorp/hcl/v2 v2.18.0 h1:wYnG7Lt31t2zYkcquwgKo6MWXzRUDIeIVU5naZwHLl8= -github.com/hashicorp/hcl/v2 v2.18.0/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= +github.com/hashicorp/hcl/v2 v2.19.1 h1://i05Jqznmb2EXqa39Nsvyan2o5XyMowW5fnCKW5RPI= +github.com/hashicorp/hcl/v2 v2.19.1/go.mod h1:ThLC89FV4p9MPW804KVbe/cEXoQ8NZEh+JtMeeGErHE= github.com/hashicorp/logutils v1.0.0 h1:dLEQVugN8vlakKOUE3ihGLTZJRB4j+M2cdTm/ORI65Y= github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO+LraFDTW64= -github.com/hashicorp/terraform-exec v0.19.0 h1:FpqZ6n50Tk95mItTSS9BjeOVUb4eg81SpgVtZNNtFSM= -github.com/hashicorp/terraform-exec v0.19.0/go.mod h1:tbxUpe3JKruE9Cuf65mycSIT8KiNPZ0FkuTE3H4urQg= -github.com/hashicorp/terraform-json v0.17.1 h1:eMfvh/uWggKmY7Pmb3T85u86E2EQg6EQHgyRwf3RkyA= -github.com/hashicorp/terraform-json v0.17.1/go.mod h1:Huy6zt6euxaY9knPAFKjUITn8QxUFIe9VuSzb4zn/0o= github.com/hashicorp/terraform-plugin-go v0.19.0 h1:BuZx/6Cp+lkmiG0cOBk6Zps0Cb2tmqQpDM3iAtnhDQU= github.com/hashicorp/terraform-plugin-go v0.19.0/go.mod h1:EhRSkEPNoylLQntYsk5KrDHTZJh9HQoumZXbOGOXmec= github.com/hashicorp/terraform-plugin-log v0.9.0 h1:i7hOA+vdAItN1/7UrfBqBwvYPQ9TFvymaRGZED3FCV0= github.com/hashicorp/terraform-plugin-log v0.9.0/go.mod h1:rKL8egZQ/eXSyDqzLUuwUYLVdlYeamldAHSxjUFADow= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0 h1:wcOKYwPI9IorAJEBLzgclh3xVolO7ZorYd6U1vnok14= -github.com/hashicorp/terraform-plugin-sdk/v2 v2.29.0/go.mod h1:qH/34G25Ugdj5FcM95cSoXzUgIbgfhVLXCcEcYaMwq8= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0 h1:X7vB6vn5tON2b49ILa4W7mFAsndeqJ7bZFOGbVO+0Cc= +github.com/hashicorp/terraform-plugin-sdk/v2 v2.30.0/go.mod h1:ydFcxbdj6klCqYEPkPvdvFKiNGKZLUs+896ODUXCyao= github.com/hashicorp/terraform-registry-address v0.2.2 h1:lPQBg403El8PPicg/qONZJDC6YlgCVbWDtNmmZKtBno= github.com/hashicorp/terraform-registry-address v0.2.2/go.mod h1:LtwNbCihUoUZ3RYriyS2wF/lGPB6gF9ICLRtuDk7hSo= github.com/hashicorp/terraform-svchost v0.1.1 h1:EZZimZ1GxdqFRinZ1tpJwVxxt49xc/S52uzrw4x0jKQ= github.com/hashicorp/terraform-svchost v0.1.1/go.mod h1:mNsjQfZyf/Jhz35v6/0LWcv26+X7JPS+buii2c9/ctc= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ= github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM= -github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= -github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A= github.com/jhump/protoreflect v1.15.1 h1:HUMERORf3I3ZdX05WaQ6MIpd/NJ434hTp5YiKgfCL6c= -github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= -github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= -github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= -github.com/karrick/godirwalk v1.8.0/go.mod h1:H5KPZjojv4lE+QYImBI8xVtrBRgYrIVsaRPx4tDPEn4= -github.com/karrick/godirwalk v1.10.3/go.mod h1:RoGL9dQei4vP9ilrpETWE8CLOZ1kiN0LhBygSwrAsHA= -github.com/kevinburke/ssh_config v1.2.0 h1:x584FjTGwHzMwvHx18PXxbBVzfnxogHaAReU4gf13a4= -github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk= -github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= -github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/jhump/protoreflect v1.15.1/go.mod h1:jD/2GMKKE6OqX8qTjhADU1e6DShO+gavG9e0Q693nKo= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= +github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI= github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= 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 v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc= -github.com/ladydascalie/currency v1.6.0 h1:r5s/TMCYcpn6jPRHLV3F8nI7YjpY8trvstfuixxiHns= -github.com/ladydascalie/currency v1.6.0/go.mod h1:C9eil8e6tthhBb5yhwoH1U0LT5hm1BP/g+v/V82KYjY= -github.com/leodido/go-urn v1.2.2 h1:7z68G0FCGvDk646jz1AelTYNYWrTNm0bEcFAo147wt4= -github.com/leodido/go-urn v1.2.2/go.mod h1:kUaIbLZWttglzwNuG0pgsh5vuV6u2YcGBYz1hIPjtOQ= -github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= -github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0= -github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= -github.com/markbates/oncer v0.0.0-20181203154359-bf2de49a0be2/go.mod h1:Ld9puTsIW75CHf65OeIOkyKbteujpZVXDpWK6YGZbxE= -github.com/markbates/safe v1.0.1/go.mod h1:nAqgmRi7cY2nqMc92/bSEeQA+R4OheNU2T1kNSCBdG0= +github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw= github.com/mattn/go-colorable v0.1.9/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.12 h1:jF+Du6AlPIjs2BiUiQlKOX0rt3SujHxPnksPKZbaA40= github.com/mattn/go-colorable v0.1.12/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4= -github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= -github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y= github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94= -github.com/mattn/go-isatty v0.0.16 h1:bq3VjFmv/sOjHtdEhmkEV4x1AJtvUvOJ2PFAZ5+peKQ= -github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw= github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s= github.com/mitchellh/go-testing-interface v1.14.1 h1:jrgshOhYAUVNMAJiKbEu7EqAwgJJ2JqpQmpLJOu07cU= github.com/mitchellh/go-testing-interface v1.14.1/go.mod h1:gfgS7OtZj6MA4U1UrDRp04twqAjfvlZyCfX3sDjEym8= github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= -github.com/mitchellh/mapstructure v1.3.3/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= -github.com/mitchellh/mapstructure v1.4.1/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY= github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo= github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ= github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= -github.com/montanaflynn/stats v0.0.0-20171201202039-1bf9dbcd8cbe/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= -github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw= github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA= -github.com/oklog/ulid v1.3.1 h1:EGfNDEx6MqHz8B3uNV6QAib1UR2Lm97sHi3ocA6ESJ4= -github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= -github.com/opentracing/opentracing-go v1.2.0 h1:uEJPy/1a5RIPAJ0Ov+OIO8OxWu77jEv+1B0VhjKrZUs= -github.com/opentracing/opentracing-go v1.2.0/go.mod h1:GxEUsuufX4nBwe+T+Wl9TAgYrxe9dPLANfrWvHYVTgc= -github.com/pelletier/go-toml v1.7.0/go.mod h1:vwGMzjaWMwyfHwgIBhI2YUM4fB6nL6lVAvS1LBMMhTE= -github.com/pjbgf/sha1cd v0.3.0 h1:4D5XXmUUBUl/xQ6IjCkEAbqXskkq/4O7LmGn0AqMDs4= -github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= -github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= -github.com/rogpeppe/go-internal v1.1.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.2.2/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= -github.com/rwtodd/Go.Sed v0.0.0-20210816025313-55464686f9ef/go.mod h1:8AEUvGVi2uQ5b24BIhcr0GCcpd/RNAFWaN2CJFrWIIQ= -github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ= -github.com/shopspring/decimal v1.3.1 h1:2Usl1nmF/WZucqkFZhnfFYxxxu8LG21F6nPQBE5gKV8= -github.com/shopspring/decimal v1.3.1/go.mod h1:DKyhrW/HYNuLGql+MJL6WCR6knT2jwCFRcu2hWCYk4o= -github.com/sirupsen/logrus v1.4.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= -github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= -github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= -github.com/sirupsen/logrus v1.8.2 h1:Na+MAUL+cI0P3CtS35fqYIYVL6uKkDYY7sptpCtHHlI= -github.com/sirupsen/logrus v1.8.2/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ= -github.com/skeema/knownhosts v1.2.0 h1:h9r9cf0+u7wSE+M183ZtMGgOJKiL96brpaz5ekfJCpM= -github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= -github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= -github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= -github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.7.2/go.mod h1:R6va5+xMeoiuVRoj+gSkQ7d3FALtqAAGI1FQKckRals= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= -github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= -github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= -github.com/tidwall/pretty v1.0.0 h1:HsD+QiTn7sK6flMKIvNmpqz1qrpP3Ps6jOKIKMooyg4= -github.com/tidwall/pretty v1.0.0/go.mod h1:XNkn88O1ChpSDQmQeStsy+sBenx6DDtFZJxhVysOjyk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= @@ -277,141 +106,43 @@ github.com/vmihailenco/msgpack/v5 v5.3.5 h1:5gO0H1iULLWGhs2H5tbAHIZTV8/cYafcFOr9 github.com/vmihailenco/msgpack/v5 v5.3.5/go.mod h1:7xyJ9e+0+9SaZT0Wt1RGleJXzli6Q/V5KbhBonMG9jc= github.com/vmihailenco/tagparser/v2 v2.0.0 h1:y09buUbR+b5aycVFQs/g70pqKVZNBmxwAhO7/IwNM9g= github.com/vmihailenco/tagparser/v2 v2.0.0/go.mod h1:Wri+At7QHww0WTrCBeu4J6bNtoV6mEfg5OIWRZA9qds= -github.com/xanzy/ssh-agent v0.3.3 h1:+/15pJfg/RsTxqYcX6fHqOXZwwMP+2VyYWJeWM2qQFM= -github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI= -github.com/xdg-go/scram v1.0.2/go.mod h1:1WAq6h33pAW+iRreB34OORO2Nf7qel3VV3fjBj+hCSs= -github.com/xdg-go/scram v1.1.1/go.mod h1:RaEWvsqvNKKvBPvcKeFjrG2cJqOkHTiyTpzz23ni57g= -github.com/xdg-go/stringprep v1.0.2/go.mod h1:8F9zXuvzgwmyT5DUm4GUfZGDdT3W+LCvS6+da4O5kxM= -github.com/xdg-go/stringprep v1.0.3/go.mod h1:W3f5j4i+9rC0kuIEJL0ky1VpHXQU3ocBgklLGvcBnW8= -github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA= -github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= -github.com/zclconf/go-cty v1.14.0 h1:/Xrd39K7DXbHzlisFP9c4pHao4yyf+/Ug9LEz+Y/yhc= -github.com/zclconf/go-cty v1.14.0/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= -go.mongodb.org/mongo-driver v1.7.3/go.mod h1:NqaYOwnXWr5Pm7AOpO5QFxKJ503nbMse/R79oO62zWg= -go.mongodb.org/mongo-driver v1.7.5/go.mod h1:VXEWRZ6URJIkUq2SCAyapmhH0ZLRBP+FT4xhp5Zvxng= -go.mongodb.org/mongo-driver v1.10.0/go.mod h1:wsihk0Kdgv8Kqu1Anit4sfK+22vSFbUrAVEYRhCXrA8= -go.mongodb.org/mongo-driver v1.11.3 h1:Ql6K6qYHEzB6xvu4+AU0BoRoqf9vFPcc4o7MUIdPW8Y= -go.mongodb.org/mongo-driver v1.11.3/go.mod h1:PTSz5yu21bkT/wXpkS7WR5f0ddqw5quethTUn9WM+2g= -go.opentelemetry.io/otel v1.14.0 h1:/79Huy8wbf5DnIPhemGB+zEPVwnN6fuQybr/SRXa6hM= -go.opentelemetry.io/otel v1.14.0/go.mod h1:o4buv+dJzx8rohcUeRmWUZhqupFvzWis188WlggnNeU= -go.opentelemetry.io/otel/sdk v1.14.0 h1:PDCppFRDq8A1jL9v6KMI6dYesaq+DFcDZvjsoGvxGzY= -go.opentelemetry.io/otel/trace v1.14.0 h1:wp2Mmvj41tDsyAJXiWDWpfNsOiIyd38fy85pyKcFq/M= -go.opentelemetry.io/otel/trace v1.14.0/go.mod h1:8avnQLK+CG77yNLUae4ea2JDQ6iT+gozhnZjy/rw9G8= -golang.org/x/crypto v0.0.0-20180904163835-0709b304e793/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= +github.com/zclconf/go-cty v1.14.1 h1:t9fyA35fwjjUMcmL5hLER+e/rEPqrbCK1/OSE4SI9KA= +github.com/zclconf/go-cty v1.14.1/go.mod h1:VvMs5i0vgZdhYawQNq5kePSpLAoz8u1xvZgrPIxfnZE= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190422162423-af44ce270edf/go.mod h1:WFFai1msRO1wXaEeE5yQxYXgSfI8pQAWXbQop6sCtWE= -golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.0.0-20220622213112-05595931fe9d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.3.1-0.20221117191849-2c476679df9a/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4= -golang.org/x/crypto v0.7.0/go.mod h1:pYwdfH91IfpZVANVyUOhSIPZaFoJGxTFbZhFTx+dXZU= -golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck= -golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc= -golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= -golang.org/x/net v0.0.0-20210421230115-4e50805a0758/go.mod h1:72T/g9IO56b78aLF+1Kcs5dz7/ng1VjMUvfKvpfy+jM= -golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY= -golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= -golang.org/x/net v0.8.0/go.mod h1:QVkue5JL9kW//ek3r6jTKnTFis1tRmNAW2P1shuFdJc= -golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8= -golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk= +golang.org/x/net v0.17.0 h1:pVaXccu2ozPjCXewfr1S7xza/zcXTity9cCdXQYSjIM= +golang.org/x/net v0.17.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20190412183630-56d357773e84/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-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/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.1.0/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/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-20190403152447-81d4e9dc473e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190419153524-e8e3143a4f4a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190531175056-4c3a928424d2/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210420072515-93ed5bcd2bfe/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220503163025-988cb79eb6c6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.3.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o= -golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -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.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc= -golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= -golang.org/x/term v0.6.0/go.mod h1:m6U89DPEgQRMq3DNkDClhWw02AUbt2daBVO4cn4Hv9U= +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/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.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= -golang.org/x/text v0.3.6/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.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= -golang.org/x/text v0.8.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= -golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k= -golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE= +golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ= +golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190416151739-9c9e1878f421/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190420181800-aa740d480789/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20190531172133-b3315ee88b7d/go.mod h1:/rFqwRUd4F7ZHNgwSSTFct+R/Kf4OFW1sUzUTQQTgfc= -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.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM= -golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= -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.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c= google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19 h1:0nDDozoAU19Qb2HwhXadU8OcsiO/09cnTqhUtq2MEOM= google.golang.org/genproto/googleapis/rpc v0.0.0-20230525234030-28d5490b6b19/go.mod h1:66JfowdXAEgad5O9NnYcsNPLCPZJD++2L9X0PCMODrA= -google.golang.org/grpc v1.57.0 h1:kfzNeI/klCGD2YPMUlaGNT3pxvYfga7smW3Vth8Zsiw= -google.golang.org/grpc v1.57.0/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= +google.golang.org/grpc v1.57.1 h1:upNTNqv0ES+2ZOOqACwVtS3Il8M12/+Hz41RCPzAjQg= +google.golang.org/grpc v1.57.1/go.mod h1:Sd+9RMTACXwmub0zcNY2c4arhtrbBYD1AUHI/dt16Mo= 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.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= 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-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= -gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME= -gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= -gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY= -gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200605160147-a5ece683394c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20200615113413-eeeca48fe776/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= -gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/main.go b/main.go index 81b01699..fb3176e5 100644 --- a/main.go +++ b/main.go @@ -16,11 +16,9 @@ func main() { flag.StringVar(&address, "address", "provider", "this value is used in the TF_REATTACH_PROVIDERS environment variable during debugging") flag.Parse() - opts := &plugin.ServeOpts{ + plugin.Serve(&plugin.ServeOpts{ Debug: debug, ProviderAddr: address, ProviderFunc: edgecenter.Provider, - } - - plugin.Serve(opts) + }) } diff --git a/scripts/errcheck.sh b/scripts/errcheck.sh deleted file mode 100755 index e80c04d2..00000000 --- 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-plugin-sdk/v2/helper/schema:Set' \ - -ignore 'bytes:.*' \ - -ignore 'io:Close|Write' \ - $(go list -f '{{.Dir}}' ./...| 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 new file mode 100755 index 00000000..1c055815 --- /dev/null +++ b/scripts/gofmtcheck.sh @@ -0,0 +1,13 @@ +#!/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/terraform-registry-manifest.json b/terraform-registry-manifest.json deleted file mode 100644 index 625ab562..00000000 --- a/terraform-registry-manifest.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "version": 1, - "metadata": { - "protocol_versions": ["5.0"] - } -} \ No newline at end of file