Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a5f6c60a71 | ||
|
|
105273af48 | ||
|
|
e501417166 |
37
.github/workflows/release.yml
vendored
37
.github/workflows/release.yml
vendored
@@ -1,37 +0,0 @@
|
||||
name: Release
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- '*'
|
||||
|
||||
jobs:
|
||||
release:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v3
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Fetch all tags
|
||||
run: git fetch --force --tags
|
||||
|
||||
- name: Setup Go
|
||||
uses: actions/setup-go@v3
|
||||
with:
|
||||
go-version: 1.18
|
||||
|
||||
- name: Import GPG key
|
||||
id: import_gpg
|
||||
uses: crazy-max/ghaction-import-gpg@v4
|
||||
with:
|
||||
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
|
||||
passphrase: ${{ secrets.PASSPHRASE }}
|
||||
|
||||
- name: Run GoReleaser
|
||||
uses: goreleaser/goreleaser-action@v3
|
||||
with:
|
||||
args: release --rm-dist --release-notes CHANGELOG.md
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -1,5 +1,2 @@
|
||||
decort/vendor/
|
||||
examples/
|
||||
url_scrapping/
|
||||
terraform-provider-decort*
|
||||
.vscode/
|
||||
@@ -1,35 +0,0 @@
|
||||
linters:
|
||||
enable:
|
||||
- bodyclose
|
||||
- decorder
|
||||
- dogsled
|
||||
- errorlint
|
||||
- exportloopref
|
||||
#- gocognit - disabled till better times
|
||||
- goconst
|
||||
- gocyclo
|
||||
- gosec
|
||||
- ifshort
|
||||
- makezero
|
||||
#- nestif - disabled till better times
|
||||
- nilerr
|
||||
- prealloc
|
||||
- unconvert
|
||||
- unparam
|
||||
|
||||
linters-settings:
|
||||
errcheck:
|
||||
exclude-functions:
|
||||
- (*github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.ResourceData).Set
|
||||
staticcheck:
|
||||
go: "1.18"
|
||||
checks:
|
||||
- all
|
||||
- -SA1019
|
||||
nestif:
|
||||
min-complexity: 7
|
||||
gocyclo:
|
||||
min-complexity: 40
|
||||
|
||||
issues:
|
||||
max-same-issues: 0
|
||||
@@ -1,50 +0,0 @@
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
main: ./cmd/decort
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- freebsd
|
||||
- windows
|
||||
- linux
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
- '386'
|
||||
- arm64
|
||||
ignore:
|
||||
- goos: darwin
|
||||
goarch: '386'
|
||||
- goos: windows
|
||||
goarch: arm64
|
||||
binary: '{{ .ProjectName }}_v{{ .Version }}'
|
||||
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:
|
||||
- "--batch"
|
||||
- "--local-user"
|
||||
- "{{ .Env.GPG_FINGERPRINT }}"
|
||||
- "--output"
|
||||
- "${signature}"
|
||||
- "--detach-sign"
|
||||
- "${artifact}"
|
||||
release:
|
||||
extra_files:
|
||||
- glob: 'terraform-registry-manifest.json'
|
||||
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
|
||||
changelog:
|
||||
skip: false
|
||||
@@ -1,5 +0,0 @@
|
||||
## Version 4.0.1
|
||||
|
||||
## Bug Fix
|
||||
- Fixed incorrect state reading when creating/deleting port_forwarding in decort_kvmvm
|
||||
- Fixed possible segmentation fault with multiple concurrent resource manipulations
|
||||
83
Makefile
83
Makefile
@@ -1,83 +0,0 @@
|
||||
TEST?=$$(go list ./... | grep -v 'vendor')
|
||||
HOSTNAME=digitalenergy.online
|
||||
NAMESPACE=decort
|
||||
NAME=terraform-provider-decort
|
||||
BINDIR = ./bin
|
||||
ZIPDIR = ./zip
|
||||
#BINARY=terraform-provider-${NAME}
|
||||
BINARY=${NAME}.exe
|
||||
WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH}
|
||||
MAINPATH = ./cmd/decort/
|
||||
VERSION=4.0.1
|
||||
#OS_ARCH=darwin_amd64
|
||||
OS_ARCH=windows_amd64
|
||||
#OS_ARCH=linux_amd64
|
||||
|
||||
FILES= ${BINARY}_${VERSION}_darwin_amd64\
|
||||
${BINARY}_${VERSION}_freebsd_386\
|
||||
${BINARY}_${VERSION}_freebsd_amd64\
|
||||
${BINARY}_${VERSION}_freebsd_arm\
|
||||
${BINARY}_${VERSION}_linux_386\
|
||||
${BINARY}_${VERSION}_linux_amd64\
|
||||
${BINARY}_${VERSION}_linux_arm\
|
||||
${BINARY}_${VERSION}_openbsd_386\
|
||||
${BINARY}_${VERSION}_openbsd_amd64\
|
||||
${BINARY}_${VERSION}_solaris_amd64\
|
||||
${BINARY}_${VERSION}_windows_386 \
|
||||
${BINARY}_${VERSION}_windows_amd64\
|
||||
|
||||
BINS = $(addprefix bin/, $(FILES))
|
||||
|
||||
default: install
|
||||
|
||||
image:
|
||||
GOOS=linux GOARCH=amd64 go build -o terraform-provider-decort ./cmd/decort/
|
||||
docker build . -t rudecs/tf:3.2.2
|
||||
rm terraform-provider-decort
|
||||
|
||||
lint:
|
||||
golangci-lint run --timeout 600s
|
||||
|
||||
st:
|
||||
go build -o ${BINARY} ${MAINPATH}
|
||||
cp ${BINARY} ${WORKPATH}
|
||||
rm ${BINARY}
|
||||
|
||||
build:
|
||||
go build -o ${BINARY} ${MAINPATH}
|
||||
|
||||
release: $(FILES)
|
||||
|
||||
$(FILES) : $(BINDIR) $(ZIPDIR) $(BINS)
|
||||
zip -r $(ZIPDIR)/$@.zip $(BINDIR)/$@
|
||||
|
||||
$(BINDIR):
|
||||
mkdir $@
|
||||
|
||||
$(ZIPDIR):
|
||||
mkdir $@
|
||||
|
||||
$(BINS):
|
||||
GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64 $(MAINPATH)
|
||||
GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386 $(MAINPATH)
|
||||
GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64 $(MAINPATH)
|
||||
GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm $(MAINPATH)
|
||||
GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386 $(MAINPATH)
|
||||
GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64 $(MAINPATH)
|
||||
GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm $(MAINPATH)
|
||||
GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386 $(MAINPATH)
|
||||
GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64 $(MAINPATH)
|
||||
GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64 $(MAINPATH)
|
||||
GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386 $(MAINPATH)
|
||||
GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64 $(MAINPATH)
|
||||
|
||||
install: build
|
||||
mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH}
|
||||
mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH}
|
||||
|
||||
test:
|
||||
go test -i $(TEST) || exit 1
|
||||
echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
|
||||
|
||||
testacc:
|
||||
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m
|
||||
188
README.md
188
README.md
@@ -1,169 +1,55 @@
|
||||
# terraform-provider-decort
|
||||
Terraform provider for Digital Energy Cloud Orchestration Technology (DECORT) platform
|
||||
|
||||
Terraform provider для платформы Digital Energy Cloud Orchestration Technology (DECORT)
|
||||
NOTE: provider rc-1.40 is designed for DECORT API 3.7.x. For older API versions please use:
|
||||
- DECORT API 3.6.x versions - provider version rc-1.10
|
||||
- DECORT API versions prior to 3.6.0 - Terraform DECS provider (https://github.com/rudecs/terraform-provider-decs)
|
||||
|
||||
## Соответсвие версий платформы версиям провайдера
|
||||
With this provider you can manage Compute instances, disks, virtual network segments and resource
|
||||
groups in DECORT platform, as well as query the platform for information about existing resources.
|
||||
This provider supports Import operations on pre-existing resources.
|
||||
|
||||
| Версия DECORT API | Версия провайдера Terraform |
|
||||
| ------ | ------ |
|
||||
| 3.8.6 | 4.x.x |
|
||||
| 3.8.5 | 3.4.x |
|
||||
| 3.8.0 - 3.8.4 | 3.3.1 |
|
||||
| 3.7.x | rc-1.25 |
|
||||
| 3.6.x | rc-1.10 |
|
||||
| до 3.6.0 | [terraform-provider-decs](https://github.com/rudecs/terraform-provider-decs) |
|
||||
See user guide at https://github.com/rudecs/terraform-provider-decort/wiki
|
||||
|
||||
## Режимы работы
|
||||
For a quick start follow these steps (assuming that your build host is running Linux; this provider builds on Windows as well, however, some paths may differ from what is mentioned below).
|
||||
|
||||
Провайдер позволяет работать в двух режимах:
|
||||
|
||||
- Режим пользователя,
|
||||
- Режим администратора. <br>
|
||||
Используйте ресурсы `decort_cb_` для администрирования. <br>
|
||||
Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
|
||||
## Возможности провайдера
|
||||
|
||||
- Работа с Compute instances,
|
||||
- Работа с disks,
|
||||
- Работа с k8s,
|
||||
- Работа с image,
|
||||
- Работа с reource groups,
|
||||
- Работа с VINS,
|
||||
- Работа с pfw,
|
||||
- Работа с accounts,
|
||||
- Работа с snapshots,
|
||||
- Работа с pcidevice,
|
||||
- Работа с sep,
|
||||
- Работа с vgpu,
|
||||
- Работа с bservice,
|
||||
- Работа с extnets,
|
||||
- Работа с locations,
|
||||
- Работа с load balancer.
|
||||
|
||||
Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
|
||||
## Начало
|
||||
|
||||
Старт возможен по двум путям:
|
||||
|
||||
1. Установка через собранные пакеты.
|
||||
2. Ручная установка.
|
||||
|
||||
### Установка через собранные пакеты.
|
||||
|
||||
1. Скачайте и установите terraform по ссылке: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
|
||||
2. Создайте файл `main.tf` и добавьте в него следующий блок.
|
||||
|
||||
```terraform
|
||||
provider "decort" {
|
||||
authenticator = "oauth2"
|
||||
#controller_url = <DECORT_CONTROLLER_URL>
|
||||
controller_url = "https://ds1.digitalenergy.online"
|
||||
#oauth2_url = <DECORT_SSO_URL>
|
||||
oauth2_url = "https://sso.digitalenergy.online"
|
||||
allow_unverified_ssl = true
|
||||
}
|
||||
1. Obtain the latest GO compiler. As of beginning 2021 it is recommended to use v.1.16.3 but as new Terraform versions are released newer Go compiler may be required, so check official Terraform repository regularly for more information.
|
||||
```
|
||||
cd /tmp
|
||||
wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz
|
||||
tar xvf ./go1.16.3.linux-amd64.tar.gz
|
||||
sudo mv go /usr/local
|
||||
```
|
||||
|
||||
3. Выполните команду
|
||||
|
||||
2. Add the following environment variables' declarations to shell startup script:
|
||||
```
|
||||
terraform init
|
||||
export GOPATH=/opt/gopkg:~/
|
||||
export GOROOT=/usr/local/go
|
||||
export PATH=$PATH:$GOROOT/bin
|
||||
```
|
||||
|
||||
Провайдер автоматически будет установлен на ваш компьютер из terraform registry.
|
||||
|
||||
### Ручная установка
|
||||
|
||||
1. Скачайте и установите Go по ссылке: https://go.dev/dl/
|
||||
2. Скачайте и установите terraform по ссылке: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
|
||||
3. Склонируйте репозиторий с провайдером, выполнив команду:
|
||||
|
||||
```bash
|
||||
git clone https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
3. Clone Terraform Plugin SDK framework repository to $GOPKG/src/github.com/hashicorp
|
||||
```
|
||||
mkdir -p $GOPKG/src/github.com/hashicorp
|
||||
cd $GOPKG/src/github.com/hashicorp
|
||||
git clone https://github.com/hashicorp/terraform-plugin-sdk.git
|
||||
```
|
||||
|
||||
4. Перейдите в скачанную папку с провайдером и выполните команду
|
||||
|
||||
```bash
|
||||
go build -o terraform-provider-decort
|
||||
4. Clone jwt-go package repository to $GOPKG/src/github.com/dgrijalva/jwt-go:
|
||||
```
|
||||
mkdir -p $GOPKG/src/github.com/dgrijalva
|
||||
cd $GOPKG/src/github.com/dgrijalva
|
||||
git clone https://github.com/dgrijalva/jwt-go.git
|
||||
```
|
||||
|
||||
Если вы знаете как устроен _makefile_, то можно изменить в файле `Makefile` параметры под вашу ОС и выполнить команду
|
||||
|
||||
```bash
|
||||
make build
|
||||
5. Clone Terraform DECORT provider repository to $GOPKG/src/github.com/terraform-provider-decort
|
||||
```
|
||||
cd $GOPKG/src/github.com
|
||||
git clone https://github.com/rudecs/terraform-provider-decort.git
|
||||
```
|
||||
|
||||
5. Полученный файл необходимо поместить:
|
||||
Linux:
|
||||
|
||||
```bash
|
||||
~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target}
|
||||
6. Build Terraform DECORT provider:
|
||||
```
|
||||
|
||||
Windows:
|
||||
|
||||
```powershell
|
||||
%APPDATA%\terraform.d\plugins\${host_name}\${namespace}\${type}\${version}\${target}
|
||||
```
|
||||
|
||||
ВНИМАНИЕ: для ОС Windows `%APP_DATA%` является каталогом, в котором будут помещены будущие файлы terraform.
|
||||
Где:
|
||||
|
||||
- host_name - имя хоста, держателя провайдера, например, digitalenergy.online
|
||||
- namespace - пространство имен хоста, например decort
|
||||
- type - тип провайдера, может совпадать с пространством имен, например, decort
|
||||
- version - версия провайдера, например 1.2
|
||||
- target - версия ОС, например windows_amd64
|
||||
|
||||
6. После этого, создайте файл `main.tf`.
|
||||
7. Добавьте в него следующий блок
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.2"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
В поле `version` указывается версия провайдера.
|
||||
Обязательный параметр
|
||||
Тип поля - строка
|
||||
ВНИМАНИЕ: Версии в блоке и в репозитории, в который был помещен провайдер должны совпадать!
|
||||
|
||||
В поле `source` помещается путь до репозитория с версией вида:
|
||||
|
||||
```bash
|
||||
${host_name}/${namespace}/${type}
|
||||
```
|
||||
|
||||
ВНИМАНИЕ: все параметры должны совпадать с путем репозитория, в котором помещен провайдер.
|
||||
|
||||
8. В консоле выполнить команду
|
||||
|
||||
```bash
|
||||
terraform init
|
||||
```
|
||||
|
||||
9. Если все прошло хорошо - ошибок не будет.
|
||||
|
||||
Более подробно о сборке провайдера можно найти по ссылке: https://learn.hashicorp.com/tutorials/terraform/provider-use?in=terraform/providers
|
||||
|
||||
## Примеры работы
|
||||
|
||||
Примеры работы можно найти:
|
||||
|
||||
- На вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
- В папке `samples`
|
||||
|
||||
Схемы к terraform'у доступны:
|
||||
|
||||
- В папке `docs`
|
||||
|
||||
Хорошей работы!
|
||||
cd $GOPKG/src/github.com/terraform-provider-decort
|
||||
go build -o terraform-provider-decort
|
||||
```
|
||||
168
README_EN.md
168
README_EN.md
@@ -1,168 +0,0 @@
|
||||
# terraform-provider-decort
|
||||
|
||||
Terraform provider for Digital Energy Cloud Orchestration Technology (DECORT) platform
|
||||
|
||||
## Mapping of platform versions with provider versions
|
||||
|
||||
| DECORT API version | Terraform provider version |
|
||||
| ------ | ------ |
|
||||
| 3.8.5 | 3.4.x |
|
||||
| 3.8.0 - 3.8.4 | 3.3.1 |
|
||||
| 3.7.x | rc-1.25 |
|
||||
| 3.6.x | rc-1.10 |
|
||||
| до 3.6.0 | [terraform-provider-decs](https://github.com/rudecs/terraform-provider-decs) |
|
||||
|
||||
## Working modes
|
||||
|
||||
The provider support two working modes:
|
||||
|
||||
- User mode,
|
||||
- Administator mode.
|
||||
Use flag DECORT_ADMIN_MODE for swithcing beetwen modes.
|
||||
See user guide at https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
|
||||
## Features
|
||||
|
||||
- Work with Compute instances,
|
||||
- Work with disks,
|
||||
- Work with k8s,
|
||||
- Work with image,
|
||||
- Work with reource groups,
|
||||
- Work with VINS,
|
||||
- Work with pfw,
|
||||
- Work with accounts,
|
||||
- Work with snapshots,
|
||||
- Work with pcidevice.
|
||||
- Work with sep,
|
||||
- Work with vgpu,
|
||||
- Work with bservice,
|
||||
- Work with extnets,
|
||||
- Work with locations,
|
||||
- Work with load balancers.
|
||||
|
||||
This provider supports Import operations on pre-existing resources.
|
||||
|
||||
See user guide at https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
|
||||
## Get Started
|
||||
|
||||
Two ways for starting:
|
||||
|
||||
1. Installing via binary packages
|
||||
2. Manual installing
|
||||
|
||||
### Installing via binary packages
|
||||
|
||||
1. Download and install terraform: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
|
||||
2. Create a file `main.tf` and add to it next section.
|
||||
|
||||
```terraform
|
||||
provider "decort" {
|
||||
authenticator = "oauth2"
|
||||
#controller_url = <DECORT_CONTROLLER_URL>
|
||||
controller_url = "https://ds1.digitalenergy.online"
|
||||
#oauth2_url = <DECORT_SSO_URL>
|
||||
oauth2_url = "https://sso.digitalenergy.online"
|
||||
allow_unverified_ssl = true
|
||||
}
|
||||
```
|
||||
|
||||
3. Execute next command
|
||||
|
||||
```
|
||||
terraform init
|
||||
```
|
||||
|
||||
The Provider will automatically install on your computer from the terrafrom registry.
|
||||
|
||||
### Manual installing
|
||||
|
||||
1. Download and install Go Programming Language: https://go.dev/dl/
|
||||
2. Download and install terraform: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
|
||||
3. Clone provider's repo:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/rudecs/terraform-provider-decort.git
|
||||
```
|
||||
|
||||
4. Change directory to clone provider's and execute next command
|
||||
|
||||
```bash
|
||||
go build -o terraform-provider-decort
|
||||
```
|
||||
|
||||
If you have experience with _makefile_, you can change `Makefile`'s paramters and execute next command
|
||||
|
||||
```bash
|
||||
make build
|
||||
```
|
||||
|
||||
5. Now move compilled file to:
|
||||
Linux:
|
||||
|
||||
```bash
|
||||
~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target}
|
||||
```
|
||||
|
||||
Windows:
|
||||
|
||||
```powershell
|
||||
%APPDATA%\terraform.d\plugins\${host_name}/${namespace}/${type}/${version}/${target}
|
||||
```
|
||||
|
||||
NOTE: for Windows OS `%APP_DATA%` is a cataloge, where will place terraform files.
|
||||
Example:
|
||||
|
||||
- host_name - digitalenergy.online
|
||||
- namespace - decort
|
||||
- type - decort
|
||||
- version - 1.2
|
||||
- target - windows_amd64
|
||||
|
||||
6. After all, create a file `main.tf`.
|
||||
7. Add to the file next code section
|
||||
|
||||
```terraform
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.2"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`version`- field for provider's version
|
||||
Required
|
||||
String
|
||||
Note: Versions in code section and in a repository must be equal!
|
||||
|
||||
`source` - path to repository with provider's version
|
||||
|
||||
```bash
|
||||
${host_name}/${namespace}/${type}
|
||||
```
|
||||
|
||||
NOTE: all paramters must be equal to the repository path!
|
||||
|
||||
8. Execute command in your terminal
|
||||
|
||||
```bash
|
||||
terraform init
|
||||
```
|
||||
|
||||
9. If everything all right - you got green message in your terminal!
|
||||
|
||||
More details about the provider's building process: https://learn.hashicorp.com/tutorials/terraform/provider-use?in=terraform/providers
|
||||
|
||||
## Examples and Samples
|
||||
|
||||
- Examples: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
- Samples: see in repository `samples`
|
||||
|
||||
Terraform schemas in:
|
||||
|
||||
- See in repository `docs`
|
||||
|
||||
Good work!
|
||||
@@ -1,9 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,22 +15,29 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package constants
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
// LimitMaxVinsPerResgroup set maximum number of VINs instances per Resource Group
|
||||
const LimitMaxVinsPerResgroup = 4
|
||||
const LimitMaxVinsPerResgroup=4
|
||||
|
||||
// MaxSshKeysPerCompute sets maximum number of user:ssh_key pairs to authorize when creating new compute
|
||||
const MaxSshKeysPerCompute = 12
|
||||
const MaxSshKeysPerCompute=12
|
||||
|
||||
// MaxExtraDisksPerCompute sets maximum number of extra disks that can be added when creating new compute
|
||||
const MaxExtraDisksPerCompute = 12
|
||||
const MaxExtraDisksPerCompute=12
|
||||
|
||||
// MaxNetworksPerCompute sets maximum number of vNICs per compute
|
||||
const MaxNetworksPerCompute = 8
|
||||
const MaxNetworksPerCompute=8
|
||||
|
||||
// MaxCpusPerCompute sets maximum number of vCPUs per compute
|
||||
const MaxCpusPerCompute = 128
|
||||
const MaxCpusPerCompute=128
|
||||
|
||||
// MinRamPerCompute sets minimum amount of RAM per compute in MB
|
||||
const MinRamPerCompute = 128
|
||||
const MinRamPerCompute=128
|
||||
@@ -1,9 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,11 +15,18 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package controller
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
@@ -30,56 +34,50 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
// "time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
decort "repository.basistech.ru/BASIS/decort-golang-sdk"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/config"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/interfaces"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker"
|
||||
|
||||
jwt "github.com/golang-jwt/jwt/v4"
|
||||
"github.com/dgrijalva/jwt-go"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
)
|
||||
|
||||
// enumerated constants that define authentication modes
|
||||
// enumerated constants that define authentication modes
|
||||
const (
|
||||
MODE_UNDEF = iota // this is the invalid mode - it should never be seen
|
||||
MODE_LEGACY = iota
|
||||
MODE_OAUTH2 = iota
|
||||
MODE_JWT = iota
|
||||
MODE_UNDEF = iota // this is the invalid mode - it should never be seen
|
||||
MODE_LEGACY = iota
|
||||
MODE_OAUTH2 = iota
|
||||
MODE_JWT = iota
|
||||
)
|
||||
|
||||
type ControllerCfg struct {
|
||||
controller_url string // always required
|
||||
auth_mode_code int // always required
|
||||
auth_mode_txt string // always required, it is a text representation of auth mode
|
||||
legacy_user string // required for legacy mode
|
||||
legacy_password string // required for legacy mode
|
||||
legacy_sid string // obtained from DECORT controller on successful login in legacy mode
|
||||
jwt string // obtained from Outh2 provider on successful login in oauth2 mode, required in jwt mode
|
||||
app_id string // required for oauth2 mode
|
||||
app_secret string // required for oauth2 mode
|
||||
oauth2_url string // always required
|
||||
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
|
||||
cc_client *http.Client // assigned when all initial checks successfully passed
|
||||
caller interfaces.Caller
|
||||
controller_url string // always required
|
||||
auth_mode_code int // always required
|
||||
auth_mode_txt string // always required, it is a text representation of auth mode
|
||||
legacy_user string // required for legacy mode
|
||||
legacy_password string // required for legacy mode
|
||||
legacy_sid string // obtained from DECORT controller on successful login in legacy mode
|
||||
jwt string // obtained from Outh2 provider on successful login in oauth2 mode, required in jwt mode
|
||||
app_id string // required for oauth2 mode
|
||||
app_secret string // required for oauth2 mode
|
||||
oauth2_url string // always required
|
||||
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
|
||||
cc_client *http.Client // assigned when all initial checks successfully passed
|
||||
}
|
||||
|
||||
func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
// This function first will check that all required provider parameters for the
|
||||
// This function first will check that all required provider parameters for the
|
||||
// selected authenticator mode are set correctly and initialize ControllerCfg structure
|
||||
// based on the provided parameters.
|
||||
//
|
||||
// Next, it will check for validity of supplied credentials by initiating connection to the specified
|
||||
// DECORT controller URL and, if succeeded, completes ControllerCfg structure with the rest of computed
|
||||
// Next, it will check for validity of supplied credentials by initiating connection to the specified
|
||||
// DECORT controller URL and, if succeeded, completes ControllerCfg structure with the rest of computed
|
||||
// parameters (e.g. JWT, session ID and Oauth2 user name).
|
||||
//
|
||||
// The structure created by this function should be used with subsequent calls to decortAPICall() method,
|
||||
// The structure created by this function should be used with subsequent calls to decortAPICall() method,
|
||||
// which is a DECORT authentication mode aware wrapper around standard HTTP requests.
|
||||
|
||||
ret_config := &ControllerCfg{
|
||||
@@ -92,10 +90,11 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
app_id: d.Get("app_id").(string),
|
||||
app_secret: d.Get("app_secret").(string),
|
||||
oauth2_url: d.Get("oauth2_url").(string),
|
||||
decort_username: "",
|
||||
decort_username: "",
|
||||
}
|
||||
|
||||
allow_unverified_ssl := d.Get("allow_unverified_ssl").(bool)
|
||||
var allow_unverified_ssl bool
|
||||
allow_unverified_ssl = d.Get("allow_unverified_ssl").(bool)
|
||||
|
||||
if ret_config.controller_url == "" {
|
||||
return nil, fmt.Errorf("Empty DECORT cloud controller URL provided.")
|
||||
@@ -133,37 +132,29 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
}
|
||||
ret_config.auth_mode_code = MODE_LEGACY
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown authenticator mode %q provided.", ret_config.auth_mode_txt)
|
||||
return nil, fmt.Errorf("Unknown authenticator mode %s provided.", ret_config.auth_mode_txt)
|
||||
}
|
||||
|
||||
if allow_unverified_ssl {
|
||||
log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!")
|
||||
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}} //nolint:gosec
|
||||
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true},}
|
||||
ret_config.cc_client = &http.Client{
|
||||
Transport: transCfg,
|
||||
Timeout: Timeout180s,
|
||||
}
|
||||
} else {
|
||||
ret_config.cc_client = &http.Client{}
|
||||
ret_config.cc_client = &http.Client{
|
||||
Timeout: Timeout180s, // time.Second * 30,
|
||||
}
|
||||
}
|
||||
|
||||
switch ret_config.auth_mode_code {
|
||||
case MODE_LEGACY:
|
||||
ok, err := ret_config.validateLegacyUser()
|
||||
ok, err := ret_config.validateLegacyUser()
|
||||
if !ok {
|
||||
return nil, err
|
||||
}
|
||||
ret_config.decort_username = ret_config.legacy_user
|
||||
|
||||
sdkConf := config.LegacyConfig{
|
||||
Username: ret_config.legacy_user,
|
||||
Password: ret_config.legacy_password,
|
||||
DecortURL: ret_config.controller_url,
|
||||
Retries: 0,
|
||||
SSLSkipVerify: allow_unverified_ssl,
|
||||
}
|
||||
|
||||
ret_config.caller = decort.NewLegacy(sdkConf)
|
||||
|
||||
case MODE_JWT:
|
||||
//
|
||||
ok, err := ret_config.validateJWT("")
|
||||
@@ -171,13 +162,13 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
return nil, err
|
||||
}
|
||||
case MODE_OAUTH2:
|
||||
// on success getOAuth2JWT will set config.jwt to the obtained JWT, so there is no
|
||||
// on success getOAuth2JWT will set config.jwt to the obtained JWT, so there is no
|
||||
// need to set it once again here
|
||||
_, err := ret_config.getOAuth2JWT()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
// we are not verifying the JWT when parsing because actual verification is done on the
|
||||
// we are not verifying the JWT when parsing because actual verification is done on the
|
||||
// OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user")
|
||||
// and JWT issuer name (claim "iss")
|
||||
parser := jwt.Parser{}
|
||||
@@ -190,21 +181,10 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
tbuf.WriteString(claims["username"].(string))
|
||||
tbuf.WriteString("@")
|
||||
tbuf.WriteString(claims["iss"].(string))
|
||||
ret_config.decort_username = tbuf.String()
|
||||
ret_config.decort_username = tbuf.String()
|
||||
} else {
|
||||
return nil, fmt.Errorf("Failed to extract user and iss fields from JWT token in oauth2 mode.")
|
||||
}
|
||||
|
||||
sdkConf := config.Config{
|
||||
AppID: ret_config.app_id,
|
||||
AppSecret: ret_config.app_secret,
|
||||
SSOURL: ret_config.oauth2_url,
|
||||
DecortURL: ret_config.controller_url,
|
||||
SSLSkipVerify: allow_unverified_ssl,
|
||||
}
|
||||
|
||||
ret_config.caller = decort.New(sdkConf)
|
||||
|
||||
default:
|
||||
// FYI, this should never happen due to all above checks, but we want to be fool proof
|
||||
return nil, fmt.Errorf("Unknown authenticator mode code %d provided.", ret_config.auth_mode_code)
|
||||
@@ -215,7 +195,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
return ret_config, nil
|
||||
}
|
||||
|
||||
func (config *ControllerCfg) GetDecortUsername() string {
|
||||
func (config *ControllerCfg) getDecortUsername() (string) {
|
||||
return config.decort_username
|
||||
}
|
||||
|
||||
@@ -225,7 +205,7 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
||||
return "", fmt.Errorf("getOAuth2JWT method called for undefined authorization mode.")
|
||||
}
|
||||
if config.auth_mode_code != MODE_OAUTH2 {
|
||||
return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
||||
return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %s.", config.auth_mode_txt)
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -236,14 +216,14 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
||||
params.Add("validity", "3600")
|
||||
params_str := params.Encode()
|
||||
|
||||
req, err := http.NewRequest("POST", config.oauth2_url+"/v1/oauth/access_token", strings.NewReader(params_str))
|
||||
req, err := http.NewRequest("POST", config.oauth2_url + "/v1/oauth/access_token", strings.NewReader(params_str))
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
||||
|
||||
resp, err := config.cc_client.Do(req)
|
||||
resp, err := config.cc_client.Do(req)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -251,16 +231,16 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
||||
// fmt.Println("response Status:", resp.Status)
|
||||
// fmt.Println("response Headers:", resp.Header)
|
||||
// fmt.Println("response Headers:", req.URL)
|
||||
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
|
||||
resp.StatusCode, req.URL, config.app_id, params_str)
|
||||
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %s for APP_ID %s, request Body %s",
|
||||
resp.StatusCode, req.URL, config.app_id, params_str)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
responseData, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// validation successful - store JWT in the corresponding field of the ControllerCfg structure
|
||||
config.jwt = strings.TrimSpace(string(responseData))
|
||||
|
||||
@@ -269,10 +249,10 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
||||
|
||||
func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
||||
/*
|
||||
Validate JWT against DECORT controller. JWT can be supplied as argument to this method. If empty string supplied as
|
||||
argument, JWT will be taken from config attribute.
|
||||
DECORT controller URL will always be taken from the config attribute assigned at instantiation.
|
||||
Validation is accomplished by attempting API call that lists account for the invoking user.
|
||||
Validate JWT against DECORT controller. JWT can be supplied as argument to this method. If empty string supplied as
|
||||
argument, JWT will be taken from config attribute.
|
||||
DECORT controller URL will always be taken from the config attribute assigned at instantiation.
|
||||
Validation is accomplished by attempting API call that lists accounts for the invoking user.
|
||||
*/
|
||||
if jwt == "" {
|
||||
if config.jwt == "" {
|
||||
@@ -285,7 +265,7 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
||||
return false, fmt.Errorf("validateJWT method called, but no OAuth2 URL provided.")
|
||||
}
|
||||
|
||||
req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/account/list", nil)
|
||||
req, err := http.NewRequest("POST", config.controller_url + "/restmachine/cloudapi/accounts/list", nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -293,14 +273,14 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", jwt))
|
||||
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
// req.Header.Set("Content-Length", strconv.Itoa(0))
|
||||
|
||||
resp, err := config.cc_client.Do(req)
|
||||
|
||||
resp, err := config.cc_client.Do(req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q.",
|
||||
resp.StatusCode, req.URL)
|
||||
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %s.",
|
||||
resp.StatusCode, req.URL)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
@@ -309,16 +289,16 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
||||
|
||||
func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
||||
/*
|
||||
Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls
|
||||
to DECORT controller.
|
||||
If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any
|
||||
reason, the method will return false and error.
|
||||
Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls
|
||||
to DECORT controller.
|
||||
If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any
|
||||
reason, the method will return false and error.
|
||||
*/
|
||||
if config.auth_mode_code == MODE_UNDEF {
|
||||
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode.")
|
||||
}
|
||||
if config.auth_mode_code != MODE_LEGACY {
|
||||
return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
||||
return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %s.", config.auth_mode_txt)
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -326,7 +306,7 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
||||
params.Add("password", config.legacy_password)
|
||||
params_str := params.Encode()
|
||||
|
||||
req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/user/authenticate", strings.NewReader(params_str))
|
||||
req, err := http.NewRequest("POST", config.controller_url + "/restmachine/cloudapi/users/authenticate", strings.NewReader(params_str))
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -334,58 +314,40 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
||||
|
||||
resp, err := config.cc_client.Do(req)
|
||||
resp, err := config.cc_client.Do(req)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
if resp.StatusCode != http.StatusOK {
|
||||
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q.",
|
||||
resp.StatusCode, config.legacy_user, config.controller_url)
|
||||
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %s against %s.",
|
||||
resp.StatusCode, config.legacy_user, config.controller_url)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
responseData, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
// validation successful - keep session ID for future use
|
||||
config.legacy_sid = string(responseData)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (config *ControllerCfg) CloudAPI() *cloudapi.CloudAPI {
|
||||
if config.auth_mode_code == MODE_LEGACY {
|
||||
client, _ := config.caller.(*decort.LegacyDecortClient)
|
||||
return client.CloudAPI()
|
||||
}
|
||||
|
||||
client, _ := config.caller.(*decort.DecortClient)
|
||||
return client.CloudAPI()
|
||||
}
|
||||
|
||||
func (config *ControllerCfg) CloudBroker() *cloudbroker.CloudBroker {
|
||||
if config.auth_mode_code == MODE_LEGACY {
|
||||
client, _ := config.caller.(*decort.LegacyDecortClient)
|
||||
return client.CloudBroker()
|
||||
}
|
||||
|
||||
client, _ := config.caller.(*decort.DecortClient)
|
||||
return client.CloudBroker()
|
||||
}
|
||||
|
||||
func (config *ControllerCfg) DecortAPICall(ctx context.Context, method string, api_name string, url_values *url.Values) (json_resp string, err error) { //nolint:unparam
|
||||
// This is a convenience wrapper around standard HTTP request methods that is aware of the
|
||||
func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error, hrc int) {
|
||||
// This is a convenience wrapper around standard HTTP request methods that is aware of the
|
||||
// authorization mode for which the provider was initialized and compiles request accordingly.
|
||||
|
||||
hrc = 0 // HTTP Response Code
|
||||
|
||||
if config.cc_client == nil {
|
||||
// this should never happen if ClientConfig was properly called prior to decortAPICall
|
||||
return "", fmt.Errorf("decortAPICall method called with unconfigured DECORT cloud controller HTTP client.")
|
||||
// this should never happen if ClientConfig was properly called prior to decortAPICall
|
||||
return "", fmt.Errorf("decortAPICall method called with unconfigured DECORT cloud controller HTTP client."), 0
|
||||
}
|
||||
|
||||
// Example: to create api_params, one would generally do the following:
|
||||
//
|
||||
//
|
||||
// data := []byte(`{"machineId": "2638"}`)
|
||||
// api_params := bytes.NewBuffer(data))
|
||||
//
|
||||
@@ -399,7 +361,7 @@ func (config *ControllerCfg) DecortAPICall(ctx context.Context, method string, a
|
||||
//
|
||||
|
||||
if config.auth_mode_code == MODE_UNDEF {
|
||||
return "", fmt.Errorf("decortAPICall method called for unknown authorization mode.")
|
||||
return "", fmt.Errorf("decortAPICall method called for unknown authorization mode."), 0
|
||||
}
|
||||
|
||||
if config.auth_mode_code == MODE_LEGACY {
|
||||
@@ -407,49 +369,42 @@ func (config *ControllerCfg) DecortAPICall(ctx context.Context, method string, a
|
||||
}
|
||||
params_str := url_values.Encode()
|
||||
|
||||
req, err := http.NewRequest(method, config.controller_url+api_name, strings.NewReader(params_str))
|
||||
req, err := http.NewRequest(method, config.controller_url + api_name, strings.NewReader(params_str))
|
||||
if err != nil {
|
||||
return "", err
|
||||
return "", err, 0
|
||||
}
|
||||
|
||||
req = req.WithContext(ctx)
|
||||
|
||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
||||
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
||||
req.Header.Set("Accept", "application/json")
|
||||
|
||||
if config.auth_mode_code == MODE_OAUTH2 || config.auth_mode_code == MODE_JWT {
|
||||
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", config.jwt))
|
||||
}
|
||||
|
||||
resp, err := config.cc_client.Do(req)
|
||||
if err != nil {
|
||||
return "", err, 0
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
var resp *http.Response
|
||||
var body []byte
|
||||
for i := 0; i < 5; i++ {
|
||||
resp, err = config.cc_client.Do(req)
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
tmp_body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
body, err = ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
resp.Body.Close()
|
||||
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, body)
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return string(body), nil
|
||||
} else {
|
||||
if resp.StatusCode == http.StatusInternalServerError {
|
||||
log.Warnf("got 500, retrying %d/5", i+1)
|
||||
time.Sleep(time.Second * 5)
|
||||
continue
|
||||
}
|
||||
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %q with request Body %q. Respone:\n%s",
|
||||
resp.StatusCode, req.URL, params_str, body)
|
||||
}
|
||||
return "", err, resp.StatusCode
|
||||
}
|
||||
json_resp := Jo2JSON(string(tmp_body))
|
||||
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, json_resp)
|
||||
return json_resp, nil, resp.StatusCode
|
||||
} else {
|
||||
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %s with request Body %s",
|
||||
resp.StatusCode, req.URL, params_str), resp.StatusCode
|
||||
}
|
||||
|
||||
/*
|
||||
if resp.StatusCode == StatusServiceUnavailable {
|
||||
return nil, fmt.Errorf("decortAPICall method called for incompatible authorization mode %s.", config.auth_mode_txt), resp.StatusCode
|
||||
}
|
||||
*/
|
||||
|
||||
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %q with request Body %q. Respone:\n%s",
|
||||
resp.StatusCode, req.URL, params_str, body)
|
||||
return "", err, resp.StatusCode
|
||||
}
|
||||
|
||||
132
decort/data_source_account.go
Normal file
132
decort/data_source_account.go
Normal file
@@ -0,0 +1,132 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
// "net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func flattenAccount(d *schema.ResourceData, acc_facts string) error {
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourceAccountExists(...) method
|
||||
|
||||
// log.Debugf("flattenAccount: ready to decode response body from %q", CloudspacesGetAPI)
|
||||
details := AccountRecord{}
|
||||
err := json.Unmarshal([]byte(acc_facts), &details)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("flattenAccount: decoded Account name %q / ID %d, status %q", details.Name, details.ID, details.Status)
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", details.ID))
|
||||
d.Set("name", details.Name)
|
||||
d.Set("status", details.Status)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceAccountRead(d *schema.ResourceData, m interface{}) error {
|
||||
acc_facts, err := utilityAccountCheckPresence(d, m)
|
||||
if acc_facts == "" {
|
||||
// if empty string is returned from utilityAccountCheckPresence then there is no
|
||||
// such account and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty in this case
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenAccount(d, acc_facts)
|
||||
}
|
||||
|
||||
func dataSourceAccount() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourceAccountRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Name of the account. Names are case sensitive and unique.",
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Unique ID of the account. If account ID is specified, then account name is ignored.",
|
||||
},
|
||||
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current status of the account.",
|
||||
},
|
||||
|
||||
/* We keep the following attributes commented out, as we are not implementing account
|
||||
management with Terraform plugin, so we do not need this extra info.
|
||||
|
||||
"quota": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: quotaRgSubresourceSchema(), // this is a dictionary
|
||||
},
|
||||
Description: "Quotas on the resources for this account and all its resource groups.",
|
||||
},
|
||||
|
||||
"resource_groups": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of resource groups in this account."
|
||||
},
|
||||
|
||||
"vins": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of VINSes created at the account level."
|
||||
},
|
||||
*/
|
||||
},
|
||||
}
|
||||
}
|
||||
463
decort/data_source_compute.go
Normal file
463
decort/data_source_compute.go
Normal file
@@ -0,0 +1,463 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
// "net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
// Parse list of all disks from API compute/get into a list of "extra disks" attached to this compute
|
||||
// Extra disks are all compute disks but a boot disk.
|
||||
func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
||||
// this return value will be used to d.Set("extra_disks",) item of dataSourceCompute schema,
|
||||
// which is a simple list of integer disk IDs excluding boot disk ID
|
||||
length := len(disks)
|
||||
log.Debugf("parseComputeDisksToExtraDisks: called for %d disks", length)
|
||||
|
||||
if length == 0 || ( length == 1 && disks[0].Type == "B" ) {
|
||||
// the disk list is empty (which is kind of strange - diskless compute?), or
|
||||
// there is only one disk in the list and it is a boot disk;
|
||||
// as we skip boot disks, the result will be of 0 length anyway
|
||||
return make([]interface{}, 0)
|
||||
}
|
||||
|
||||
result := make([]interface{}, length-1)
|
||||
idx := 0
|
||||
for _, value := range disks {
|
||||
if value.Type == "B" {
|
||||
// skip boot disk when iterating over the list of disks
|
||||
continue
|
||||
}
|
||||
|
||||
result[idx] = value.ID
|
||||
idx++
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// NOTE: this is a legacy function, which is not used as of rc-1.10
|
||||
// Use "parseComputeDisksToExtraDisks" instead
|
||||
func parseComputeDisks(disks []DiskRecord) []interface{} {
|
||||
// Return value was designed to d.Set("disks",) item of dataSourceCompute schema
|
||||
// However, this item was excluded from the schema as it is not directly
|
||||
// managed through Terraform
|
||||
length := len(disks)
|
||||
log.Debugf("parseComputeDisks: called for %d disks", length)
|
||||
|
||||
/*
|
||||
if length == 1 && disks[0].Type == "B" {
|
||||
// there is only one disk in the list and it is a boot disk
|
||||
// as we skip boot disks, the result will be of 0 lenght
|
||||
length = 0
|
||||
}
|
||||
*/
|
||||
|
||||
result := []interface{}{}
|
||||
|
||||
if length == 0 {
|
||||
return result
|
||||
}
|
||||
|
||||
for _, value := range disks {
|
||||
/*
|
||||
if value.Type == "B" {
|
||||
// skip boot disk when parsing the list of disks
|
||||
continue
|
||||
}
|
||||
*/
|
||||
elem := make(map[string]interface{})
|
||||
// keys in this map should correspond to the Schema definition
|
||||
// as returned by dataSourceDiskSchemaMake()
|
||||
elem["name"] = value.Name
|
||||
elem["disk_id"] = value.ID
|
||||
elem["account_id"] = value.AccountID
|
||||
elem["account_name"] = value.AccountName
|
||||
elem["description"] = value.Desc
|
||||
elem["image_id"] = value.ImageID
|
||||
elem["size"] = value.SizeMax
|
||||
elem["type"] = value.Type
|
||||
elem["sep_id"] = value.SepID
|
||||
elem["sep_type"] = value.SepType
|
||||
elem["pool"] = value.Pool
|
||||
// elem["status"] = value.Status
|
||||
// elem["tech_status"] = value.TechStatus
|
||||
elem["compute_id"] = value.ComputeID
|
||||
|
||||
result = append(result, elem)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func parseBootDiskSize(disks []DiskRecord) int {
|
||||
// this return value will be used to d.Set("boot_disk_size",) item of dataSourceCompute schema
|
||||
if len(disks) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
for _, value := range disks {
|
||||
if value.Type == "B" {
|
||||
return value.SizeMax
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
func parseBootDiskId(disks []DiskRecord) uint {
|
||||
// this return value will be used to d.Set("boot_disk_id",) item of dataSourceCompute schema
|
||||
if len(disks) == 0 {
|
||||
return 0
|
||||
}
|
||||
|
||||
for _, value := range disks {
|
||||
if value.Type == "B" {
|
||||
return value.ID
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
// Parse the list of interfaces from compute/get response into a list of networks
|
||||
// attached to this compute
|
||||
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
||||
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
||||
length := len(ifaces)
|
||||
log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length)
|
||||
|
||||
result := []interface{}{}
|
||||
|
||||
for _, value := range ifaces {
|
||||
elem := make(map[string]interface{})
|
||||
// Keys in this map should correspond to the Schema definition
|
||||
// as returned by networkSubresourceSchemaMake()
|
||||
elem["net_id"] = value.NetID
|
||||
elem["net_type"] = value.NetType
|
||||
elem["ip_address"] = value.IPAddress
|
||||
elem["mac"] = value.MAC
|
||||
|
||||
// log.Debugf(" element %d: net_id=%d, net_type=%s", i, value.NetID, value.NetType)
|
||||
|
||||
result = append(result, elem)
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
// NOTE: this function is retained for historical purposes and actually not used as of rc-1.10
|
||||
func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
|
||||
// return value was designed to d.Set("interfaces",) item of dataSourceCompute schema
|
||||
// However, this item was excluded from the schema as it is not directly
|
||||
// managed through Terraform
|
||||
length := len(ifaces)
|
||||
log.Debugf("parseComputeInterfaces: called for %d ifaces", length)
|
||||
|
||||
result := make([]map[string]interface{}, length, length)
|
||||
|
||||
for i, value := range ifaces {
|
||||
// Keys in this map should correspond to the Schema definition
|
||||
// as returned by dataSourceInterfaceSchemaMake()
|
||||
elem := make(map[string]interface{})
|
||||
|
||||
elem["net_id"] = value.NetID
|
||||
elem["net_type"] = value.NetType
|
||||
elem["ip_address"] = value.IPAddress
|
||||
elem["netmask"] = value.NetMask
|
||||
elem["mac"] = value.MAC
|
||||
elem["default_gw"] = value.DefaultGW
|
||||
elem["name"] = value.Name
|
||||
elem["connection_id"] = value.ConnID
|
||||
elem["connection_type"] = value.ConnType
|
||||
|
||||
/* TODO: add code to parse QoS
|
||||
qos_schema := interfaceQosSubresourceSchemaMake()
|
||||
qos_schema.Set("egress_rate", value.QOS.ERate)
|
||||
qos_schema.Set("ingress_rate", value.QOS.InRate)
|
||||
qos_schema.Set("ingress_burst", value.QOS.InBurst)
|
||||
elem["qos"] = qos_schema
|
||||
*/
|
||||
|
||||
result[i] = elem
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||
// This function expects that compFacts string contains response from API compute/get,
|
||||
// i.e. detailed information about compute instance.
|
||||
//
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourceComputeExists(...) method
|
||||
model := ComputeGetResp{}
|
||||
log.Debugf("flattenCompute: ready to unmarshal string %s", compFacts)
|
||||
err := json.Unmarshal([]byte(compFacts), &model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("flattenCompute: ID %d, RG ID %d", model.ID, model.RgID)
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", model.ID))
|
||||
// d.Set("compute_id", model.ID) - we should NOT set compute_id in the schema here: if it was set - it is already set, if it wasn't - we shouldn't
|
||||
d.Set("name", model.Name)
|
||||
d.Set("rg_id", model.RgID)
|
||||
d.Set("rg_name", model.RgName)
|
||||
d.Set("account_id", model.AccountID)
|
||||
d.Set("account_name", model.AccountName)
|
||||
d.Set("arch", model.Arch)
|
||||
d.Set("cpu", model.Cpu)
|
||||
d.Set("ram", model.Ram)
|
||||
// d.Set("boot_disk_size", model.BootDiskSize) - bootdiskSize key in API compute/get is always zero, so we set boot_disk_size in another way
|
||||
d.Set("boot_disk_size", parseBootDiskSize(model.Disks))
|
||||
d.Set("boot_disk_id", parseBootDiskId(model.Disks)) // we may need boot disk ID in resize operations
|
||||
d.Set("image_id", model.ImageID)
|
||||
d.Set("description", model.Desc)
|
||||
d.Set("cloud_init", "applied") // NOTE: for existing compute we hard-code this value as an indicator for DiffSuppress fucntion
|
||||
// d.Set("status", model.Status)
|
||||
// d.Set("tech_status", model.TechStatus)
|
||||
|
||||
if len(model.Disks) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(model.Disks))
|
||||
if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(model.Interfaces) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(model.Interfaces))
|
||||
if err = d.Set("network", parseComputeInterfacesToNetworks(model.Interfaces)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if len(model.OsUsers) > 0 {
|
||||
log.Debugf("flattenCompute: calling parseOsUsers for %d logins", len(model.OsUsers))
|
||||
if err = d.Set("os_users", parseOsUsers(model.OsUsers)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceComputeRead(d *schema.ResourceData, m interface{}) error {
|
||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
||||
if compFacts == "" {
|
||||
// if empty string is returned from utilityComputeCheckPresence then there is no
|
||||
// such Compute and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenCompute(d, compFacts)
|
||||
}
|
||||
|
||||
func dataSourceCompute() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourceComputeRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Name of this compute instance. NOTE: this parameter is case sensitive.",
|
||||
},
|
||||
|
||||
// TODO: consider removing compute_id from the schema, as it not practical to call this data provider if
|
||||
// corresponding compute ID is already known
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the compute instance. If ID is specified, name and resource group ID are ignored.",
|
||||
},
|
||||
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the resource group where this compute instance is located.",
|
||||
},
|
||||
|
||||
"rg_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the resource group where this compute instance is located.",
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the account this compute instance belongs to.",
|
||||
},
|
||||
|
||||
"account_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the account this compute instance belongs to.",
|
||||
},
|
||||
|
||||
"arch": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Hardware architecture of this compute instance.",
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Number of CPUs allocated for this compute instance.",
|
||||
},
|
||||
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Amount of RAM in MB allocated for this compute instance.",
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the OS image this compute instance is based on.",
|
||||
},
|
||||
|
||||
"image_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the OS image this compute instance is based on.",
|
||||
},
|
||||
|
||||
"boot_disk_size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "This compute instance boot disk size in GB.",
|
||||
},
|
||||
|
||||
"boot_disk_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "This compute instance boot disk ID.",
|
||||
},
|
||||
|
||||
"extra_disks": {
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
MaxItems: MaxExtraDisksPerCompute,
|
||||
Elem: &schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "IDs of the extra disk(s) attached to this compute.",
|
||||
},
|
||||
|
||||
/*
|
||||
"disks": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
||||
},
|
||||
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
||||
},
|
||||
*/
|
||||
|
||||
"network": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
MaxItems: MaxNetworksPerCompute,
|
||||
Elem: &schema.Resource{
|
||||
Schema: networkSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Network connection(s) for this compute.",
|
||||
},
|
||||
|
||||
/*
|
||||
"interfaces": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: interfaceSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Specification for the virtual NICs configured on this compute instance.",
|
||||
},
|
||||
*/
|
||||
|
||||
"os_users": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: osUsersSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Guest OS users provisioned on this compute instance.",
|
||||
},
|
||||
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "User-defined text description of this compute instance.",
|
||||
},
|
||||
|
||||
"cloud_init": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Placeholder for cloud_init parameters.",
|
||||
},
|
||||
|
||||
/*
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current model status of this compute instance.",
|
||||
},
|
||||
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current technical status of this compute instance.",
|
||||
},
|
||||
|
||||
"internal_ip": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Internal IP address of this Compute.",
|
||||
},
|
||||
*/
|
||||
},
|
||||
}
|
||||
}
|
||||
201
decort/data_source_disk.go
Normal file
201
decort/data_source_disk.go
Normal file
@@ -0,0 +1,201 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
// "net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func flattenDisk(d *schema.ResourceData, disk_facts string) error {
|
||||
// This function expects disk_facts string to contain a response from disks/get API
|
||||
//
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourceDiskExists(...) method. Use utilityDiskCheckPresence instead.
|
||||
|
||||
log.Debugf("flattenDisk: ready to unmarshal string %s", disk_facts)
|
||||
|
||||
model := DiskRecord{}
|
||||
|
||||
err := json.Unmarshal([]byte(disk_facts), &model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("flattenDisk: disk ID %d, disk AccountID %d", model.ID, model.AccountID)
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", model.ID))
|
||||
// d.Set("disk_id", model.ID) - we should NOT update disk_id in the schema. If it was set - it is already set, if it wasn't - we shouldn't
|
||||
d.Set("name", model.Name)
|
||||
d.Set("account_id", model.AccountID)
|
||||
d.Set("account_name", model.AccountName)
|
||||
d.Set("size", model.SizeMax)
|
||||
// d.Set("sizeUsed", model.SizeUsed)
|
||||
d.Set("type", model.Type)
|
||||
d.Set("image_id", model.ImageID)
|
||||
d.Set("sep_id", model.SepID)
|
||||
d.Set("sep_type", model.SepType)
|
||||
d.Set("pool", model.Pool)
|
||||
// d.Set("compute_id", model.ComputeID)
|
||||
|
||||
d.Set("description", model.Desc)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceDiskRead(d *schema.ResourceData, m interface{}) error {
|
||||
disk_facts, err := utilityDiskCheckPresence(d, m)
|
||||
if disk_facts == "" {
|
||||
// if empty string is returned from utilityDiskCheckPresence then there is no
|
||||
// such Disk and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenDisk(d, disk_facts)
|
||||
}
|
||||
|
||||
func dataSourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Name of this disk. NOTE: disk names are NOT unique within an account. If disk ID is specified, disk name is ignored.",
|
||||
},
|
||||
|
||||
"disk_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the disk to get. If disk ID is specified, then disk name and account ID are ignored.",
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the account this disk belongs to. If disk ID is specified, then account ID is ignored.",
|
||||
},
|
||||
|
||||
// The rest of the data source Disk schema are all computed
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Storage end-point provider serving this disk.",
|
||||
},
|
||||
|
||||
"pool": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Pool where this disk is located.",
|
||||
},
|
||||
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Size of the disk in GB.",
|
||||
},
|
||||
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of this disk. E.g. D for data disks, B for boot.",
|
||||
},
|
||||
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "User-defined text description of this disk.",
|
||||
},
|
||||
|
||||
"account_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the account this disk belongs to. If account ID is specified, account name is ignored.",
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the image, which this disk was cloned from (valid for disk clones only).",
|
||||
},
|
||||
|
||||
"sep_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of the storage end-point provider serving this disk.",
|
||||
},
|
||||
|
||||
/*
|
||||
"snapshots": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource {
|
||||
Schema: snapshotSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "List of user-created snapshots for this disk."
|
||||
},
|
||||
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current model status of this disk.",
|
||||
},
|
||||
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current technical status of this disk.",
|
||||
},
|
||||
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the compute instance where this disk is attached to, or 0 for unattached disk.",
|
||||
},
|
||||
*/
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func dataSourceDisk() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourceDiskRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceDiskSchemaMake(),
|
||||
}
|
||||
}
|
||||
145
decort/data_source_image.go
Normal file
145
decort/data_source_image.go
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func dataSourceImageRead(d *schema.ResourceData, m interface{}) error {
|
||||
name := d.Get("name").(string)
|
||||
// rg_id, rgid_set := d.GetOk("rg_id")
|
||||
accId, accSet := d.GetOk("account_id")
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
url_values := &url.Values{}
|
||||
if accSet {
|
||||
url_values.Add("accountId", fmt.Sprintf("%d", accId.(int)))
|
||||
}
|
||||
body_string, err, _ := controller.decortAPICall("POST", ImagesListAPI, url_values)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("dataSourceImageRead: ready to decode response body from %s", ImagesListAPI)
|
||||
model := ImagesListResp{}
|
||||
err = json.Unmarshal([]byte(body_string), &model)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
// log.Printf("%#v", model)
|
||||
log.Debugf("dataSourceImageRead: traversing decoded JSON of length %d", len(model))
|
||||
for index, item := range model {
|
||||
// need to match Image by name
|
||||
if item.Name == name {
|
||||
log.Debugf("dataSourceImageRead: index %d, matched name %s", index, item.Name)
|
||||
d.SetId(fmt.Sprintf("%d", item.ID))
|
||||
d.Set("account_id", item.AccountID)
|
||||
d.Set("arch", item.Arch)
|
||||
d.Set("sep_id", item.SepID)
|
||||
d.Set("pool", item.Pool)
|
||||
d.Set("status", item.Status)
|
||||
d.Set("size", item.Size)
|
||||
// d.Set("field_name", value)
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
return fmt.Errorf("Cannot find Image name %s", name)
|
||||
}
|
||||
|
||||
func dataSourceImage() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourceImageRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the image to locate. This parameter is case sensitive.",
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "Optional ID of the account to limit image search to.",
|
||||
},
|
||||
|
||||
"arch": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Binary architecture of this image.",
|
||||
},
|
||||
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Storage end-point provider serving this image.",
|
||||
},
|
||||
|
||||
/*
|
||||
"sep_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of the storage end-point provider serving this image.",
|
||||
},
|
||||
*/
|
||||
|
||||
"pool": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Pool where this image is located.",
|
||||
},
|
||||
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Size of the image in GB.",
|
||||
},
|
||||
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current model status of this image.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
144
decort/data_source_pfw.go
Normal file
144
decort/data_source_pfw.go
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
// "hash/fnv"
|
||||
log "github.com/sirupsen/logrus"
|
||||
// "net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
|
||||
func flattenPfw(d *schema.ResourceData, pfwFacts string) error {
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourcePfwExists(...) method
|
||||
pfwRecord := ComputePfwListResp{}
|
||||
err := json.Unmarshal([]byte(pfwFacts), &pfwRecord)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("flattenPfw: decoded %d PFW rules for compute ID %s on ViNS ID %d",
|
||||
len(pfwRecord.Rules), pfwRecord.Header.VinsID, pfwRecord.Header.VinsID)
|
||||
|
||||
/*
|
||||
Here it gets a little bit interesting.
|
||||
Unlike compute or disk, port forwaring rules are NOT represented by any cloud
|
||||
platform resource, which might have had a unique ID. They are just a subset of
|
||||
rules in the list maintained by the corresponding ViNS instance. However,
|
||||
Terraform needs a unique ID for each resource it manages so that it could be
|
||||
stored in the state file and retrieved for use.
|
||||
|
||||
Therefore we need to make up an ID and supply it to Terraform in a standard
|
||||
way (i.e. by calling d.SetId(...)).
|
||||
|
||||
Fortunately, a combination of Compute ID and ViNS ID with GW VNF, where this
|
||||
compute is plugged in, makes a unique string, so we use it as an ID for
|
||||
the PFW ruleset.
|
||||
|
||||
The following few lines are legacy from the first attempt to make an ID
|
||||
as a hash of concatenated Compute ID & ViNS ID, but it did not work as
|
||||
expected for a number of reasons, which explanation is not a primary
|
||||
intent of the comment in the source code.
|
||||
|
||||
combo := fmt.Sprintf("%d:%d", compId.(int), pfwRecord.ViNS.VinsID)
|
||||
hasher := fnv.New32a()
|
||||
hasher.Write([]byte(combo))
|
||||
d.SetId(fmt.Sprintf("%d", hasher.Sum32()))
|
||||
*/
|
||||
// set ID of this PFW rule set as "compute_id:vins_id"
|
||||
d.SetId(fmt.Sprintf("%d:%d", pfwRecord.Header.ComputeID, pfwRecord.Header.VinsID))
|
||||
log.Debugf("flattenPfw: PFW rule set ID %s", d.Id())
|
||||
d.Set("compute_id", pfwRecord.Header.ComputeID)
|
||||
d.Set("vins_id", pfwRecord.Header.VinsID)
|
||||
|
||||
pfwRulesList := []interface{}{}
|
||||
for _, runner := range pfwRecord.Rules {
|
||||
rule := map[string]interface{}{
|
||||
"pub_port_start": runner.PublicPortStart,
|
||||
"pub_port_end": runner.PublicPortEnd,
|
||||
"local_port": runner.LocalPort,
|
||||
"proto": runner.Protocol,
|
||||
"rule_id": runner.ID,
|
||||
}
|
||||
pfwRulesList = append(pfwRulesList, rule)
|
||||
}
|
||||
if err = d.Set("rule", pfwRulesList); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourcePfwRead(d *schema.ResourceData, m interface{}) error {
|
||||
pfwFacts, err := utilityPfwCheckPresence(d, m)
|
||||
if pfwFacts == "" {
|
||||
// if empty string is returned from dataSourcePfwRead then we got no
|
||||
// PFW rules. It could also be because there was some error, which
|
||||
// is indicated by non-nil err value
|
||||
d.SetId("") // ensure ID is empty in this case anyway
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenPfw(d, pfwFacts)
|
||||
}
|
||||
|
||||
func dataSourcePfw() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourcePfwRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the compute instance to configure port forwarding rules for.",
|
||||
},
|
||||
|
||||
"vins_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the ViNS to configure port forwarding rules on. Compute must be already plugged into this ViNS and ViNS must have external network connection.",
|
||||
},
|
||||
|
||||
// TODO: consider making "rule" attribute Required with MinItems = 1
|
||||
"rule": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: rulesSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Port forwarding rule. You may specify several rules, one in each such block.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,75 +16,84 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package rg
|
||||
package decort
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
// "net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func flattenResgroup(d *schema.ResourceData, rgData *rg.RecordRG) error {
|
||||
func flattenResgroup(d *schema.ResourceData, rg_facts string) error {
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourceRsgroupExists(...) method
|
||||
// log.Debugf("%s", rg_facts)
|
||||
log.Debugf("flattenResgroup: ready to decode response body from API")
|
||||
details := ResgroupGetResp{}
|
||||
err := json.Unmarshal([]byte(rg_facts), &details)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d",
|
||||
rgData.Name, rgData.ID, rgData.AccountID)
|
||||
details.Name, details.ID, details.AccountID)
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", rgData.ID))
|
||||
d.Set("rg_id", rgData.ID)
|
||||
d.Set("name", rgData.Name)
|
||||
d.Set("account_name", rgData.AccountName)
|
||||
d.Set("account_id", rgData.AccountID)
|
||||
// d.Set("grid_id", rgData.GridID)
|
||||
d.Set("description", rgData.Description)
|
||||
d.Set("status", rgData.Status)
|
||||
d.Set("def_net_type", rgData.DefNetType)
|
||||
d.Set("def_net_id", rgData.DefNetID)
|
||||
d.SetId(fmt.Sprintf("%d", details.ID))
|
||||
d.Set("rg_id", details.ID)
|
||||
d.Set("name", details.Name)
|
||||
d.Set("account_name", details.AccountName)
|
||||
d.Set("account_id", details.AccountID)
|
||||
// d.Set("grid_id", details.GridID)
|
||||
d.Set("description", details.Desc)
|
||||
d.Set("status", details.Status)
|
||||
d.Set("def_net_type", details.DefaultNetType)
|
||||
d.Set("def_net_id", details.DefaultNetID)
|
||||
/*
|
||||
d.Set("vins", details.Vins)
|
||||
d.Set("computes", details.Computes)
|
||||
*/
|
||||
|
||||
// log.Debugf("flattenResgroup: calling flattenQuota()")
|
||||
// if err := d.Set("quota", parseQuota(rgData.Resources)); err != nil {
|
||||
// return err
|
||||
// }
|
||||
log.Debugf("flattenResgroup: calling flattenQuota()")
|
||||
if err = d.Set("quota", parseQuota(details.Quota)); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if rg_facts == nil {
|
||||
func dataSourceResgroupRead(d *schema.ResourceData, m interface{}) error {
|
||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
||||
if rg_facts == "" {
|
||||
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
||||
// such resource group and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty in this case
|
||||
return diag.FromErr(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return diag.FromErr(flattenResgroup(d, rg_facts))
|
||||
return flattenResgroup(d, rg_facts)
|
||||
}
|
||||
|
||||
func DataSourceResgroup() *schema.Resource {
|
||||
func dataSourceResgroup() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceResgroupRead,
|
||||
Read: dataSourceResgroupRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
@@ -131,6 +138,7 @@ func DataSourceResgroup() *schema.Resource {
|
||||
"quota": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: quotaRgSubresourceSchemaMake(), // this is a dictionary
|
||||
},
|
||||
@@ -150,30 +158,30 @@ func DataSourceResgroup() *schema.Resource {
|
||||
},
|
||||
|
||||
/*
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current status of this resource group.",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current status of this resource group.",
|
||||
},
|
||||
|
||||
"vins": {
|
||||
Type: schema.TypeList, // this is a list of ints
|
||||
Computed: true,
|
||||
MaxItems: LimitMaxVinsPerResgroup,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "List of VINs deployed in this resource group.",
|
||||
"vins": {
|
||||
Type: schema.TypeList, // this is a list of ints
|
||||
Computed: true,
|
||||
MaxItems: LimitMaxVinsPerResgroup,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "List of VINs deployed in this resource group.",
|
||||
},
|
||||
|
||||
"computes": {
|
||||
Type: schema.TypeList, //t his is a list of ints
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "List of computes deployed in this resource group.",
|
||||
"computes": {
|
||||
Type: schema.TypeList, //t his is a list of ints
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "List of computes deployed in this resource group.",
|
||||
},
|
||||
*/
|
||||
},
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Copyright (c) 2020-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,61 +16,64 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package vins
|
||||
package decort
|
||||
|
||||
import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"reflect"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/vins"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
|
||||
// "net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func flattenVins(d *schema.ResourceData, vinsRecord *vins.RecordVINS) diag.Diagnostics {
|
||||
// vins_facts is a response string from API vins/get
|
||||
func flattenVins(d *schema.ResourceData, vins_facts string) error {
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourceVinsExists(...) method
|
||||
// log.Debugf("flattenVins: ready to decode response body from API %s", vins_facts)
|
||||
vinsRecord := VinsRecord{}
|
||||
err := json.Unmarshal([]byte(vins_facts), &vinsRecord)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d",
|
||||
vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RGID)
|
||||
vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID)
|
||||
|
||||
d.SetId(fmt.Sprintf("%d", vinsRecord.ID))
|
||||
d.Set("name", vinsRecord.Name)
|
||||
d.Set("account_id", vinsRecord.AccountID)
|
||||
// d.Set("account_name", vinsRecord.AccountName)
|
||||
d.Set("rg_id", vinsRecord.RGID)
|
||||
d.Set("description", vinsRecord.Description)
|
||||
d.Set("ipcidr", vinsRecord.Network)
|
||||
d.Set("account_name", vinsRecord.AccountName)
|
||||
err = d.Set("rg_id", vinsRecord.RgID)
|
||||
d.Set("description", vinsRecord.Desc)
|
||||
d.Set("ipcidr", vinsRecord.IPCidr)
|
||||
|
||||
noExtNetConnection := true
|
||||
gw := vinsRecord.VNFs.GW
|
||||
if !reflect.ValueOf(gw).IsZero() {
|
||||
log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", gw.ID, vinsRecord.ID)
|
||||
extNetID := gw.Config.ExtNetID
|
||||
extNetIP := gw.Config.ExtNetIP
|
||||
if extNetID != 0 && extNetIP != "" {
|
||||
log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", extNetID, extNetIP)
|
||||
d.Set("ext_ip_addr", extNetIP)
|
||||
d.Set("ext_net_id", extNetID)
|
||||
} else {
|
||||
return diag.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.")
|
||||
for _, value := range vinsRecord.VNFs {
|
||||
if value.Type == "GW" {
|
||||
log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", value.ID, vinsRecord.ID)
|
||||
extNetID, idOk := value.Config["ext_net_id"] // NOTE: unknown numbers are unmarshalled to float64. This is by design!
|
||||
extNetIP, ipOk := value.Config["ext_net_ip"]
|
||||
if idOk && ipOk {
|
||||
log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", int(extNetID.(float64)), extNetIP.(string))
|
||||
d.Set("ext_ip_addr", extNetIP.(string))
|
||||
d.Set("ext_net_id", int(extNetID.(float64)))
|
||||
} else {
|
||||
return fmt.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.")
|
||||
}
|
||||
noExtNetConnection = false
|
||||
break
|
||||
}
|
||||
noExtNetConnection = false
|
||||
}
|
||||
|
||||
if noExtNetConnection {
|
||||
@@ -85,25 +86,27 @@ func flattenVins(d *schema.ResourceData, vinsRecord *vins.RecordVINS) diag.Diagn
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
vinsFacts, err := utilityVinsCheckPresence(ctx, d, m)
|
||||
if vinsFacts == nil {
|
||||
d.SetId("")
|
||||
return diag.FromErr(err)
|
||||
func dataSourceVinsRead(d *schema.ResourceData, m interface{}) error {
|
||||
vinsFacts, err := utilityVinsCheckPresence(d, m)
|
||||
if vinsFacts == "" {
|
||||
// if empty string is returned from utilityVinsCheckPresence then there is no
|
||||
// such ViNS and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty in this case
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenVins(d, vinsFacts)
|
||||
}
|
||||
|
||||
func DataSourceVins() *schema.Resource {
|
||||
func dataSourceVins() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
ReadContext: dataSourceVinsRead,
|
||||
Read: dataSourceVinsRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &constants.Timeout30s,
|
||||
Default: &constants.Timeout60s,
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
@@ -114,11 +117,11 @@ func DataSourceVins() *schema.Resource {
|
||||
},
|
||||
|
||||
/*
|
||||
"vins_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
|
||||
},
|
||||
"vins_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
|
||||
},
|
||||
*/
|
||||
|
||||
"rg_id": {
|
||||
86
decort/disk_subresource.go
Normal file
86
decort/disk_subresource.go
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
// log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
|
||||
// ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
||||
func diskSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of this disk.",
|
||||
},
|
||||
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "Size of the disk in GB.",
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the account this disk belongs to.",
|
||||
},
|
||||
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Type of this disk.",
|
||||
},
|
||||
|
||||
"sep_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "default",
|
||||
Description: "ID of the storage end-point provider serving this disk.",
|
||||
},
|
||||
|
||||
"sep_type": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "default",
|
||||
Description: "Type of the storage provider serving this disk.",
|
||||
},
|
||||
|
||||
"pool": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "default",
|
||||
Description: "Pool on the storage where this disk is located.",
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the binary Image this disk resource is cloned from (if any).",
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
331
decort/interface_subresource.go
Normal file
331
decort/interface_subresource.go
Normal file
@@ -0,0 +1,331 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file contains definitions and code for handling Interface component of Compute schema
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
/*
|
||||
"log"
|
||||
"strconv"
|
||||
"strings"
|
||||
*/
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func interfaceSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"net_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the network entity this interface is connected to.",
|
||||
},
|
||||
|
||||
"net_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of the network entity this interface is connected to.",
|
||||
},
|
||||
|
||||
"ip_address": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "IP addresses assigned to this interface.",
|
||||
},
|
||||
|
||||
"netmask": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Network mask to be used with this interface.",
|
||||
},
|
||||
|
||||
"mac": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "MAC address of this interface.",
|
||||
},
|
||||
|
||||
"default_gw": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Default gateway associated with this interface.",
|
||||
},
|
||||
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Interface name.",
|
||||
},
|
||||
|
||||
"connection_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "VxLAN or VLAN ID this interface is connected to.",
|
||||
},
|
||||
|
||||
"connection_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of the segment (VLAN or VxLAN) this interface is connected to.",
|
||||
},
|
||||
|
||||
"qos": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: interfaceQosSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "QoS settings for this interface.",
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func interfaceQosSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"egress_rate": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Egress rate limit on this interface.",
|
||||
},
|
||||
|
||||
"ingress_burst": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Ingress burst limit on this interface.",
|
||||
},
|
||||
|
||||
"ingress_rate": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Ingress rate limit on this interface.",
|
||||
},
|
||||
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "GUID of this QoS record.",
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
/*
|
||||
func flattenNetworks(nets []NicRecord) []interface{} {
|
||||
// this function expects an array of NicRecord as returned by machines/get API call
|
||||
// NOTE: it does NOT expect a strucutre as returned by externalnetwork/list
|
||||
var length = 0
|
||||
var strarray []string
|
||||
|
||||
for _, value := range nets {
|
||||
if value.NicType == "PUBLIC" {
|
||||
length += 1
|
||||
}
|
||||
}
|
||||
log.Debugf("flattenNetworks: found %d NICs with PUBLIC type", length)
|
||||
|
||||
result := make([]interface{}, length)
|
||||
if length == 0 {
|
||||
return result
|
||||
}
|
||||
|
||||
elem := make(map[string]interface{})
|
||||
|
||||
var subindex = 0
|
||||
for index, value := range nets {
|
||||
if value.NicType == "PUBLIC" {
|
||||
// this will be changed as network segments entity
|
||||
// value.Params for ext net comes in a form "gateway:176.118.165.1 externalnetworkId:6"
|
||||
// for network_id we need to extract from this string
|
||||
strarray = strings.Split(value.Params, " ")
|
||||
substr := strings.Split(strarray[1], ":")
|
||||
elem["network_id"], _ = strconv.Atoi(substr[1])
|
||||
elem["ip_range"] = value.IPAddress
|
||||
// elem["label"] = ... - should be uncommented for the future release
|
||||
log.Debugf("flattenNetworks: parsed element %d - network_id %d, ip_range %s",
|
||||
index, elem["network_id"].(int), value.IPAddress)
|
||||
result[subindex] = elem
|
||||
subindex += 1
|
||||
}
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func makePortforwardsConfig(arg_list []interface{}) (pfws []PortforwardConfig, count int) {
|
||||
count = len(arg_list)
|
||||
if count < 1 {
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
pfws = make([]PortforwardConfig, count)
|
||||
var subres_data map[string]interface{}
|
||||
for index, value := range arg_list {
|
||||
subres_data = value.(map[string]interface{})
|
||||
// pfws[index].Label = subres_data["label"].(string) - should be uncommented for future release
|
||||
pfws[index].ExtPort = subres_data["ext_port"].(int)
|
||||
pfws[index].IntPort = subres_data["int_port"].(int)
|
||||
pfws[index].Proto = subres_data["proto"].(string)
|
||||
}
|
||||
|
||||
return pfws, count
|
||||
}
|
||||
|
||||
func flattenPortforwards(pfws []PortforwardRecord) []interface{} {
|
||||
result := make([]interface{}, len(pfws))
|
||||
elem := make(map[string]interface{})
|
||||
var port_num int
|
||||
|
||||
for index, value := range pfws {
|
||||
// elem["label"] = ... - should be uncommented for the future release
|
||||
|
||||
// external port field is of TypeInt in the portforwardSubresourceSchema, but string is returned
|
||||
// by portforwards/list API, so we need conversion here
|
||||
port_num, _ = strconv.Atoi(value.ExtPort)
|
||||
elem["ext_port"] = port_num
|
||||
// internal port field is of TypeInt in the portforwardSubresourceSchema, but string is returned
|
||||
// by portforwards/list API, so we need conversion here
|
||||
port_num, _ = strconv.Atoi(value.IntPort)
|
||||
elem["int_port"] = port_num
|
||||
elem["proto"] = value.Proto
|
||||
elem["ext_ip"] = value.ExtIP
|
||||
elem["int_ip"] = value.IntIP
|
||||
result[index] = elem
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func portforwardSubresourceSchema() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"label": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Unique label of this network connection to identify it amnong other connections for this VM.",
|
||||
},
|
||||
|
||||
"ext_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "External port number for this port forwarding rule.",
|
||||
},
|
||||
|
||||
"int_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "Internal port number for this port forwarding rule.",
|
||||
},
|
||||
|
||||
"proto": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
// ValidateFunc: validation.IntBetween(1, ),
|
||||
Description: "Protocol type for this port forwarding rule. Should be either 'tcp' or 'udp'.",
|
||||
},
|
||||
|
||||
"ext_ip": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: ".",
|
||||
},
|
||||
|
||||
"int_ip": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: ".",
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func flattenNICs(nics []NicRecord) []interface{} {
|
||||
var result = make([]interface{}, len(nics))
|
||||
elem := make(map[string]interface{})
|
||||
|
||||
for index, value := range nics {
|
||||
elem["status"] = value.Status
|
||||
elem["type"] = value.NicType
|
||||
elem["mac"] = value.MacAddress
|
||||
elem["ip_address"] = value.IPAddress
|
||||
elem["parameters"] = value.Params
|
||||
elem["reference_id"] = value.ReferenceID
|
||||
elem["network_id"] = value.NetworkID
|
||||
result[index] = elem
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
|
||||
func nicSubresourceSchema() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current status of this NIC.",
|
||||
},
|
||||
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of this NIC.",
|
||||
},
|
||||
|
||||
"mac": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "MAC address assigned to this NIC.",
|
||||
},
|
||||
|
||||
"ip_address": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "IP address assigned to this NIC.",
|
||||
},
|
||||
|
||||
"parameters": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Additional NIC parameters.",
|
||||
},
|
||||
|
||||
"reference_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Reference ID of this NIC.",
|
||||
},
|
||||
|
||||
"network_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Network ID which this NIC is connected to.",
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
*/
|
||||
610
decort/models_api.go
Normal file
610
decort/models_api.go
Normal file
@@ -0,0 +1,610 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"time"
|
||||
)
|
||||
|
||||
//
|
||||
// timeouts for API calls from CRUD functions of Terraform plugin
|
||||
var Timeout30s = time.Second * 30
|
||||
var Timeout60s = time.Second * 60
|
||||
var Timeout180s = time.Second * 180
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/rg/list API
|
||||
//
|
||||
type UserAclRecord struct {
|
||||
IsExplicit bool `json:"explicit"`
|
||||
Rights string `json:"right"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
UgroupID string `json:"userGroupId"`
|
||||
// CanBeDeleted bool `json:"canBeDeleted"`
|
||||
}
|
||||
|
||||
type AccountAclRecord struct {
|
||||
IsExplicit bool `json:"explicit"`
|
||||
Guid string `json:"guid"`
|
||||
Rights string `json:"right"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
UgroupID string `json:"userGroupId"`
|
||||
}
|
||||
|
||||
type ResgroupRecord struct {
|
||||
ACLs []UserAclRecord `json:"acl"`
|
||||
Owner AccountAclRecord `json:"accountAcl"`
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
DefaultNetID int `json:"def_net_id"`
|
||||
DefaultNetType string `json:"def_net_type"`
|
||||
Decsription string `json:"desc"`
|
||||
GridID int `json:"gid"`
|
||||
ID uint `json:"id"`
|
||||
LockStatus string `json:"lockStatus"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
UpdatedTime uint64 `json:"updatedTime"`
|
||||
Vins []int `json:"vins"`
|
||||
Computes []int `json:"vms"`
|
||||
}
|
||||
|
||||
const ResgroupListAPI = "/restmachine/cloudapi/rg/list"
|
||||
|
||||
type ResgroupListResp []ResgroupRecord
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/rg/create API call
|
||||
//
|
||||
const ResgroupCreateAPI = "/restmachine/cloudapi/rg/create"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/rg/update API call
|
||||
//
|
||||
const ResgroupUpdateAPI = "/restmachine/cloudapi/rg/update"
|
||||
|
||||
type ResgroupUpdateParam struct {
|
||||
RgId int `json:"rgId"`
|
||||
Name string `json:"name"`
|
||||
Desc string `json:"decs"`
|
||||
Ram int `json:"maxMemoryCapacity"`
|
||||
Disk int `json:"maxVDiskCapacity"`
|
||||
Cpu int `json:"maxCPUCapacity"`
|
||||
NetTraffic int `json:"maxNetworkPeerTransfer"`
|
||||
Reason string `json:"reason"`
|
||||
}
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/rg/get API call
|
||||
//
|
||||
type QuotaRecord struct { // this is how quota is reported by /api/.../rg/get
|
||||
Cpu int `json:"CU_C"` // CPU count in pcs
|
||||
Ram float64 `json:"CU_M"` // RAM volume in MB, it is STILL reported as FLOAT
|
||||
Disk int `json:"CU_D"` // Disk capacity in GB
|
||||
ExtIPs int `json:"CU_I"` // Ext IPs count
|
||||
ExtTraffic int `json:"CU_NP"` // Ext network traffic
|
||||
GpuUnits int `json:"gpu_units"` // GPU count
|
||||
}
|
||||
|
||||
type ResourceRecord struct { // this is how actual usage is reported by /api/.../rg/get
|
||||
Cpu int `json:"cpu"`
|
||||
Disk int `json:"disksize"`
|
||||
ExtIPs int `json:"extips"`
|
||||
ExtTraffic int `json:"exttraffic"`
|
||||
Gpu int `json:"gpu"`
|
||||
Ram int `json:"ram"`
|
||||
}
|
||||
|
||||
type UsageRecord struct {
|
||||
Current ResourceRecord `json:"Current"`
|
||||
Reserved ResourceRecord `json:"Reserved"`
|
||||
}
|
||||
|
||||
const ResgroupGetAPI = "/restmachine/cloudapi/rg/get"
|
||||
|
||||
type ResgroupGetResp struct {
|
||||
ACLs []UserAclRecord `json:"ACLs"`
|
||||
Usage UsageRecord `json:"Resources"`
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
GridID int `json:"gid"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
DefaultNetID int `json:"def_net_id"`
|
||||
DefaultNetType string `json:"def_net_type"`
|
||||
DeletedBy string `json:"deletedBy"`
|
||||
DeletedTime uint64 `json:"deletedTime"`
|
||||
Desc string `json:"desc"`
|
||||
ID uint `json:"id"`
|
||||
LockStatus string `json:"lockStatus"`
|
||||
Name string `json:"name"`
|
||||
Quota QuotaRecord `json:"resourceLimits"`
|
||||
Status string `json:"status"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
UpdatedTime uint64 `json:"updatedTime"`
|
||||
Vins []int `json:"vins"`
|
||||
Computes []int `json:"vms"`
|
||||
|
||||
Ignored map[string]interface{} `json:"-"`
|
||||
}
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/rg/delete API
|
||||
//
|
||||
const ResgroupDeleteAPI = "/restmachine/cloudapi/rg/delete"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/rg/listComputes API
|
||||
//
|
||||
type ComputeBriefRecord struct { // this is a brief compute specifiaction as returned by API rg/listComputes
|
||||
// we do not even include here all fields as returned by this API, but only the most important that
|
||||
// are really necessary to identify and distinguish computes
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
Name string `json:"name"`
|
||||
ID uint `json:"id"`
|
||||
RgID int `json:"rgId"`
|
||||
RgName string `json:"rgName"`
|
||||
Status string `json:"status"`
|
||||
TechStatus string `json:"techStatus"`
|
||||
}
|
||||
|
||||
const RgListComputesAPI = "/restmachine/cloudapi/rg/listComputes"
|
||||
|
||||
type RgListComputesResp []ComputeBriefRecord
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/kvmXXX/create APIs
|
||||
//
|
||||
const KvmX86CreateAPI = "/restmachine/cloudapi/kvmx86/create"
|
||||
const KvmPPCCreateAPI = "/restmachine/cloudapi/kvmppc/create"
|
||||
|
||||
type KvmVmCreateParam struct { // this is unified structure for both x86 and PPC based KVM VMs creation
|
||||
RgID uint `json:"rgId"`
|
||||
Name string `json:"name"`
|
||||
Cpu int `json:"cpu"`
|
||||
Ram int `json:"ram"`
|
||||
ImageID int `json:"imageId"`
|
||||
BootDisk int `json:"bootDisk"`
|
||||
NetType string `json:"netType"`
|
||||
NetId int `json:"netId"`
|
||||
IPAddr string `json:"ipAddr"`
|
||||
UserData string `json:"userdata"`
|
||||
Desc string `json:"desc"`
|
||||
Start bool `json:"start"`
|
||||
}
|
||||
|
||||
// structures related to cloudapi/compute/start API
|
||||
const ComputeStartAPI = "/restmachine/cloudapi/compute/start"
|
||||
|
||||
// structures related to cloudapi/compute/delete API
|
||||
const ComputeDeleteAPI = "/restmachine/cloudapi/compute/delete"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/compute/list API
|
||||
//
|
||||
|
||||
type InterfaceQosRecord struct {
|
||||
ERate int `json:"eRate"`
|
||||
Guid string `json:"guid"`
|
||||
InBurst int `json:"inBurst"`
|
||||
InRate int `json:"inRate"`
|
||||
}
|
||||
|
||||
type InterfaceRecord struct {
|
||||
ConnID int `json:"connId"` // This is VLAN ID or VxLAN ID, depending on ConnType
|
||||
ConnType string `json:"connType"` // Either "VLAN" or "VXLAN" tag
|
||||
DefaultGW string `json:"defGw"`
|
||||
Guid string `json:"guid"`
|
||||
IPAddress string `json:"ipAddress"` // without trailing network mask, i.e. "192.168.1.3"
|
||||
MAC string `json:"mac"`
|
||||
Name string `json:"name"`
|
||||
NetID int `json:"netId"` // This is either ExtNet ID or ViNS ID, depending on NetType
|
||||
NetMask int `json:"netMask"`
|
||||
NetType string `json:"netType"` // Either "EXTNET" or "VINS" tag
|
||||
PciSlot int `json:"pciSlot"`
|
||||
Target string `json:"target"`
|
||||
Type string `json:"type"`
|
||||
VNFs []int `json:"vnfs"`
|
||||
QOS InterfaceQosRecord `json:"qos"`
|
||||
}
|
||||
|
||||
type SnapSetRecord struct {
|
||||
Disks []int `json:"disks"`
|
||||
Guid string `json:"guid"`
|
||||
Label string `json:"label"`
|
||||
TimeStamp uint64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type ComputeRecord struct {
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
ACLs []UserAclRecord `json:"acl"`
|
||||
Arch string `json:"arch"`
|
||||
BootDiskSize int `json:"bootdiskSize"`
|
||||
CloneReference int `json:"cloneReference"`
|
||||
Clones []int `json:"clones"`
|
||||
Cpus int `json:"cpus"`
|
||||
CreatedBy string `json:"createdBy"`
|
||||
CreatedTime uint64 `json:"createdTime"`
|
||||
DeletedBy string `json:"deletedBy"`
|
||||
DeletedTime uint64 `json:"deletedTime"`
|
||||
Desc string `json:"desc"`
|
||||
Disks []int `json:"disks"`
|
||||
GridID int `json:"gid"`
|
||||
ID uint `json:"id"`
|
||||
ImageID int `json:"imageId"`
|
||||
Interfaces []InterfaceRecord `json:"interfaces"`
|
||||
LockStatus string `json:"lockStatus"`
|
||||
ManagerID int `json:"managerId"`
|
||||
Name string `json:"name"`
|
||||
Ram int `json:"ram"`
|
||||
RgID int `json:"rgId"`
|
||||
RgName string `json:"rgName"`
|
||||
SnapSets []SnapSetRecord `json:"snapSets"`
|
||||
Status string `json:"status"`
|
||||
// Tags []string `json:"tags"` // Tags were reworked since DECORT 3.7.1
|
||||
TechStatus string `json:"techStatus"`
|
||||
TotalDiskSize int `json:"totalDiskSize"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
UpdateTime uint64 `json:"updateTime"`
|
||||
UserManaged bool `json:"userManaged"`
|
||||
Vgpus []int `json:"vgpus"`
|
||||
VinsConnected int `json:"vinsConnected"`
|
||||
VirtualImageID int `json:"virtualImageId"`
|
||||
}
|
||||
|
||||
const ComputeListAPI = "/restmachine/cloudapi/compute/list"
|
||||
|
||||
type ComputeListResp []ComputeRecord
|
||||
|
||||
const ComputeResizeAPI = "/restmachine/cloudapi/compute/resize"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/compute/get
|
||||
//
|
||||
type SnapshotRecord struct {
|
||||
Guid string `json:"guid"`
|
||||
Label string `json:"label"`
|
||||
SnapSetGuid string `json:"snapSetGuid"`
|
||||
SnapSetTime uint64 `json:"snapSetTime"`
|
||||
TimeStamp uint64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type DiskRecord struct {
|
||||
// ACLs `json:"ACL"` - it is a dictionary, special parsing required
|
||||
// was - Acl map[string]string `json:"acl"`
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"` // NOTE: absent from compute/get output
|
||||
BootPartition int `json:"bootPartition"`
|
||||
CreatedTime uint64 `json:"creationTime"`
|
||||
DeletedTime uint64 `json:"deletionTime"`
|
||||
Desc string `json:"desc"`
|
||||
DestructionTime uint64 `json:"destructionTime"`
|
||||
DiskPath string `json:"diskPath"`
|
||||
GridID int `json:"gid"`
|
||||
ID uint `json:"id"`
|
||||
ImageID int `json:"imageId"`
|
||||
Images []int `json:"images"`
|
||||
// IOTune 'json:"iotune" - it is a dictionary
|
||||
Name string `json:"name"`
|
||||
// Order `json:"order"`
|
||||
ParentId int `json:"parentId"`
|
||||
PciSlot int `json:"pciSlot"`
|
||||
// ResID string `json:"resId"`
|
||||
// ResName string `json:"resName"`
|
||||
// Params string `json:"params"`
|
||||
Pool string `json:"pool"`
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
// Role string `json:"role"`
|
||||
SepType string `json:"sepType"`
|
||||
SepID int `json:"sepId"` // NOTE: absent from compute/get output
|
||||
SizeMax int `json:"sizeMax"`
|
||||
SizeUsed int `json:"sizeUsed"` // sum over all snapshots of this disk to report total consumed space
|
||||
Snapshots []SnapshotRecord `json:"snapshots"`
|
||||
Status string `json:"status"`
|
||||
TechStatus string `json:"techStatus"`
|
||||
Type string `json:"type"`
|
||||
ComputeID int `json:"vmid"`
|
||||
}
|
||||
|
||||
type OsUserRecord struct {
|
||||
Guid string `json:"guid"`
|
||||
Login string `json:"login"`
|
||||
Password string `json:"password"`
|
||||
PubKey string `json:"pubkey"`
|
||||
}
|
||||
|
||||
const ComputeGetAPI = "/restmachine/cloudapi/compute/get"
|
||||
|
||||
type ComputeGetResp struct {
|
||||
// ACLs `json:"ACL"` - it is a dictionary, special parsing required
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
Arch string `json:"arch"`
|
||||
BootDiskSize int `json:"bootdiskSize"`
|
||||
CloneReference int `json:"cloneReference"`
|
||||
Clones []int `json:"clones"`
|
||||
Cpu int `json:"cpus"`
|
||||
Desc string `json:"desc"`
|
||||
Disks []DiskRecord `json:"disks"`
|
||||
GridID int `json:"gid"`
|
||||
ID uint `json:"id"`
|
||||
ImageID int `json:"imageId"`
|
||||
ImageName string `json:"imageName"`
|
||||
Interfaces []InterfaceRecord `json:"interfaces"`
|
||||
LockStatus string `json:"lockStatus"`
|
||||
ManagerID int `json:"managerId"`
|
||||
ManagerType string `json:"manageType"`
|
||||
Name string `json:"name"`
|
||||
NatableVinsID int `json:"natableVinsId"`
|
||||
NatableVinsIP string `json:"natableVinsIp"`
|
||||
NatableVinsName string `json:"natableVinsName"`
|
||||
NatableVinsNet string `json:"natableVinsNetwork"`
|
||||
NatableVinsNetName string `json:"natableVinsNetworkName"`
|
||||
OsUsers []OsUserRecord `json:"osUsers"`
|
||||
Ram int `json:"ram"`
|
||||
RgID int `json:"rgId"`
|
||||
RgName string `json:"rgName"`
|
||||
SnapSets []SnapSetRecord `json:"snapSets"`
|
||||
Status string `json:"status"`
|
||||
// Tags []string `json:"tags"` // Tags were reworked since DECORT 3.7.1
|
||||
TechStatus string `json:"techStatus"`
|
||||
TotalDiskSize int `json:"totalDiskSize"`
|
||||
UpdatedBy string `json:"updatedBy"`
|
||||
UpdateTime uint64 `json:"updateTime"`
|
||||
UserManaged bool `json:"userManaged"`
|
||||
Vgpus []int `json:"vgpus"`
|
||||
VinsConnected int `json:"vinsConnected"`
|
||||
VirtualImageID int `json:"virtualImageId"`
|
||||
}
|
||||
|
||||
//
|
||||
// structures related to /restmachine/cloudapi/image/list API
|
||||
//
|
||||
type ImageRecord struct {
|
||||
AccountID uint `json:"accountId"`
|
||||
Arch string `json:"architecture"`
|
||||
BootType string `json:"bootType"`
|
||||
IsBootable bool `json:"bootable"`
|
||||
IsCdrom bool `json:"cdrom"`
|
||||
Desc string `json:"desc"`
|
||||
IsHotResize bool `json:"hotResize"`
|
||||
ID uint `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Pool string `json:"pool"`
|
||||
SepID int `json:"sepId"`
|
||||
Size int `json:"size"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
Username string `json:"username"`
|
||||
IsVirtual bool `json:"virtual"`
|
||||
}
|
||||
|
||||
const ImagesListAPI = "/restmachine/cloudapi/image/list"
|
||||
|
||||
type ImagesListResp []ImageRecord
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/extnet/list API
|
||||
//
|
||||
type ExtNetRecord struct {
|
||||
Name string `json:"name"`
|
||||
ID uint `json:"id"`
|
||||
IPCIDR string `json:"ipcidr"`
|
||||
}
|
||||
|
||||
const ExtNetListAPI = "/restmachine/cloudapi/extnet/list"
|
||||
|
||||
type ExtNetListResp []ExtNetRecord
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/account/list API
|
||||
//
|
||||
type AccountRecord struct {
|
||||
// ACLs []UserAclRecord `json:"acl"`
|
||||
// CreatedTime uint64 `json:"creationTime"`
|
||||
// DeletedTime uint64 `json:"deletionTime"`
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"`
|
||||
// UpdatedTime uint64 `json:"updateTime"`
|
||||
}
|
||||
|
||||
const AccountsGetAPI = "/restmachine/cloudapi/account/get" // returns AccountRecord superset
|
||||
|
||||
const AccountsListAPI = "/restmachine/cloudapi/account/list" // returns list of abdridged info about accounts
|
||||
type AccountsListResp []AccountRecord
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/portforwarding/list API
|
||||
//
|
||||
// Note the specifics of compute/pfwList response in API 3.7.x (this may be changed in the future):
|
||||
// 1) if there are no PFW rules and compute is not connected to any PFW-able ViNS
|
||||
// the response will be empty string
|
||||
// 2) if there are no PFW rules but compute is connected to a PFW-able ViNS
|
||||
// the response will contain a list with a single element - prefix (see PfwPrefixRecord)
|
||||
// 3) if there are port forwarding rules, the response will contain a list which starts
|
||||
// with prefix (see PfwPrefixRecord) and then followed by one or more rule records
|
||||
// (see PfwRuleRecord)
|
||||
type PfwPrefixRecord struct {
|
||||
VinsID int `json:"vinsId"`
|
||||
VinsName string `json:"vinsName"`
|
||||
ComputeID int `json:"computeId"`
|
||||
}
|
||||
type PfwRuleRecord struct {
|
||||
ID int `json:"id"`
|
||||
LocalIP string `json:"localIp"`
|
||||
LocalPort int `json:"localPort"`
|
||||
Protocol string `json:"protocol"`
|
||||
PublicPortEnd int `json:"publicPortEnd"`
|
||||
PublicPortStart int `json:"publicPortStart"`
|
||||
ComputeID int `json:"vmId"`
|
||||
}
|
||||
|
||||
type ComputePfwListResp struct {
|
||||
Header PfwPrefixRecord `json:"header"`
|
||||
Rules []PfwRuleRecord `json:"rules"`
|
||||
}
|
||||
|
||||
const ComputePfwListAPI = "/restmachine/cloudapi/compute/pfwList"
|
||||
|
||||
const ComputePfwAddAPI = "/restmachine/cloudapi/compute/pfwAdd"
|
||||
|
||||
const ComputePfwDelAPI = "/restmachine/cloudapi/compute/pfwDel"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/compute/net Attach/Detach API
|
||||
//
|
||||
type ComputeNetMgmtRecord struct { // used to "cache" network specs when preparing to manage compute networks
|
||||
ID int
|
||||
Type string
|
||||
IPAddress string
|
||||
MAC string
|
||||
}
|
||||
const ComputeNetAttachAPI = "/restmachine/cloudapi/compute/netAttach"
|
||||
|
||||
const ComputeNetDetachAPI = "/restmachine/cloudapi/compute/netDetach"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/compute/disk Attach/Detach API
|
||||
//
|
||||
const ComputeDiskAttachAPI = "/restmachine/cloudapi/compute/diskAttach"
|
||||
|
||||
const ComputeDiskDetachAPI = "/restmachine/cloudapi/compute/diskDetach"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/disks/create
|
||||
//
|
||||
const DisksCreateAPI = "/restmachine/cloudapi/disks/create"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/disks/get
|
||||
//
|
||||
const DisksGetAPI = "/restmachine/cloudapi/disks/get" // Returns single DiskRecord on success
|
||||
|
||||
const DisksListAPI = "/restmachine/cloudapi/disks/list" // Returns list of DiskRecord on success
|
||||
type DisksListResp []DiskRecord
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/disks/resize
|
||||
//
|
||||
const DisksResizeAPI = "/restmachine/cloudapi/disks/resize2"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/disks/resize
|
||||
//
|
||||
const DisksRenameAPI = "/restmachine/cloudapi/disks/rename"
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/disks/delete
|
||||
//
|
||||
const DisksDeleteAPI = "/restmachine/cloudapi/disks/delete"
|
||||
|
||||
|
||||
//
|
||||
// ViNS structures
|
||||
//
|
||||
|
||||
// this is the structure of the element in the list returned by vins/search API
|
||||
type VinsSearchRecord struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IPCidr string `json:"network"`
|
||||
VxLanID int `json:"vxlanId"`
|
||||
ExternalIP string `json:"externalIP"`
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
RgID int `json:"rgId"`
|
||||
RgName string `json:"rgName"`
|
||||
}
|
||||
|
||||
const VinsSearchAPI = "/restmachine/cloudapi/vins/search"
|
||||
type VinsSearchResp []VinsSearchRecord
|
||||
|
||||
type VnfRecord struct {
|
||||
ID int `json:"id"`
|
||||
AccountID int `json:"accountId"`
|
||||
Type string `json:"type"` // "DHCP", "NAT", "GW" etc
|
||||
Config map[string]interface{} `json:"config"` // NOTE: VNF specs vary by VNF type
|
||||
}
|
||||
|
||||
type VnfGwConfigRecord struct { // describes GW VNF config structure inside ViNS, as returned by API vins/get
|
||||
ExtNetID int `json:"ext_net_id"`
|
||||
ExtNetIP string `json:"ext_net_ip"`
|
||||
ExtNetMask int `json:"ext_net_mask"`
|
||||
DefaultGW string `json:"default_gw"`
|
||||
}
|
||||
type VinsRecord struct { // represents part of the response from API vins/get
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
IPCidr string `json:"network"`
|
||||
VxLanID int `json:"vxlanId"`
|
||||
ExternalIP string `json:"externalIP"`
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
RgID int `json:"rgid"`
|
||||
RgName string `json:"rgName"`
|
||||
VNFs map[string]VnfRecord `json:"vnfs"`
|
||||
Desc string `json:"desc"`
|
||||
}
|
||||
|
||||
const VinsGetAPI = "/restmachine/cloudapi/vins/get"
|
||||
|
||||
const VinsCreateInAccountAPI = "/restmachine/cloudapi/vins/createInAccount"
|
||||
const VinsCreateInRgAPI = "/restmachine/cloudapi/vins/createInRG"
|
||||
|
||||
const VinsExtNetConnectAPI = "/restmachine/cloudapi/vins/extNetConnect"
|
||||
const VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect"
|
||||
|
||||
const VinsDeleteAPI = "/restmachine/cloudapi/vins/delete"
|
||||
|
||||
//
|
||||
// Grid ID structures
|
||||
//
|
||||
type LocationRecord struct {
|
||||
GridID int `json:"gid"`
|
||||
Id int `json:"id"`
|
||||
LocationCode string `json:"locationCode"`
|
||||
Name string `json:"name"`
|
||||
Flag string `json:"flag"`
|
||||
}
|
||||
|
||||
const LocationsListAPI = "/restmachine/cloudapi/locations/list" // Returns list of GridRecord on success
|
||||
type LocationsListResp []LocationRecord
|
||||
|
||||
//
|
||||
// Auxiliary structures
|
||||
//
|
||||
type SshKeyConfig struct {
|
||||
User string
|
||||
SshKey string
|
||||
UserShell string
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,31 +15,21 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package kvmvm
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
"bytes"
|
||||
"hash/fnv"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs"
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
// "net/url"
|
||||
"sort"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/validation"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/v2/internal/helper/hashcode"
|
||||
)
|
||||
|
||||
// This is subresource of compute resource used when creating/managing compute network connections
|
||||
@@ -55,19 +43,19 @@ func networkSubresIPAddreDiffSupperss(key, oldVal, newVal string, d *schema.Reso
|
||||
return true // suppress difference
|
||||
}
|
||||
|
||||
// This function is based on the original Terraform SerializeResourceForHash found
|
||||
// This function is based on the original Terraform SerializeResourceForHash found
|
||||
// in helper/schema/serialize.go
|
||||
// It skips network subresource attributes, which are irrelevant for identification
|
||||
// It skips network subresource attributes, which are irrelevant for identification
|
||||
// of unique network blocks
|
||||
func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource *schema.Resource) {
|
||||
if val == nil {
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
rs := resource.Schema
|
||||
m := val.(map[string]interface{})
|
||||
|
||||
keys := make([]string, 0, len(rs))
|
||||
var keys []string
|
||||
allComputed := true
|
||||
|
||||
for k, val := range rs {
|
||||
@@ -108,7 +96,7 @@ func networkSubresourceSerialize(output *bytes.Buffer, val interface{}, resource
|
||||
// from network subresource (e.g. in flattenCompute)
|
||||
//
|
||||
// This function is based on the original Terraform function HashResource from
|
||||
// helper/schema/set.go
|
||||
// helper/schema/set.go
|
||||
func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc {
|
||||
return func(v interface{}) int {
|
||||
var serialized bytes.Buffer
|
||||
@@ -123,11 +111,11 @@ func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc {
|
||||
func networkSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"net_type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
StateFunc: statefuncs.StateFuncToUpper,
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
StateFunc: stateFuncToUpper,
|
||||
ValidateFunc: validation.StringInSlice([]string{"EXTNET", "VINS"}, false), // observe case while validating
|
||||
Description: "Type of the network for this connection, either EXTNET or VINS.",
|
||||
Description: "Type of the network for this connection, either EXTNET or VINS.",
|
||||
},
|
||||
|
||||
"net_id": {
|
||||
@@ -137,11 +125,11 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
},
|
||||
|
||||
"ip_address": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
DiffSuppressFunc: networkSubresIPAddreDiffSupperss,
|
||||
Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.",
|
||||
Description: "Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.",
|
||||
},
|
||||
|
||||
"mac": {
|
||||
@@ -149,6 +137,7 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
Computed: true,
|
||||
Description: "MAC address associated with this connection. MAC address is assigned automatically.",
|
||||
},
|
||||
|
||||
}
|
||||
return rets
|
||||
}
|
||||
@@ -1,8 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -17,34 +15,22 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package kvmvm
|
||||
package decort
|
||||
|
||||
import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/compute"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func parseOsUsers(logins compute.ListOSUsers) []interface{} {
|
||||
func parseOsUsers(logins []OsUserRecord) []interface{} {
|
||||
var result = make([]interface{}, len(logins))
|
||||
|
||||
for index, value := range logins {
|
||||
elem := make(map[string]interface{})
|
||||
elem := make(map[string]interface{})
|
||||
|
||||
elem["guid"] = value.GUID
|
||||
for index, value := range logins {
|
||||
elem["guid"] = value.Guid
|
||||
elem["login"] = value.Login
|
||||
elem["password"] = value.Password
|
||||
elem["public_key"] = value.PubKey
|
||||
@@ -1,129 +1,147 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package provider
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"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"
|
||||
"golang.org/x/net/context"
|
||||
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/location"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/statefuncs"
|
||||
)
|
||||
|
||||
func Provider() *schema.Provider {
|
||||
return &schema.Provider{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"authenticator": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
StateFunc: statefuncs.StateFuncToLower,
|
||||
ValidateFunc: validation.StringInSlice([]string{"oauth2", "legacy", "jwt"}, true), // ignore case while validating
|
||||
Description: "Authentication mode to use when connecting to DECORT cloud API. Should be one of 'oauth2', 'legacy' or 'jwt'.",
|
||||
},
|
||||
|
||||
"oauth2_url": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
StateFunc: statefuncs.StateFuncToLower,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_OAUTH2_URL", nil),
|
||||
Description: "OAuth2 application URL in 'oauth2' authentication mode.",
|
||||
},
|
||||
|
||||
"controller_url": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: statefuncs.StateFuncToLower,
|
||||
Description: "URL of DECORT Cloud controller to use. API calls will be directed to this URL.",
|
||||
},
|
||||
|
||||
"user": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_USER", nil),
|
||||
Description: "User name for DECORT cloud API operations in 'legacy' authentication mode.",
|
||||
},
|
||||
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_PASSWORD", nil),
|
||||
Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.",
|
||||
},
|
||||
|
||||
"app_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil),
|
||||
Description: "Application ID to access DECORT cloud API in 'oauth2' authentication mode.",
|
||||
},
|
||||
|
||||
"app_secret": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil),
|
||||
Description: "Application secret to access DECORT cloud API in 'oauth2' authentication mode.",
|
||||
},
|
||||
|
||||
"jwt": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_JWT", nil),
|
||||
Description: "JWT to access DECORT cloud API in 'jwt' authentication mode.",
|
||||
},
|
||||
|
||||
"allow_unverified_ssl": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!",
|
||||
},
|
||||
},
|
||||
|
||||
ResourcesMap: newResourcesMap(),
|
||||
|
||||
DataSourcesMap: newDataSourcesMap(),
|
||||
|
||||
ConfigureContextFunc: providerConfigure,
|
||||
}
|
||||
}
|
||||
|
||||
func providerConfigure(ctx context.Context, d *schema.ResourceData) (interface{}, diag.Diagnostics) {
|
||||
decsController, err := controller.ControllerConfigure(d)
|
||||
if err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
|
||||
gridId, err := location.UtilityLocationGetDefaultGridID(ctx, decsController)
|
||||
if err != nil {
|
||||
return nil, diag.FromErr(err)
|
||||
}
|
||||
if gridId == 0 {
|
||||
return nil, diag.FromErr(fmt.Errorf("providerConfigure: invalid default Grid ID = 0"))
|
||||
}
|
||||
|
||||
return decsController, nil
|
||||
}
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
)
|
||||
|
||||
var decsController *ControllerCfg
|
||||
|
||||
func Provider() *schema.Provider {
|
||||
return &schema.Provider{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"authenticator": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
StateFunc: stateFuncToLower,
|
||||
ValidateFunc: validation.StringInSlice([]string{"oauth2", "legacy", "jwt"}, true), // ignore case while validating
|
||||
Description: "Authentication mode to use when connecting to DECORT cloud API. Should be one of 'oauth2', 'legacy' or 'jwt'.",
|
||||
},
|
||||
|
||||
"oauth2_url": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
StateFunc: stateFuncToLower,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_OAUTH2_URL", nil),
|
||||
Description: "OAuth2 application URL in 'oauth2' authentication mode.",
|
||||
},
|
||||
|
||||
"controller_url": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: stateFuncToLower,
|
||||
Description: "URL of DECORT Cloud controller to use. API calls will be directed to this URL.",
|
||||
},
|
||||
|
||||
"user": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_USER", nil),
|
||||
Description: "User name for DECORT cloud API operations in 'legacy' authentication mode.",
|
||||
},
|
||||
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_PASSWORD", nil),
|
||||
Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.",
|
||||
},
|
||||
|
||||
"app_id": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil),
|
||||
Description: "Application ID to access DECORT cloud API in 'oauth2' authentication mode.",
|
||||
},
|
||||
|
||||
"app_secret": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil),
|
||||
Description: "Application secret to access DECORT cloud API in 'oauth2' authentication mode.",
|
||||
},
|
||||
|
||||
"jwt": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_JWT", nil),
|
||||
Description: "JWT to access DECORT cloud API in 'jwt' authentication mode.",
|
||||
},
|
||||
|
||||
"allow_unverified_ssl": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!",
|
||||
},
|
||||
},
|
||||
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"decort_resgroup": resourceResgroup(),
|
||||
"decort_kvmvm": resourceCompute(),
|
||||
"decort_disk": resourceDisk(),
|
||||
"decort_vins": resourceVins(),
|
||||
"decort_pfw": resourcePfw(),
|
||||
},
|
||||
|
||||
DataSourcesMap: map[string]*schema.Resource{
|
||||
"decort_account": dataSourceAccount(),
|
||||
"decort_resgroup": dataSourceResgroup(),
|
||||
"decort_kvmvm": dataSourceCompute(),
|
||||
"decort_image": dataSourceImage(),
|
||||
"decort_disk": dataSourceDisk(),
|
||||
"decort_vins": dataSourceVins(),
|
||||
"decort_pfw": dataSourcePfw(),
|
||||
},
|
||||
|
||||
ConfigureFunc: providerConfigure,
|
||||
}
|
||||
}
|
||||
|
||||
func stateFuncToLower(argval interface{}) string {
|
||||
return strings.ToLower(argval.(string))
|
||||
}
|
||||
|
||||
func stateFuncToUpper(argval interface{}) string {
|
||||
return strings.ToUpper(argval.(string))
|
||||
}
|
||||
|
||||
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
||||
decsController, err := ControllerConfigure(d)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// initialize global default Grid ID - it will be needed to create some resource types, e.g. disks
|
||||
gridId, err := decsController.utilityLocationGetDefaultGridID()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if gridId == 0 {
|
||||
return nil, fmt.Errorf("providerConfigure: invalid default Grid ID = 0")
|
||||
}
|
||||
|
||||
return decsController, nil
|
||||
}
|
||||
@@ -1,9 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -18,61 +15,55 @@ See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
*/
|
||||
|
||||
package rg
|
||||
package decort
|
||||
|
||||
import (
|
||||
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
// "log"
|
||||
// "net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func makeQuotaRecord(arg_list []interface{}) QuotaRecord {
|
||||
func makeQuotaRecord(arg_list []interface{}) (QuotaRecord, int) {
|
||||
quota := QuotaRecord{
|
||||
Cpu: -1,
|
||||
Ram: -1,
|
||||
Ram: -1., // this is float64, but may change in the future
|
||||
Disk: -1,
|
||||
ExtTraffic: -1,
|
||||
ExtIPs: -1,
|
||||
GpuUnits: -1,
|
||||
}
|
||||
if len(arg_list) != 0 {
|
||||
subres_data := arg_list[0].(map[string]interface{})
|
||||
subres_data := arg_list[0].(map[string]interface{})
|
||||
|
||||
if subres_data["cpu"].(int) > 0 {
|
||||
quota.Cpu = subres_data["cpu"].(int)
|
||||
}
|
||||
|
||||
if subres_data["disk"].(int) > 0 {
|
||||
quota.Disk = subres_data["disk"].(int) // Disk capacity ib GB
|
||||
}
|
||||
|
||||
if subres_data["ram"].(float64) > 0 {
|
||||
quota.Ram = subres_data["ram"].(float64) // RAM volume in MB, as float64!
|
||||
}
|
||||
|
||||
if subres_data["ext_traffic"].(int) > 0 {
|
||||
quota.ExtTraffic = subres_data["ext_traffic"].(int)
|
||||
}
|
||||
|
||||
if subres_data["ext_ips"].(int) > 0 {
|
||||
quota.ExtIPs = subres_data["ext_ips"].(int)
|
||||
}
|
||||
|
||||
if subres_data["gpu_units"].(int) > 0 {
|
||||
quota.GpuUnits = subres_data["gpu_units"].(int)
|
||||
}
|
||||
if subres_data["cpu"].(int) > 0 {
|
||||
quota.Cpu = subres_data["cpu"].(int)
|
||||
}
|
||||
return quota
|
||||
|
||||
if subres_data["disk"].(int) > 0 {
|
||||
quota.Disk = subres_data["disk"].(int) // Disk capacity ib GB
|
||||
}
|
||||
|
||||
if subres_data["ram"].(float64) > 0 {
|
||||
quota.Ram = subres_data["ram"].(float64) // RAM volume in MB, as float64!
|
||||
}
|
||||
|
||||
if subres_data["ext_traffic"].(int) > 0 {
|
||||
quota.ExtTraffic = subres_data["ext_traffic"].(int)
|
||||
}
|
||||
|
||||
if subres_data["ext_ips"].(int) > 0 {
|
||||
quota.ExtIPs = subres_data["ext_ips"].(int)
|
||||
}
|
||||
|
||||
if subres_data["gpu_units"].(int) > 0 {
|
||||
quota.GpuUnits = subres_data["gpu_units"].(int)
|
||||
}
|
||||
|
||||
return quota, 1
|
||||
}
|
||||
|
||||
func parseQuota(quota QuotaRecord) []interface{} {
|
||||
554
decort/resource_compute.go
Normal file
554
decort/resource_compute.go
Normal file
@@ -0,0 +1,554 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
|
||||
if oldVal == "" && newVal != "applied" {
|
||||
// if old value for "cloud_init" resource is empty string, it means that we are creating new compute
|
||||
// and there is a chance that the user will want custom cloud init parameters - so we check if
|
||||
// cloud_init is explicitly set in TF file by making sure that its new value is different from "applied",
|
||||
// which is a reserved key word.
|
||||
log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal)
|
||||
return false // there is a difference between stored and new value
|
||||
}
|
||||
log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal)
|
||||
return true // suppress difference
|
||||
}
|
||||
|
||||
func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
// we assume all mandatory parameters it takes to create a comptue instance are properly
|
||||
// specified - we rely on schema "Required" attributes to let Terraform validate them for us
|
||||
|
||||
log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
// create basic Compute (i.e. without extra disks and network connections - those will be attached
|
||||
// by subsequent individual API calls).
|
||||
// creating Compute is a multi-step workflow, which may fail at some step, so we use "partial" feature of Terraform
|
||||
d.Partial(true)
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", d.Get("rg_id").(int)))
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("cpu", fmt.Sprintf("%d", d.Get("cpu").(int)))
|
||||
urlValues.Add("ram", fmt.Sprintf("%d", d.Get("ram").(int)))
|
||||
urlValues.Add("imageId", fmt.Sprintf("%d", d.Get("image_id").(int)))
|
||||
urlValues.Add("bootDisk", fmt.Sprintf("%d", d.Get("boot_disk_size").(int)))
|
||||
urlValues.Add("netType", "NONE") // at the 1st step create isolated compute
|
||||
urlValues.Add("start", "0") // at the 1st step create compute in a stopped state
|
||||
|
||||
argVal, argSet := d.GetOk("description")
|
||||
if argSet {
|
||||
urlValues.Add("desc", argVal.(string))
|
||||
}
|
||||
|
||||
/*
|
||||
sshKeysVal, sshKeysSet := d.GetOk("ssh_keys")
|
||||
if sshKeysSet {
|
||||
// process SSH Key settings and set API values accordingly
|
||||
log.Debugf("resourceComputeCreate: calling makeSshKeysArgString to setup SSH keys for guest login(s)")
|
||||
urlValues.Add("userdata", makeSshKeysArgString(sshKeysVal.([]interface{})))
|
||||
}
|
||||
*/
|
||||
|
||||
computeCreateAPI := KvmX86CreateAPI
|
||||
arch := d.Get("arch").(string)
|
||||
if arch == "KVM_PPC" {
|
||||
computeCreateAPI = KvmPPCCreateAPI
|
||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC")
|
||||
} else { // note that we do not validate arch value for explicit "KVM_X86" here
|
||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("cloud_init")
|
||||
if argSet {
|
||||
// userdata must not be empty string and must not be a reserved keyword "applied"
|
||||
userdata := argVal.(string)
|
||||
if userdata != "" && userdata != "applied" {
|
||||
urlValues.Add("userdata", userdata)
|
||||
}
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", computeCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Compute create API returns ID of the new Compute instance on success
|
||||
|
||||
d.SetId(apiResp) // update ID of the resource to tell Terraform that the resource exists, albeit partially
|
||||
compId, _ := strconv.Atoi(apiResp)
|
||||
d.SetPartial("name")
|
||||
d.SetPartial("description")
|
||||
d.SetPartial("cpu")
|
||||
d.SetPartial("ram")
|
||||
d.SetPartial("image_id")
|
||||
d.SetPartial("boot_disk_size")
|
||||
/*
|
||||
if sshKeysSet {
|
||||
d.SetPartial("ssh_keys")
|
||||
}
|
||||
*/
|
||||
|
||||
log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", compId, d.Get("name").(string))
|
||||
|
||||
// Configure data disks if any
|
||||
extraDisksOk := true
|
||||
argVal, argSet = d.GetOk("extra_disks")
|
||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||
// urlValues.Add("desc", argVal.(string))
|
||||
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
|
||||
err = controller.utilityComputeExtraDisksConfigure(d, false) // do_delta=false, as we are working on a new compute
|
||||
if err != nil {
|
||||
log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %s: %s", compId, err)
|
||||
extraDisksOk = false
|
||||
}
|
||||
}
|
||||
if extraDisksOk {
|
||||
d.SetPartial("extra_disks")
|
||||
}
|
||||
|
||||
// Configure external networks if any
|
||||
netsOk := true
|
||||
argVal, argSet = d.GetOk("network")
|
||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||
log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len())
|
||||
err = controller.utilityComputeNetworksConfigure(d, false) // do_delta=false, as we are working on a new compute
|
||||
if err != nil {
|
||||
log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", compId, err)
|
||||
netsOk = false
|
||||
}
|
||||
}
|
||||
if netsOk {
|
||||
// there were no errors reported when configuring networks
|
||||
d.SetPartial("network")
|
||||
}
|
||||
|
||||
if extraDisksOk && netsOk {
|
||||
// if there were no errors in setting any of the subresources, we may leave Partial mode
|
||||
d.Partial(false)
|
||||
}
|
||||
|
||||
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
|
||||
// now we need to start it before we report the sequence complete
|
||||
reqValues := &url.Values{}
|
||||
reqValues.Add("computeId", fmt.Sprintf("%d", compId))
|
||||
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId)
|
||||
apiResp, err, _ = controller.decortAPICall("POST", ComputeStartAPI, reqValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", compId, d.Get("name").(string))
|
||||
|
||||
// We may reuse dataSourceComputeRead here as we maintain similarity
|
||||
// between Compute resource and Compute data source schemas
|
||||
// Compute read function will also update resource ID on success, so that Terraform
|
||||
// will know the resource exists
|
||||
return dataSourceComputeRead(d, m)
|
||||
}
|
||||
|
||||
func resourceComputeRead(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceComputeRead: called for Compute name %s, RG ID %d",
|
||||
d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
||||
if compFacts == "" {
|
||||
d.SetId("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// Compute with such name and RG ID was not found
|
||||
return nil
|
||||
}
|
||||
|
||||
if err = flattenCompute(d, compFacts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("resourceComputeRead: after flattenCompute: Compute ID %s, name %q, RG ID %d",
|
||||
d.Id(), d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceComputeUpdate: called for Compute ID %s / name %s, RGID %d",
|
||||
d.Id(), d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
|
||||
/*
|
||||
1. Resize CPU/RAM
|
||||
2. Resize (grow) boot disk
|
||||
3. Update extra disks
|
||||
4. Update networks
|
||||
*/
|
||||
|
||||
// 1. Resize CPU/RAM
|
||||
params := &url.Values{}
|
||||
doUpdate := false
|
||||
params.Add("computeId", d.Id())
|
||||
|
||||
d.Partial(true)
|
||||
|
||||
oldCpu, newCpu := d.GetChange("cpu")
|
||||
if oldCpu.(int) != newCpu.(int) {
|
||||
params.Add("cpu", fmt.Sprintf("%d", newCpu.(int)))
|
||||
doUpdate = true
|
||||
} else {
|
||||
params.Add("cpu", "0") // no change to CPU allocation
|
||||
}
|
||||
|
||||
oldRam, newRam := d.GetChange("ram")
|
||||
if oldRam.(int) != newRam.(int) {
|
||||
params.Add("ram", fmt.Sprintf("%d", newRam.(int)))
|
||||
doUpdate = true
|
||||
} else {
|
||||
params.Add("ram", "0")
|
||||
}
|
||||
|
||||
if doUpdate {
|
||||
log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d",
|
||||
oldCpu.(int), newCpu.(int),
|
||||
oldRam.(int), newRam.(int))
|
||||
_, err, _ := controller.decortAPICall("POST", ComputeResizeAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.SetPartial("cpu")
|
||||
d.SetPartial("ram")
|
||||
}
|
||||
|
||||
// 2. Resize (grow) Boot disk
|
||||
oldSize, newSize := d.GetChange("boot_disk_size")
|
||||
if oldSize.(int) < newSize.(int) {
|
||||
bdsParams := &url.Values{}
|
||||
bdsParams.Add("diskId", fmt.Sprintf("%d", d.Get("boot_disk_id").(int)))
|
||||
bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
||||
log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d",
|
||||
d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int))
|
||||
_, err, _ := controller.decortAPICall("POST", DisksResizeAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.SetPartial("boot_disk_size")
|
||||
} else if oldSize.(int) > newSize.(int) {
|
||||
log.Warnf("resourceComputeUpdate: compute ID %d - shrinking boot disk is not allowed", d.Id())
|
||||
}
|
||||
|
||||
// 3. Calculate and apply changes to data disks
|
||||
err := controller.utilityComputeExtraDisksConfigure(d, true) // pass do_delta = true to apply changes, if any
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
d.SetPartial("extra_disks")
|
||||
}
|
||||
|
||||
// 4. Calculate and apply changes to network connections
|
||||
err = controller.utilityComputeNetworksConfigure(d, true) // pass do_delta = true to apply changes, if any
|
||||
if err != nil {
|
||||
return err
|
||||
} else {
|
||||
d.SetPartial("network")
|
||||
}
|
||||
|
||||
d.Partial(false)
|
||||
|
||||
// we may reuse dataSourceComputeRead here as we maintain similarity
|
||||
// between Compute resource and Compute data source schemas
|
||||
return dataSourceComputeRead(d, m)
|
||||
}
|
||||
|
||||
func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
||||
// NOTE: this function destroys target Compute instance "permanently", so
|
||||
// there is no way to restore it.
|
||||
// If compute being destroyed has some extra disks attached, they are
|
||||
// detached from the compute
|
||||
log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d",
|
||||
d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
||||
if compFacts == "" {
|
||||
// the target Compute does not exist - in this case according to Terraform best practice
|
||||
// we exit from Destroy method without error
|
||||
return nil
|
||||
}
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
|
||||
model := ComputeGetResp{}
|
||||
log.Debugf("resourceComputeDelete: ready to unmarshal string %s", compFacts)
|
||||
err = json.Unmarshal([]byte(compFacts), &model)
|
||||
if err == nil && len(model.Disks) > 0 {
|
||||
// prepare to detach data disks from compute - do it only if compFacts unmarshalled
|
||||
// properly and the resulting model contains non-empty Disks list
|
||||
for _, diskFacts := range model.Disks {
|
||||
if diskFacts.Type == "B" {
|
||||
// boot disk is never detached on compute delete
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("resourceComputeDelete: ready to detach data disk ID %d from compute ID %s", diskFacts.ID, d.Id())
|
||||
|
||||
detachParams := &url.Values{}
|
||||
detachParams.Add("computeId", d.Id())
|
||||
detachParams.Add("diskId", fmt.Sprintf("%d", diskFacts.ID))
|
||||
|
||||
_, err, _ = controller.decortAPICall("POST", ComputeDiskDetachAPI, detachParams)
|
||||
if err != nil {
|
||||
// We do not fail compute deletion on data disk detach errors
|
||||
log.Errorf("resourceComputeDelete: error when detaching Disk ID %d: %s", diskFacts.ID, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
params := &url.Values{}
|
||||
params.Add("computeId", d.Id())
|
||||
params.Add("permanently", "1")
|
||||
// TODO: this is for the upcoming API update - params.Add("detachdisks", "1")
|
||||
|
||||
_, err, _ = controller.decortAPICall("POST", ComputeDeleteAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceComputeExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
||||
log.Debugf("resourceComputeExist: called for Compute name %s, RG ID %d",
|
||||
d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
||||
if compFacts == "" {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourceCompute() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceComputeCreate,
|
||||
Read: resourceComputeRead,
|
||||
Update: resourceComputeUpdate,
|
||||
Delete: resourceComputeDelete,
|
||||
Exists: resourceComputeExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout180s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout180s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.",
|
||||
},
|
||||
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the resource group where this compute should be deployed.",
|
||||
},
|
||||
|
||||
"arch": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: stateFuncToUpper,
|
||||
ValidateFunc: validation.StringInSlice([]string{"KVM_X86", "KVM_PPC"}, false), // observe case while validating
|
||||
Description: "Hardware architecture of this compute instance.",
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, MaxCpusPerCompute),
|
||||
Description: "Number of CPUs to allocate to this compute instance.",
|
||||
},
|
||||
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(MinRamPerCompute),
|
||||
Description: "Amount of RAM in MB to allocate to this compute instance.",
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the OS image to base this compute instance on.",
|
||||
},
|
||||
|
||||
"boot_disk_size": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.",
|
||||
},
|
||||
|
||||
"extra_disks": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
MaxItems: MaxExtraDisksPerCompute,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.",
|
||||
},
|
||||
|
||||
"network": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
MaxItems: MaxNetworksPerCompute,
|
||||
Elem: &schema.Resource{
|
||||
Schema: networkSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.",
|
||||
},
|
||||
|
||||
/*
|
||||
"ssh_keys": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: MaxSshKeysPerCompute,
|
||||
Elem: &schema.Resource{
|
||||
Schema: sshSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "SSH keys to authorize on this compute instance.",
|
||||
},
|
||||
*/
|
||||
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Optional text description of this compute instance.",
|
||||
},
|
||||
|
||||
|
||||
"cloud_init": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "applied",
|
||||
DiffSuppressFunc: cloudInitDiffSupperss,
|
||||
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
|
||||
},
|
||||
|
||||
// The rest are Compute properties, which are "computed" once it is created
|
||||
"rg_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the resource group where this compute instance is located.",
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the account this compute instance belongs to.",
|
||||
},
|
||||
|
||||
"account_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the account this compute instance belongs to.",
|
||||
},
|
||||
|
||||
"boot_disk_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "This compute instance boot disk ID.",
|
||||
},
|
||||
|
||||
"os_users": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: osUsersSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Guest OS users provisioned on this compute instance.",
|
||||
},
|
||||
|
||||
/*
|
||||
"disks": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
||||
},
|
||||
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
||||
},
|
||||
|
||||
"interfaces": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: interfaceSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Specification for the virtual NICs configured on this compute instance.",
|
||||
},
|
||||
|
||||
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current model status of this compute instance.",
|
||||
},
|
||||
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current technical status of this compute instance.",
|
||||
},
|
||||
*/
|
||||
},
|
||||
}
|
||||
}
|
||||
323
decort/resource_disk.go
Normal file
323
decort/resource_disk.go
Normal file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
// "encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func resourceDiskCreate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceDiskCreate: called for Disk name %q, Account ID %d", d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
// accountId, gid, name, description, size, type, sep_id, pool
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
||||
urlValues.Add("gid", fmt.Sprintf("%d", DefaultGridID)) // we use default Grid ID, which was obtained along with DECORT Controller init
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("size", fmt.Sprintf("%d", d.Get("size").(int)))
|
||||
urlValues.Add("type", "D") // NOTE: only disks of Data type are managed via plugin
|
||||
urlValues.Add("sep_id", fmt.Sprintf("%d", d.Get("sep_id").(int)))
|
||||
urlValues.Add("pool", d.Get("pool").(string))
|
||||
|
||||
argVal, argSet := d.GetOk("description")
|
||||
if argSet {
|
||||
urlValues.Add("description", argVal.(string))
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", DisksCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(apiResp) // update ID of the resource to tell Terraform that the disk resource exists
|
||||
diskId, _ := strconv.Atoi(apiResp)
|
||||
|
||||
log.Debugf("resourceDiskCreate: new Disk ID / name %d / %s creation sequence complete", diskId, d.Get("name").(string))
|
||||
|
||||
// We may reuse dataSourceDiskRead here as we maintain similarity
|
||||
// between Disk resource and Disk data source schemas
|
||||
// Disk resource read function will also update resource ID on success, so that Terraform
|
||||
// will know the resource exists (however, we already did it a few lines before)
|
||||
return dataSourceDiskRead(d, m)
|
||||
}
|
||||
|
||||
func resourceDiskRead(d *schema.ResourceData, m interface{}) error {
|
||||
diskFacts, err := utilityDiskCheckPresence(d, m)
|
||||
if diskFacts == "" {
|
||||
// if empty string is returned from utilityDiskCheckPresence then there is no
|
||||
// such Disk and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenDisk(d, diskFacts)
|
||||
}
|
||||
|
||||
func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
// Update will only change the following attributes of the disk:
|
||||
// - Size; to keep data safe, shrinking disk is not allowed.
|
||||
// - Name
|
||||
//
|
||||
// Attempt to change disk type will throw an error and mark disk
|
||||
// resource as partially updated
|
||||
log.Debugf("resourceDiskUpdate: called for Disk ID / name %s / %s, Account ID %d",
|
||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
d.Partial(true)
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
|
||||
oldSize, newSize := d.GetChange("size")
|
||||
if oldSize.(int) < newSize.(int) {
|
||||
log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB",
|
||||
d.Id(), oldSize.(int), newSize.(int))
|
||||
sizeParams := &url.Values{}
|
||||
sizeParams.Add("diskId", d.Id())
|
||||
sizeParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
||||
_, err, _ := controller.decortAPICall("POST", DisksResizeAPI, sizeParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.SetPartial("size")
|
||||
} else if oldSize.(int) > newSize.(int) {
|
||||
return fmt.Errorf("resourceDiskUpdate: Disk ID %s - reducing disk size is not allowed", d.Id())
|
||||
}
|
||||
|
||||
oldName, newName := d.GetChange("name")
|
||||
if oldName.(string) != newName.(string) {
|
||||
log.Debugf("resourceDiskUpdate: renaming disk ID %d - %s -> %s",
|
||||
d.Get("disk_id").(int), oldName.(string), newName.(string))
|
||||
renameParams := &url.Values{}
|
||||
renameParams.Add("diskId", d.Id())
|
||||
renameParams.Add("name", newName.(string))
|
||||
_, err, _ := controller.decortAPICall("POST", DisksRenameAPI, renameParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.SetPartial("name")
|
||||
}
|
||||
|
||||
/*
|
||||
NOTE: plugin will manage disks of type "Data" only, and type cannot be changed once disk is created
|
||||
|
||||
oldType, newType := d.GetChange("type")
|
||||
if oldType.(string) != newType.(string) {
|
||||
return fmt.Errorf("resourceDiskUpdate: Disk ID %s - changing type of existing disk not allowed", d.Id())
|
||||
}
|
||||
*/
|
||||
|
||||
d.Partial(false)
|
||||
|
||||
// we may reuse dataSourceDiskRead here as we maintain similarity
|
||||
// between Compute resource and Compute data source schemas
|
||||
return dataSourceDiskRead(d, m)
|
||||
}
|
||||
|
||||
func resourceDiskDelete(d *schema.ResourceData, m interface{}) error {
|
||||
// NOTE: this function tries to detach and destroy target Disk "permanently", so
|
||||
// there is no way to restore it.
|
||||
// If, however, the disk is attached to a compute, the method will
|
||||
// fail (by failing the underpinning DECORt API call, which is issued with detach=false)
|
||||
log.Debugf("resourceDiskDelete: called for Disk ID / name %d / %s, Account ID %d",
|
||||
d.Get("disk_id").(int), d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
diskFacts, err := utilityDiskCheckPresence(d, m)
|
||||
if diskFacts == "" {
|
||||
// the specified Disk does not exist - in this case according to Terraform best practice
|
||||
// we exit from Destroy method without error
|
||||
return nil
|
||||
}
|
||||
|
||||
params := &url.Values{}
|
||||
params.Add("diskId", d.Id())
|
||||
// NOTE: we are not force-detaching disk from a compute (if attached) thus protecting
|
||||
// data that may be on that disk from destruction.
|
||||
// However, this may change in the future, as TF state management logic may want
|
||||
// to delete disk resource BEFORE it is detached from compute instance, and, while
|
||||
// perfectly OK from data preservation viewpoint, this is breaking expected TF workflow
|
||||
// in the eyes of an experienced TF user
|
||||
params.Add("detach", "0")
|
||||
params.Add("permanently", "1")
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
_, err, _ = controller.decortAPICall("POST", DisksDeleteAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceDiskExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
||||
log.Debugf("resourceDiskExists: called for Disk ID / name %d / %s, Account ID %d",
|
||||
d.Get("disk_id").(int), d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
diskFacts, err := utilityDiskCheckPresence(d, m)
|
||||
if diskFacts == "" {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Name of this disk. NOTE: disk names are NOT unique within an account. If disk ID is specified, disk name is ignored.",
|
||||
},
|
||||
|
||||
"disk_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the disk to get. If disk ID is specified, then disk name and account ID are ignored.",
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "ID of the account this disk belongs to.",
|
||||
},
|
||||
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "Storage end-point provider serving this disk. Cannot be changed for existing disk.",
|
||||
},
|
||||
|
||||
"pool": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.StringIsNotEmpty,
|
||||
Description: "Pool where this disk is located. Cannot be changed for existing disk.",
|
||||
},
|
||||
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "Size of the disk in GB. Note, that existing disks can only be grown in size.",
|
||||
},
|
||||
|
||||
/* We moved "type" attribute to computed attributes section, as plugin manages disks of only
|
||||
one type - "D", e.g. data disks.
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "D",
|
||||
StateFunc: stateFuncToUpper,
|
||||
ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false),
|
||||
Description: "Optional type of this disk. Defaults to D, i.e. data disk. Cannot be changed for existing disks.",
|
||||
},
|
||||
*/
|
||||
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "Disk resource managed by Terraform",
|
||||
Description: "Optional user-defined text description of this disk.",
|
||||
},
|
||||
|
||||
// The rest of the attributes are all computed
|
||||
"account_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the account this disk belongs to.",
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of the image, which this disk was cloned from (if ever cloned).",
|
||||
},
|
||||
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of this disk.",
|
||||
},
|
||||
|
||||
"sep_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of the storage end-point provider serving this disk.",
|
||||
},
|
||||
|
||||
/*
|
||||
"snapshots": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource {
|
||||
Schema: snapshotSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "List of user-created snapshots for this disk."
|
||||
},
|
||||
*/
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func resourceDisk() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceDiskCreate,
|
||||
Read: resourceDiskRead,
|
||||
Update: resourceDiskUpdate,
|
||||
Delete: resourceDiskDelete,
|
||||
Exists: resourceDiskExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout180s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout180s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: resourceDiskSchemaMake(),
|
||||
}
|
||||
}
|
||||
212
decort/resource_pfw.go
Normal file
212
decort/resource_pfw.go
Normal file
@@ -0,0 +1,212 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
// "encoding/json"
|
||||
"fmt"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func resourcePfwCreate(d *schema.ResourceData, m interface{}) error {
|
||||
compId := d.Get("compute_id")
|
||||
|
||||
rules_set, ok := d.GetOk("rule")
|
||||
if !ok || rules_set.(*schema.Set).Len() == 0 {
|
||||
log.Debugf("resourcePfwCreate: empty new PFW rules set requested for compute ID %d - nothing to create", compId.(int))
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debugf("resourcePfwCreate: ready to setup %d PFW rules for compute ID %d",
|
||||
rules_set.(*schema.Set).Len(), compId.(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
apiErrCount := 0
|
||||
var lastSavedError error
|
||||
|
||||
for _, runner := range rules_set.(*schema.Set).List() {
|
||||
rule := runner.(map[string]interface{})
|
||||
params := &url.Values{}
|
||||
params.Add("computeId", fmt.Sprintf("%d", compId.(int)))
|
||||
params.Add("publicPortStart", fmt.Sprintf("%d", rule["pub_port_start"].(int)))
|
||||
params.Add("publicPortEnd", fmt.Sprintf("%d", rule["pub_port_end"].(int)))
|
||||
params.Add("localBasePort", fmt.Sprintf("%d", rule["local_port"].(int)))
|
||||
params.Add("proto", rule["proto"].(string))
|
||||
log.Debugf("resourcePfwCreate: ready to add rule %d:%d -> %d %s for Compute ID %d",
|
||||
rule["pub_port_start"].(int),rule["pub_port_end"].(int),
|
||||
rule["local_port"].(int), rule["proto"].(string),
|
||||
compId.(int))
|
||||
_, err, _ := controller.decortAPICall("POST", ComputePfwAddAPI, params)
|
||||
if err != nil {
|
||||
log.Errorf("resourcePfwCreate: error adding rule %d:%d -> %d %s for Compute ID %d: %s",
|
||||
rule["pub_port_start"].(int),rule["pub_port_end"].(int),
|
||||
rule["local_port"].(int), rule["proto"].(string),
|
||||
compId.(int),
|
||||
err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
if apiErrCount > 0 {
|
||||
log.Errorf("resourcePfwCreate: there were %d error(s) adding PFW rules to Compute ID %s. Last error was: %s",
|
||||
apiErrCount, compId.(int), lastSavedError)
|
||||
return lastSavedError
|
||||
}
|
||||
|
||||
return resourcePfwRead(d, m)
|
||||
}
|
||||
|
||||
func resourcePfwRead(d *schema.ResourceData, m interface{}) error {
|
||||
pfwFacts, err := utilityPfwCheckPresence(d, m)
|
||||
if pfwFacts == "" {
|
||||
// if empty string is returned from dataSourcePfwRead then we got no
|
||||
// PFW rules. It could also be because there was some error, which
|
||||
// is indicated by non-nil err value
|
||||
d.SetId("") // ensure ID is empty in this case anyway
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenPfw(d, pfwFacts)
|
||||
}
|
||||
|
||||
func resourcePfwUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
// TODO: update not implemented yet
|
||||
compId := d.Get("compute_id")
|
||||
return fmt.Errorf("resourcePfwUpdate: method is not implemented yet (Compute ID %d)", compId.(int))
|
||||
|
||||
// return resourcePfwRead(d, m)
|
||||
}
|
||||
|
||||
func resourcePfwDelete(d *schema.ResourceData, m interface{}) error {
|
||||
compId := d.Get("compute_id")
|
||||
|
||||
rules_set, ok := d.GetOk("rule")
|
||||
if !ok || rules_set.(*schema.Set).Len() == 0 {
|
||||
log.Debugf("resourcePfwDelete: no PFW rules defined for compute ID %d - nothing to delete", compId.(int))
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debugf("resourcePfwDelete: ready to delete %d PFW rules from compute ID %d",
|
||||
rules_set.(*schema.Set).Len(), compId.(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
apiErrCount := 0
|
||||
var lastSavedError error
|
||||
|
||||
for _, runner := range rules_set.(*schema.Set).List() {
|
||||
rule := runner.(map[string]interface{})
|
||||
params := &url.Values{}
|
||||
params.Add("computeId", fmt.Sprintf("%d", compId.(int)))
|
||||
params.Add("ruleId", fmt.Sprintf("%d", rule["rule_id"].(int)))
|
||||
log.Debugf("resourcePfwCreate: ready to delete rule ID%s (%d:%d -> %d %s) from Compute ID %d",
|
||||
rule["rule_id"].(int),
|
||||
rule["pub_port_start"].(int),rule["pub_port_end"].(int),
|
||||
rule["local_port"].(int), rule["proto"].(string),
|
||||
compId.(int))
|
||||
_, err, _ := controller.decortAPICall("POST", ComputePfwDelAPI, params)
|
||||
if err != nil {
|
||||
log.Errorf("resourcePfwDelete: error deleting rule ID %d (%d:%d -> %d %s) from Compute ID %d: %s",
|
||||
rule["rule_id"].(int),
|
||||
rule["pub_port_start"].(int),rule["pub_port_end"].(int),
|
||||
rule["local_port"].(int), rule["proto"].(string),
|
||||
compId.(int),
|
||||
err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
if apiErrCount > 0 {
|
||||
log.Errorf("resourcePfwDelete: there were %d error(s) when deleting PFW rules from Compute ID %s. Last error was: %s",
|
||||
apiErrCount, compId.(int), lastSavedError)
|
||||
return lastSavedError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourcePfwExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
||||
log.Debugf("resourcePfwExists: called for Compute ID %d", d.Get("compute_id").(int))
|
||||
|
||||
pfwFacts, err := utilityPfwCheckPresence(d, m)
|
||||
if pfwFacts == "" {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourcePfw() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourcePfwCreate,
|
||||
Read: resourcePfwRead,
|
||||
Update: resourcePfwUpdate,
|
||||
Delete: resourcePfwDelete,
|
||||
Exists: resourcePfwExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout180s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout180s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the compute instance to configure port forwarding rules for.",
|
||||
},
|
||||
|
||||
"vins_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the ViNS to configure port forwarding rules on. Compute must be already plugged into this ViNS and ViNS must have external network connection.",
|
||||
},
|
||||
|
||||
// TODO: consider making "rule" attribute Required with MinItems = 1 to prevent
|
||||
// empty PFW list definition
|
||||
"rule": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: rulesSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Port forwarding rule. You may specify several rules, one in each such block.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,5 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions. All Rights Reserved.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
@@ -10,7 +7,7 @@ You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
@@ -18,128 +15,134 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||
Orchestration Technology) with Terraform by Hashicorp.
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||
|
||||
Please see README.md to learn where to place source code so that it
|
||||
builds seamlessly.
|
||||
|
||||
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package rg
|
||||
package decort
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudbroker/rg"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/location"
|
||||
|
||||
"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/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func resourceResgroupCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
||||
// First validate that we have all parameters required to create the new Resource Group
|
||||
|
||||
// Valid account ID is required to create new resource group
|
||||
// obtain Account ID by account name - it should not be zero on success
|
||||
validated_account_id, err := utilityGetAccountIdBySchema(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
rg_name, arg_set := d.GetOk("name")
|
||||
if !arg_set {
|
||||
return diag.FromErr(fmt.Errorf("Cannot create new RG: missing name."))
|
||||
return fmt.Errorf("Cannot create new RG: missing name.")
|
||||
}
|
||||
log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d",
|
||||
rg_name.(string), d.Get("account_id").(int))
|
||||
|
||||
/* Current version of provider works with default grid id (same is true for disk resources)
|
||||
grid_id, arg_set := d.GetOk("grid_id")
|
||||
if !arg_set {
|
||||
return fmt.Errorf("Cannot create new RG %q in account ID %d: missing Grid ID.",
|
||||
rg_name.(string), validated_account_id)
|
||||
}
|
||||
if grid_id.(int) < 1 {
|
||||
grid_id = DefaultGridID
|
||||
}
|
||||
*/
|
||||
|
||||
// all required parameters are set in the schema - we can continue with RG creation
|
||||
log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d",
|
||||
rg_name.(string), validated_account_id)
|
||||
|
||||
// quota settings are optional
|
||||
set_quota := false
|
||||
var quota_record QuotaRecord
|
||||
arg_value, arg_set := d.GetOk("quota")
|
||||
if arg_set {
|
||||
log.Debugf("resourceResgroupCreate: setting Quota on RG requested")
|
||||
quota_record = makeQuotaRecord(arg_value.([]interface{}))
|
||||
quota_record, _ = makeQuotaRecord(arg_value.([]interface{}))
|
||||
set_quota = true
|
||||
}
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
controller := m.(*ControllerCfg)
|
||||
log.Debugf("resourceResgroupCreate: called by user %q for RG name %s, account ID %d",
|
||||
c.GetDecortUsername(),
|
||||
rg_name.(string), d.Get("account_id").(int))
|
||||
controller.getDecortUsername(),
|
||||
rg_name.(string), validated_account_id)
|
||||
|
||||
req := rg.CreateRequest{
|
||||
AccountID: uint64(d.Get("account_id").(int)),
|
||||
Name: rg_name.(string),
|
||||
GID: uint64(location.DefaultGridID),
|
||||
Owner: c.GetDecortUsername(),
|
||||
}
|
||||
url_values := &url.Values{}
|
||||
url_values.Add("accountId", fmt.Sprintf("%d", validated_account_id))
|
||||
url_values.Add("name", rg_name.(string))
|
||||
url_values.Add("gid", fmt.Sprintf("%d", DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention
|
||||
url_values.Add("owner", controller.getDecortUsername())
|
||||
|
||||
// pass quota values as set
|
||||
if set_quota {
|
||||
req.MaxCPUCapacity = int64(quota_record.Cpu)
|
||||
req.MaxVDiskCapacity = int64(quota_record.Disk)
|
||||
req.MaxMemoryCapacity = int64(quota_record.Ram)
|
||||
req.MaxNetworkPeerTransfer = int64(quota_record.ExtTraffic)
|
||||
req.MaxNumPublicIP = int64(quota_record.ExtIPs)
|
||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quota_record.Cpu))
|
||||
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quota_record.Disk))
|
||||
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quota_record.Ram)) // RAM quota is float; this may change in the future
|
||||
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quota_record.ExtTraffic))
|
||||
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quota_record.ExtIPs))
|
||||
// url_values.Add("???", fmt.Sprintf("%d", quota_record.GpuUnits))
|
||||
}
|
||||
|
||||
// parse and handle network settings
|
||||
def_net_type, arg_set := d.GetOk("def_net_type")
|
||||
if arg_set {
|
||||
req.DefNet = def_net_type.(string)
|
||||
url_values.Add("def_net", def_net_type.(string)) // NOTE: in API default network type is set by "def_net" parameter
|
||||
}
|
||||
|
||||
ipcidr, arg_set := d.GetOk("ipcidr")
|
||||
if arg_set {
|
||||
req.IPCIDR = ipcidr.(string)
|
||||
url_values.Add("ipcidr", ipcidr.(string))
|
||||
}
|
||||
|
||||
ext_net_id, arg_set := d.GetOk("ext_net_id")
|
||||
if arg_set {
|
||||
req.ExtNetID = uint64(ext_net_id.(int))
|
||||
url_values.Add("extNetId", fmt.Sprintf("%d", ext_net_id.(int)))
|
||||
}
|
||||
|
||||
ext_ip, arg_set := d.GetOk("ext_ip")
|
||||
if arg_set {
|
||||
req.ExtIP = ext_ip.(string)
|
||||
url_values.Add("extIp", ext_ip.(string))
|
||||
}
|
||||
|
||||
rgId, err := c.CloudBroker().RG().Create(ctx, req)
|
||||
api_resp, err, _ := controller.decortAPICall("POST", ResgroupCreateAPI, url_values)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(strconv.FormatUint(rgId, 10))
|
||||
if !set_quota {
|
||||
resp, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
|
||||
d.Set("quota", parseQuota(resp.ResourceLimits))
|
||||
}
|
||||
d.SetId(api_resp) // rg/create API returns ID of the newly creted resource group on success
|
||||
// rg.ID, _ = strconv.Atoi(api_resp)
|
||||
|
||||
// re-read newly created RG to make sure schema contains complete and up to date set of specifications
|
||||
return resourceResgroupRead(ctx, d, m)
|
||||
return resourceResgroupRead(d, m)
|
||||
}
|
||||
|
||||
func resourceResgroupRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d",
|
||||
func resourceResgroupRead(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceResgroupRead: called for RG name %s, account ID %s",
|
||||
d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if rg_facts == nil {
|
||||
|
||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
||||
if rg_facts == "" {
|
||||
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
||||
// such resource group and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty
|
||||
return diag.FromErr(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return diag.FromErr(flattenResgroup(d, rg_facts))
|
||||
return flattenResgroup(d, rg_facts)
|
||||
}
|
||||
|
||||
func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceResgroupUpdate: called for RG name %s, account ID %d",
|
||||
d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
@@ -154,22 +157,21 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
for _, attr := range []string{"def_net_type", "ipcidr", "ext_ip"} {
|
||||
attr_new, attr_old := d.GetChange("def_net_type")
|
||||
if attr_new.(string) != attr_old.(string) {
|
||||
return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing %s for existing RG is not allowed", d.Id(), attr))
|
||||
return fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing %s for existing RG is not allowed", d.Id(), attr)
|
||||
}
|
||||
}
|
||||
|
||||
attr_new, attr_old := d.GetChange("ext_net_id")
|
||||
if attr_new.(int) != attr_old.(int) {
|
||||
return diag.FromErr(fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing ext_net_id for existing RG is not allowed", d.Id()))
|
||||
return fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing ext_net_id for existing RG is not allowed", d.Id())
|
||||
}
|
||||
|
||||
|
||||
do_general_update := false // will be true if general RG update is necessary (API rg/update)
|
||||
do_general_update := false // will be true if general RG update is necessary (API rg/update)
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
rgId, _ := strconv.ParseUint(d.Id(), 10, 64)
|
||||
req := rg.UpdateRequest{
|
||||
RGID: rgId,
|
||||
}
|
||||
controller := m.(*ControllerCfg)
|
||||
url_values := &url.Values{}
|
||||
url_values.Add("rgId", d.Id())
|
||||
|
||||
name_new, name_set := d.GetOk("name")
|
||||
if name_set {
|
||||
@@ -177,45 +179,45 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
name_old, _ := d.GetChange("name")
|
||||
if name_old.(string) != name_new.(string) {
|
||||
do_general_update = true
|
||||
req.Name = name_new.(string)
|
||||
url_values.Add("name", name_new.(string))
|
||||
}
|
||||
}
|
||||
|
||||
quota_value, quota_set := d.GetOk("quota")
|
||||
if quota_set {
|
||||
log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.")
|
||||
quotarecord_new := makeQuotaRecord(quota_value.([]interface{}))
|
||||
quotarecord_new, _ := makeQuotaRecord(quota_value.([]interface{}))
|
||||
quota_value_old, _ := d.GetChange("quota") // returns old as 1st, new as 2nd return value
|
||||
quotarecord_old := makeQuotaRecord(quota_value_old.([]interface{}))
|
||||
quotarecord_old, _ := makeQuotaRecord(quota_value_old.([]interface{}))
|
||||
|
||||
if quotarecord_new.Cpu != quotarecord_old.Cpu {
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu)
|
||||
req.MaxCPUCapacity = int64(quotarecord_new.Cpu)
|
||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu))
|
||||
}
|
||||
|
||||
if quotarecord_new.Disk != quotarecord_old.Disk {
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.Disk)
|
||||
req.MaxVDiskCapacity = int64(quotarecord_new.Disk)
|
||||
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk))
|
||||
}
|
||||
|
||||
if quotarecord_new.Ram != quotarecord_old.Ram { // NB: quota on RAM is stored as float32, in units of MB
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram)
|
||||
req.MaxMemoryCapacity = int64(quotarecord_new.Ram)
|
||||
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram))
|
||||
}
|
||||
|
||||
if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic {
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic)
|
||||
req.MaxNetworkPeerTransfer = int64(quotarecord_new.ExtTraffic)
|
||||
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.ExtTraffic))
|
||||
}
|
||||
|
||||
if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs {
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs)
|
||||
req.MaxNumPublicIP = int64(quotarecord_new.ExtIPs)
|
||||
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -225,70 +227,83 @@ func resourceResgroupUpdate(ctx context.Context, d *schema.ResourceData, m inter
|
||||
desc_old, _ := d.GetChange("description")
|
||||
if desc_old.(string) != desc_new.(string) {
|
||||
do_general_update = true
|
||||
req.Description = desc_new.(string)
|
||||
url_values.Add("desc", desc_new.(string))
|
||||
}
|
||||
}
|
||||
|
||||
if do_general_update {
|
||||
log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG")
|
||||
_, err := c.CloudBroker().RG().Update(ctx, req)
|
||||
_, err, _ := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
log.Debugf("resourceResgroupUpdate: no difference between old and new state - no update on the RG will be done")
|
||||
}
|
||||
|
||||
return resourceResgroupRead(ctx, d, m)
|
||||
return resourceResgroupRead(d, m)
|
||||
}
|
||||
|
||||
func resourceResgroupDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
|
||||
log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d",
|
||||
func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error {
|
||||
// NOTE: this method forcibly destroys target resource group with flag "permanently", so there is no way to
|
||||
// restore the destroyed resource group as well all Computes & VINSes that existed in it
|
||||
log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %s",
|
||||
d.Get("name").(string), d.Get("account_id").(int))
|
||||
|
||||
rg_facts, err := utilityResgroupCheckPresence(ctx, d, m)
|
||||
if rg_facts == nil {
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
}
|
||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
||||
if rg_facts == "" {
|
||||
// the target RG does not exist - in this case according to Terraform best practice
|
||||
// we exit from Destroy method without error
|
||||
return nil
|
||||
}
|
||||
|
||||
req := rg.DeleteRequest{
|
||||
RGID: rg_facts.ID,
|
||||
Force: true,
|
||||
Permanently: true,
|
||||
Reason: "Destroyed by DECORT Terraform provider",
|
||||
}
|
||||
url_values := &url.Values{}
|
||||
url_values.Add("rgId", d.Id())
|
||||
url_values.Add("force", "1")
|
||||
url_values.Add("permanently", "1")
|
||||
url_values.Add("reason", "Destroyed by DECORT Terraform provider")
|
||||
|
||||
c := m.(*controller.ControllerCfg)
|
||||
_, err = c.CloudBroker().RG().Delete(ctx, req)
|
||||
controller := m.(*ControllerCfg)
|
||||
_, err, _ = controller.decortAPICall("POST", ResgroupDeleteAPI, url_values)
|
||||
if err != nil {
|
||||
return diag.FromErr(err)
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func ResourceResgroup() *schema.Resource {
|
||||
func resourceResgroupExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
// Reminder: according to Terraform rules, this function should NOT modify ResourceData argument
|
||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
||||
if rg_facts == "" {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourceResgroup() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
CreateContext: resourceResgroupCreate,
|
||||
ReadContext: resourceResgroupRead,
|
||||
UpdateContext: resourceResgroupUpdate,
|
||||
DeleteContext: resourceResgroupDelete,
|
||||
Create: resourceResgroupCreate,
|
||||
Read: resourceResgroupRead,
|
||||
Update: resourceResgroupUpdate,
|
||||
Delete: resourceResgroupDelete,
|
||||
Exists: resourceResgroupExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
StateContext: schema.ImportStatePassthroughContext,
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &constants.Timeout180s,
|
||||
Read: &constants.Timeout30s,
|
||||
Update: &constants.Timeout180s,
|
||||
Delete: &constants.Timeout60s,
|
||||
Default: &constants.Timeout60s,
|
||||
Create: &Timeout180s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout180s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
@@ -299,18 +314,18 @@ func ResourceResgroup() *schema.Resource {
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "Unique ID of the account, which this resource group belongs to.",
|
||||
Description: "Unique ID of the account, which this resource group belongs to.",
|
||||
},
|
||||
|
||||
"def_net_type": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "PRIVATE",
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "PRIVATE",
|
||||
ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false),
|
||||
Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.",
|
||||
Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.",
|
||||
},
|
||||
|
||||
"def_net_id": {
|
||||
@@ -339,7 +354,7 @@ func ResourceResgroup() *schema.Resource {
|
||||
},
|
||||
|
||||
/* commented out, as in this version of provider we use default Grid ID
|
||||
"grid_id": {
|
||||
"grid_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 0, // if 0 is passed, default Grid ID will be used
|
||||
@@ -352,7 +367,6 @@ func ResourceResgroup() *schema.Resource {
|
||||
"quota": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: quotaRgSubresourceSchemaMake(),
|
||||
@@ -373,30 +387,30 @@ func ResourceResgroup() *schema.Resource {
|
||||
},
|
||||
|
||||
/*
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current status of this resource group.",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current status of this resource group.",
|
||||
},
|
||||
|
||||
"vins": {
|
||||
Type: schema.TypeList, // this is a list of ints
|
||||
Computed: true,
|
||||
MaxItems: LimitMaxVinsPerResgroup,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "List of VINs deployed in this resource group.",
|
||||
"vins": {
|
||||
Type: schema.TypeList, // this is a list of ints
|
||||
Computed: true,
|
||||
MaxItems: LimitMaxVinsPerResgroup,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "List of VINs deployed in this resource group.",
|
||||
},
|
||||
|
||||
"computes": {
|
||||
Type: schema.TypeList, // this is a list of ints
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "List of computes deployed in this resource group.",
|
||||
"computes": {
|
||||
Type: schema.TypeList, // this is a list of ints
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "List of computes deployed in this resource group.",
|
||||
},
|
||||
*/
|
||||
},
|
||||
}
|
||||
318
decort/resource_vins.go
Normal file
318
decort/resource_vins.go
Normal file
@@ -0,0 +1,318 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
// "encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
|
||||
if oldVal == "" && newVal != "" {
|
||||
// if old value for "ipcidr" resource is empty string, it means that we are creating new ViNS
|
||||
// and there is a chance that the user will want specific IP address range for this ViNS -
|
||||
// check if "ipcidr" is explicitly set in TF file to a non-empty string.
|
||||
log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal)
|
||||
return false // there is a difference between stored and new value
|
||||
}
|
||||
log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal)
|
||||
return true // suppress difference
|
||||
}
|
||||
|
||||
func resourceVinsCreate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d",
|
||||
d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
||||
|
||||
apiToCall := VinsCreateInAccountAPI
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
|
||||
argVal, argSet := d.GetOk("rg_id")
|
||||
if argSet && argVal.(int) > 0 {
|
||||
apiToCall = VinsCreateInRgAPI
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int)))
|
||||
} else {
|
||||
// RG ID either not set at all or set to 0 - user may want ViNS at account level
|
||||
argVal, argSet = d.GetOk("account_id")
|
||||
if !argSet || argVal.(int) <= 0 {
|
||||
// No valid Account ID (and no RG ID either) - cannot create ViNS
|
||||
return fmt.Errorf("resourceVinsCreate: ViNS name %s - no valid account and/or resource group ID specified", d.Id())
|
||||
}
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", argVal.(int)))
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("ext_net_id") // NB: even if ext_net_id value is explicitly set to 0, argSet = false anyway
|
||||
if argSet {
|
||||
if argVal.(int) > 0 {
|
||||
// connect to specific external network
|
||||
urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int)))
|
||||
/*
|
||||
Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform!
|
||||
|
||||
// in case of specific ext net connection user may also want a particular IP address
|
||||
argVal, argSet = d.GetOk("ext_net_ip")
|
||||
if argSet && argVal.(string) != "" {
|
||||
urlValues.Add("extIp", argVal.(string))
|
||||
}
|
||||
*/
|
||||
} else {
|
||||
// ext_net_id is set to a negative value - connect to default external network
|
||||
// no particular IP address selection in this case
|
||||
urlValues.Add("extNetId", "0")
|
||||
}
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("ipcidr")
|
||||
if argSet && argVal.(string) != "" {
|
||||
log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string))
|
||||
urlValues.Add("ipcidr", argVal.(string))
|
||||
}
|
||||
|
||||
argVal, argSet = d.GetOk("description")
|
||||
if argSet {
|
||||
urlValues.Add("desc", argVal.(string))
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", apiToCall, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(apiResp) // update ID of the resource to tell Terraform that the ViNS resource exists
|
||||
vinsId, _ := strconv.Atoi(apiResp)
|
||||
|
||||
log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsId, d.Get("name").(string))
|
||||
|
||||
// We may reuse dataSourceVinsRead here as we maintain similarity
|
||||
// between ViNS resource and ViNS data source schemas
|
||||
// ViNS resource read function will also update resource ID on success, so that Terraform
|
||||
// will know the resource exists (however, we already did it a few lines before)
|
||||
return dataSourceVinsRead(d, m)
|
||||
}
|
||||
|
||||
func resourceVinsRead(d *schema.ResourceData, m interface{}) error {
|
||||
vinsFacts, err := utilityVinsCheckPresence(d, m)
|
||||
if vinsFacts == "" {
|
||||
// if empty string is returned from utilityVinsCheckPresence then there is no
|
||||
// such ViNS and err tells so - just return it to the calling party
|
||||
d.SetId("") // ensure ID is empty
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenVins(d, vinsFacts)
|
||||
}
|
||||
|
||||
func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d",
|
||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
|
||||
d.Partial(true)
|
||||
|
||||
// 1. Handle external network connection change
|
||||
oldExtNetId, newExtNedId := d.GetChange("ext_net_id")
|
||||
if oldExtNetId.(int) != newExtNedId.(int) {
|
||||
log.Debugf("resourceVinsUpdate: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int))
|
||||
|
||||
extnetParams := &url.Values{}
|
||||
extnetParams.Add("vinsId", d.Id())
|
||||
|
||||
if oldExtNetId.(int) > 0 {
|
||||
// there was preexisting external net connection - disconnect ViNS
|
||||
_, err, _ := controller.decortAPICall("POST", VinsExtNetDisconnectAPI, extnetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if newExtNedId.(int) > 0 {
|
||||
// new external network connection requested - connect ViNS
|
||||
extnetParams.Add("netId", fmt.Sprintf("%d", newExtNedId.(int)))
|
||||
_, err, _ := controller.decortAPICall("POST", VinsExtNetConnectAPI, extnetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
d.SetPartial("ext_net_id")
|
||||
}
|
||||
|
||||
d.Partial(false)
|
||||
|
||||
// we may reuse dataSourceVinsRead here as we maintain similarity
|
||||
// between Compute resource and Compute data source schemas
|
||||
return dataSourceVinsRead(d, m)
|
||||
}
|
||||
|
||||
func resourceVinsDelete(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceVinsDelete: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d",
|
||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
||||
|
||||
vinsFacts, err := utilityVinsCheckPresence(d, m)
|
||||
if vinsFacts == "" {
|
||||
// the specified ViNS does not exist - in this case according to Terraform best practice
|
||||
// we exit from Destroy method without error
|
||||
return nil
|
||||
}
|
||||
|
||||
params := &url.Values{}
|
||||
params.Add("vinsId", d.Id())
|
||||
params.Add("force", "1") // disconnect all computes before deleting ViNS
|
||||
params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
_, err, _ = controller.decortAPICall("POST", VinsDeleteAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceVinsExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
||||
log.Debugf("resourceVinsExists: called for ViNS name %s, Account ID %d, RG ID %d",
|
||||
d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
||||
|
||||
vinsFacts, err := utilityVinsCheckPresence(d, m)
|
||||
if vinsFacts == "" {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourceVinsSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ValidateFunc: validation.StringIsNotEmpty,
|
||||
Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.",
|
||||
},
|
||||
|
||||
/* we do not need ViNS ID as an argument because if we already know this ID, it is not practical to call resource provider.
|
||||
Resource Import will work anyway, as it obtains the ID of ViNS to be imported through another mechanism.
|
||||
"vins_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
|
||||
},
|
||||
*/
|
||||
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Default: 0,
|
||||
Description: "ID of the resource group, where this ViNS belongs to. Non-zero for ViNS created at resource group level, 0 otherwise.",
|
||||
},
|
||||
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.",
|
||||
},
|
||||
|
||||
"ext_net_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(0),
|
||||
Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.",
|
||||
},
|
||||
|
||||
"ipcidr": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
DiffSuppressFunc: ipcidrDiffSupperss,
|
||||
Description: "Network address to use by this ViNS. This parameter is only valid when creating new ViNS.",
|
||||
},
|
||||
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "",
|
||||
Description: "Optional user-defined text description of this ViNS.",
|
||||
},
|
||||
|
||||
// the rest of attributes are computed
|
||||
"account_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the account, which this ViNS belongs to.",
|
||||
},
|
||||
|
||||
"ext_ip_addr": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "IP address of the external connection (valid for ViNS connected to external network, ignored otherwise).",
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func resourceVins() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceVinsCreate,
|
||||
Read: resourceVinsRead,
|
||||
Update: resourceVinsUpdate,
|
||||
Delete: resourceVinsDelete,
|
||||
Exists: resourceVinsExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout180s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout180s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: resourceVinsSchemaMake(),
|
||||
}
|
||||
}
|
||||
77
decort/rules_subresource.go
Normal file
77
decort/rules_subresource.go
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
// "bytes"
|
||||
// log "github.com/sirupsen/logrus"
|
||||
// "net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
// This is rules subresource of PFW resource used
|
||||
// when creating/managing port forwarding rules for a compute connected
|
||||
// to the corresponding network
|
||||
|
||||
func rulesSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"pub_port_start": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "Port number on the external interface. For a ranged rule it set the starting port number.",
|
||||
},
|
||||
|
||||
"pub_port_end": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "End port number on the external interface for a ranged rule. Set it equal to start port for a single port rule.",
|
||||
},
|
||||
|
||||
"local_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "Port number on the local interface.",
|
||||
},
|
||||
|
||||
"proto": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
StateFunc: stateFuncToLower,
|
||||
ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false),
|
||||
Description: "Protocol for this rule. Could be either tcp or udp.",
|
||||
},
|
||||
|
||||
// the rest are computed
|
||||
|
||||
"rule_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Rule ID as assigned by the cloud platform.",
|
||||
},
|
||||
|
||||
}
|
||||
return rets
|
||||
}
|
||||
104
decort/ssh_subresource.go
Normal file
104
decort/ssh_subresource.go
Normal file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
/*
|
||||
func makeSshKeysConfig(arg_list []interface{}) (sshkeys []SshKeyConfig, count int) {
|
||||
count = len(arg_list)
|
||||
if count < 1 {
|
||||
return nil, 0
|
||||
}
|
||||
|
||||
sshkeys = make([]SshKeyConfig, count)
|
||||
var subres_data map[string]interface{}
|
||||
for index, value := range arg_list {
|
||||
subres_data = value.(map[string]interface{})
|
||||
sshkeys[index].User = subres_data["user"].(string)
|
||||
sshkeys[index].SshKey = subres_data["public_key"].(string)
|
||||
sshkeys[index].UserShell = subres_data["shell"].(string)
|
||||
}
|
||||
|
||||
return sshkeys, count
|
||||
}
|
||||
*/
|
||||
|
||||
func makeSshKeysArgString(arg_list []interface{}) string {
|
||||
// This function expects arg_list = data.Get("ssh_keys"), where "data" is a populated schema for Compute
|
||||
// Resource (see func resourceCompute() definition) or Compute Data Source (see func dataSourceCompute())
|
||||
|
||||
// Prepare a string with username and public ssh key value in a format recognized by cloud-init utility.
|
||||
// It is designed to be passed as "userdata" argument of virtual machine create API call.
|
||||
// The following format is expected:
|
||||
// '{"users": [{"ssh-authorized-keys": ["SSH_PUBCIC_KEY_VALUE"], "shell": "SHELL_VALUE", "name": "USERNAME_VALUE"}, {...}, ]}'
|
||||
|
||||
/*
|
||||
`%s\n
|
||||
- name: %s\n
|
||||
ssh-authorized-keys:
|
||||
- %s\n
|
||||
shell: /bin/bash`
|
||||
*/
|
||||
|
||||
if len(arg_list) < 1 {
|
||||
return ""
|
||||
}
|
||||
|
||||
out := `{"users": [`
|
||||
const UserdataTemplate = `%s{"ssh-authorized-keys": ["%s"], "shell": "%s", "name": "%s"}, `
|
||||
const out_suffix = `]}`
|
||||
|
||||
for _, value := range arg_list {
|
||||
subres_data := value.(map[string]interface{})
|
||||
|
||||
out = fmt.Sprintf(UserdataTemplate, out, subres_data["public_key"].(string), subres_data["shell"].(string), subres_data["user"].(string))
|
||||
}
|
||||
out = fmt.Sprintf("%s %s", out, out_suffix)
|
||||
return out
|
||||
}
|
||||
|
||||
func sshSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"user": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the guest OS user of a new compute, for which the following SSH key will be authorized.",
|
||||
},
|
||||
|
||||
"public_key": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Public SSH key to authorize to the specified guest OS user on the compute being created.",
|
||||
},
|
||||
|
||||
"shell": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "/bin/bash",
|
||||
Description: "Guest user shell. This parameter is optional, default is /bin/bash.",
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
156
decort/utility_account.go
Normal file
156
decort/utility_account.go
Normal file
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func utilityAccountCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
accId, argSet := d.GetOk("account_id")
|
||||
if argSet {
|
||||
// get Account right away by its ID
|
||||
log.Debugf("utilityAccountCheckPresence: locating Account by its ID %d", accId.(int))
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", accId.(int)))
|
||||
apiResp, err, _ := controller.decortAPICall("POST", AccountsGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return apiResp, nil
|
||||
}
|
||||
|
||||
accName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
// neither ID nor name - no account for you!
|
||||
return "", fmt.Errorf("Cannot check account presence if name is empty and no account ID specified")
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", AccountsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// log.Debugf("%s", apiResp)
|
||||
// log.Debugf("utilityAccountCheckPresence: ready to decode response body from %q", AccountsListAPI)
|
||||
accList := AccountsListResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &accList)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("utilityAccountCheckPresence: traversing decoded Json of length %d", len(accList))
|
||||
for index, item := range accList {
|
||||
// match by account name
|
||||
if item.Name == accName.(string) {
|
||||
log.Debugf("utilityAccountCheckPresence: match account name %q / ID %d at index %d",
|
||||
item.Name, item.ID, index)
|
||||
|
||||
// NB: unlike accounts/get API, accounts/list API returns abridged set of account info,
|
||||
// for instance it does not return quotas
|
||||
|
||||
reencodedItem, err := json.Marshal(item)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(reencodedItem[:]), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Cannot find account name %q", accName.(string))
|
||||
}
|
||||
|
||||
func utilityGetAccountIdBySchema(d *schema.ResourceData, m interface{}) (int, error) {
|
||||
/*
|
||||
This function expects schema that contains the following two elements:
|
||||
|
||||
"account_name": &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
Required: Optional,
|
||||
Description: "Name of the account, ....",
|
||||
},
|
||||
|
||||
"account_id": &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "Unique ID of the account, ....",
|
||||
},
|
||||
|
||||
Then it will check, which argument is set, and if account name is present, it will
|
||||
initiate API calls to the DECORT cloud controller and try to match relevant account
|
||||
by the name.
|
||||
|
||||
NOTE that for some resources (most notably, Resource Group) "account_name" attribute is
|
||||
marked as "Computed: true", so the only way to fully identify Resource Group is to specify
|
||||
"account_id", which is marked as "Required: true"
|
||||
|
||||
*/
|
||||
|
||||
accId, argSet := d.GetOk("account_id")
|
||||
if argSet {
|
||||
if accId.(int) > 0 {
|
||||
return accId.(int), nil
|
||||
}
|
||||
return 0, fmt.Errorf("Account ID must be positive")
|
||||
}
|
||||
|
||||
accName, argSet := d.GetOk("account_name")
|
||||
if !argSet {
|
||||
return 0, fmt.Errorf("Either non-empty account name or valid account ID must be specified")
|
||||
}
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
apiResp, err, _ := controller.decortAPICall("POST", AccountsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
model := AccountsListResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &model)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
log.Debugf("utilityGetAccountIdBySchema: traversing decoded Json of length %d", len(model))
|
||||
for index, item := range model {
|
||||
// need to match Account by name
|
||||
if item.Name == accName.(string) {
|
||||
log.Debugf("utilityGetAccountIdBySchema: match Account name %q / ID %d at index %d",
|
||||
item.Name, item.ID, index)
|
||||
return item.ID, nil
|
||||
}
|
||||
}
|
||||
|
||||
return 0, fmt.Errorf("Cannot find account %q for the current user. Check account name and your access rights", accName.(string))
|
||||
}
|
||||
298
decort/utility_compute.go
Normal file
298
decort/utility_compute.go
Normal file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceData, do_delta bool) error {
|
||||
// d is filled with data according to computeResource schema, so extra disks config is retrieved via "extra_disks" key
|
||||
// If do_delta is true, this function will identify changes between new and existing specs for extra disks and try to
|
||||
// update compute configuration accordingly
|
||||
// Otherwise it will apply whatever is found in the new set of "extra_disks" right away.
|
||||
// Primary use of do_delta=false is when calling this function from compute Create handler.
|
||||
|
||||
// Note that this function will not abort on API errors, but will continue to configure (attach / detach) other individual
|
||||
// disks via atomic API calls. However, it will not retry failed manipulation on the same disk.
|
||||
log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %b", d.Id(), do_delta)
|
||||
|
||||
// NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt
|
||||
old_set, new_set := d.GetChange("extra_disks")
|
||||
|
||||
apiErrCount := 0
|
||||
var lastSavedError error
|
||||
|
||||
if !do_delta {
|
||||
if new_set.(*schema.Set).Len() < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, disk := range new_set.(*schema.Set).List() {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int)))
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to attach extra disk - partial resource update
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
if apiErrCount > 0 {
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s",
|
||||
apiErrCount, d.Id(), lastSavedError)
|
||||
return lastSavedError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
|
||||
log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
|
||||
for _, diskId := range detach_set.List() {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeDiskDetachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to detach disk - there will be partial resource update
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
|
||||
log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
|
||||
for _, diskId := range attach_set.List() {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to attach disk - there will be partial resource update
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
if apiErrCount > 0 {
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s",
|
||||
apiErrCount, d.Id(), lastSavedError)
|
||||
return lastSavedError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceData, do_delta bool) error {
|
||||
// "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key
|
||||
// If do_delta is true, this function will identify changes between new and existing specs for network and try to
|
||||
// update compute configuration accordingly
|
||||
// Otherwise it will apply whatever is found in the new set of "network" right away.
|
||||
// Primary use of do_delta=false is when calling this function from compute Create handler.
|
||||
|
||||
old_set, new_set := d.GetChange("network")
|
||||
|
||||
apiErrCount := 0
|
||||
var lastSavedError error
|
||||
|
||||
if !do_delta {
|
||||
if new_set.(*schema.Set).Len() < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, runner := range new_set.(*schema.Set).List() {
|
||||
urlValues := &url.Values{}
|
||||
net_data := runner.(map[string]interface{})
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("netType", net_data["net_type"].(string))
|
||||
urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
|
||||
ipaddr, ipSet := net_data["ip_address"] // "ip_address" key is optional
|
||||
if ipSet {
|
||||
urlValues.Add("ipAddr", ipaddr.(string))
|
||||
}
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to attach network - partial resource update
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
if apiErrCount > 0 {
|
||||
log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s",
|
||||
apiErrCount, d.Id(), lastSavedError)
|
||||
return lastSavedError
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
|
||||
log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
|
||||
for _, runner := range detach_set.List() {
|
||||
urlValues := &url.Values{}
|
||||
net_data := runner.(map[string]interface{})
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
||||
urlValues.Add("mac", net_data["mac"].(string))
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeNetDetachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to detach this network - there will be partial resource update
|
||||
log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s",
|
||||
net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
|
||||
log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
|
||||
for _, runner := range attach_set.List() {
|
||||
urlValues := &url.Values{}
|
||||
net_data := runner.(map[string]interface{})
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("netId", fmt.Sprintf("%d",net_data["net_id"].(int)))
|
||||
urlValues.Add("netType", net_data["net_type"].(string))
|
||||
if net_data["ip_address"].(string) != "" {
|
||||
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
||||
}
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to attach this network - there will be partial resource update
|
||||
log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s",
|
||||
net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
if apiErrCount > 0 {
|
||||
log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s",
|
||||
apiErrCount, d.Id(), lastSavedError)
|
||||
return lastSavedError
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func utilityComputeCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
||||
// This function tries to locate Compute by one of the following approaches:
|
||||
// - if compute_id is specified - locate by compute ID
|
||||
// - if compute_name is specified - locate by a combination of compute name and resource
|
||||
// group ID
|
||||
//
|
||||
// If succeeded, it returns non-empty string that contains JSON formatted facts about the
|
||||
// Compute as returned by compute/get API call.
|
||||
// Otherwise it returns empty string and meaningful error.
|
||||
//
|
||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||
// method for resource's Exists method.
|
||||
//
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
// make it possible to use "read" & "check presence" functions with compute ID set so
|
||||
// that Import of Compute resource is possible
|
||||
idSet := false
|
||||
theId, err := strconv.Atoi(d.Id())
|
||||
if err != nil || theId <= 0 {
|
||||
computeId, argSet := d.GetOk("compute_id") // NB: compute_id is NOT present in computeResource schema!
|
||||
if argSet {
|
||||
theId = computeId.(int)
|
||||
idSet = true
|
||||
}
|
||||
} else {
|
||||
idSet = true
|
||||
}
|
||||
|
||||
if idSet {
|
||||
// compute ID is specified, try to get compute instance straight by this ID
|
||||
log.Debugf("utilityComputeCheckPresence: locating compute by its ID %d", theId)
|
||||
urlValues.Add("computeId", fmt.Sprintf("%d", theId))
|
||||
computeFacts, err, _ := controller.decortAPICall("POST", ComputeGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return computeFacts, nil
|
||||
}
|
||||
|
||||
// ID was not set in the schema upon entering this function - work through Compute name
|
||||
// and RG ID
|
||||
computeName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
return "", fmt.Errorf("Cannot locate compute instance if name is empty and no compute ID specified")
|
||||
}
|
||||
|
||||
rgId, argSet := d.GetOk("rg_id")
|
||||
if !argSet {
|
||||
return "", fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string))
|
||||
}
|
||||
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgId))
|
||||
apiResp, err, _ := controller.decortAPICall("POST", RgListComputesAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("utilityComputeCheckPresence: ready to unmarshal string %s", apiResp)
|
||||
|
||||
computeList := RgListComputesResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &computeList)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// log.Printf("%#v", computeList)
|
||||
log.Debugf("utilityComputeCheckPresence: traversing decoded JSON of length %d", len(computeList))
|
||||
for index, item := range computeList {
|
||||
// need to match Compute by name, skip Computes with the same name in DESTROYED satus
|
||||
if item.Name == computeName.(string) && item.Status != "DESTROYED" {
|
||||
log.Debugf("utilityComputeCheckPresence: index %d, matched name %s", index, item.Name)
|
||||
// we found the Compute we need - now get detailed information via compute/get API
|
||||
cgetValues := &url.Values{}
|
||||
cgetValues.Add("computeId", fmt.Sprintf("%d", item.ID))
|
||||
apiResp, err, _ = controller.decortAPICall("POST", ComputeGetAPI, cgetValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return apiResp, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil // there should be no error if Compute does not exist
|
||||
}
|
||||
143
decort/utility_disk.go
Normal file
143
decort/utility_disk.go
Normal file
@@ -0,0 +1,143 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
|
||||
func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
||||
// This function tries to locate Disk by one of the following algorithms depending on
|
||||
// the parameters passed:
|
||||
// - if disk ID is specified -> by disk ID
|
||||
// - if disk name is specifeid -> by disk name and either account ID or account name
|
||||
//
|
||||
// NOTE: disk names are not unique, so the first occurence of this name in the account will
|
||||
// be returned. There is no such ambiguity when locating disk by its ID.
|
||||
//
|
||||
// If succeeded, it returns non empty string that contains JSON formatted facts about the disk
|
||||
// as returned by disks/get API call.
|
||||
// Otherwise it returns empty string and meaningful error.
|
||||
//
|
||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||
// method for resource's Exists method.
|
||||
//
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
// make it possible to use "read" & "check presence" functions with disk ID set so
|
||||
// that Import of preexisting Disk resource is possible
|
||||
idSet := false
|
||||
theId, err := strconv.Atoi(d.Id())
|
||||
if err != nil || theId <= 0 {
|
||||
diskId, argSet := d.GetOk("disk_id")
|
||||
if argSet {
|
||||
theId =diskId.(int)
|
||||
idSet = true
|
||||
}
|
||||
} else {
|
||||
idSet = true
|
||||
}
|
||||
|
||||
if idSet {
|
||||
// disk ID is specified, try to get disk instance straight by this ID
|
||||
log.Debugf("utilityDiskCheckPresence: locating disk by its ID %d", theId)
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", theId))
|
||||
diskFacts, err, _ := controller.decortAPICall("POST", DisksGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return diskFacts, nil
|
||||
}
|
||||
|
||||
// ID or disk_di was not set in the schema upon entering this function - rely on Disk name
|
||||
// and Account ID to find the disk
|
||||
diskName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
// no disk ID and no disk name - we cannot locate disk in this case
|
||||
return "", fmt.Errorf("Cannot locate disk if name is empty and no disk ID specified")
|
||||
}
|
||||
|
||||
// Valid account ID is required to locate disks
|
||||
// obtain Account ID by account name - it should not be zero on success
|
||||
validatedAccountId, err := utilityGetAccountIdBySchema(d, m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", validatedAccountId))
|
||||
diskFacts, err, _ := controller.decortAPICall("POST", DisksListAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("utilityDiskCheckPresence: ready to unmarshal string %s", diskFacts)
|
||||
|
||||
disksList := DisksListResp{}
|
||||
err = json.Unmarshal([]byte(diskFacts), &disksList)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// log.Printf("%#v", vm_list)
|
||||
log.Debugf("utilityDiskCheckPresence: traversing decoded JSON of length %d", len(disksList))
|
||||
for index, item := range disksList {
|
||||
// need to match disk by name, return the first match
|
||||
if item.Name == diskName.(string) && item.Status != "DESTROYED" {
|
||||
log.Debugf("utilityDiskCheckPresence: index %d, matched disk name %q", index, item.Name)
|
||||
// we found the disk we need - not get detailed information via API call to disks/get
|
||||
/*
|
||||
// TODO: this may not be optimal as it initiates one extra call to the DECORT controller
|
||||
// in spite of the fact that we already have all required information about the disk in
|
||||
// item variable
|
||||
//
|
||||
get_urlValues := &url.Values{}
|
||||
get_urlValues.Add("diskId", fmt.Sprintf("%d", item.ID))
|
||||
diskFacts, err = controller.decortAPICall("POST", DisksGetAPI, get_urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return diskFacts, nil
|
||||
*/
|
||||
reencodedItem, err := json.Marshal(item)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return string(reencodedItem[:]), nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", nil // there should be no error if disk does not exist
|
||||
}
|
||||
48
decort/utility_general.go
Normal file
48
decort/utility_general.go
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
"strings"
|
||||
|
||||
)
|
||||
|
||||
func Jo2JSON(arg_str string) string {
|
||||
// DECORT API historically returns response in the form of Python dictionary, which generally
|
||||
// looks like JSON, but does not comply with JSON syntax.
|
||||
// For Golang JSON Unmarshal to work properly we need to pre-process API response as follows:
|
||||
ret_string := strings.Replace(string(arg_str), "u'", "\"", -1)
|
||||
ret_string = strings.Replace(ret_string, "'", "\"", -1)
|
||||
ret_string = strings.Replace(ret_string, ": False", ": false", -1)
|
||||
ret_string = strings.Replace(ret_string, ": True", ": true", -1)
|
||||
ret_string = strings.Replace(ret_string, "null", "\"\"", -1)
|
||||
ret_string = strings.Replace(ret_string, "None", "\"\"", -1)
|
||||
|
||||
// fix for incorrect handling of usage info
|
||||
// ret_string = strings.Replace(ret_string, "<", "\"", -1)
|
||||
// ret_string = strings.Replace(ret_string, ">", "\"", -1)
|
||||
return ret_string
|
||||
}
|
||||
@@ -1,53 +1,65 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Authors:
|
||||
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package location
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations"
|
||||
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
|
||||
)
|
||||
|
||||
var DefaultGridID int
|
||||
|
||||
func UtilityLocationGetDefaultGridID(ctx context.Context, m interface{}) (int, error) {
|
||||
c := m.(*controller.ControllerCfg)
|
||||
req := locations.ListRequest{}
|
||||
|
||||
log.Debug("utilityLocationGetDefaultGridID: retrieving locations list")
|
||||
locList, err := c.CloudAPI().Locations().List(ctx, req)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if len(locList) == 0 {
|
||||
DefaultGridID = 0
|
||||
return 0, fmt.Errorf("utilityLocationGetDefaultGridID: retrieved 0 length locations list")
|
||||
}
|
||||
|
||||
DefaultGridID = int(locList[0].GID)
|
||||
log.Debugf("utilityLocationGetDefaultGridID: default location GridID %d, name %s", DefaultGridID, locList[0].Name)
|
||||
|
||||
return DefaultGridID, nil
|
||||
}
|
||||
/*
|
||||
Copyright (c) 2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
var DefaultGridID int
|
||||
|
||||
func (controller *ControllerCfg) utilityLocationGetDefaultGridID() (int, error) {
|
||||
urlValues := &url.Values{}
|
||||
|
||||
log.Debug("utilityLocationGetDefaultGridID: retrieving locations list")
|
||||
apiResp, err, _ := controller.decortAPICall("POST", LocationsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
locList := LocationsListResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &locList)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
if len(locList) == 0 {
|
||||
DefaultGridID = 0
|
||||
return 0, fmt.Errorf("utilityLocationGetDefaultGridID: retrieved 0 length locations list")
|
||||
}
|
||||
|
||||
DefaultGridID = locList[0].GridID
|
||||
log.Debugf("utilityLocationGetDefaultGridID: default location GridID %d, name %s", DefaultGridID, locList[0].Name)
|
||||
|
||||
return DefaultGridID, nil
|
||||
}
|
||||
|
||||
208
decort/utility_pfw.go
Normal file
208
decort/utility_pfw.go
Normal file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
Copyright (c) 2020-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityPfwCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
||||
//
|
||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||
// method for the Terraform resource Exists method.
|
||||
//
|
||||
|
||||
// The string returned by this method mimics response of an imaginary API that will
|
||||
// report PFW rules (if any) as following:
|
||||
// {
|
||||
// "header": {
|
||||
// "computeId": <int>,
|
||||
// "vinsId": <int>,
|
||||
// },
|
||||
// "rules": [
|
||||
// {
|
||||
// "id": <int>,
|
||||
// "localPort": <int>,
|
||||
// "protocol": <int>,
|
||||
// "publicPortStart": <int>,
|
||||
// "publicPortEnd": <int>,
|
||||
// "vmId": <int>,
|
||||
// },
|
||||
// {
|
||||
// ...
|
||||
// },
|
||||
// ],
|
||||
// }
|
||||
// This response unmarshalls into ComputePfwListResp structure.
|
||||
// NOTE: If there are no rules for this compute, an empty string is returned along with err=nil
|
||||
//
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
var compId, vinsId int
|
||||
|
||||
// PFW resource ID is a combination of compute_id and vins_id separated by ":"
|
||||
// See a note in "flattenPfw" method explaining the rationale behind this approach.
|
||||
if d.Id() != "" {
|
||||
log.Debugf("utilityPfwCheckPresence: setting context from PFW ID %s", d.Id())
|
||||
idParts := strings.SplitN(d.Id(), ":", 2)
|
||||
compId, _ = strconv.Atoi(idParts[0])
|
||||
vinsId, _ = strconv.Atoi(idParts[1])
|
||||
log.Debugf("utilityPfwCheckPresence: extracted Compute ID %d, ViNS %d", compId, vinsId)
|
||||
if compId <= 0 || vinsId <= 0 {
|
||||
return "", fmt.Errorf("Ivalid context from d.Id %s", d.Id())
|
||||
}
|
||||
} else {
|
||||
scId, cSet := d.GetOk("compute_id")
|
||||
svId, vSet := d.GetOk("vins_id")
|
||||
if cSet || vSet {
|
||||
log.Debugf("utilityPfwCheckPresence: setting Compute ID from schema")
|
||||
compId = scId.(int)
|
||||
vinsId = svId.(int)
|
||||
log.Debugf("utilityPfwCheckPresence: extracted Compute ID %d, ViNS %d", compId, vinsId)
|
||||
} else {
|
||||
return "", fmt.Errorf("Cannot get context to check PFW rules neither from PFW ID nor from schema")
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("utilityPfwCheckPresence: preparing to get PFW rules for Compute ID %d on ViNS ID %d", compId, vinsId)
|
||||
|
||||
urlValues.Add("computeId", fmt.Sprintf("%d", compId))
|
||||
apiResp, err, respCode := controller.decortAPICall("POST", ComputePfwListAPI, urlValues)
|
||||
if respCode == 500 {
|
||||
// this is workaround for API 3.7.0 "feature" - will be removed in one of the future versions
|
||||
log.Errorf("utilityPfwCheckPresence: Compute ID %d has no PFW and no connection to PFW-ready ViNS", compId)
|
||||
return "", nil
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
pfwListResp := ComputePfwListResp{}
|
||||
|
||||
// Note the specifics of compute/pfwList response in API 3.7.x (this may be changed in the future):
|
||||
// 1) if there are no PFW rules and compute is not connected to any PFW-able ViNS
|
||||
// the response will be empty string (or HTTP error code 500)
|
||||
// 2) if there are no PFW rules but compute is connected to a PFW-able ViNS
|
||||
// the response will contain a list with a single element - prefix (see PfwPrefixRecord)
|
||||
// 3) if there are port forwarding rules, the response will contain a list which starts
|
||||
// with prefix (see PfwPrefixRecord) and then followed by one or more rule records
|
||||
// (see PfwRuleRecord)
|
||||
//
|
||||
// EXTRA NOTE: in API 3.7.0 and the likes pfwList returns HTTP response code 500 for a compute
|
||||
// that is not connected to any PFW-able ViNS - need to implement temporary workaround
|
||||
|
||||
if apiResp == "" {
|
||||
// No port forward rules defined for this compute
|
||||
return "", nil
|
||||
}
|
||||
|
||||
log.Debugf("utilityPfwCheckPresence: ready to split API response string %s", apiResp)
|
||||
|
||||
twoParts := strings.SplitN(apiResp, "},", 2)
|
||||
if len(twoParts) < 1 || len(twoParts) > 2 {
|
||||
// Case: invalid format of API response
|
||||
log.Errorf("utilityPfwCheckPresence: non-empty pfwList response for compute ID %d failed to split properly", compId)
|
||||
return "", fmt.Errorf("Non-empty pfwList response failed to split properly")
|
||||
}
|
||||
|
||||
if len(twoParts) == 1 {
|
||||
// Case: compute is connected to a PWF-ready ViNS but has no PFW rules defined
|
||||
log.Debugf("utilityPfwCheckPresence: compute ID %d is connected to PFW-ready ViNS but has no PFW rules", compId)
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Case: compute is connected to a PFW ready ViNS and has some PFW rule
|
||||
prefixResp := strings.TrimSuffix(strings.TrimPrefix(twoParts[0], "["), ",") + "}"
|
||||
log.Debugf("utilityPfwCheckPresence: ready to unmarshal prefix part %s", prefixResp)
|
||||
err = json.Unmarshal([]byte(prefixResp), &pfwListResp.Header)
|
||||
if err != nil {
|
||||
log.Errorf("utilityPfwCheckPresence: failed to unmarshal prefix part of API response: %s", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
rulesResp := "[" + twoParts[1]
|
||||
log.Debugf("utilityPfwCheckPresence: ready to unmarshal rules part %s", rulesResp)
|
||||
err = json.Unmarshal([]byte(rulesResp), &pfwListResp.Rules)
|
||||
if err != nil {
|
||||
log.Errorf("utilityPfwCheckPresence: failed to unmarshal rules part of API response: %s", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("utilityPfwCheckPresence: successfully read %d port forward rules for Compute ID %d",
|
||||
len(pfwListResp.Rules), compId)
|
||||
|
||||
if len(pfwListResp.Rules) == 0 {
|
||||
// this compute technically can have rules, but no rules are currently defined
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Now we can double check that the PFWs we've got do belong to the compute & ViNS specified in the
|
||||
// PFW definition. Do so by reading compute details and comparing NatableVinsID value with the
|
||||
// specified ViNS ID
|
||||
//
|
||||
// We may reuse urlValues here, as it already contains computeId field (see initialization above)
|
||||
apiResp, err, _ = controller.decortAPICall("POST", ComputeGetAPI, urlValues)
|
||||
if err != nil || apiResp == "" {
|
||||
log.Errorf("utilityPfwCheckPresence: failed to get Compute ID %d details", compId)
|
||||
return "", err
|
||||
}
|
||||
compFacts := ComputeGetResp{}
|
||||
err = json.Unmarshal([]byte(rulesResp), &apiResp)
|
||||
if err != nil {
|
||||
log.Errorf("utilityPfwCheckPresence: failed to unmarshal compute details for ID %d: %s", compId, err)
|
||||
return "", err
|
||||
}
|
||||
if compFacts.NatableVinsID <= 0 {
|
||||
log.Errorf("utilityPfwCheckPresence: compute ID %d is not connected to a NAT-able ViNS", compId)
|
||||
return "", fmt.Errorf("Compute ID %d is not connected to a NAT-able ViNS", compId)
|
||||
}
|
||||
if compFacts.NatableVinsID != vinsId {
|
||||
log.Errorf("utilityPfwCheckPresence: ViNS ID mismatch for PFW rules on compute ID %d: actual %d, required %d",
|
||||
compId, compFacts.NatableVinsID, vinsId)
|
||||
return "", fmt.Errorf("ViNS ID mismatch for PFW rules on compute ID %d: actual %d, required %d",
|
||||
compId, compFacts.NatableVinsID, vinsId)
|
||||
}
|
||||
|
||||
// reconstruct API response string to return
|
||||
pfwListResp.Header.ComputeID = compId
|
||||
pfwListResp.Header.VinsID = compFacts.NatableVinsID
|
||||
reencodedItem, err := json.Marshal(pfwListResp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(reencodedItem[:]), nil
|
||||
}
|
||||
175
decort/utility_rg.go
Normal file
175
decort/utility_rg.go
Normal file
@@ -0,0 +1,175 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func (ctrl *ControllerCfg) utilityResgroupConfigGet(rgid int) (*ResgroupGetResp, error) {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgid))
|
||||
rgFacts, err, _ := ctrl.decortAPICall("POST", ResgroupGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("utilityResgroupConfigGet: ready to unmarshal string %s", rgFacts)
|
||||
model := &ResgroupGetResp{}
|
||||
err = json.Unmarshal([]byte(rgFacts), model)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
/*
|
||||
ret := &ResgroupConfig{}
|
||||
ret.AccountID = model.AccountID
|
||||
ret.Location = model.Location
|
||||
ret.Name = model.Name
|
||||
ret.ID = rgid
|
||||
ret.GridID = model.GridID
|
||||
ret.ExtIP = model.ExtIP // legacy field for VDC - this will eventually become obsoleted by true Resource Groups
|
||||
// Quota ResgroupQuotaConfig
|
||||
// Network NetworkConfig
|
||||
*/
|
||||
log.Debugf("utilityResgroupConfigGet: account ID %d, GridID %d, Name %s",
|
||||
model.AccountID, model.GridID, model.Name)
|
||||
|
||||
return model, nil
|
||||
}
|
||||
|
||||
// On success this function returns a string, as returned by API rg/get, which could be unmarshalled
|
||||
// into ResgroupGetResp structure
|
||||
func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
||||
// This function tries to locate resource group by one of the following algorithms depending
|
||||
// on the parameters passed:
|
||||
// - if resource group ID is specified -> by RG ID
|
||||
// - if resource group name is specifeid -> by RG name and either account ID or account name
|
||||
//
|
||||
// If succeeded, it returns non empty string that contains JSON formatted facts about the
|
||||
// resource group as returned by rg/get API call.
|
||||
// Otherwise it returns empty string and a meaningful error.
|
||||
//
|
||||
// NOTE: As our provider always deletes RGs permanently, there is no "restore" method and
|
||||
// consequently we are not interested in matching RGs in DELETED state. Hence, we call
|
||||
// .../rg/list API with includedeleted=false
|
||||
//
|
||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||
// method for the Terraform resource Exists method.
|
||||
//
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
// make it possible to use "read" & "check presence" functions with RG ID set so
|
||||
// that Import of RG resource is possible
|
||||
idSet := false
|
||||
theId, err := strconv.Atoi(d.Id())
|
||||
if err != nil || theId <= 0 {
|
||||
rgId, argSet := d.GetOk("rg_id")
|
||||
if argSet {
|
||||
theId = rgId.(int)
|
||||
idSet = true
|
||||
}
|
||||
} else {
|
||||
idSet = true
|
||||
}
|
||||
|
||||
if idSet {
|
||||
// go straight for the RG by its ID
|
||||
log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId)
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", theId))
|
||||
rgFacts, err, _ := controller.decortAPICall("POST", ResgroupGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return rgFacts, nil
|
||||
}
|
||||
|
||||
rgName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
// no RG ID and no RG name - we cannot locate resource group in this case
|
||||
return "", fmt.Errorf("Cannot check resource group presence if name is empty and no resource group ID specified")
|
||||
}
|
||||
|
||||
// Valid account ID is required to locate a resource group
|
||||
// obtain Account ID by account name - it should not be zero on success
|
||||
validatedAccountId, err := utilityGetAccountIdBySchema(d, m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
urlValues.Add("includedeleted", "false")
|
||||
apiResp, err, _ := controller.decortAPICall("POST", ResgroupListAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
// log.Debugf("%s", apiResp)
|
||||
log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", ResgroupListAPI)
|
||||
model := ResgroupListResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &model)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model))
|
||||
for index, item := range model {
|
||||
// match by RG name & account ID
|
||||
if item.Name == rgName.(string) && item.AccountID == validatedAccountId {
|
||||
log.Debugf("utilityResgroupCheckPresence: match RG name %s / ID %d, account ID %d at index %d",
|
||||
item.Name, item.ID, item.AccountID, index)
|
||||
|
||||
// not all required information is returned by rg/list API, so we need to initiate one more
|
||||
// call to rg/get to obtain extra data to complete Resource population.
|
||||
// Namely, we need resource quota settings
|
||||
reqValues := &url.Values{}
|
||||
reqValues.Add("rgId", fmt.Sprintf("%d", item.ID))
|
||||
apiResp, err, _ := controller.decortAPICall("POST", ResgroupGetAPI, reqValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return apiResp, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, validatedAccountId)
|
||||
}
|
||||
|
||||
func utilityResgroupGetDefaultGridID() (interface{}, error) {
|
||||
if DefaultGridID > 0 {
|
||||
return fmt.Sprintf("%d", DefaultGridID), nil
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("utilityResgroupGetDefaultGridID: invalid default Grid ID %d", DefaultGridID)
|
||||
}
|
||||
166
decort/utility_vins.go
Normal file
166
decort/utility_vins.go
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
Copyright (c) 2020-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
Technology platfom.
|
||||
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func (ctrl *ControllerCfg) utilityVinsConfigGet(vinsid int) (*VinsRecord, error) {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("vinsId", fmt.Sprintf("%d", vinsid))
|
||||
vinsFacts, err, _ := ctrl.decortAPICall("POST", VinsGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsConfigGet: ready to unmarshal string %q", vinsFacts)
|
||||
model := &VinsRecord{}
|
||||
err = json.Unmarshal([]byte(vinsFacts), model)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsConfigGet: Name %d, account name:ID %s:%d, RG Name:ID %s:%d",
|
||||
model.Name, model.AccountName, model.AccountID,
|
||||
model.RgName, model.RgID)
|
||||
|
||||
return model, nil
|
||||
}
|
||||
|
||||
// On success this function returns a string, as returned by API vins/get, which could be unmarshalled
|
||||
// into VinsGetResp structure
|
||||
func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
||||
// This function tries to locate ViNS by one of the following algorithms depending
|
||||
// on the parameters passed:
|
||||
// - if resource group ID is specified -> it looks for a ViNS at the RG level
|
||||
// - if account ID is specifeid -> it looks for a ViNS at the account level
|
||||
//
|
||||
// If succeeded, it returns non empty string that contains JSON formatted facts about the
|
||||
// ViNS as returned by vins/get API call.
|
||||
// Otherwise it returns empty string and a meaningful error.
|
||||
//
|
||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||
// method for the Terraform resource Exists method.
|
||||
//
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
// make it possible to use "read" & "check presence" functions with ViNS ID set so
|
||||
// that Import of ViNS resource is possible
|
||||
idSet := false
|
||||
theId, err := strconv.Atoi(d.Id())
|
||||
if err != nil || theId <= 0 {
|
||||
vinsId, argSet := d.GetOk("vins_id") // NB: vins_id is NOT present in vinsResource schema!
|
||||
if argSet {
|
||||
theId = vinsId.(int)
|
||||
idSet = true
|
||||
}
|
||||
} else {
|
||||
idSet = true
|
||||
}
|
||||
|
||||
if idSet {
|
||||
// ViNS ID is specified, try to get compute instance straight by this ID
|
||||
log.Debugf("utilityVinsCheckPresence: locating ViNS by its ID %d", theId)
|
||||
urlValues.Add("vinsId", fmt.Sprintf("%d", theId))
|
||||
vinsFacts, err, _ := controller.decortAPICall("POST", VinsGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return vinsFacts, nil
|
||||
}
|
||||
|
||||
// ID was not set in the schema upon entering this function - work through ViNS name
|
||||
// and Account / RG ID
|
||||
|
||||
vinsName, argSet := d.GetOk("name")
|
||||
if !argSet {
|
||||
// if ViNS name is not set. then we cannot locate ViNS
|
||||
return "", fmt.Errorf("Cannot check ViNS presence if ViNS name is empty")
|
||||
}
|
||||
urlValues.Add("name", vinsName.(string))
|
||||
urlValues.Add("show_all", "false")
|
||||
log.Debugf("utilityVinsCheckPresence: preparing to locate ViNS name %s", vinsName.(string))
|
||||
|
||||
rgId, rgSet := d.GetOk("rg_id")
|
||||
if rgSet {
|
||||
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to RG ID %d", rgId.(int))
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgId.(int)))
|
||||
}
|
||||
|
||||
accountId, accountSet := d.GetOk("account_id")
|
||||
if accountSet {
|
||||
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to Account ID %d", accountId.(int))
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", accountId.(int)))
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", VinsSearchAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// log.Debugf("%s", apiResp)
|
||||
// log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", VinsSearchAPI)
|
||||
model := VinsSearchResp{}
|
||||
err = json.Unmarshal([]byte(apiResp), &model)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsCheckPresence: traversing decoded Json of length %d", len(model))
|
||||
for index, item := range model {
|
||||
if item.Name == vinsName.(string) {
|
||||
if ( accountSet && item.AccountID != accountId.(int) ) ||
|
||||
( rgSet && item.RgID != rgId.(int) ) {
|
||||
// double check that account ID and Rg ID match, if set in the schema
|
||||
continue
|
||||
}
|
||||
|
||||
log.Debugf("utilityVinsCheckPresence: match ViNS name %s / ID %d, account ID %d, RG ID %d at index %d",
|
||||
item.Name, item.ID, item.AccountID, item.RgID, index)
|
||||
|
||||
// element returned by API vins/search does not contain all information we may need to
|
||||
// manage ViNS, so we have to get detailed info by calling API vins/get
|
||||
rqValues := &url.Values{}
|
||||
rqValues.Add("vinsId", fmt.Sprintf("%d",item.ID))
|
||||
vinsGetResp, err, _ := controller.decortAPICall("POST", VinsGetAPI, rqValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return vinsGetResp, nil
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string))
|
||||
}
|
||||
@@ -1,142 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_name` (String)
|
||||
- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl))
|
||||
- `ckey` (String)
|
||||
- `company` (String)
|
||||
- `companyurl` (String)
|
||||
- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes))
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `dc_location` (String)
|
||||
- `deactivation_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `displayname` (String)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `machines` (List of Object) (see [below for nested schema](#nestedatt--machines))
|
||||
- `meta` (List of String)
|
||||
- `resource_limits` (List of Object) (see [below for nested schema](#nestedatt--resource_limits))
|
||||
- `resources` (List of Object) (see [below for nested schema](#nestedatt--resources))
|
||||
- `send_access_emails` (Boolean)
|
||||
- `service_account` (Boolean)
|
||||
- `status` (String)
|
||||
- `updated_time` (Number)
|
||||
- `version` (Number)
|
||||
- `vins` (List of Number)
|
||||
- `vinses` (Number)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--acl"></a>
|
||||
### Nested Schema for `acl`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `can_be_deleted` (Boolean)
|
||||
- `explicit` (Boolean)
|
||||
- `guid` (String)
|
||||
- `right` (String)
|
||||
- `status` (String)
|
||||
- `type` (String)
|
||||
- `user_group_id` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--computes"></a>
|
||||
### Nested Schema for `computes`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `started` (Number)
|
||||
- `stopped` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--machines"></a>
|
||||
### Nested Schema for `machines`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `halted` (Number)
|
||||
- `running` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--resource_limits"></a>
|
||||
### Nested Schema for `resource_limits`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cu_c` (Number)
|
||||
- `cu_d` (Number)
|
||||
- `cu_i` (Number)
|
||||
- `cu_m` (Number)
|
||||
- `cu_np` (Number)
|
||||
- `gpu_units` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--resources"></a>
|
||||
### Nested Schema for `resources`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `current` (List of Object) (see [below for nested schema](#nestedobjatt--resources--current))
|
||||
- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--resources--reserved))
|
||||
|
||||
<a id="nestedobjatt--resources--current"></a>
|
||||
### Nested Schema for `resources.current`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cpu` (Number)
|
||||
- `disksize` (Number)
|
||||
- `extips` (Number)
|
||||
- `exttraffic` (Number)
|
||||
- `gpu` (Number)
|
||||
- `ram` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--resources--reserved"></a>
|
||||
### Nested Schema for `resources.reserved`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cpu` (Number)
|
||||
- `disksize` (Number)
|
||||
- `extips` (Number)
|
||||
- `exttraffic` (Number)
|
||||
- `gpu` (Number)
|
||||
- `ram` (Number)
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_audits_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_audits_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `call` (String)
|
||||
- `responsetime` (Number)
|
||||
- `statuscode` (Number)
|
||||
- `timestamp` (Number)
|
||||
- `user` (String)
|
||||
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_computes_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_computes_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `compute_id` (Number)
|
||||
- `compute_name` (String)
|
||||
- `cpus` (Number)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `ram` (Number)
|
||||
- `registered` (Boolean)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `total_disks_size` (Number)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `user_managed` (Boolean)
|
||||
- `vins_connected` (Number)
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_consumed_units Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_consumed_units (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `cu_c` (Number)
|
||||
- `cu_d` (Number)
|
||||
- `cu_i` (Number)
|
||||
- `cu_m` (Number)
|
||||
- `cu_np` (Number)
|
||||
- `gpu_units` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_consumed_units_by_type Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_consumed_units_by_type (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
- `cu_type` (String) cloud unit resource type
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `cu_result` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_deleted_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_deleted_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `page` (Number) Page number
|
||||
- `size` (Number) Page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl))
|
||||
- `created_time` (Number)
|
||||
- `deleted_time` (Number)
|
||||
- `status` (String)
|
||||
- `updated_time` (Number)
|
||||
|
||||
<a id="nestedobjatt--items--acl"></a>
|
||||
### Nested Schema for `items.acl`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `explicit` (Boolean)
|
||||
- `guid` (String)
|
||||
- `right` (String)
|
||||
- `status` (String)
|
||||
- `type` (String)
|
||||
- `user_group_id` (String)
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_disks_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_disks_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `disk_id` (Number)
|
||||
- `disk_name` (String)
|
||||
- `pool` (String)
|
||||
- `sep_id` (Number)
|
||||
- `size_max` (Number)
|
||||
- `type` (String)
|
||||
|
||||
|
||||
@@ -1,67 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_flipgroups_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_flipgroups_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `client_type` (String)
|
||||
- `conn_type` (String)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `default_gw` (String)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `desc` (String)
|
||||
- `fg_id` (Number)
|
||||
- `fg_name` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `ip` (String)
|
||||
- `milestones` (Number)
|
||||
- `net_id` (Number)
|
||||
- `net_type` (String)
|
||||
- `netmask` (Number)
|
||||
- `status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `page` (Number) Page number
|
||||
- `size` (Number) Page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl))
|
||||
- `created_time` (Number)
|
||||
- `deleted_time` (Number)
|
||||
- `status` (String)
|
||||
- `updated_time` (Number)
|
||||
|
||||
<a id="nestedobjatt--items--acl"></a>
|
||||
### Nested Schema for `items.acl`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `explicit` (Boolean)
|
||||
- `guid` (String)
|
||||
- `right` (String)
|
||||
- `status` (String)
|
||||
- `type` (String)
|
||||
- `user_group_id` (String)
|
||||
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_reserved_units Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_reserved_units (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `cu_c` (Number)
|
||||
- `cu_d` (Number)
|
||||
- `cu_i` (Number)
|
||||
- `cu_m` (Number)
|
||||
- `cu_np` (Number)
|
||||
- `gpu_units` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,115 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_rg_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_rg_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `computes` (List of Object) (see [below for nested schema](#nestedobjatt--items--computes))
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `milestones` (Number)
|
||||
- `resources` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources))
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `vinses` (Number)
|
||||
|
||||
<a id="nestedobjatt--items--computes"></a>
|
||||
### Nested Schema for `items.computes`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `started` (Number)
|
||||
- `stopped` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--resources"></a>
|
||||
### Nested Schema for `items.resources`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `consumed` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--consumed))
|
||||
- `limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--limits))
|
||||
- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--items--resources--reserved))
|
||||
|
||||
<a id="nestedobjatt--items--resources--consumed"></a>
|
||||
### Nested Schema for `items.resources.consumed`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cpu` (Number)
|
||||
- `disksize` (Number)
|
||||
- `extips` (Number)
|
||||
- `exttraffic` (Number)
|
||||
- `gpu` (Number)
|
||||
- `ram` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--resources--limits"></a>
|
||||
### Nested Schema for `items.resources.limits`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cpu` (Number)
|
||||
- `disksize` (Number)
|
||||
- `extips` (Number)
|
||||
- `exttraffic` (Number)
|
||||
- `gpu` (Number)
|
||||
- `ram` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--resources--reserved"></a>
|
||||
### Nested Schema for `items.resources.reserved`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cpu` (Number)
|
||||
- `disksize` (Number)
|
||||
- `extips` (Number)
|
||||
- `exttraffic` (Number)
|
||||
- `gpu` (Number)
|
||||
- `ram` (Number)
|
||||
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_templates_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_templates_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `desc` (String)
|
||||
- `public` (Boolean)
|
||||
- `size` (Number)
|
||||
- `status` (String)
|
||||
- `template_id` (Number)
|
||||
- `template_name` (String)
|
||||
- `type` (String)
|
||||
- `unc_path` (String)
|
||||
- `username` (String)
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account_vins_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account_vins_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) ID of the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) Search Result (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `computes` (Number)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `external_ip` (String)
|
||||
- `network` (String)
|
||||
- `pri_vnf_dev_id` (Number)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `vin_id` (Number)
|
||||
- `vin_name` (String)
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_bservice Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_bservice (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `service_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `base_domain` (String)
|
||||
- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes))
|
||||
- `cpu_total` (Number)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `disk_total` (String)
|
||||
- `gid` (Number)
|
||||
- `groups` (List of Number)
|
||||
- `groups_name` (List of String)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `milestones` (Number)
|
||||
- `parent_srv_id` (Number)
|
||||
- `parent_srv_type` (String)
|
||||
- `ram_total` (Number)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `service_name` (String)
|
||||
- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots))
|
||||
- `ssh_key` (String)
|
||||
- `ssh_user` (String)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `user_managed` (Boolean)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--computes"></a>
|
||||
### Nested Schema for `computes`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `compgroup_id` (Number)
|
||||
- `compgroup_name` (String)
|
||||
- `compgroup_role` (String)
|
||||
- `id` (Number)
|
||||
- `name` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--snapshots"></a>
|
||||
### Nested Schema for `snapshots`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `label` (String)
|
||||
- `timestamp` (Number)
|
||||
- `valid` (Boolean)
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_bservice_deleted_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_bservice_deleted_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number) ID of the account to query for BasicService instances
|
||||
- `page` (Number) Page number
|
||||
- `rg_id` (Number) ID of the resource group to query for BasicService instances
|
||||
- `size` (Number) Page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `base_domain` (String)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `gid` (Number)
|
||||
- `groups` (List of Number)
|
||||
- `guid` (Number)
|
||||
- `parent_srv_id` (Number)
|
||||
- `parent_srv_type` (String)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `service_id` (Number)
|
||||
- `service_name` (String)
|
||||
- `ssh_user` (String)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `user_managed` (Boolean)
|
||||
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_bservice_group Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_bservice_group (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `compgroup_id` (Number)
|
||||
- `service_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `compgroup_name` (String)
|
||||
- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes))
|
||||
- `consistency` (Boolean)
|
||||
- `cpu` (Number)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `disk` (Number)
|
||||
- `driver` (String)
|
||||
- `extnets` (List of Number)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_id` (Number)
|
||||
- `milestones` (Number)
|
||||
- `parents` (List of Number)
|
||||
- `ram` (Number)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `role` (String)
|
||||
- `sep_id` (Number)
|
||||
- `seq_no` (Number)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `timeout_start` (Number)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `vinses` (List of Number)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--computes"></a>
|
||||
### Nested Schema for `computes`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `id` (Number)
|
||||
- `ip_addresses` (List of String)
|
||||
- `name` (String)
|
||||
- `os_users` (List of Object) (see [below for nested schema](#nestedobjatt--computes--os_users))
|
||||
|
||||
<a id="nestedobjatt--computes--os_users"></a>
|
||||
### Nested Schema for `computes.os_users`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `login` (String)
|
||||
- `password` (String)
|
||||
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_bservice_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_bservice_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number) ID of the account to query for BasicService instances
|
||||
- `page` (Number) Page number
|
||||
- `rg_id` (Number) ID of the resource group to query for BasicService instances
|
||||
- `size` (Number) Page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `base_domain` (String)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `gid` (Number)
|
||||
- `groups` (List of Number)
|
||||
- `guid` (Number)
|
||||
- `parent_srv_id` (Number)
|
||||
- `parent_srv_type` (String)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `service_id` (Number)
|
||||
- `service_name` (String)
|
||||
- `ssh_user` (String)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `user_managed` (Boolean)
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_bservice_snapshot_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_bservice_snapshot_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `service_id` (Number) ID of the BasicService instance
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `label` (String)
|
||||
- `timestamp` (Number)
|
||||
- `valid` (Boolean)
|
||||
|
||||
|
||||
@@ -1,114 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_disk Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_disk (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `disk_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `acl` (String)
|
||||
- `boot_partition` (Number)
|
||||
- `compute_id` (Number)
|
||||
- `compute_name` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_time` (Number)
|
||||
- `desc` (String)
|
||||
- `destruction_time` (Number)
|
||||
- `devicename` (String)
|
||||
- `disk_name` (String)
|
||||
- `disk_path` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_id` (Number)
|
||||
- `images` (List of String)
|
||||
- `iotune` (List of Object) (see [below for nested schema](#nestedatt--iotune))
|
||||
- `iqn` (String)
|
||||
- `login` (String)
|
||||
- `milestones` (Number)
|
||||
- `order` (Number)
|
||||
- `params` (String)
|
||||
- `parent_id` (Number)
|
||||
- `passwd` (String)
|
||||
- `pci_slot` (Number)
|
||||
- `pool` (String)
|
||||
- `purge_attempts` (Number)
|
||||
- `purge_time` (Number)
|
||||
- `reality_device_number` (Number)
|
||||
- `reference_id` (String)
|
||||
- `res_id` (String)
|
||||
- `res_name` (String)
|
||||
- `role` (String)
|
||||
- `sep_id` (Number)
|
||||
- `sep_type` (String)
|
||||
- `size_max` (Number)
|
||||
- `size_used` (Number)
|
||||
- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots))
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
- `vmid` (Number)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--iotune"></a>
|
||||
### Nested Schema for `iotune`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `read_bytes_sec` (Number)
|
||||
- `read_bytes_sec_max` (Number)
|
||||
- `read_iops_sec` (Number)
|
||||
- `read_iops_sec_max` (Number)
|
||||
- `size_iops_sec` (Number)
|
||||
- `total_bytes_sec` (Number)
|
||||
- `total_bytes_sec_max` (Number)
|
||||
- `total_iops_sec` (Number)
|
||||
- `total_iops_sec_max` (Number)
|
||||
- `write_bytes_sec` (Number)
|
||||
- `write_bytes_sec_max` (Number)
|
||||
- `write_iops_sec` (Number)
|
||||
- `write_iops_sec_max` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--snapshots"></a>
|
||||
### Nested Schema for `snapshots`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `label` (String)
|
||||
- `res_id` (String)
|
||||
- `snap_set_guid` (String)
|
||||
- `snap_set_time` (Number)
|
||||
- `timestamp` (Number)
|
||||
|
||||
|
||||
@@ -1,124 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_disk_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_disk_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number) ID of the account the disks belong to
|
||||
- `page` (Number) Page number
|
||||
- `size` (Number) Page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
- `type` (String) type of the disks
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `acl` (String)
|
||||
- `boot_partition` (Number)
|
||||
- `compute_id` (Number)
|
||||
- `compute_name` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_time` (Number)
|
||||
- `desc` (String)
|
||||
- `destruction_time` (Number)
|
||||
- `devicename` (String)
|
||||
- `disk_id` (Number)
|
||||
- `disk_name` (String)
|
||||
- `disk_path` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `image_id` (Number)
|
||||
- `images` (List of String)
|
||||
- `iotune` (List of Object) (see [below for nested schema](#nestedobjatt--items--iotune))
|
||||
- `iqn` (String)
|
||||
- `login` (String)
|
||||
- `machine_id` (Number)
|
||||
- `machine_name` (String)
|
||||
- `milestones` (Number)
|
||||
- `order` (Number)
|
||||
- `params` (String)
|
||||
- `parent_id` (Number)
|
||||
- `passwd` (String)
|
||||
- `pci_slot` (Number)
|
||||
- `pool` (String)
|
||||
- `purge_attempts` (Number)
|
||||
- `purge_time` (Number)
|
||||
- `reality_device_number` (Number)
|
||||
- `reference_id` (String)
|
||||
- `res_id` (String)
|
||||
- `res_name` (String)
|
||||
- `role` (String)
|
||||
- `sep_id` (Number)
|
||||
- `sep_type` (String)
|
||||
- `size_max` (Number)
|
||||
- `size_used` (Number)
|
||||
- `snapshots` (List of Object) (see [below for nested schema](#nestedobjatt--items--snapshots))
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
- `vmid` (Number)
|
||||
|
||||
<a id="nestedobjatt--items--iotune"></a>
|
||||
### Nested Schema for `items.iotune`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `read_bytes_sec` (Number)
|
||||
- `read_bytes_sec_max` (Number)
|
||||
- `read_iops_sec` (Number)
|
||||
- `read_iops_sec_max` (Number)
|
||||
- `size_iops_sec` (Number)
|
||||
- `total_bytes_sec` (Number)
|
||||
- `total_bytes_sec_max` (Number)
|
||||
- `total_iops_sec` (Number)
|
||||
- `total_iops_sec_max` (Number)
|
||||
- `write_bytes_sec` (Number)
|
||||
- `write_bytes_sec_max` (Number)
|
||||
- `write_iops_sec` (Number)
|
||||
- `write_iops_sec_max` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--snapshots"></a>
|
||||
### Nested Schema for `items.snapshots`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `label` (String)
|
||||
- `res_id` (String)
|
||||
- `snap_set_guid` (String)
|
||||
- `snap_set_time` (Number)
|
||||
- `timestamp` (Number)
|
||||
|
||||
|
||||
@@ -1,98 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_extnet Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_extnet (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `net_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `check__ips` (List of String)
|
||||
- `check_ips` (List of String)
|
||||
- `ckey` (String)
|
||||
- `default` (Boolean)
|
||||
- `default_qos` (List of Object) (see [below for nested schema](#nestedatt--default_qos))
|
||||
- `desc` (String)
|
||||
- `dns` (List of String)
|
||||
- `excluded` (List of String)
|
||||
- `free_ips` (Number)
|
||||
- `gateway` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `ipcidr` (String)
|
||||
- `meta` (List of String) meta
|
||||
- `milestones` (Number)
|
||||
- `net_name` (String)
|
||||
- `network` (String)
|
||||
- `network_id` (Number)
|
||||
- `pre_reservations_num` (Number)
|
||||
- `prefix` (Number)
|
||||
- `pri_vnf_dev_id` (Number)
|
||||
- `reservations` (List of Object) (see [below for nested schema](#nestedatt--reservations))
|
||||
- `shared_with` (List of Number)
|
||||
- `status` (String)
|
||||
- `vlan_id` (Number)
|
||||
- `vnfs` (List of Object) (see [below for nested schema](#nestedatt--vnfs))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--default_qos"></a>
|
||||
### Nested Schema for `default_qos`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `e_rate` (Number)
|
||||
- `guid` (String)
|
||||
- `in_burst` (Number)
|
||||
- `in_rate` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--reservations"></a>
|
||||
### Nested Schema for `reservations`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `client_type` (String)
|
||||
- `desc` (String)
|
||||
- `domainname` (String)
|
||||
- `hostname` (String)
|
||||
- `ip` (String)
|
||||
- `mac` (String)
|
||||
- `type` (String)
|
||||
- `vm_id` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--vnfs"></a>
|
||||
### Nested Schema for `vnfs`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `dhcp` (Number)
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_extnet_computes_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_extnet_computes_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) filter by account ID
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `extnets` (List of Object) (see [below for nested schema](#nestedobjatt--items--extnets))
|
||||
- `id` (Number)
|
||||
- `name` (String)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
|
||||
<a id="nestedobjatt--items--extnets"></a>
|
||||
### Nested Schema for `items.extnets`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `ipaddr` (String)
|
||||
- `ipcidr` (String)
|
||||
- `name` (String)
|
||||
- `net_id` (Number)
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_extnet_default Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_extnet_default (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `net_id` (Number)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,48 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_extnet_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_extnet_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number) filter by account ID
|
||||
- `page` (Number) Page number
|
||||
- `size` (Number) Page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `ipcidr` (String)
|
||||
- `name` (String)
|
||||
- `net_id` (Number)
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_grid Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_grid (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `grid_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `flag` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (Number) The ID of this resource.
|
||||
- `location_code` (String)
|
||||
- `name` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_grid_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_grid_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `page` (Number) page number
|
||||
- `size` (Number) page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) grid list (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `flag` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (Number)
|
||||
- `location_code` (String)
|
||||
- `name` (String)
|
||||
|
||||
|
||||
@@ -1,83 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_image (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `image_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `show_all` (Boolean)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number)
|
||||
- `acl` (String)
|
||||
- `architecture` (String)
|
||||
- `boot_type` (String)
|
||||
- `bootable` (Boolean)
|
||||
- `ckey` (String)
|
||||
- `compute_ci_id` (Number)
|
||||
- `deleted_time` (String)
|
||||
- `desc` (String)
|
||||
- `drivers` (List of String)
|
||||
- `enabled` (Boolean)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `history` (List of Object) (see [below for nested schema](#nestedatt--history))
|
||||
- `hot_resize` (Boolean)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_name` (String)
|
||||
- `last_modified` (Number)
|
||||
- `link_to` (Number)
|
||||
- `milestones` (Number)
|
||||
- `password` (String)
|
||||
- `pool_name` (String)
|
||||
- `provider_name` (String)
|
||||
- `purge_attempts` (Number)
|
||||
- `res_id` (String)
|
||||
- `rescuecd` (Boolean)
|
||||
- `sep_id` (Number)
|
||||
- `shared_with` (List of Number)
|
||||
- `size` (Number)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
- `unc_path` (String)
|
||||
- `username` (String)
|
||||
- `version` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--history"></a>
|
||||
### Nested Schema for `history`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `id` (Number)
|
||||
- `timestamp` (Number)
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_image_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number) optional account ID to include account images
|
||||
- `page` (Number) page number
|
||||
- `size` (Number) page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) image list (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `architecture` (String)
|
||||
- `boot_type` (String)
|
||||
- `bootable` (Boolean)
|
||||
- `cdrom` (Boolean)
|
||||
- `desc` (String)
|
||||
- `drivers` (List of String)
|
||||
- `hot_resize` (Boolean)
|
||||
- `image_id` (Number)
|
||||
- `image_name` (String)
|
||||
- `link_to` (Number)
|
||||
- `pool_name` (String)
|
||||
- `sep_id` (Number)
|
||||
- `size` (Number)
|
||||
- `status` (String)
|
||||
- `type` (String)
|
||||
- `username` (String)
|
||||
- `virtual` (Boolean)
|
||||
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image_list_stacks Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_image_list_stacks (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `image_id` (Number) image id
|
||||
|
||||
### Optional
|
||||
|
||||
- `page` (Number) page number
|
||||
- `size` (Number) page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) items of stacks list (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `api_key` (String)
|
||||
- `api_url` (String)
|
||||
- `app_id` (String)
|
||||
- `desc` (String)
|
||||
- `drivers` (List of String)
|
||||
- `error` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (Number)
|
||||
- `images` (List of Number)
|
||||
- `login` (String)
|
||||
- `name` (String)
|
||||
- `passwd` (String)
|
||||
- `reference_id` (String)
|
||||
- `status` (String)
|
||||
- `type` (String)
|
||||
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_kvmvm Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_kvmvm (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `compute_id` (Number) ID of the compute instance. If ID is specified, name and resource group ID are ignored.
|
||||
- `name` (String) Name of this compute instance. NOTE: this parameter is case sensitive.
|
||||
- `network` (Block Set, Max: 8) Network connection(s) for this compute. (see [below for nested schema](#nestedblock--network))
|
||||
- `rg_id` (Number) ID of the resource group where this compute instance is located.
|
||||
- `started` (Boolean) Is compute started.
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number) ID of the account this compute instance belongs to.
|
||||
- `account_name` (String) Name of the account this compute instance belongs to.
|
||||
- `boot_disk_id` (Number) This compute instance boot disk ID.
|
||||
- `boot_disk_size` (Number) This compute instance boot disk size in GB.
|
||||
- `cloud_init` (String) Placeholder for cloud_init parameters.
|
||||
- `cpu` (Number) Number of CPUs allocated for this compute instance.
|
||||
- `description` (String) User-defined text description of this compute instance.
|
||||
- `driver` (String) Hardware architecture of this compute instance.
|
||||
- `extra_disks` (Set of Number) IDs of the extra disk(s) attached to this compute.
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_id` (Number) ID of the OS image this compute instance is based on.
|
||||
- `image_name` (String) Name of the OS image this compute instance is based on.
|
||||
- `os_users` (List of Object) Guest OS users provisioned on this compute instance. (see [below for nested schema](#nestedatt--os_users))
|
||||
- `ram` (Number) Amount of RAM in MB allocated for this compute instance.
|
||||
- `rg_name` (String) Name of the resource group where this compute instance is located.
|
||||
|
||||
<a id="nestedblock--network"></a>
|
||||
### Nested Schema for `network`
|
||||
|
||||
Required:
|
||||
|
||||
- `net_id` (Number) ID of the network for this connection.
|
||||
- `net_type` (String) Type of the network for this connection, either EXTNET or VINS.
|
||||
|
||||
Optional:
|
||||
|
||||
- `ip_address` (String) Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `mac` (String) MAC address associated with this connection. MAC address is assigned automatically.
|
||||
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--os_users"></a>
|
||||
### Nested Schema for `os_users`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `login` (String)
|
||||
- `password` (String)
|
||||
- `public_key` (String)
|
||||
|
||||
|
||||
@@ -1,167 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_lb Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_lb (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `lb_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `backends` (List of Object) (see [below for nested schema](#nestedatt--backends))
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `desc` (String)
|
||||
- `dp_api_user` (String)
|
||||
- `extnet_id` (Number)
|
||||
- `frontends` (List of Object) (see [below for nested schema](#nestedatt--frontends))
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `ha_mode` (Boolean)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_id` (Number)
|
||||
- `milestones` (Number)
|
||||
- `name` (String)
|
||||
- `primary_node` (List of Object) (see [below for nested schema](#nestedatt--primary_node))
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `secondary_node` (List of Object) (see [below for nested schema](#nestedatt--secondary_node))
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `vins_id` (Number)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--backends"></a>
|
||||
### Nested Schema for `backends`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `algorithm` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--server_default_settings))
|
||||
- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers))
|
||||
|
||||
<a id="nestedobjatt--backends--server_default_settings"></a>
|
||||
### Nested Schema for `backends.server_default_settings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `downinter` (Number)
|
||||
- `fall` (Number)
|
||||
- `guid` (String)
|
||||
- `inter` (Number)
|
||||
- `maxconn` (Number)
|
||||
- `maxqueue` (Number)
|
||||
- `rise` (Number)
|
||||
- `slowstart` (Number)
|
||||
- `weight` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--backends--servers"></a>
|
||||
### Nested Schema for `backends.servers`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `address` (String)
|
||||
- `check` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `port` (Number)
|
||||
- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--backends--servers--server_settings))
|
||||
|
||||
<a id="nestedobjatt--backends--servers--server_settings"></a>
|
||||
### Nested Schema for `backends.servers.server_settings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `downinter` (Number)
|
||||
- `fall` (Number)
|
||||
- `guid` (String)
|
||||
- `inter` (Number)
|
||||
- `maxconn` (Number)
|
||||
- `maxqueue` (Number)
|
||||
- `rise` (Number)
|
||||
- `slowstart` (Number)
|
||||
- `weight` (Number)
|
||||
|
||||
|
||||
|
||||
|
||||
<a id="nestedatt--frontends"></a>
|
||||
### Nested Schema for `frontends`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend` (String)
|
||||
- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--frontends--bindings))
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
|
||||
<a id="nestedobjatt--frontends--bindings"></a>
|
||||
### Nested Schema for `frontends.bindings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `address` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `port` (Number)
|
||||
|
||||
|
||||
|
||||
<a id="nestedatt--primary_node"></a>
|
||||
### Nested Schema for `primary_node`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend_ip` (String)
|
||||
- `compute_id` (Number)
|
||||
- `frontend_ip` (String)
|
||||
- `guid` (String)
|
||||
- `mgmt_ip` (String)
|
||||
- `network_id` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--secondary_node"></a>
|
||||
### Nested Schema for `secondary_node`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend_ip` (String)
|
||||
- `compute_id` (Number)
|
||||
- `frontend_ip` (String)
|
||||
- `guid` (String)
|
||||
- `mgmt_ip` (String)
|
||||
- `network_id` (Number)
|
||||
|
||||
|
||||
@@ -1,175 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_lb_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_lb_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `includedeleted` (Boolean)
|
||||
- `page` (Number)
|
||||
- `size` (Number)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backends` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends))
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `desc` (String)
|
||||
- `dp_api_password` (String)
|
||||
- `dp_api_user` (String)
|
||||
- `extnet_id` (Number)
|
||||
- `frontends` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends))
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `ha_mode` (Boolean)
|
||||
- `image_id` (Number)
|
||||
- `lb_id` (Number)
|
||||
- `milestones` (Number)
|
||||
- `name` (String)
|
||||
- `primary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--primary_node))
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `secondary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--secondary_node))
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `vins_id` (Number)
|
||||
|
||||
<a id="nestedobjatt--items--backends"></a>
|
||||
### Nested Schema for `items.backends`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `algorithm` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--server_default_settings))
|
||||
- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers))
|
||||
|
||||
<a id="nestedobjatt--items--backends--server_default_settings"></a>
|
||||
### Nested Schema for `items.backends.server_default_settings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `downinter` (Number)
|
||||
- `fall` (Number)
|
||||
- `guid` (String)
|
||||
- `inter` (Number)
|
||||
- `maxconn` (Number)
|
||||
- `maxqueue` (Number)
|
||||
- `rise` (Number)
|
||||
- `slowstart` (Number)
|
||||
- `weight` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--backends--servers"></a>
|
||||
### Nested Schema for `items.backends.servers`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `address` (String)
|
||||
- `check` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `port` (Number)
|
||||
- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers--server_settings))
|
||||
|
||||
<a id="nestedobjatt--items--backends--servers--server_settings"></a>
|
||||
### Nested Schema for `items.backends.servers.server_settings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `downinter` (Number)
|
||||
- `fall` (Number)
|
||||
- `guid` (String)
|
||||
- `inter` (Number)
|
||||
- `maxconn` (Number)
|
||||
- `maxqueue` (Number)
|
||||
- `rise` (Number)
|
||||
- `slowstart` (Number)
|
||||
- `weight` (Number)
|
||||
|
||||
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--frontends"></a>
|
||||
### Nested Schema for `items.frontends`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend` (String)
|
||||
- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends--bindings))
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
|
||||
<a id="nestedobjatt--items--frontends--bindings"></a>
|
||||
### Nested Schema for `items.frontends.bindings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `address` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `port` (Number)
|
||||
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--primary_node"></a>
|
||||
### Nested Schema for `items.primary_node`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend_ip` (String)
|
||||
- `compute_id` (Number)
|
||||
- `frontend_ip` (String)
|
||||
- `guid` (String)
|
||||
- `mgmt_ip` (String)
|
||||
- `network_id` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--secondary_node"></a>
|
||||
### Nested Schema for `items.secondary_node`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend_ip` (String)
|
||||
- `compute_id` (Number)
|
||||
- `frontend_ip` (String)
|
||||
- `guid` (String)
|
||||
- `mgmt_ip` (String)
|
||||
- `network_id` (Number)
|
||||
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_lb_list_deleted Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_lb_list_deleted (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `page` (Number)
|
||||
- `size` (Number)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backends` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends))
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `desc` (String)
|
||||
- `dp_api_password` (String)
|
||||
- `dp_api_user` (String)
|
||||
- `extnet_id` (Number)
|
||||
- `frontends` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends))
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `ha_mode` (Boolean)
|
||||
- `image_id` (Number)
|
||||
- `lb_id` (Number)
|
||||
- `milestones` (Number)
|
||||
- `name` (String)
|
||||
- `primary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--primary_node))
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `secondary_node` (List of Object) (see [below for nested schema](#nestedobjatt--items--secondary_node))
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `vins_id` (Number)
|
||||
|
||||
<a id="nestedobjatt--items--backends"></a>
|
||||
### Nested Schema for `items.backends`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `algorithm` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `server_default_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--server_default_settings))
|
||||
- `servers` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers))
|
||||
|
||||
<a id="nestedobjatt--items--backends--server_default_settings"></a>
|
||||
### Nested Schema for `items.backends.server_default_settings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `downinter` (Number)
|
||||
- `fall` (Number)
|
||||
- `guid` (String)
|
||||
- `inter` (Number)
|
||||
- `maxconn` (Number)
|
||||
- `maxqueue` (Number)
|
||||
- `rise` (Number)
|
||||
- `slowstart` (Number)
|
||||
- `weight` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--backends--servers"></a>
|
||||
### Nested Schema for `items.backends.servers`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `address` (String)
|
||||
- `check` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `port` (Number)
|
||||
- `server_settings` (List of Object) (see [below for nested schema](#nestedobjatt--items--backends--servers--server_settings))
|
||||
|
||||
<a id="nestedobjatt--items--backends--servers--server_settings"></a>
|
||||
### Nested Schema for `items.backends.servers.server_settings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `downinter` (Number)
|
||||
- `fall` (Number)
|
||||
- `guid` (String)
|
||||
- `inter` (Number)
|
||||
- `maxconn` (Number)
|
||||
- `maxqueue` (Number)
|
||||
- `rise` (Number)
|
||||
- `slowstart` (Number)
|
||||
- `weight` (Number)
|
||||
|
||||
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--frontends"></a>
|
||||
### Nested Schema for `items.frontends`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend` (String)
|
||||
- `bindings` (List of Object) (see [below for nested schema](#nestedobjatt--items--frontends--bindings))
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
|
||||
<a id="nestedobjatt--items--frontends--bindings"></a>
|
||||
### Nested Schema for `items.frontends.bindings`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `address` (String)
|
||||
- `guid` (String)
|
||||
- `name` (String)
|
||||
- `port` (Number)
|
||||
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--primary_node"></a>
|
||||
### Nested Schema for `items.primary_node`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend_ip` (String)
|
||||
- `compute_id` (Number)
|
||||
- `frontend_ip` (String)
|
||||
- `guid` (String)
|
||||
- `mgmt_ip` (String)
|
||||
- `network_id` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--secondary_node"></a>
|
||||
### Nested Schema for `items.secondary_node`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `backend_ip` (String)
|
||||
- `compute_id` (Number)
|
||||
- `frontend_ip` (String)
|
||||
- `guid` (String)
|
||||
- `mgmt_ip` (String)
|
||||
- `network_id` (Number)
|
||||
|
||||
|
||||
@@ -1,35 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_location_url Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_location_url (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `url` (String) Location url
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_locations_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_locations_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `page` (Number) page number
|
||||
- `size` (Number) page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) Locations list (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `ckey` (String)
|
||||
- `flag` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (Number)
|
||||
- `location_code` (String)
|
||||
- `meta` (List of String)
|
||||
- `name` (String)
|
||||
|
||||
|
||||
@@ -1,49 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_pcidevice Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_pcidevice (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `device_id` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `ckey` (String)
|
||||
- `compute_id` (Number)
|
||||
- `description` (String)
|
||||
- `guid` (Number)
|
||||
- `hw_path` (String)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `meta` (List of String)
|
||||
- `name` (String)
|
||||
- `rg_id` (Number)
|
||||
- `stack_id` (Number)
|
||||
- `status` (String)
|
||||
- `system_name` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_pcidevice_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_pcidevice_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) pcidevice list (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `ckey` (String)
|
||||
- `compute_id` (Number)
|
||||
- `description` (String)
|
||||
- `device_id` (Number)
|
||||
- `guid` (Number)
|
||||
- `hw_path` (String)
|
||||
- `meta` (List of String)
|
||||
- `name` (String)
|
||||
- `rg_id` (Number)
|
||||
- `stack_id` (Number)
|
||||
- `status` (String)
|
||||
- `system_name` (String)
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_resgroup Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_resgroup (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number) Unique ID of the account, which this resource group belongs to.
|
||||
|
||||
### Optional
|
||||
|
||||
- `name` (String) Name of the resource group. Names are case sensitive and unique within the context of an account.
|
||||
- `rg_id` (Number) Unique ID of the resource group. If this ID is specified, then resource group name is ignored.
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_name` (String) Name of the account, which this resource group belongs to.
|
||||
- `def_net_id` (Number) ID of the default network for this resource group (if any).
|
||||
- `def_net_type` (String) Type of the default network for this resource group.
|
||||
- `description` (String) User-defined text description of this resource group.
|
||||
- `id` (String) The ID of this resource.
|
||||
- `quota` (List of Object) Quota settings for this resource group. (see [below for nested schema](#nestedatt--quota))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--quota"></a>
|
||||
### Nested Schema for `quota`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cpu` (Number)
|
||||
- `disk` (Number)
|
||||
- `ext_ips` (Number)
|
||||
- `ext_traffic` (Number)
|
||||
- `gpu_units` (Number)
|
||||
- `ram` (Number)
|
||||
|
||||
|
||||
@@ -1,94 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_rg_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_rg_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `includedeleted` (Boolean) included deleted resource groups
|
||||
- `page` (Number) Page number
|
||||
- `size` (Number) Page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `acl` (List of Object) (see [below for nested schema](#nestedobjatt--items--acl))
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `def_net_id` (Number)
|
||||
- `def_net_type` (String)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `desc` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `lock_status` (String)
|
||||
- `milestones` (Number)
|
||||
- `name` (String)
|
||||
- `register_computes` (Boolean)
|
||||
- `resource_limits` (List of Object) (see [below for nested schema](#nestedobjatt--items--resource_limits))
|
||||
- `rg_id` (Number)
|
||||
- `secret` (String)
|
||||
- `status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `vins` (List of Number)
|
||||
- `vms` (List of Number)
|
||||
|
||||
<a id="nestedobjatt--items--acl"></a>
|
||||
### Nested Schema for `items.acl`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `explicit` (Boolean)
|
||||
- `guid` (String)
|
||||
- `right` (String)
|
||||
- `status` (String)
|
||||
- `type` (String)
|
||||
- `user_group_id` (String)
|
||||
|
||||
|
||||
<a id="nestedobjatt--items--resource_limits"></a>
|
||||
### Nested Schema for `items.resource_limits`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cu_c` (Number)
|
||||
- `cu_d` (Number)
|
||||
- `cu_i` (Number)
|
||||
- `cu_m` (Number)
|
||||
- `cu_np` (Number)
|
||||
- `gpu_units` (Number)
|
||||
|
||||
|
||||
@@ -1,51 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_sep Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_sep (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `sep_id` (Number) sep type des id
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `ckey` (String)
|
||||
- `config` (String)
|
||||
- `consumed_by` (List of Number)
|
||||
- `desc` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `meta` (List of String)
|
||||
- `milestones` (Number)
|
||||
- `name` (String)
|
||||
- `obj_status` (String)
|
||||
- `provided_by` (List of Number)
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_sep_config Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_sep_config (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `sep_id` (Number) storage endpoint provider ID
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `config` (String) sep config json string
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,69 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_sep_consumption Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_sep_consumption (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `sep_id` (Number) sep id
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `by_pool` (List of Object) consumption divided by pool (see [below for nested schema](#nestedatt--by_pool))
|
||||
- `id` (String) The ID of this resource.
|
||||
- `total` (List of Object) total consumption (see [below for nested schema](#nestedatt--total))
|
||||
- `type` (String) sep type
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--by_pool"></a>
|
||||
### Nested Schema for `by_pool`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `disk_count` (Number)
|
||||
- `disk_usage` (Number)
|
||||
- `name` (String)
|
||||
- `snapshot_count` (Number)
|
||||
- `snapshot_usage` (Number)
|
||||
- `usage` (Number)
|
||||
- `usage_limit` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--total"></a>
|
||||
### Nested Schema for `total`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `capacity_limit` (Number)
|
||||
- `disk_count` (Number)
|
||||
- `disk_usage` (Number)
|
||||
- `snapshot_count` (Number)
|
||||
- `snapshot_usage` (Number)
|
||||
- `usage` (Number)
|
||||
- `usage_limit` (Number)
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_sep_disk_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_sep_disk_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `sep_id` (Number) storage endpoint provider ID
|
||||
|
||||
### Optional
|
||||
|
||||
- `pool_name` (String) pool name
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Number) sep disk list
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,58 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_sep_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_sep_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `page` (Number) page number
|
||||
- `size` (Number) page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) sep list (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `ckey` (String)
|
||||
- `config` (String)
|
||||
- `consumed_by` (List of Number)
|
||||
- `desc` (String)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `meta` (List of String)
|
||||
- `milestones` (Number)
|
||||
- `name` (String)
|
||||
- `obj_status` (String)
|
||||
- `provided_by` (List of Number)
|
||||
- `sep_id` (Number)
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_sep_pool Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_sep_pool (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `pool_name` (String) pool name
|
||||
- `sep_id` (Number) storage endpoint provider ID
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `pool` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_snapshot_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_snapshot_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `compute_id` (Number) ID of the compute instance to create snapshot for.
|
||||
|
||||
### Optional
|
||||
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) snapshot list (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `disks` (List of Number)
|
||||
- `guid` (String)
|
||||
- `label` (String)
|
||||
- `timestamp` (Number)
|
||||
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_vgpu Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_vgpu (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `vgpu_id` (Number)
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `mode` (String)
|
||||
- `pgpu` (Number)
|
||||
- `profile_id` (Number)
|
||||
- `ram` (Number)
|
||||
- `status` (String)
|
||||
- `type` (String)
|
||||
- `vm_id` (Number)
|
||||
|
||||
|
||||
@@ -1,45 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_vins Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_vins (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `name` (String) Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number) Unique ID of the account, which this ViNS belongs to.
|
||||
- `rg_id` (Number) Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise).
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_name` (String) Name of the account, which this ViNS belongs to.
|
||||
- `description` (String) User-defined text description of this ViNS.
|
||||
- `ext_ip_addr` (String) IP address of the external connection (valid for ViNS connected to external network, empty string otherwise).
|
||||
- `ext_net_id` (Number) ID of the external network this ViNS is connected to (-1 means no external connection).
|
||||
- `id` (String) The ID of this resource.
|
||||
- `ipcidr` (String) Network address used by this ViNS.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
@@ -1,61 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_vins_list Data Source - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_vins_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- `include_deleted` (Boolean) include deleted computes
|
||||
- `page` (Number) Page number
|
||||
- `size` (Number) Page size
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
- `items` (List of Object) (see [below for nested schema](#nestedatt--items))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `default` (String)
|
||||
- `read` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--items"></a>
|
||||
### Nested Schema for `items`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `external_ip` (String)
|
||||
- `network` (String)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `vins_id` (Number)
|
||||
- `vins_name` (String)
|
||||
- `vxlan_id` (Number)
|
||||
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort Provider"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort Provider
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `authenticator` (String) Authentication mode to use when connecting to DECORT cloud API. Should be one of 'oauth2', 'legacy' or 'jwt'.
|
||||
- `controller_url` (String) URL of DECORT Cloud controller to use. API calls will be directed to this URL.
|
||||
|
||||
### Optional
|
||||
|
||||
- `allow_unverified_ssl` (Boolean) If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!
|
||||
- `app_id` (String) Application ID to access DECORT cloud API in 'oauth2' authentication mode.
|
||||
- `app_secret` (String) Application secret to access DECORT cloud API in 'oauth2' authentication mode.
|
||||
- `jwt` (String) JWT to access DECORT cloud API in 'jwt' authentication mode.
|
||||
- `oauth2_url` (String) OAuth2 application URL in 'oauth2' authentication mode.
|
||||
- `password` (String) User password for DECORT cloud API operations in 'legacy' authentication mode.
|
||||
- `user` (String) User name for DECORT cloud API operations in 'legacy' authentication mode.
|
||||
@@ -1,164 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_name` (String) account name
|
||||
- `username` (String) username of owner the account
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number)
|
||||
- `emailaddress` (String) email
|
||||
- `enable` (Boolean) enable/disable account
|
||||
- `permanently` (Boolean) whether to completely delete the account
|
||||
- `resource_limits` (Block List, Max: 1) (see [below for nested schema](#nestedblock--resource_limits))
|
||||
- `restore` (Boolean) restore a deleted account
|
||||
- `send_access_emails` (Boolean) if true send emails when a user is granted access to resources
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
- `users` (Block List) (see [below for nested schema](#nestedblock--users))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `acl` (List of Object) (see [below for nested schema](#nestedatt--acl))
|
||||
- `ckey` (String)
|
||||
- `company` (String)
|
||||
- `companyurl` (String)
|
||||
- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes))
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `dc_location` (String)
|
||||
- `deactivation_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `displayname` (String)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `machines` (List of Object) (see [below for nested schema](#nestedatt--machines))
|
||||
- `meta` (List of String)
|
||||
- `resources` (List of Object) (see [below for nested schema](#nestedatt--resources))
|
||||
- `service_account` (Boolean)
|
||||
- `status` (String)
|
||||
- `updated_time` (Number)
|
||||
- `version` (Number)
|
||||
- `vins` (List of Number)
|
||||
- `vinses` (Number)
|
||||
|
||||
<a id="nestedblock--resource_limits"></a>
|
||||
### Nested Schema for `resource_limits`
|
||||
|
||||
Optional:
|
||||
|
||||
- `cu_c` (Number)
|
||||
- `cu_d` (Number)
|
||||
- `cu_i` (Number)
|
||||
- `cu_m` (Number)
|
||||
- `cu_np` (Number)
|
||||
- `gpu_units` (Number)
|
||||
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedblock--users"></a>
|
||||
### Nested Schema for `users`
|
||||
|
||||
Required:
|
||||
|
||||
- `access_type` (String)
|
||||
- `user_id` (String)
|
||||
|
||||
Optional:
|
||||
|
||||
- `recursive_delete` (Boolean)
|
||||
|
||||
|
||||
<a id="nestedatt--acl"></a>
|
||||
### Nested Schema for `acl`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `can_be_deleted` (Boolean)
|
||||
- `explicit` (Boolean)
|
||||
- `guid` (String)
|
||||
- `right` (String)
|
||||
- `status` (String)
|
||||
- `type` (String)
|
||||
- `user_group_id` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--computes"></a>
|
||||
### Nested Schema for `computes`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `started` (Number)
|
||||
- `stopped` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--machines"></a>
|
||||
### Nested Schema for `machines`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `halted` (Number)
|
||||
- `running` (Number)
|
||||
|
||||
|
||||
<a id="nestedatt--resources"></a>
|
||||
### Nested Schema for `resources`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `current` (List of Object) (see [below for nested schema](#nestedobjatt--resources--current))
|
||||
- `reserved` (List of Object) (see [below for nested schema](#nestedobjatt--resources--reserved))
|
||||
|
||||
<a id="nestedobjatt--resources--current"></a>
|
||||
### Nested Schema for `resources.current`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cpu` (Number)
|
||||
- `disksize` (Number)
|
||||
- `extips` (Number)
|
||||
- `exttraffic` (Number)
|
||||
- `gpu` (Number)
|
||||
- `ram` (Number)
|
||||
|
||||
|
||||
<a id="nestedobjatt--resources--reserved"></a>
|
||||
### Nested Schema for `resources.reserved`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `cpu` (Number)
|
||||
- `disksize` (Number)
|
||||
- `extips` (Number)
|
||||
- `exttraffic` (Number)
|
||||
- `gpu` (Number)
|
||||
- `ram` (Number)
|
||||
|
||||
|
||||
@@ -1,101 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_bservice Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_bservice (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `rg_id` (Number) ID of the Resource Group where this service will be placed
|
||||
- `service_name` (String) Name of the service
|
||||
|
||||
### Optional
|
||||
|
||||
- `enable` (Boolean) if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately
|
||||
- `permanently` (Boolean) if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately
|
||||
- `restore` (Boolean) Restores BasicService instance
|
||||
- `service_id` (Number)
|
||||
- `snapshots` (Block List) (see [below for nested schema](#nestedblock--snapshots))
|
||||
- `ssh_key` (String) SSH key to deploy for the specified user. Same key will be deployed to all computes of the service.
|
||||
- `ssh_user` (String) name of the user to deploy SSH key for. Pass empty string if no SSH key deployment is required
|
||||
- `start` (Boolean) Start service. Starting a service technically means starting computes from all service groups according to group relations
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `base_domain` (String)
|
||||
- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes))
|
||||
- `cpu_total` (Number)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `disk_total` (String)
|
||||
- `gid` (Number)
|
||||
- `groups` (List of Number)
|
||||
- `groups_name` (List of String)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `milestones` (Number)
|
||||
- `parent_srv_id` (Number)
|
||||
- `parent_srv_type` (String)
|
||||
- `ram_total` (Number)
|
||||
- `rg_name` (String)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
- `user_managed` (Boolean)
|
||||
|
||||
<a id="nestedblock--snapshots"></a>
|
||||
### Nested Schema for `snapshots`
|
||||
|
||||
Optional:
|
||||
|
||||
- `label` (String)
|
||||
- `rollback` (Boolean)
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `timestamp` (Number)
|
||||
- `valid` (Boolean)
|
||||
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--computes"></a>
|
||||
### Nested Schema for `computes`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `compgroup_id` (Number)
|
||||
- `compgroup_name` (String)
|
||||
- `compgroup_role` (String)
|
||||
- `id` (Number)
|
||||
- `name` (String)
|
||||
|
||||
|
||||
@@ -1,97 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_bservice_group Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_bservice_group (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `comp_count` (Number) computes number. Defines how many computes must be there in the group
|
||||
- `compgroup_name` (String) name of the Compute Group to add
|
||||
- `cpu` (Number) compute CPU number. All computes in the group have the same CPU count
|
||||
- `disk` (Number) compute boot disk size in GB
|
||||
- `driver` (String) compute driver like a KVM_X86, KVM_PPC, etc.
|
||||
- `image_id` (Number) OS image ID to create computes from
|
||||
- `ram` (Number) compute RAM volume in MB. All computes in the group have the same RAM volume
|
||||
- `service_id` (Number) ID of the Basic Service to add a group to
|
||||
|
||||
### Optional
|
||||
|
||||
- `compgroup_id` (Number)
|
||||
- `extnets` (List of Number) list of external networks to connect computes to
|
||||
- `force_stop` (Boolean) force stop Compute Group
|
||||
- `force_update` (Boolean) force resize Compute Group
|
||||
- `mode` (String) (RELATIVE;ABSOLUTE) either delta or absolute value of computes
|
||||
- `parents` (List of Number)
|
||||
- `remove_computes` (List of Number)
|
||||
- `role` (String) group role tag. Can be empty string, does not have to be unique
|
||||
- `start` (Boolean) Start the specified Compute Group within BasicService
|
||||
- `timeout_start` (Number) time of Compute Group readiness
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
- `vinses` (List of Number) list of ViNSes to connect computes to
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number)
|
||||
- `account_name` (String)
|
||||
- `computes` (List of Object) (see [below for nested schema](#nestedatt--computes))
|
||||
- `consistency` (Boolean)
|
||||
- `created_by` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_by` (String)
|
||||
- `deleted_time` (Number)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `milestones` (Number)
|
||||
- `rg_id` (Number)
|
||||
- `rg_name` (String)
|
||||
- `sep_id` (Number)
|
||||
- `seq_no` (Number)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `updated_by` (String)
|
||||
- `updated_time` (Number)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--computes"></a>
|
||||
### Nested Schema for `computes`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `id` (Number)
|
||||
- `ip_addresses` (List of String)
|
||||
- `name` (String)
|
||||
- `os_users` (List of Object) (see [below for nested schema](#nestedobjatt--computes--os_users))
|
||||
|
||||
<a id="nestedobjatt--computes--os_users"></a>
|
||||
### Nested Schema for `computes.os_users`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `login` (String)
|
||||
- `password` (String)
|
||||
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_cdrom_image Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_cdrom_image (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `drivers` (List of String) List of types of compute suitable for image. Example: [ "KVM_X86" ]
|
||||
- `gid` (Number) grid (platform) ID where this template should be create in
|
||||
- `name` (String) Name of the rescue disk
|
||||
- `url` (String) URL where to download ISO from
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number) AccountId to make the image exclusive
|
||||
- `architecture` (String) binary architecture of this image, one of X86_64 of PPC64_LE
|
||||
- `bootable` (Boolean) Does this image boot OS
|
||||
- `computeci_id` (Number)
|
||||
- `enabled` (Boolean)
|
||||
- `enabled_stacks` (List of String)
|
||||
- `hot_resize` (Boolean) Does this machine supports hot resize
|
||||
- `password` (String) Optional password for the image
|
||||
- `password_dl` (String) password for upload binary media
|
||||
- `permanently` (Boolean) Whether to completely delete the image
|
||||
- `pool_name` (String) pool for image create
|
||||
- `sep_id` (Number) storage endpoint provider ID
|
||||
- `shared_with` (List of Number)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
- `username` (String) Optional username for the image
|
||||
- `username_dl` (String) username for upload binary media
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `boot_type` (String) Boot type of image bios or uefi
|
||||
- `desc` (String)
|
||||
- `guid` (Number)
|
||||
- `history` (List of Object) (see [below for nested schema](#nestedatt--history))
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_id` (Number) image id
|
||||
- `image_type` (String) Image type linux, windows or other
|
||||
- `link_to` (Number)
|
||||
- `meta` (List of String) meta
|
||||
- `milestones` (Number)
|
||||
- `provider_name` (String)
|
||||
- `purge_attempts` (Number)
|
||||
- `reference_id` (String)
|
||||
- `res_id` (String)
|
||||
- `res_name` (String)
|
||||
- `rescuecd` (Boolean)
|
||||
- `size` (Number) image size
|
||||
- `status` (String) status
|
||||
- `tech_status` (String) tech atatus
|
||||
- `unc_path` (String) unc path
|
||||
- `version` (String) version
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--history"></a>
|
||||
### Nested Schema for `history`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `id` (Number)
|
||||
- `timestamp` (Number)
|
||||
|
||||
|
||||
@@ -1,43 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_delete_images Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_delete_images (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `image_ids` (List of Number) images ids for deleting
|
||||
- `reason` (String) reason for deleting the images
|
||||
|
||||
### Optional
|
||||
|
||||
- `permanently` (Boolean) whether to completely delete the images
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_disk Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_disk (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `account_id` (Number)
|
||||
- `disk_name` (String)
|
||||
- `gid` (Number)
|
||||
- `size_max` (Number)
|
||||
|
||||
### Optional
|
||||
|
||||
- `desc` (String)
|
||||
- `detach` (Boolean) detach disk from machine first
|
||||
- `iotune` (Block List, Max: 1) (see [below for nested schema](#nestedblock--iotune))
|
||||
- `permanently` (Boolean) whether to completely delete the disk, works only with non attached disks
|
||||
- `pool` (String)
|
||||
- `reason` (String) reason for an action
|
||||
- `restore` (Boolean) restore deleting disk
|
||||
- `sep_id` (Number)
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
- `type` (String)
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_name` (String)
|
||||
- `acl` (String)
|
||||
- `boot_partition` (Number)
|
||||
- `compute_id` (Number)
|
||||
- `compute_name` (String)
|
||||
- `created_time` (Number)
|
||||
- `deleted_time` (Number)
|
||||
- `destruction_time` (Number)
|
||||
- `devicename` (String)
|
||||
- `disk_id` (Number)
|
||||
- `disk_path` (String)
|
||||
- `guid` (Number)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_id` (Number)
|
||||
- `images` (List of String)
|
||||
- `iqn` (String)
|
||||
- `login` (String)
|
||||
- `milestones` (Number)
|
||||
- `order` (Number)
|
||||
- `params` (String)
|
||||
- `parent_id` (Number)
|
||||
- `passwd` (String)
|
||||
- `pci_slot` (Number)
|
||||
- `purge_attempts` (Number)
|
||||
- `purge_time` (Number)
|
||||
- `reality_device_number` (Number)
|
||||
- `reference_id` (String)
|
||||
- `res_id` (String)
|
||||
- `res_name` (String)
|
||||
- `role` (String)
|
||||
- `sep_type` (String)
|
||||
- `size_used` (Number)
|
||||
- `snapshots` (List of Object) (see [below for nested schema](#nestedatt--snapshots))
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `vmid` (Number)
|
||||
|
||||
<a id="nestedblock--iotune"></a>
|
||||
### Nested Schema for `iotune`
|
||||
|
||||
Optional:
|
||||
|
||||
- `read_bytes_sec` (Number)
|
||||
- `read_bytes_sec_max` (Number)
|
||||
- `read_iops_sec` (Number)
|
||||
- `read_iops_sec_max` (Number)
|
||||
- `size_iops_sec` (Number)
|
||||
- `total_bytes_sec` (Number)
|
||||
- `total_bytes_sec_max` (Number)
|
||||
- `total_iops_sec` (Number)
|
||||
- `total_iops_sec_max` (Number)
|
||||
- `write_bytes_sec` (Number)
|
||||
- `write_bytes_sec_max` (Number)
|
||||
- `write_iops_sec` (Number)
|
||||
- `write_iops_sec_max` (Number)
|
||||
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--snapshots"></a>
|
||||
### Nested Schema for `snapshots`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `label` (String)
|
||||
- `res_id` (String)
|
||||
- `snap_set_guid` (String)
|
||||
- `snap_set_time` (Number)
|
||||
- `timestamp` (Number)
|
||||
|
||||
|
||||
@@ -1,90 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_image (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `boot_type` (String) Boot type of image bios or uefi
|
||||
- `drivers` (List of String)
|
||||
- `gid` (Number) grid (platform) ID where this template should be create in
|
||||
- `name` (String) Name of the rescue disk
|
||||
- `type` (String) Image type linux, windows or other
|
||||
- `url` (String) URL where to download media from
|
||||
|
||||
### Optional
|
||||
|
||||
- `account_id` (Number) AccountId to make the image exclusive
|
||||
- `architecture` (String) binary architecture of this image, one of X86_64 of PPC64_LE
|
||||
- `hot_resize` (Boolean) Does this machine supports hot resize
|
||||
- `image_id` (Number) image id
|
||||
- `password` (String) Optional password for the image
|
||||
- `password_dl` (String) password for upload binary media
|
||||
- `permanently` (Boolean) whether to completely delete the image
|
||||
- `pool_name` (String) pool for image create
|
||||
- `sep_id` (Number) storage endpoint provider ID
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
- `username` (String) Optional username for the image
|
||||
- `username_dl` (String) username for upload binary media
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `acl` (String)
|
||||
- `bootable` (Boolean)
|
||||
- `ckey` (String)
|
||||
- `compute_ci_id` (Number)
|
||||
- `deleted_time` (String)
|
||||
- `desc` (String)
|
||||
- `enabled` (Boolean)
|
||||
- `guid` (Number)
|
||||
- `history` (List of Object) (see [below for nested schema](#nestedatt--history))
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_name` (String)
|
||||
- `last_modified` (Number)
|
||||
- `link_to` (Number)
|
||||
- `milestones` (Number)
|
||||
- `provider_name` (String)
|
||||
- `purge_attempts` (Number)
|
||||
- `res_id` (String)
|
||||
- `rescuecd` (Boolean)
|
||||
- `shared_with` (List of Number)
|
||||
- `size` (Number)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `unc_path` (String)
|
||||
- `version` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--history"></a>
|
||||
### Nested Schema for `history`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `id` (Number)
|
||||
- `timestamp` (Number)
|
||||
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image_virtual Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_image_virtual (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `link_to` (Number) ID of real image to link this virtual image to upon creation
|
||||
- `name` (String) Name of the rescue disk
|
||||
|
||||
### Optional
|
||||
|
||||
- `permanently` (Boolean) whether to completely delete the image
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number)
|
||||
- `acl` (String)
|
||||
- `architecture` (String)
|
||||
- `boot_type` (String)
|
||||
- `bootable` (Boolean)
|
||||
- `ckey` (String)
|
||||
- `compute_ci_id` (Number)
|
||||
- `deleted_time` (String)
|
||||
- `desc` (String)
|
||||
- `drivers` (List of String)
|
||||
- `enabled` (Boolean)
|
||||
- `gid` (Number)
|
||||
- `guid` (Number)
|
||||
- `history` (List of Object) (see [below for nested schema](#nestedatt--history))
|
||||
- `hot_resize` (Boolean)
|
||||
- `id` (String) The ID of this resource.
|
||||
- `image_id` (Number) Image id
|
||||
- `image_name` (String)
|
||||
- `last_modified` (Number)
|
||||
- `milestones` (Number)
|
||||
- `password` (String)
|
||||
- `pool_name` (String)
|
||||
- `provider_name` (String)
|
||||
- `purge_attempts` (Number)
|
||||
- `res_id` (String)
|
||||
- `rescuecd` (Boolean)
|
||||
- `sep_id` (Number)
|
||||
- `shared_with` (List of Number)
|
||||
- `size` (Number)
|
||||
- `status` (String)
|
||||
- `tech_status` (String)
|
||||
- `type` (String)
|
||||
- `unc_path` (String)
|
||||
- `username` (String)
|
||||
- `version` (String)
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--history"></a>
|
||||
### Nested Schema for `history`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `id` (Number)
|
||||
- `timestamp` (Number)
|
||||
|
||||
|
||||
@@ -1,72 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_k8s Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_k8s (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `k8sci_id` (Number) ID of the k8s catalog item to base this instance on.
|
||||
- `name` (String) Name of the cluster.
|
||||
- `rg_id` (Number) Resource group ID that this instance belongs to.
|
||||
- `wg_name` (String) Name for first worker group created with cluster.
|
||||
|
||||
### Optional
|
||||
|
||||
- `extnet_id` (Number) ID of the external network to connect workers to. If omitted network will be chosen by the platfom.
|
||||
- `masters` (Block List, Max: 1) Master node(s) configuration. (see [below for nested schema](#nestedblock--masters))
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
- `workers` (Block List, Max: 1) Worker node(s) configuration. (see [below for nested schema](#nestedblock--workers))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `default_wg_id` (Number) ID of default workers group for this instace.
|
||||
- `id` (String) The ID of this resource.
|
||||
- `kubeconfig` (String) Kubeconfig for cluster access.
|
||||
- `lb_ip` (String) IP address of default load balancer.
|
||||
|
||||
<a id="nestedblock--masters"></a>
|
||||
### Nested Schema for `masters`
|
||||
|
||||
Required:
|
||||
|
||||
- `cpu` (Number) Node CPU count.
|
||||
- `disk` (Number) Node boot disk size in GB.
|
||||
- `num` (Number) Number of nodes to create.
|
||||
- `ram` (Number) Node RAM in MB.
|
||||
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedblock--workers"></a>
|
||||
### Nested Schema for `workers`
|
||||
|
||||
Required:
|
||||
|
||||
- `cpu` (Number) Node CPU count.
|
||||
- `disk` (Number) Node boot disk size in GB.
|
||||
- `num` (Number) Number of nodes to create.
|
||||
- `ram` (Number) Node RAM in MB.
|
||||
|
||||
|
||||
@@ -1,46 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_k8s_wg Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_k8s_wg (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `k8s_id` (Number) ID of k8s instance.
|
||||
- `name` (String) Name of the worker group.
|
||||
|
||||
### Optional
|
||||
|
||||
- `cpu` (Number) Worker node CPU count.
|
||||
- `disk` (Number) Worker node boot disk size. If unspecified or 0, size is defined by OS image size.
|
||||
- `num` (Number) Number of worker nodes to create.
|
||||
- `ram` (Number) Worker node RAM in MB.
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `id` (String) The ID of this resource.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
@@ -1,91 +0,0 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_kvmvm Resource - decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_kvmvm (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- `boot_disk_size` (Number) This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.
|
||||
- `cpu` (Number) Number of CPUs to allocate to this compute instance.
|
||||
- `driver` (String) Hardware architecture of this compute instance.
|
||||
- `image_id` (Number) ID of the OS image to base this compute instance on.
|
||||
- `name` (String) Name of this compute. Compute names are case sensitive and must be unique in the resource group.
|
||||
- `ram` (Number) Amount of RAM in MB to allocate to this compute instance.
|
||||
- `rg_id` (Number) ID of the resource group where this compute should be deployed.
|
||||
|
||||
### Optional
|
||||
|
||||
- `cloud_init` (String) Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.
|
||||
- `description` (String) Optional text description of this compute instance.
|
||||
- `detach_disks` (Boolean)
|
||||
- `extra_disks` (Set of Number) Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.
|
||||
- `ipa_type` (String) compute purpose
|
||||
- `is` (String) system name
|
||||
- `network` (Block Set, Max: 8) Optional network connection(s) for this compute. You may specify several network blocks, one for each connection. (see [below for nested schema](#nestedblock--network))
|
||||
- `permanently` (Boolean)
|
||||
- `pool` (String) Pool to use if sepId is set, can be also empty if needed to be chosen by system.
|
||||
- `sep_id` (Number) ID of SEP to create bootDisk on. Uses image's sepId if not set.
|
||||
- `started` (Boolean) Is compute started.
|
||||
- `timeouts` (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- `account_id` (Number) ID of the account this compute instance belongs to.
|
||||
- `account_name` (String) Name of the account this compute instance belongs to.
|
||||
- `boot_disk_id` (Number) This compute instance boot disk ID.
|
||||
- `id` (String) The ID of this resource.
|
||||
- `os_users` (List of Object) Guest OS users provisioned on this compute instance. (see [below for nested schema](#nestedatt--os_users))
|
||||
- `rg_name` (String) Name of the resource group where this compute instance is located.
|
||||
|
||||
<a id="nestedblock--network"></a>
|
||||
### Nested Schema for `network`
|
||||
|
||||
Required:
|
||||
|
||||
- `net_id` (Number) ID of the network for this connection.
|
||||
- `net_type` (String) Type of the network for this connection, either EXTNET or VINS.
|
||||
|
||||
Optional:
|
||||
|
||||
- `ip_address` (String) Optional IP address to assign to this connection. This IP should belong to the selected network and free for use.
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `mac` (String) MAC address associated with this connection. MAC address is assigned automatically.
|
||||
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- `create` (String)
|
||||
- `default` (String)
|
||||
- `delete` (String)
|
||||
- `read` (String)
|
||||
- `update` (String)
|
||||
|
||||
|
||||
<a id="nestedatt--os_users"></a>
|
||||
### Nested Schema for `os_users`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- `guid` (String)
|
||||
- `login` (String)
|
||||
- `password` (String)
|
||||
- `public_key` (String)
|
||||
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user