Compare commits
36 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
94f222fe19 | ||
|
|
a3da44f2ad | ||
|
|
ef7fa62e79 | ||
|
|
4bb75fe0d7 | ||
|
|
8cf4680ce1 | ||
|
|
bf1afc66dd | ||
|
|
d9c10c0d9c | ||
|
|
f28588fea5 | ||
|
|
3e72f72d15 | ||
|
|
bf179b9d12 | ||
|
|
9379289e58 | ||
|
|
edf7728cb5 | ||
|
|
95cd7cb820 | ||
|
|
06c0578fa6 | ||
|
|
1bf17c23c8 | ||
|
|
668d57cd3b | ||
|
|
fef6040cc6 | ||
|
|
d0165918c3 | ||
|
|
dfeb9a9165 | ||
|
|
e0dcd053c5 | ||
|
|
ab070b73cb | ||
|
|
80a4b70db8 | ||
|
|
28db919ffa | ||
|
|
3164793f69 | ||
|
|
5db588e5dc | ||
|
|
8058b1c08f | ||
|
|
fb83398df9 | ||
|
|
a63a35ca93 | ||
|
|
cf669a7a72 | ||
|
|
8da3f8d348 | ||
|
|
d0fdf38473 | ||
|
|
92c52794d4 | ||
|
|
7480160dc5 | ||
|
|
e86224f95f | ||
|
|
1ea7a27b21 | ||
|
|
ec4e63c2c8 |
37
.github/workflows/release.yml
vendored
Normal file
37
.github/workflows/release.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: Release to registry
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- 'v*'
|
||||
|
||||
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@v2
|
||||
with:
|
||||
go-version: 1.17
|
||||
|
||||
- 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@v2
|
||||
with:
|
||||
args: release --rm-dist --release-notes CHANGELOG.md
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}
|
||||
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,2 +1,4 @@
|
||||
decort/vendor/
|
||||
examples/
|
||||
url_scrapping/
|
||||
terraform-provider-decort*
|
||||
|
||||
46
.goreleaser.yml
Normal file
46
.goreleaser.yml
Normal file
@@ -0,0 +1,46 @@
|
||||
before:
|
||||
hooks:
|
||||
- go mod tidy
|
||||
builds:
|
||||
- env:
|
||||
- CGO_ENABLED=0
|
||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||
flags:
|
||||
- -trimpath
|
||||
goos:
|
||||
- freebsd
|
||||
- windows
|
||||
- linux
|
||||
- darwin
|
||||
goarch:
|
||||
- amd64
|
||||
- '386'
|
||||
ignore:
|
||||
- goos: darwin
|
||||
goarch: '386'
|
||||
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
|
||||
5
CHANGELOG.md
Normal file
5
CHANGELOG.md
Normal file
@@ -0,0 +1,5 @@
|
||||
### Bug fixes
|
||||
- k8s state import
|
||||
|
||||
### Minor changes
|
||||
- increased k8s and k8s\_wg create/update timeouts
|
||||
39
Makefile
Normal file
39
Makefile
Normal file
@@ -0,0 +1,39 @@
|
||||
TEST?=$$(go list ./... | grep -v 'vendor')
|
||||
HOSTNAME=digitalenergy.online
|
||||
NAMESPACE=decort
|
||||
NAME=terraform-provider-decort
|
||||
#BINARY=terraform-provider-${NAME}
|
||||
BINARY=${NAME}.exe
|
||||
VERSION=0.2
|
||||
#OS_ARCH=darwin_amd64
|
||||
OS_ARCH=windows_amd64
|
||||
|
||||
default: install
|
||||
|
||||
build:
|
||||
go build -o ${BINARY}
|
||||
|
||||
release:
|
||||
GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64
|
||||
GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386
|
||||
GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64
|
||||
GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm
|
||||
GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386
|
||||
GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64
|
||||
GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm
|
||||
GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386
|
||||
GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64
|
||||
GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64
|
||||
GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386
|
||||
GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64
|
||||
|
||||
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
|
||||
145
README.md
145
README.md
@@ -1,54 +1,117 @@
|
||||
# terraform-provider-decort
|
||||
Terraform provider for Digital Energy Cloud Orchestration Technology (DECORT) platform
|
||||
Terraform provider для платформы Digital Energy Cloud Orchestration Technology (DECORT)
|
||||
|
||||
NOTE: this provider is designed for DECORT API 3.6.x. For older API versions please use
|
||||
Terraform DECS provider (https://github.com/rudecs/terraform-provider-decs).
|
||||
Внимание: провайдер версии rc-1.25 разработан для DECORT API 3.7.x.
|
||||
Для более старых версий можно использовать:
|
||||
- DECORT API 3.6.x - версия провайдера rc-1.10
|
||||
- DECORT API до 3.6.0 - terraform DECS provider (https://github.com/rudecs/terraform-provider-decs)
|
||||
|
||||
With this provider you can manage Compute instances, disks 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.
|
||||
## Возможности провайдера
|
||||
- Работа с Compute instances,
|
||||
- Работа с disks,
|
||||
- Работа с k8s,
|
||||
- Работа с virtual network segments,
|
||||
- Работа с image,
|
||||
- Работа с reource groups,
|
||||
- Работа с VINS,
|
||||
- Работа с pfw,
|
||||
- Работа с accounts.
|
||||
|
||||
See user guide at https://github.com/rudecs/terraform-provider-decort/wiki
|
||||
Вики проекта: 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).
|
||||
## Начало
|
||||
Старт возможен по двум путям:
|
||||
1. Установка через собранные пакеты.
|
||||
2. Ручная установка.
|
||||
|
||||
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.
|
||||
### Установка через собранные пакеты.
|
||||
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
|
||||
}
|
||||
```
|
||||
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. Выполните команду
|
||||
```
|
||||
terraform init
|
||||
```
|
||||
Провайдер автоматически будет установлен на ваш компьютер из 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://github.com/rudecs/terraform-provider-decort.git
|
||||
```
|
||||
4. Перейдите в скачанную папку с провайдером и выполните команду
|
||||
```bash
|
||||
go build -o terraform-provider-decort
|
||||
```
|
||||
Если вы знаете как устроен _makefile_, то можно изменить в файле `Makefile` параметры под вашу ОС и выполнить команду
|
||||
```bash
|
||||
make build
|
||||
```
|
||||
5. Полученный файл необходимо поместить:
|
||||
Linux:
|
||||
```bash
|
||||
~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target}
|
||||
```
|
||||
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
|
||||
```
|
||||
|
||||
2. Add the following environment variables' declarations to shell startup script:
|
||||
```
|
||||
export GOPATH=/opt/gopkg:~/
|
||||
export GOROOT=/usr/local/go
|
||||
export PATH=$PATH:$GOROOT/bin
|
||||
```
|
||||
9. Если все прошло хорошо - ошибок не будет.
|
||||
|
||||
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
|
||||
```
|
||||
Более подробно о сборке провайдера можно найти по ссылке: https://learn.hashicorp.com/tutorials/terraform/provider-use?in=terraform/providers
|
||||
|
||||
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
|
||||
```
|
||||
## Примеры работы
|
||||
Примеры работы можно найти:
|
||||
- На вики проекта: https://github.com/rudecs/terraform-provider-decort/wiki
|
||||
- В папке `samples`
|
||||
|
||||
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
|
||||
```
|
||||
Схемы к terraform'у доступны:
|
||||
- В папке `docs`
|
||||
|
||||
6. Build Terraform DECORT provider:
|
||||
```
|
||||
cd $GOPKG/src/github.com/terraform-provider-decort
|
||||
go build -o terraform-provider-decort
|
||||
```
|
||||
Хорошей работы!
|
||||
|
||||
118
README_EN.md
Normal file
118
README_EN.md
Normal file
@@ -0,0 +1,118 @@
|
||||
# terraform-provider-decort
|
||||
Terraform provider for Digital Energy Cloud Orchestration Technology (DECORT) platform
|
||||
|
||||
NOTE: provider rc-1.25 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)
|
||||
|
||||
## Features
|
||||
- Work with Compute instances,
|
||||
- Work with disks,
|
||||
- Work with k8s,
|
||||
- Work with virtual network segments,
|
||||
- Work with image,
|
||||
- Work with reource groups,
|
||||
- Work with VINS,
|
||||
- Work with pfw,
|
||||
- Work with accounts.
|
||||
|
||||
This provider supports Import operations on pre-existing resources.
|
||||
|
||||
See user guide at https://github.com/rudecs/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://github.com/rudecs/terraform-provider-decort/wiki
|
||||
- Samples: see in repository `samples`
|
||||
|
||||
Terraform schemas in:
|
||||
- See in repository `docs`
|
||||
|
||||
Good work!
|
||||
@@ -16,16 +16,15 @@ limitations under the License.
|
||||
*/
|
||||
|
||||
/*
|
||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
||||
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.
|
||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
"bytes"
|
||||
"crypto/tls"
|
||||
"fmt"
|
||||
@@ -34,6 +33,7 @@ import (
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
// "time"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -42,42 +42,41 @@ import (
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
// "github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
|
||||
)
|
||||
|
||||
// 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
|
||||
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{
|
||||
@@ -90,7 +89,7 @@ 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: "",
|
||||
}
|
||||
|
||||
var allow_unverified_ssl bool
|
||||
@@ -137,10 +136,10 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
|
||||
if allow_unverified_ssl {
|
||||
log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!")
|
||||
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true},}
|
||||
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
|
||||
ret_config.cc_client = &http.Client{
|
||||
Transport: transCfg,
|
||||
Timeout: Timeout180s,
|
||||
Timeout: Timeout180s,
|
||||
}
|
||||
} else {
|
||||
ret_config.cc_client = &http.Client{
|
||||
@@ -150,7 +149,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
|
||||
switch ret_config.auth_mode_code {
|
||||
case MODE_LEGACY:
|
||||
ok, err := ret_config.validateLegacyUser()
|
||||
ok, err := ret_config.validateLegacyUser()
|
||||
if !ok {
|
||||
return nil, err
|
||||
}
|
||||
@@ -162,13 +161,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{}
|
||||
@@ -181,7 +180,7 @@ 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.")
|
||||
}
|
||||
@@ -195,7 +194,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
|
||||
}
|
||||
|
||||
@@ -216,14 +215,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
|
||||
}
|
||||
@@ -231,16 +230,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 %q for APP_ID %q, request Body %q",
|
||||
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))
|
||||
|
||||
@@ -249,10 +248,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 accounts 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 == "" {
|
||||
@@ -265,7 +264,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/accounts/list", nil)
|
||||
req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/accounts/list", nil)
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
@@ -273,14 +272,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 %q.",
|
||||
resp.StatusCode, req.URL)
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
@@ -289,10 +288,10 @@ 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.")
|
||||
@@ -306,7 +305,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/users/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
|
||||
}
|
||||
@@ -314,21 +313,21 @@ 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 %q against %q.",
|
||||
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)
|
||||
|
||||
@@ -336,16 +335,16 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
||||
}
|
||||
|
||||
func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error) {
|
||||
// This is a convenience wrapper around standard HTTP request methods that is aware of the
|
||||
// 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.
|
||||
|
||||
if config.cc_client == nil {
|
||||
// this should never happen if ClientConfig was properly called prior to decortAPICall
|
||||
// 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.")
|
||||
}
|
||||
|
||||
// Example: to create api_params, one would generally do the following:
|
||||
//
|
||||
//
|
||||
// data := []byte(`{"machineId": "2638"}`)
|
||||
// api_params := bytes.NewBuffer(data))
|
||||
//
|
||||
@@ -367,42 +366,40 @@ func (config *ControllerCfg) decortAPICall(method string, api_name string, url_v
|
||||
}
|
||||
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
|
||||
}
|
||||
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
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
tmp_body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
json_resp := Jo2JSON(string(tmp_body))
|
||||
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, json_resp)
|
||||
return json_resp, nil
|
||||
body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, body)
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
return string(body), nil
|
||||
} else {
|
||||
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %q with request Body %q",
|
||||
resp.StatusCode, req.URL, params_str)
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if resp.StatusCode == StatusServiceUnavailable {
|
||||
return nil, fmt.Errorf("decortAPICall method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
||||
}
|
||||
if resp.StatusCode == StatusServiceUnavailable {
|
||||
return nil, fmt.Errorf("decortAPICall method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
||||
}
|
||||
*/
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
|
||||
@@ -27,6 +27,7 @@ package decort
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
|
||||
// "net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
@@ -36,20 +37,20 @@ import (
|
||||
)
|
||||
|
||||
// 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.
|
||||
// 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,
|
||||
// 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" ) {
|
||||
|
||||
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 {
|
||||
@@ -62,39 +63,40 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
||||
idx++
|
||||
}
|
||||
|
||||
return result
|
||||
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
|
||||
// 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
|
||||
}
|
||||
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 := make([]interface{}, length)
|
||||
|
||||
result := []interface{}{}
|
||||
|
||||
if length == 0 {
|
||||
return result
|
||||
}
|
||||
|
||||
elem := make(map[string]interface{})
|
||||
|
||||
for i, value := range disks {
|
||||
for _, value := range disks {
|
||||
/*
|
||||
if value.Type == "B" {
|
||||
// skip boot disk when parsing the list of disks
|
||||
continue
|
||||
}
|
||||
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
|
||||
@@ -111,10 +113,11 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
|
||||
// elem["status"] = value.Status
|
||||
// elem["tech_status"] = value.TechStatus
|
||||
elem["compute_id"] = value.ComputeID
|
||||
result[i] = elem
|
||||
|
||||
result = append(result, elem)
|
||||
}
|
||||
|
||||
return result
|
||||
return result
|
||||
}
|
||||
|
||||
func parseBootDiskSize(disks []DiskRecord) int {
|
||||
@@ -129,7 +132,7 @@ func parseBootDiskSize(disks []DiskRecord) int {
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
return 0
|
||||
}
|
||||
|
||||
func parseBootDiskId(disks []DiskRecord) uint {
|
||||
@@ -144,13 +147,38 @@ func parseBootDiskId(disks []DiskRecord) uint {
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
return 0
|
||||
}
|
||||
|
||||
// Parse the list of interfaces from compute/get response into a list of networks
|
||||
// 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
|
||||
}
|
||||
|
||||
/*
|
||||
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]interface{} {
|
||||
// return value will be used to d.Set("network",) item of dataSourceCompute schema
|
||||
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
||||
length := len(ifaces)
|
||||
log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length)
|
||||
|
||||
@@ -170,13 +198,15 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]int
|
||||
result[i] = elem
|
||||
}
|
||||
|
||||
return result
|
||||
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
|
||||
// managed through Terraform
|
||||
length := len(ifaces)
|
||||
log.Debugf("parseComputeInterfaces: called for %d ifaces", length)
|
||||
|
||||
@@ -208,11 +238,11 @@ func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
|
||||
result[i] = elem
|
||||
}
|
||||
|
||||
return result
|
||||
return result
|
||||
}
|
||||
|
||||
func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||
// This function expects that comp_facts string contains response from API compute/get,
|
||||
// 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
|
||||
@@ -233,7 +263,7 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||
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("driver", model.Driver)
|
||||
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
|
||||
@@ -241,9 +271,16 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||
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 model.TechStatus == "STARTED" {
|
||||
d.Set("started", true)
|
||||
} else {
|
||||
d.Set("started", false)
|
||||
}
|
||||
|
||||
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 {
|
||||
@@ -298,6 +335,8 @@ func dataSourceCompute() *schema.Resource {
|
||||
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,
|
||||
@@ -328,7 +367,7 @@ func dataSourceCompute() *schema.Resource {
|
||||
Description: "Name of the account this compute instance belongs to.",
|
||||
},
|
||||
|
||||
"arch": {
|
||||
"driver": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Hardware architecture of this compute instance.",
|
||||
@@ -371,28 +410,28 @@ func dataSourceCompute() *schema.Resource {
|
||||
},
|
||||
|
||||
"extra_disks": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Type: schema.TypeSet,
|
||||
Computed: true,
|
||||
MaxItems: MaxExtraDisksPerCompute,
|
||||
Elem: &schema.Schema {
|
||||
Type: schema.TypeInt,
|
||||
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
|
||||
"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).",
|
||||
},
|
||||
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
||||
},
|
||||
*/
|
||||
|
||||
"network": {
|
||||
Type: schema.TypeList,
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
MaxItems: MaxNetworksPerCompute,
|
||||
Elem: &schema.Resource{
|
||||
@@ -402,14 +441,14 @@ func dataSourceCompute() *schema.Resource {
|
||||
},
|
||||
|
||||
/*
|
||||
"interfaces": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: interfaceSubresourceSchemaMake(),
|
||||
"interfaces": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: interfaceSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Specification for the virtual NICs configured on this compute instance.",
|
||||
},
|
||||
Description: "Specification for the virtual NICs configured on this compute instance.",
|
||||
},
|
||||
*/
|
||||
|
||||
"os_users": {
|
||||
@@ -427,24 +466,37 @@ func dataSourceCompute() *schema.Resource {
|
||||
Description: "User-defined text description of this compute instance.",
|
||||
},
|
||||
|
||||
"cloud_init": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Placeholder for cloud_init parameters.",
|
||||
},
|
||||
|
||||
"started": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
Description: "Is compute started.",
|
||||
},
|
||||
|
||||
/*
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current model status of 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.",
|
||||
},
|
||||
"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.",
|
||||
},
|
||||
"internal_ip": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Internal IP address of this Compute.",
|
||||
},
|
||||
*/
|
||||
},
|
||||
}
|
||||
|
||||
@@ -67,18 +67,6 @@ func flattenDisk(d *schema.ResourceData, disk_facts string) error {
|
||||
// d.Set("compute_id", model.ComputeID)
|
||||
|
||||
d.Set("description", model.Desc)
|
||||
// d.Set("status", model.Status)
|
||||
// d.Set("tech_status", model.TechStatus)
|
||||
|
||||
/* we do not manage snapshots via Terraform yet (and probably, never will), so
|
||||
// keep this block commented out for a while
|
||||
if len(model.Snapshots) > 0 {
|
||||
log.Debugf("flattenDisk: calling flattenDiskSnapshots")
|
||||
if err = d.Set("nics", flattenDiskSnapshots(model.Snapshots)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -137,7 +125,7 @@ func dataSourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Type of this disk.",
|
||||
Description: "Type of this disk. E.g. D for data disks, B for boot.",
|
||||
},
|
||||
|
||||
"description": {
|
||||
|
||||
100
decort/data_source_grid.go
Normal file
100
decort/data_source_grid.go
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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 (
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func flattenGrid(d *schema.ResourceData, grid *Grid) {
|
||||
d.Set("name", grid.Name)
|
||||
d.Set("flag", grid.Flag)
|
||||
d.Set("gid", grid.Gid)
|
||||
d.Set("guid", grid.Guid)
|
||||
d.Set("location_code", grid.LocationCode)
|
||||
d.Set("id", grid.Id)
|
||||
return
|
||||
}
|
||||
|
||||
func dataSourceGridRead(d *schema.ResourceData, m interface{}) error {
|
||||
grid, err := utilityGridCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.SetId(strconv.Itoa(grid.Id))
|
||||
flattenGrid(d, grid)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceGetGridSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"grid_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
},
|
||||
"flag": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"location_code": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceGrid() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourceGridRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceGetGridSchemaMake(),
|
||||
}
|
||||
}
|
||||
128
decort/data_source_grid_list.go
Normal file
128
decort/data_source_grid_list.go
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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 (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func flattenGridList(gl GridList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range gl {
|
||||
temp := map[string]interface{}{
|
||||
"name": item.Name,
|
||||
"flag": item.Flag,
|
||||
"gid": item.Gid,
|
||||
"guid": item.Guid,
|
||||
"location_code": item.LocationCode,
|
||||
"id": item.Id,
|
||||
}
|
||||
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func dataSourceGridListRead(d *schema.ResourceData, m interface{}) error {
|
||||
gridList, err := utilityGridListCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("items", flattenGridList(gridList))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceGridListSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"page": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "page number",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "page size",
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "grid list",
|
||||
Elem: &schema.Resource{
|
||||
Schema: dataSourceGridSchemaMake(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func dataSourceGridSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"flag": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"location_code": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceGridList() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourceGridListRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceGridListSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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.
|
||||
@@ -25,57 +25,275 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func flattenImage(d *schema.ResourceData, image *Image) {
|
||||
d.Set("name", image.Name)
|
||||
d.Set("drivers", image.Drivers)
|
||||
d.Set("url", image.Url)
|
||||
d.Set("gid", image.Gid)
|
||||
d.Set("image_id", image.ImageId)
|
||||
d.Set("boot_type", image.Boottype)
|
||||
d.Set("image_type", image.Imagetype)
|
||||
d.Set("bootable", image.Bootable)
|
||||
d.Set("sep_id", image.SepId)
|
||||
d.Set("unc_path", image.UNCPath)
|
||||
d.Set("link_to", image.LinkTo)
|
||||
d.Set("status", image.Status)
|
||||
d.Set("tech_status", image.TechStatus)
|
||||
d.Set("version", image.Version)
|
||||
d.Set("size", image.Size)
|
||||
d.Set("enabled", image.Enabled)
|
||||
d.Set("computeci_id", image.ComputeciId)
|
||||
d.Set("pool_name", image.PoolName)
|
||||
d.Set("username", image.Username)
|
||||
d.Set("username_dl", image.UsernameDL)
|
||||
d.Set("password", image.Password)
|
||||
d.Set("password_dl", image.PasswordDL)
|
||||
d.Set("account_id", image.AccountId)
|
||||
d.Set("guid", image.Guid)
|
||||
d.Set("milestones", image.Milestones)
|
||||
d.Set("provider_name", image.ProviderName)
|
||||
d.Set("purge_attempts", image.PurgeAttempts)
|
||||
d.Set("reference_id", image.ReferenceId)
|
||||
d.Set("res_id", image.ResId)
|
||||
d.Set("res_name", image.ResName)
|
||||
d.Set("rescuecd", image.Rescuecd)
|
||||
d.Set("architecture", image.Architecture)
|
||||
d.Set("hot_resize", image.Hotresize)
|
||||
d.Set("history", flattenHistory(image.History))
|
||||
d.Set("last_modified", image.LastModified)
|
||||
d.Set("meta", flattenMeta(image.Meta))
|
||||
d.Set("desc", image.Desc)
|
||||
d.Set("shared_with", image.SharedWith)
|
||||
return
|
||||
}
|
||||
|
||||
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)
|
||||
image, err := utilityImageCheckPresence(d, m)
|
||||
if err != nil {
|
||||
|
||||
return err
|
||||
}
|
||||
d.SetId(strconv.Itoa(image.Guid))
|
||||
flattenImage(d, image)
|
||||
|
||||
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
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceImageSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Name of the rescue disk",
|
||||
},
|
||||
"url": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "URL where to download media from",
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "grid (platform) ID where this template should be create in",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Boot type of image bios or uefi",
|
||||
},
|
||||
"image_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image type linux, windows or other",
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
|
||||
},
|
||||
"meta": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "meta",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
},
|
||||
"username_dl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "username for upload binary media",
|
||||
},
|
||||
"password_dl": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "password for upload binary media",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
|
||||
},
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "image id",
|
||||
},
|
||||
"permanently": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Whether to completely delete the image",
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
Description: "Does this image boot OS",
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "unc path",
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "status",
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "tech atatus",
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "version",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "image size",
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"computeci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"reference_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"res_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
|
||||
// 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 {
|
||||
@@ -89,57 +307,6 @@ func dataSourceImage() *schema.Resource {
|
||||
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.",
|
||||
},
|
||||
},
|
||||
Schema: dataSourceImageSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
140
decort/data_source_image_list.go
Normal file
140
decort/data_source_image_list.go
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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 (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func flattenImageList(il ImageList) []map[string]interface{} {
|
||||
res := make([]map[string]interface{}, 0)
|
||||
for _, item := range il {
|
||||
temp := map[string]interface{}{
|
||||
"name": item.Name,
|
||||
"url": item.Url,
|
||||
"gid": item.Gid,
|
||||
"guid": item.Guid,
|
||||
"drivers": item.Drivers,
|
||||
"image_id": item.ImageId,
|
||||
"boot_type": item.Boottype,
|
||||
"bootable": item.Bootable,
|
||||
"image_type": item.Imagetype,
|
||||
"status": item.Status,
|
||||
"tech_status": item.TechStatus,
|
||||
"version": item.Version,
|
||||
"username": item.Username,
|
||||
"username_dl": item.UsernameDL,
|
||||
"password": item.Password,
|
||||
"password_dl": item.PasswordDL,
|
||||
"purge_attempts": item.PurgeAttempts,
|
||||
"architecture": item.Architecture,
|
||||
"account_id": item.AccountId,
|
||||
"computeci_id": item.ComputeciId,
|
||||
"enabled": item.Enabled,
|
||||
"reference_id": item.ReferenceId,
|
||||
"res_id": item.ResId,
|
||||
"res_name": item.ResName,
|
||||
"rescuecd": item.Rescuecd,
|
||||
"provider_name": item.ProviderName,
|
||||
"milestones": item.Milestones,
|
||||
"size": item.Size,
|
||||
"sep_id": item.SepId,
|
||||
"link_to": item.LinkTo,
|
||||
"unc_path": item.UNCPath,
|
||||
"pool_name": item.PoolName,
|
||||
"hot_resize": item.Hotresize,
|
||||
"history": flattenHistory(item.History),
|
||||
"last_modified": item.LastModified,
|
||||
"meta": flattenMeta(item.Meta),
|
||||
"desc": item.Desc,
|
||||
"shared_with": item.SharedWith,
|
||||
}
|
||||
res = append(res, temp)
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
||||
func dataSourceImageListRead(d *schema.ResourceData, m interface{}) error {
|
||||
imageList, err := utilityImageListCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("items", flattenImageList(imageList))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceImageListSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "filter images by storage endpoint provider ID",
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "filter images by account ID availability",
|
||||
},
|
||||
"page": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "page number",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "page size",
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Description: "image list",
|
||||
Elem: &schema.Resource{
|
||||
Schema: dataSourceImageSchemaMake(),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return rets
|
||||
}
|
||||
|
||||
func dataSourceImageList() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourceImageListRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceImageListSchemaMake(),
|
||||
}
|
||||
}
|
||||
182
decort/data_source_image_list_stacks.go
Normal file
182
decort/data_source_image_list_stacks.go
Normal file
@@ -0,0 +1,182 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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 (
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func flattenImageListStacks(d *schema.ResourceData, stack ImageListStacks) []map[string]interface{} {
|
||||
temp := make([]map[string]interface{}, 0)
|
||||
for _, item := range stack {
|
||||
t := map[string]interface{}{
|
||||
"api_url": item.ApiURL,
|
||||
"api_key": item.ApiKey,
|
||||
"app_id": item.AppId,
|
||||
"desc": item.Desc,
|
||||
"drivers": item.Drivers,
|
||||
"error": item.Error,
|
||||
"guid": item.Guid,
|
||||
"id": item.Id,
|
||||
"images": item.Images,
|
||||
"login": item.Login,
|
||||
"name": item.Name,
|
||||
"passwd": item.Passwd,
|
||||
"reference_id": item.ReferenceId,
|
||||
"status": item.Status,
|
||||
"type": item.Type,
|
||||
}
|
||||
|
||||
temp = append(temp, t)
|
||||
}
|
||||
return temp
|
||||
}
|
||||
|
||||
func dataSourceImageListStacksRead(d *schema.ResourceData, m interface{}) error {
|
||||
imageListStacks, err := utilityImageListStacksCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
d.Set("items", flattenImageListStacks(d, imageListStacks))
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourceImageListStackSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"api_url": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"api_key": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"app_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"error": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"images": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"login": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"passwd": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"reference_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceImageListStacksSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "image id",
|
||||
},
|
||||
"page": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "page number",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "page size",
|
||||
},
|
||||
"items": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: dataSourceImageListStackSchemaMake(),
|
||||
},
|
||||
Description: "items of stacks list",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func dataSourceImageListStacks() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourceImageListStacksRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: dataSourceImageListStacksSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -51,12 +51,14 @@ func flattenVins(d *schema.ResourceData, vins_facts string) error {
|
||||
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)
|
||||
err = d.Set("rg_id", vinsRecord.RgID)
|
||||
d.Set("description", vinsRecord.Desc)
|
||||
d.Set("ipcidr", vinsRecord.IPCidr)
|
||||
|
||||
noExtNetConnection := true
|
||||
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)
|
||||
@@ -69,10 +71,16 @@ func flattenVins(d *schema.ResourceData, vins_facts string) error {
|
||||
} else {
|
||||
return fmt.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.")
|
||||
}
|
||||
noExtNetConnection = false
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if noExtNetConnection {
|
||||
d.Set("ext_ip_addr", "")
|
||||
d.Set("ext_net_id", 0)
|
||||
}
|
||||
|
||||
log.Debugf("flattenVins: EXTRA CHECK - schema rg_id=%d, ext_net_id=%d", d.Get("rg_id").(int), d.Get("ext_net_id").(int))
|
||||
|
||||
return nil
|
||||
@@ -104,7 +112,7 @@ func dataSourceVins() *schema.Resource {
|
||||
Schema: map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Required: true,
|
||||
Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.",
|
||||
},
|
||||
|
||||
|
||||
@@ -44,6 +44,7 @@ func diskSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the account this disk belongs to.",
|
||||
},
|
||||
|
||||
|
||||
@@ -25,6 +25,9 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
|
||||
package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
@@ -33,6 +36,7 @@ import (
|
||||
var Timeout30s = time.Second * 30
|
||||
var Timeout60s = time.Second * 60
|
||||
var Timeout180s = time.Second * 180
|
||||
var Timeout20m = time.Minute * 20
|
||||
|
||||
//
|
||||
// structures related to /cloudapi/rg/list API
|
||||
@@ -105,12 +109,12 @@ type ResgroupUpdateParam struct {
|
||||
// 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
|
||||
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
|
||||
@@ -130,27 +134,27 @@ type UsageRecord struct {
|
||||
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"`
|
||||
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:"-"`
|
||||
}
|
||||
@@ -187,20 +191,24 @@ 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"`
|
||||
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"
|
||||
const ComputeStopAPI = "/restmachine/cloudapi/compute/stop"
|
||||
|
||||
// structures related to cloudapi/compute/delete API
|
||||
const ComputeDeleteAPI = "/restmachine/cloudapi/compute/delete"
|
||||
|
||||
@@ -268,14 +276,14 @@ type ComputeRecord struct {
|
||||
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"`
|
||||
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"
|
||||
@@ -299,7 +307,7 @@ 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
|
||||
AccountName string `json:"accountName"` // NOTE: absent from compute/get output
|
||||
BootPartition int `json:"bootPartition"`
|
||||
CreatedTime uint64 `json:"creationTime"`
|
||||
DeletedTime uint64 `json:"deletionTime"`
|
||||
@@ -322,7 +330,7 @@ type DiskRecord struct {
|
||||
PurgeTime uint64 `json:"purgeTime"`
|
||||
// Role string `json:"role"`
|
||||
SepType string `json:"sepType"`
|
||||
SepID int `json:"sepId"` // NOTE: absent from compute/get output
|
||||
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"`
|
||||
@@ -352,6 +360,7 @@ type ComputeGetResp struct {
|
||||
Cpu int `json:"cpus"`
|
||||
Desc string `json:"desc"`
|
||||
Disks []DiskRecord `json:"disks"`
|
||||
Driver string `json:"driver"`
|
||||
GridID int `json:"gid"`
|
||||
ID uint `json:"id"`
|
||||
ImageID int `json:"imageId"`
|
||||
@@ -373,14 +382,14 @@ type ComputeGetResp struct {
|
||||
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"`
|
||||
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"`
|
||||
}
|
||||
|
||||
//
|
||||
@@ -465,11 +474,12 @@ 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
|
||||
ID int
|
||||
Type string
|
||||
IPAddress string
|
||||
MAC string
|
||||
}
|
||||
|
||||
const ComputeNetAttachAPI = "/restmachine/cloudapi/compute/netAttach"
|
||||
|
||||
const ComputeNetDetachAPI = "/restmachine/cloudapi/compute/netDetach"
|
||||
@@ -509,68 +519,164 @@ const DisksRenameAPI = "/restmachine/cloudapi/disks/rename"
|
||||
//
|
||||
const DisksDeleteAPI = "/restmachine/cloudapi/disks/delete"
|
||||
|
||||
|
||||
//
|
||||
// ViNS structures
|
||||
// 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"`
|
||||
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
|
||||
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"`
|
||||
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"`
|
||||
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 VinsCreateAPI = "/restmachine/cloudapi/vins/create"
|
||||
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"
|
||||
|
||||
//
|
||||
// K8s structures
|
||||
//
|
||||
|
||||
//K8sNodeRecord represents a worker/master group
|
||||
type K8sNodeRecord struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Disk int `json:"disk"`
|
||||
Cpu int `json:"cpu"`
|
||||
Num int `json:"num"`
|
||||
Ram int `json:"ram"`
|
||||
DetailedInfo []struct {
|
||||
ID int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
} `json:"detailedInfo"`
|
||||
}
|
||||
|
||||
//K8sRecord represents k8s instance
|
||||
type K8sRecord struct {
|
||||
AccountID int `json:"accountId"`
|
||||
AccountName string `json:"accountName"`
|
||||
CI int `json:"ciId"`
|
||||
ID int `json:"id"`
|
||||
Groups struct {
|
||||
Masters K8sNodeRecord `json:"masters"`
|
||||
Workers []K8sNodeRecord `json:"workers"`
|
||||
} `json:"k8sGroups"`
|
||||
Name string `json:"name"`
|
||||
RgID int `json:"rgId"`
|
||||
RgName string `json:"rgName"`
|
||||
}
|
||||
|
||||
const K8sCreateAPI = "/restmachine/cloudapi/k8s/create"
|
||||
const K8sGetAPI = "/restmachine/cloudapi/k8s/get"
|
||||
const K8sUpdateAPI = "/restmachine/cloudapi/k8s/update"
|
||||
const K8sDeleteAPI = "/restmachine/cloudapi/k8s/delete"
|
||||
|
||||
const K8sWgCreateAPI = "/restmachine/cloudapi/k8s/workersGroupAdd"
|
||||
const K8sWgDeleteAPI = "/restmachine/cloudapi/k8s/workersGroupDelete"
|
||||
|
||||
const K8sWorkerAddAPI = "/restmachine/cloudapi/k8s/workerAdd"
|
||||
const K8sWorkerDeleteAPI = "/restmachine/cloudapi/k8s/deleteWorkerFromGroup"
|
||||
|
||||
const K8sGetConfigAPI = "/restmachine/cloudapi/k8s/getConfig"
|
||||
|
||||
//Blasphemous workaround for parsing Result value
|
||||
type TaskResult int
|
||||
|
||||
func (r *TaskResult) UnmarshalJSON(b []byte) error {
|
||||
if b[0] == '"' {
|
||||
b := b[1 : len(b)-1]
|
||||
if len(b) == 0 {
|
||||
*r = 0
|
||||
return nil
|
||||
}
|
||||
n, err := strconv.Atoi(string(b))
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
*r = TaskResult(n)
|
||||
} else if b[0] == '[' {
|
||||
res := []interface{}{}
|
||||
if err := json.Unmarshal(b, &res); err != nil {
|
||||
return err
|
||||
}
|
||||
if n, ok := res[0].(float64); ok {
|
||||
*r = TaskResult(n)
|
||||
} else {
|
||||
return fmt.Errorf("could not unmarshal %v into int", res[0])
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
//AsyncTask represents a long task completion status
|
||||
type AsyncTask struct {
|
||||
AuditID string `json:"auditId"`
|
||||
Completed bool `json:"completed"`
|
||||
Error string `json:"error"`
|
||||
Log []string `json:"log"`
|
||||
Result TaskResult `json:"result"`
|
||||
Stage string `json:"stage"`
|
||||
Status string `json:"status"`
|
||||
UpdateTime uint64 `json:"updateTime"`
|
||||
UpdatedTime uint64 `json:"updatedTime"`
|
||||
}
|
||||
|
||||
const AsyncTaskGetAPI = "/restmachine/cloudapi/tasks/get"
|
||||
|
||||
//
|
||||
// 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"`
|
||||
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
|
||||
@@ -584,3 +690,112 @@ type SshKeyConfig struct {
|
||||
SshKey string
|
||||
UserShell string
|
||||
}
|
||||
|
||||
////////////////////
|
||||
// IMAGE API //
|
||||
////////////////////
|
||||
const imageCreateAPI = "/restmachine/cloudbroker/image/createImage"
|
||||
const imageSyncCreateAPI = "/restmachine/cloudbroker/image/syncCreateImage"
|
||||
const imageCreateVirtualAPI = "/restmachine/cloudbroker/image/createVirtual"
|
||||
const imageCreateCDROMAPI = "/restmachine/cloudbroker/image/createCDROMImage"
|
||||
const imageListStacksApi = "/restmachine/cloudbroker/image/listStacks"
|
||||
const imageGetAPI = "/restmachine/cloudbroker/image/get"
|
||||
const imageListGetAPI = "/restmachine/cloudbroker/image/list"
|
||||
const imageEditAPI = "/restmachine/cloudbroker/image/edit"
|
||||
const imageDeleteAPI = "/restmachine/cloudbroker/image/delete"
|
||||
const imageDeleteCDROMAPI = "/restmachine/cloudbroker/image/deleteCDROMImage"
|
||||
const imageEnableAPI = "/restmachine/cloudbroker/image/enable"
|
||||
const imageDisableAPI = "/restmachine/cloudbroker/image/disable"
|
||||
const imageEditNameAPI = "/restmachine/cloudbroker/image/rename"
|
||||
const imageLinkAPI = "/restmachine/cloudbroker/image/link"
|
||||
const imageShareAPI = "/restmachine/cloudbroker/image/share"
|
||||
const imageComputeciSetAPI = "/restmachine/cloudbroker/image/computeciSet"
|
||||
const imageComputeciUnsetAPI = "/restmachine/cloudbroker/image/computeciUnset"
|
||||
const imageUpdateNodesAPI = "/restmachine/cloudbroker/image/updateNodes"
|
||||
const imageDeleteImagesAPI = "/restmachine/cloudbroker/image/deleteImages"
|
||||
|
||||
type History struct {
|
||||
Guid string `json:"guid"`
|
||||
Id int `json:"id"`
|
||||
Timestamp int64 `json:"timestamp"`
|
||||
}
|
||||
|
||||
type Image struct {
|
||||
ImageId int `json:"id"`
|
||||
Name string `json:"name"`
|
||||
Url string `json:"url"`
|
||||
Gid int `json:"gid"`
|
||||
Guid int `json:"guid"`
|
||||
Boottype string `json:"bootType"`
|
||||
Imagetype string `json:"type"`
|
||||
Drivers []string `json:"drivers"`
|
||||
Hotresize bool `json:"hotResize"`
|
||||
Bootable bool `json:"bootable"`
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
AccountId int `json:"accountId"`
|
||||
UsernameDL string `json:"usernameDL"`
|
||||
PasswordDL string `json:"passwordDL"`
|
||||
SepId int `json:"sepId"`
|
||||
PoolName string `json:"pool"`
|
||||
Architecture string `json:"architecture"`
|
||||
UNCPath string `json:"UNCPath"`
|
||||
LinkTo int `json:"linkTo"`
|
||||
Status string `json:"status"`
|
||||
TechStatus string `json:"techStatus"`
|
||||
Size int `json:"size"`
|
||||
Version string `json:"version"`
|
||||
Enabled bool `json:"enabled"`
|
||||
ComputeciId int `json:"computeciId"`
|
||||
Milestones int `json:"milestones"`
|
||||
ProviderName string `json:"provider_name"`
|
||||
PurgeAttempts int `json:"purgeAttempts"`
|
||||
ReferenceId string `json:"referenceId"`
|
||||
ResId string `json:"resId"`
|
||||
ResName string `json:"resName"`
|
||||
Rescuecd bool `json:"rescuecd"`
|
||||
Meta []interface{} `json:"_meta"`
|
||||
History []History `json:"history"`
|
||||
LastModified int64 `json:"lastModified"`
|
||||
Desc string `json:"desc"`
|
||||
SharedWith []int `json:"sharedWith"`
|
||||
}
|
||||
|
||||
type ImageList []Image
|
||||
|
||||
type ImageStack struct {
|
||||
ApiURL string `json:"apiUrl"`
|
||||
ApiKey string `json:"apikey"`
|
||||
AppId string `json:"appId"`
|
||||
Desc string `json:"desc"`
|
||||
Drivers []string `json:"drivers"`
|
||||
Error int `json:"error"`
|
||||
Guid int `json:"guid"`
|
||||
Id int `json:"id"`
|
||||
Images []int `json:"images"`
|
||||
Login string `json:"login"`
|
||||
Name string `json:"name"`
|
||||
Passwd string `json:"passwd"`
|
||||
ReferenceId string `json:"referenceId"`
|
||||
Status string `json:"status"`
|
||||
Type string `json:"type"`
|
||||
}
|
||||
|
||||
type ImageListStacks []ImageStack
|
||||
|
||||
/////////////////
|
||||
// GRID API //
|
||||
/////////////////
|
||||
const GridListGetAPI = "/restmachine/cloudbroker/grid/list"
|
||||
const GridGetAPI = "/restmachine/cloudbroker/grid/get"
|
||||
|
||||
type Grid struct {
|
||||
Flag string `json:"flag"`
|
||||
Gid int `json:"gid"`
|
||||
Guid int `json:"guid"`
|
||||
Id int `json:"id"`
|
||||
LocationCode string `json:"locationCode"`
|
||||
Name string `json:"name"`
|
||||
}
|
||||
|
||||
type GridList []Grid
|
||||
|
||||
@@ -21,11 +21,15 @@ import (
|
||||
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
"bytes"
|
||||
"hash/fnv"
|
||||
log "github.com/sirupsen/logrus"
|
||||
// "net/url"
|
||||
"sort"
|
||||
|
||||
"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
|
||||
@@ -39,6 +43,71 @@ func networkSubresIPAddreDiffSupperss(key, oldVal, newVal string, d *schema.Reso
|
||||
return true // suppress difference
|
||||
}
|
||||
|
||||
// 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
|
||||
// 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{})
|
||||
|
||||
var keys []string
|
||||
allComputed := true
|
||||
|
||||
for k, val := range rs {
|
||||
if val.Optional || val.Required {
|
||||
allComputed = false
|
||||
}
|
||||
|
||||
keys = append(keys, k)
|
||||
}
|
||||
|
||||
sort.Strings(keys)
|
||||
for _, k := range keys {
|
||||
// explicitly ignore "ip_address" when hashing
|
||||
if k == "ip_address" {
|
||||
continue
|
||||
}
|
||||
|
||||
subSchema := rs[k]
|
||||
// Skip attributes that are not user-provided. Computed attributes
|
||||
// do not contribute to the hash since their ultimate value cannot
|
||||
// be known at plan/diff time.
|
||||
if !allComputed && !(subSchema.Required || subSchema.Optional) {
|
||||
continue
|
||||
}
|
||||
|
||||
output.WriteString(k)
|
||||
output.WriteRune(':')
|
||||
value := m[k]
|
||||
schema.SerializeValueForHash(output, value, subSchema)
|
||||
}
|
||||
}
|
||||
|
||||
// HashNetworkSubresource hashes network subresource of compute resource. It uses
|
||||
// specially designed networkSubresourceSerialize (see above) to make sure hashing
|
||||
// does not involve attributes that we deem irrelevant to the uniqueness of network
|
||||
// subresource definitions.
|
||||
// It is this function that should be specified as SchemaSetFunc when creating Set
|
||||
// from network subresource (e.g. in flattenCompute)
|
||||
//
|
||||
// This function is based on the original Terraform function HashResource from
|
||||
// helper/schema/set.go
|
||||
func HashNetworkSubresource(resource *schema.Resource) schema.SchemaSetFunc {
|
||||
return func(v interface{}) int {
|
||||
var serialized bytes.Buffer
|
||||
networkSubresourceSerialize(&serialized, v, resource)
|
||||
|
||||
hs := fnv.New32a()
|
||||
hs.Write(serialized.Bytes())
|
||||
return int(hs.Sum32())
|
||||
}
|
||||
}
|
||||
|
||||
func networkSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"net_type": {
|
||||
@@ -58,6 +127,7 @@ func networkSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
"ip_address": {
|
||||
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.",
|
||||
},
|
||||
|
||||
98
decort/node_subresource.go
Normal file
98
decort/node_subresource.go
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
|
||||
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 "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
|
||||
func nodeMasterDefault() K8sNodeRecord {
|
||||
return K8sNodeRecord{
|
||||
Num: 1,
|
||||
Cpu: 2,
|
||||
Ram: 2048,
|
||||
Disk: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func nodeWorkerDefault() K8sNodeRecord {
|
||||
return K8sNodeRecord{
|
||||
Num: 1,
|
||||
Cpu: 1,
|
||||
Ram: 1024,
|
||||
Disk: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func parseNode(nodeList []interface{}) K8sNodeRecord {
|
||||
node := nodeList[0].(map[string]interface{})
|
||||
|
||||
return K8sNodeRecord{
|
||||
Num: node["num"].(int),
|
||||
Cpu: node["cpu"].(int),
|
||||
Ram: node["ram"].(int),
|
||||
Disk: node["disk"].(int),
|
||||
}
|
||||
}
|
||||
|
||||
func nodeToResource(node K8sNodeRecord) []interface{} {
|
||||
mp := make(map[string]interface{})
|
||||
|
||||
mp["num"] = node.Num
|
||||
mp["cpu"] = node.Cpu
|
||||
mp["ram"] = node.Ram
|
||||
mp["disk"] = node.Disk
|
||||
|
||||
return []interface{}{mp}
|
||||
}
|
||||
|
||||
func nodeK8sSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"num": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "Number of nodes to create.",
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Node CPU count.",
|
||||
},
|
||||
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Node RAM in MB.",
|
||||
},
|
||||
|
||||
"disk": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Node boot disk size in GB.",
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -27,9 +27,9 @@ import (
|
||||
func parseOsUsers(logins []OsUserRecord) []interface{} {
|
||||
var result = make([]interface{}, len(logins))
|
||||
|
||||
elem := make(map[string]interface{})
|
||||
|
||||
for index, value := range logins {
|
||||
elem := make(map[string]interface{})
|
||||
|
||||
elem["guid"] = value.Guid
|
||||
elem["login"] = value.Login
|
||||
elem["password"] = value.Password
|
||||
|
||||
@@ -99,20 +99,30 @@ func Provider() *schema.Provider {
|
||||
},
|
||||
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"decort_resgroup": resourceResgroup(),
|
||||
"decort_kvmvm": resourceCompute(),
|
||||
"decort_disk": resourceDisk(),
|
||||
// "decort_vins": resourceVins(),
|
||||
// "decort_pfw": resourcePfw(),
|
||||
"decort_resgroup": resourceResgroup(),
|
||||
"decort_kvmvm": resourceCompute(),
|
||||
"decort_disk": resourceDisk(),
|
||||
"decort_vins": resourceVins(),
|
||||
"decort_pfw": resourcePfw(),
|
||||
"decort_k8s": resourceK8s(),
|
||||
"decort_k8s_wg": resourceK8sWg(),
|
||||
"decort_image": resourceImage(),
|
||||
"decort_virtual_image": resourceVirtualImage(),
|
||||
"decort_cdrom_image": resourceCDROMImage(),
|
||||
"decort_delete_images": resourceDeleteImages(),
|
||||
},
|
||||
|
||||
DataSourcesMap: map[string]*schema.Resource{
|
||||
"decort_account": dataSourceAccount(),
|
||||
"decort_resgroup": dataSourceResgroup(),
|
||||
"decort_kvmvm": dataSourceCompute(),
|
||||
"decort_image": dataSourceImage(),
|
||||
"decort_disk": dataSourceDisk(),
|
||||
"decort_vins": dataSourceVins(),
|
||||
"decort_account": dataSourceAccount(),
|
||||
"decort_resgroup": dataSourceResgroup(),
|
||||
"decort_kvmvm": dataSourceCompute(),
|
||||
"decort_image": dataSourceImage(),
|
||||
"decort_disk": dataSourceDisk(),
|
||||
"decort_vins": dataSourceVins(),
|
||||
"decort_grid": dataSourceGrid(),
|
||||
"decort_grid_list": dataSourceGridList(),
|
||||
"decort_image_list": dataSourceImageList(),
|
||||
"decort_image_list_stacks": dataSourceImageListStacks(),
|
||||
// "decort_pfw": dataSourcePfw(),
|
||||
},
|
||||
|
||||
|
||||
449
decort/resource_cdrom_image.go
Normal file
449
decort/resource_cdrom_image.go
Normal file
@@ -0,0 +1,449 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
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 (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/customdiff"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceCDROMImageCreate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceCDROMImageCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("url", d.Get("url").(string))
|
||||
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
|
||||
|
||||
tstr := d.Get("drivers").([]interface{})
|
||||
temp := ""
|
||||
l := len(tstr)
|
||||
for i, str := range tstr {
|
||||
s := "\"" + str.(string) + "\""
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("drivers", temp)
|
||||
|
||||
if username, ok := d.GetOk("username"); ok {
|
||||
urlValues.Add("username", username.(string))
|
||||
}
|
||||
if password, ok := d.GetOk("password"); ok {
|
||||
urlValues.Add("password", password.(string))
|
||||
}
|
||||
if accountId, ok := d.GetOk("account_id"); ok {
|
||||
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
||||
}
|
||||
if usernameDL, ok := d.GetOk("username_dl"); ok {
|
||||
urlValues.Add("usernameDL", usernameDL.(string))
|
||||
}
|
||||
if passwordDL, ok := d.GetOk("password_dl"); ok {
|
||||
urlValues.Add("passwordDL", passwordDL.(string))
|
||||
}
|
||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
|
||||
}
|
||||
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||
urlValues.Add("pool_name", poolName.(string))
|
||||
}
|
||||
if architecture, ok := d.GetOk("architecture"); ok {
|
||||
urlValues.Add("architecture", architecture.(string))
|
||||
}
|
||||
|
||||
imageId, err := controller.decortAPICall("POST", imageCreateCDROMAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(imageId)
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
image, err := utilityImageCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(image.ImageId))
|
||||
d.Set("bootable", image.Bootable)
|
||||
//d.Set("image_id", image.ImageId)
|
||||
|
||||
err = resourceImageRead(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCDROMImageDelete(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceCDROMImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
image, err := utilityImageCheckPresence(d, m)
|
||||
if image == nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
|
||||
if permanently, ok := d.GetOk("permanently"); ok {
|
||||
urlValues.Add("permanently", strconv.FormatBool(permanently.(bool)))
|
||||
}
|
||||
|
||||
_, err = controller.decortAPICall("POST", imageDeleteCDROMAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceCDROMImageSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
},
|
||||
"url": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "URL where to download ISO from",
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "grid (platform) ID where this template should be create in",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Boot type of image bios or uefi",
|
||||
},
|
||||
"image_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image type linux, windows or other",
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
|
||||
},
|
||||
"meta": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "meta",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
},
|
||||
"username_dl": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "username for upload binary media",
|
||||
},
|
||||
"password_dl": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "password for upload binary media",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
|
||||
},
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "image id",
|
||||
},
|
||||
"permanently": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Whether to completely delete the image",
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this image boot OS",
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "unc path",
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "status",
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "tech atatus",
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "version",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "image size",
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"computeci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"reference_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"res_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"enabled_stacks": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceCDROMImage() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceCDROMImageCreate,
|
||||
Read: resourceImageRead,
|
||||
Update: resourceImageEdit,
|
||||
Delete: resourceCDROMImageDelete,
|
||||
Exists: resourceImageExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout60s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout60s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
CustomizeDiff: customdiff.All(
|
||||
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
|
||||
if old.(bool) != new.(bool) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageChangeEnabled),
|
||||
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
|
||||
if old.(string) != new.(string) && old.(string) != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageEditName),
|
||||
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
|
||||
o := old.([]interface{})
|
||||
n := new.([]interface{})
|
||||
|
||||
if len(o) != len(n) {
|
||||
return true
|
||||
} else if len(o) == 0 {
|
||||
return false
|
||||
}
|
||||
count := 0
|
||||
for i, v := range n {
|
||||
if v.(int) == o[i].(int) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageShare),
|
||||
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
|
||||
if old.(int) != new.(int) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageChangeComputeci),
|
||||
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
|
||||
o := old.([]interface{})
|
||||
n := new.([]interface{})
|
||||
|
||||
if len(o) != len(n) {
|
||||
return true
|
||||
} else if len(o) == 0 {
|
||||
return false
|
||||
}
|
||||
count := 0
|
||||
for i, v := range n {
|
||||
if v.(string) == o[i].(string) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageUpdateNodes),
|
||||
),
|
||||
|
||||
Schema: resourceCDROMImageSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
|
||||
package decort
|
||||
|
||||
import (
|
||||
// "encoding/json"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
@@ -36,16 +36,29 @@ import (
|
||||
"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
|
||||
// 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)
|
||||
d.Partial(true)
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", d.Get("rg_id").(int)))
|
||||
@@ -55,29 +68,40 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
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", "false") // at the 1st step create compute in a stopped state
|
||||
urlValues.Add("start", "0") // at the 1st step create compute in a stopped state
|
||||
|
||||
argVal, argSet := d.GetOk("description")
|
||||
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{})))
|
||||
}
|
||||
/*
|
||||
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" {
|
||||
driver := d.Get("driver").(string)
|
||||
if driver == "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
|
||||
@@ -92,21 +116,23 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
d.SetPartial("ram")
|
||||
d.SetPartial("image_id")
|
||||
d.SetPartial("boot_disk_size")
|
||||
if sshKeysSet {
|
||||
d.SetPartial("ssh_keys")
|
||||
}
|
||||
/*
|
||||
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 && len(argVal.([]interface{})) > 0 {
|
||||
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)", len(argVal.([]interface{})))
|
||||
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 disks to a new Compute ID %s: %s", compId, err)
|
||||
log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %s: %s", compId, err)
|
||||
extraDisksOk = false
|
||||
}
|
||||
}
|
||||
@@ -116,9 +142,9 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
// Configure external networks if any
|
||||
netsOk := true
|
||||
argVal, argSet = d.GetOk("network")
|
||||
if argSet && len(argVal.([]interface{})) > 0 {
|
||||
log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", len(argVal.([]interface{})))
|
||||
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)
|
||||
@@ -134,14 +160,26 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
// 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
|
||||
if d.Get("started").(bool) {
|
||||
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
|
||||
// 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
|
||||
// Compute read function will also update resource ID on success, so that Terraform
|
||||
// will know the resource exists
|
||||
return dataSourceComputeRead(d, m)
|
||||
return dataSourceComputeRead(d, m)
|
||||
}
|
||||
|
||||
func resourceComputeRead(d *schema.ResourceData, m interface{}) error {
|
||||
@@ -173,11 +211,12 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
|
||||
/*
|
||||
1. Resize CPU/RAM
|
||||
2. Resize (grow) boot disk
|
||||
3. Update extra disks
|
||||
4. Update networks
|
||||
/*
|
||||
1. Resize CPU/RAM
|
||||
2. Resize (grow) boot disk
|
||||
3. Update extra disks
|
||||
4. Update networks
|
||||
5. Start/stop
|
||||
*/
|
||||
|
||||
// 1. Resize CPU/RAM
|
||||
@@ -194,7 +233,7 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
} 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)))
|
||||
@@ -205,8 +244,8 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
if doUpdate {
|
||||
log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d",
|
||||
oldCpu.(int), newCpu.(int),
|
||||
oldRam.(int), newRam.(int))
|
||||
oldCpu.(int), newCpu.(int),
|
||||
oldRam.(int), newRam.(int))
|
||||
_, err := controller.decortAPICall("POST", ComputeResizeAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -215,14 +254,14 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
d.SetPartial("ram")
|
||||
}
|
||||
|
||||
// 2. Resize (grow) Boot disk
|
||||
// 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))
|
||||
d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int))
|
||||
_, err := controller.decortAPICall("POST", DisksResizeAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -248,17 +287,33 @@ func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
d.SetPartial("network")
|
||||
}
|
||||
|
||||
if d.HasChange("started") {
|
||||
params := &url.Values{}
|
||||
params.Add("computeId", d.Id())
|
||||
if d.Get("started").(bool) {
|
||||
if _, err := controller.decortAPICall("POST", ComputeStartAPI, params); err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
if _, err := controller.decortAPICall("POST", ComputeStopAPI, params); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
d.SetPartial("started")
|
||||
}
|
||||
|
||||
d.Partial(false)
|
||||
|
||||
// we may reuse dataSourceComputeRead here as we maintain similarity
|
||||
// we may reuse dataSourceComputeRead here as we maintain similarity
|
||||
// between Compute resource and Compute data source schemas
|
||||
return dataSourceComputeRead(d, m)
|
||||
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. It also destroys all extra disks
|
||||
// attached to this compute, so "User, ye be warned!"
|
||||
// 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))
|
||||
|
||||
@@ -269,11 +324,39 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) 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", "true")
|
||||
params.Add("permanently", "1")
|
||||
// TODO: this is for the upcoming API update - params.Add("detachdisks", "1")
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
_, err = controller.decortAPICall("POST", ComputeDeleteAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
@@ -284,7 +367,7 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
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 %q, RG ID %d",
|
||||
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)
|
||||
@@ -333,13 +416,13 @@ func resourceCompute() *schema.Resource {
|
||||
Description: "ID of the resource group where this compute should be deployed.",
|
||||
},
|
||||
|
||||
"arch": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
StateFunc: stateFuncToUpper,
|
||||
"driver": {
|
||||
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.",
|
||||
Description: "Hardware architecture of this compute instance.",
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
@@ -357,20 +440,21 @@ func resourceCompute() *schema.Resource {
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "ID of the OS image to base this compute instance on.",
|
||||
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,
|
||||
Optional: true,
|
||||
Description: "This compute instance boot disk size in GB.",
|
||||
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.TypeList,
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
MaxItems: MaxExtraDisksPerCompute,
|
||||
Elem: &schema.Schema{
|
||||
@@ -380,7 +464,7 @@ func resourceCompute() *schema.Resource {
|
||||
},
|
||||
|
||||
"network": {
|
||||
Type: schema.TypeList,
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
MaxItems: MaxNetworksPerCompute,
|
||||
Elem: &schema.Resource{
|
||||
@@ -389,20 +473,30 @@ func resourceCompute() *schema.Resource {
|
||||
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(),
|
||||
/*
|
||||
"ssh_keys": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: MaxSshKeysPerCompute,
|
||||
Elem: &schema.Resource{
|
||||
Schema: sshSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "SSH keys to authorize on this compute instance.",
|
||||
},
|
||||
Description: "SSH keys to authorize on this compute instance.",
|
||||
},
|
||||
*/
|
||||
|
||||
"description": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "Description of this compute instance.",
|
||||
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
|
||||
@@ -439,37 +533,44 @@ func resourceCompute() *schema.Resource {
|
||||
Description: "Guest OS users provisioned on this compute instance.",
|
||||
},
|
||||
|
||||
"started": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: true,
|
||||
Description: "Is compute started.",
|
||||
},
|
||||
|
||||
/*
|
||||
"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
|
||||
"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).",
|
||||
},
|
||||
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(),
|
||||
"interfaces": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: interfaceSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Specification for the virtual NICs configured on this compute instance.",
|
||||
},
|
||||
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.",
|
||||
},
|
||||
"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.",
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Current technical status of this compute instance.",
|
||||
},
|
||||
*/
|
||||
},
|
||||
}
|
||||
|
||||
131
decort/resource_delete_images.go
Normal file
131
decort/resource_delete_images.go
Normal file
@@ -0,0 +1,131 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
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 (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceCreateListImages(d *schema.ResourceData, m interface{}) error {
|
||||
id := uuid.New()
|
||||
d.SetId(id.String())
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceDeleteListImages(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceDeleteListImages: start deleting...")
|
||||
|
||||
c := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
imageIds := d.Get("image_ids").([]interface{})
|
||||
temp := ""
|
||||
l := len(imageIds)
|
||||
for i, imageId := range imageIds {
|
||||
s := strconv.Itoa(imageId.(int))
|
||||
if i != (l - 1) {
|
||||
s += ",\n"
|
||||
} else {
|
||||
s += "\n"
|
||||
}
|
||||
temp = temp + s
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
|
||||
urlValues.Add("reason", d.Get("reason").(string))
|
||||
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
|
||||
urlValues.Add("imageIds", temp)
|
||||
|
||||
_, err := c.decortAPICall("POST", imageDeleteImagesAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceReadListImages(d *schema.ResourceData, m interface{}) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceDeleteImagesSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"image_ids": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
MinItems: 1,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
Description: "images ids for deleting",
|
||||
},
|
||||
"reason": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "reason for deleting the images",
|
||||
},
|
||||
"permanently": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Default: false,
|
||||
Description: "whether to completely delete the images",
|
||||
},
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func resourceDeleteImages() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceCreateListImages,
|
||||
Read: resourceReadListImages,
|
||||
Delete: resourceDeleteListImages,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout60s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout60s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: resourceDeleteImagesSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -46,7 +46,7 @@ func resourceDiskCreate(d *schema.ResourceData, m interface{}) error {
|
||||
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.Get("type").(string))
|
||||
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))
|
||||
|
||||
@@ -128,10 +128,14 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
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)
|
||||
|
||||
@@ -157,14 +161,14 @@ func resourceDiskDelete(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
params := &url.Values{}
|
||||
params.Add("diskId", d.Id())
|
||||
// NOTE: we are not force-detaching disk from a compute (if attached) this protecting
|
||||
// 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", "false")
|
||||
params.Add("permanently", "true")
|
||||
params.Add("detach", "0")
|
||||
params.Add("permanently", "1")
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
_, err = controller.decortAPICall("POST", DisksDeleteAPI, params)
|
||||
@@ -214,6 +218,7 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
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.",
|
||||
},
|
||||
|
||||
@@ -221,15 +226,19 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
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,
|
||||
@@ -238,6 +247,7 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
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,
|
||||
@@ -259,6 +269,12 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
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,
|
||||
@@ -274,24 +290,6 @@ func resourceDiskSchemaMake() map[string]*schema.Schema {
|
||||
},
|
||||
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.",
|
||||
},
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
738
decort/resource_image.go
Normal file
738
decort/resource_image.go
Normal file
@@ -0,0 +1,738 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
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 (
|
||||
"errors"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/customdiff"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceImageCreate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("url", d.Get("url").(string))
|
||||
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
|
||||
urlValues.Add("boottype", d.Get("boot_type").(string))
|
||||
urlValues.Add("imagetype", d.Get("image_type").(string))
|
||||
|
||||
tstr := d.Get("drivers").([]interface{})
|
||||
temp := ""
|
||||
l := len(tstr)
|
||||
for i, str := range tstr {
|
||||
s := "\"" + str.(string) + "\""
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("drivers", temp)
|
||||
|
||||
if hotresize, ok := d.GetOk("hot_resize"); ok {
|
||||
urlValues.Add("hotresize", strconv.FormatBool(hotresize.(bool)))
|
||||
}
|
||||
if username, ok := d.GetOk("username"); ok {
|
||||
urlValues.Add("username", username.(string))
|
||||
}
|
||||
if password, ok := d.GetOk("password"); ok {
|
||||
urlValues.Add("password", password.(string))
|
||||
}
|
||||
if accountId, ok := d.GetOk("account_id"); ok {
|
||||
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
||||
}
|
||||
if usernameDL, ok := d.GetOk("username_dl"); ok {
|
||||
urlValues.Add("usernameDL", usernameDL.(string))
|
||||
}
|
||||
if passwordDL, ok := d.GetOk("password_dl"); ok {
|
||||
urlValues.Add("passwordDL", passwordDL.(string))
|
||||
}
|
||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
|
||||
}
|
||||
if poolName, ok := d.GetOk("pool_name"); ok {
|
||||
urlValues.Add("poolName", poolName.(string))
|
||||
}
|
||||
if architecture, ok := d.GetOk("architecture"); ok {
|
||||
urlValues.Add("architecture", architecture.(string))
|
||||
}
|
||||
|
||||
api := ""
|
||||
isSync := d.Get("sync").(bool)
|
||||
if !isSync {
|
||||
api = imageCreateAPI
|
||||
} else {
|
||||
api = imageSyncCreateAPI
|
||||
}
|
||||
imageId, err := controller.decortAPICall("POST", api, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(imageId)
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
image, err := utilityImageCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(image.ImageId))
|
||||
d.Set("bootable", image.Bootable)
|
||||
//d.Set("image_id", image.ImageId)
|
||||
|
||||
err = resourceImageRead(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageRead(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageRead: called for %s id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
image, err := utilityImageCheckPresence(d, m)
|
||||
if image == nil {
|
||||
d.SetId("")
|
||||
return err
|
||||
}
|
||||
|
||||
d.Set("name", image.Name)
|
||||
d.Set("drivers", image.Drivers)
|
||||
d.Set("url", image.Url)
|
||||
d.Set("gid", image.Gid)
|
||||
d.Set("image_id", image.ImageId)
|
||||
d.Set("boot_type", image.Boottype)
|
||||
d.Set("image_type", image.Imagetype)
|
||||
d.Set("bootable", image.Bootable)
|
||||
d.Set("sep_id", image.SepId)
|
||||
d.Set("unc_path", image.UNCPath)
|
||||
d.Set("link_to", image.LinkTo)
|
||||
d.Set("status", image.Status)
|
||||
d.Set("tech_status", image.TechStatus)
|
||||
d.Set("version", image.Version)
|
||||
d.Set("size", image.Size)
|
||||
d.Set("enabled", image.Enabled)
|
||||
d.Set("computeci_id", image.ComputeciId)
|
||||
d.Set("pool_name", image.PoolName)
|
||||
d.Set("username", image.Username)
|
||||
d.Set("username_dl", image.UsernameDL)
|
||||
d.Set("password", image.Password)
|
||||
d.Set("password_dl", image.PasswordDL)
|
||||
d.Set("account_id", image.AccountId)
|
||||
d.Set("guid", image.Guid)
|
||||
d.Set("milestones", image.Milestones)
|
||||
d.Set("provider_name", image.ProviderName)
|
||||
d.Set("purge_attempts", image.PurgeAttempts)
|
||||
d.Set("reference_id", image.ReferenceId)
|
||||
d.Set("res_id", image.ResId)
|
||||
d.Set("res_name", image.ResName)
|
||||
d.Set("rescuecd", image.Rescuecd)
|
||||
d.Set("architecture", image.Architecture)
|
||||
d.Set("meta", flattenMeta(image.Meta))
|
||||
d.Set("hot_resize", image.Hotresize)
|
||||
d.Set("history", flattenHistory(image.History))
|
||||
d.Set("last_modified", image.LastModified)
|
||||
d.Set("desc", image.Desc)
|
||||
d.Set("shared_with", image.SharedWith)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageDelete(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
image, err := utilityImageCheckPresence(d, m)
|
||||
if image == nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
if reason, ok := d.GetOk("reason"); ok {
|
||||
urlValues.Add("reason", reason.(string))
|
||||
} else {
|
||||
urlValues.Add("reason", "")
|
||||
}
|
||||
if permanently, ok := d.GetOk("permanently"); ok {
|
||||
urlValues.Add("permanently", strconv.FormatBool(permanently.(bool)))
|
||||
}
|
||||
|
||||
_, err = controller.decortAPICall("POST", imageDeleteAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
d.SetId("")
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
log.Debugf("resourceImageExists: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
|
||||
image, err := utilityImageCheckPresence(d, m)
|
||||
if image == nil {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourceImageEditName(d *schema.ResourceDiff, m interface{}) error {
|
||||
log.Debugf("resourceImageEditName: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
_, err := c.decortAPICall("POST", imageEditNameAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageEdit(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
|
||||
urlValues.Add("username", d.Get("username").(string))
|
||||
urlValues.Add("password", d.Get("password").(string))
|
||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
||||
urlValues.Add("bootable", strconv.FormatBool(d.Get("bootable").(bool)))
|
||||
urlValues.Add("hotresize", strconv.FormatBool(d.Get("hot_resize").(bool)))
|
||||
|
||||
//_, err := c.decortAPICall("POST", imageEditAPI, urlValues)
|
||||
_, err := c.decortAPICall("POST", imageEditAPI, urlValues)
|
||||
if err != nil {
|
||||
err = resourceImageRead(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
err = resourceImageRead(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageChangeEnabled(d *schema.ResourceDiff, m interface{}) error {
|
||||
var api string
|
||||
|
||||
c := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
if d.Get("enabled").(bool) {
|
||||
api = imageEnableAPI
|
||||
} else {
|
||||
api = imageDisableAPI
|
||||
}
|
||||
resp, err := c.decortAPICall("POST", api, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
res, err := strconv.ParseBool(resp)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if !res {
|
||||
return errors.New("Cannot enable/disable")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageLink(d *schema.ResourceDiff, m interface{}) error {
|
||||
log.Debugf("resourceVirtualImageLink: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
urlValues.Add("targetId", strconv.Itoa(d.Get("link_to").(int)))
|
||||
_, err := c.decortAPICall("POST", imageLinkAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageShare(d *schema.ResourceDiff, m interface{}) error {
|
||||
log.Debugf("resourceImageShare: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
accIds := d.Get("shared_with").([]interface{})
|
||||
temp := ""
|
||||
l := len(accIds)
|
||||
for i, accId := range accIds {
|
||||
s := strconv.Itoa(accId.(int))
|
||||
if i != (l - 1) {
|
||||
s += ",\n"
|
||||
} else {
|
||||
s += "\n"
|
||||
}
|
||||
temp = temp + s
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("accounts", temp)
|
||||
_, err := c.decortAPICall("POST", imageShareAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageChangeComputeci(d *schema.ResourceDiff, m interface{}) error {
|
||||
c := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
computeci := d.Get("computeci_id").(int)
|
||||
|
||||
api := ""
|
||||
|
||||
if computeci == 0 {
|
||||
api = imageComputeciUnsetAPI
|
||||
} else {
|
||||
urlValues.Add("computeciId", strconv.Itoa(computeci))
|
||||
api = imageComputeciSetAPI
|
||||
}
|
||||
|
||||
_, err := c.decortAPICall("POST", api, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageUpdateNodes(d *schema.ResourceDiff, m interface{}) error {
|
||||
log.Debugf("resourceImageUpdateNodes: called for %s, id: %s", d.Get("name").(string), d.Id())
|
||||
c := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
enabledStacks := d.Get("enabled_stacks").([]interface{})
|
||||
temp := ""
|
||||
l := len(enabledStacks)
|
||||
for i, stackId := range enabledStacks {
|
||||
s := stackId.(string)
|
||||
if i != (l - 1) {
|
||||
s += ","
|
||||
}
|
||||
temp = temp + s
|
||||
}
|
||||
temp = "[" + temp + "]"
|
||||
urlValues.Add("enabledStacks", temp)
|
||||
_, err := c.decortAPICall("POST", imageUpdateNodesAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceImageSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the rescue disk",
|
||||
},
|
||||
"url": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "URL where to download media from",
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "grid (platform) ID where this template should be create in",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Boot type of image bios or uefi",
|
||||
},
|
||||
"image_type": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Image type linux, windows or other",
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Required: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
|
||||
},
|
||||
"meta": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "meta",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
},
|
||||
"username_dl": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "username for upload binary media",
|
||||
},
|
||||
"password_dl": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "password for upload binary media",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
|
||||
},
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "image id",
|
||||
},
|
||||
"permanently": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Whether to completely delete the image",
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this image boot OS",
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "unc path",
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "status",
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "tech atatus",
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "version",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "image size",
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"computeci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"reference_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"res_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"reason": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
"sync": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Default: false,
|
||||
Description: "Create image from a media identified by URL (in synchronous mode)",
|
||||
},
|
||||
"enabled_stacks": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceImage() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceImageCreate,
|
||||
Read: resourceImageRead,
|
||||
Update: resourceImageEdit,
|
||||
Delete: resourceImageDelete,
|
||||
Exists: resourceImageExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout60s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout60s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
CustomizeDiff: customdiff.All(
|
||||
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
|
||||
if old.(bool) != new.(bool) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageChangeEnabled),
|
||||
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
|
||||
if old.(string) != new.(string) && old.(string) != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageEditName),
|
||||
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
|
||||
o := old.([]interface{})
|
||||
n := new.([]interface{})
|
||||
|
||||
if len(o) != len(n) {
|
||||
return true
|
||||
} else if len(o) == 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
count := 0
|
||||
for i, v := range n {
|
||||
if v.(int) == o[i].(int) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageShare),
|
||||
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
|
||||
if old.(int) != new.(int) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageChangeComputeci),
|
||||
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
|
||||
o := old.([]interface{})
|
||||
n := new.([]interface{})
|
||||
|
||||
if len(o) != len(n) {
|
||||
return true
|
||||
} else if len(o) == 0 {
|
||||
return false
|
||||
}
|
||||
count := 0
|
||||
for i, v := range n {
|
||||
if v.(string) == o[i].(string) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageUpdateNodes),
|
||||
),
|
||||
|
||||
Schema: resourceImageSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
func flattenMeta(m []interface{}) []string {
|
||||
output := []string{}
|
||||
for _, item := range m {
|
||||
switch d := item.(type) {
|
||||
case string:
|
||||
output = append(output, d)
|
||||
case int:
|
||||
output = append(output, strconv.Itoa(d))
|
||||
case int64:
|
||||
output = append(output, strconv.FormatInt(d, 10))
|
||||
case float64:
|
||||
output = append(output, strconv.FormatInt(int64(d), 10))
|
||||
default:
|
||||
output = append(output, "")
|
||||
}
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
func flattenHistory(history []History) []map[string]interface{} {
|
||||
temp := make([]map[string]interface{}, 0)
|
||||
for _, item := range history {
|
||||
t := map[string]interface{}{
|
||||
"id": item.Id,
|
||||
"guid": item.Guid,
|
||||
"timestamp": item.Timestamp,
|
||||
}
|
||||
|
||||
temp = append(temp, t)
|
||||
}
|
||||
return temp
|
||||
}
|
||||
358
decort/resource_k8s.go
Normal file
358
decort/resource_k8s.go
Normal file
@@ -0,0 +1,358 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
|
||||
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"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceK8sCreate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceK8sCreate: called with name %s, rg %d", d.Get("name").(string), d.Get("rg_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int)))
|
||||
urlValues.Add("k8ciId", strconv.Itoa(d.Get("k8sci_id").(int)))
|
||||
urlValues.Add("workerGroupName", d.Get("wg_name").(string))
|
||||
|
||||
var masterNode K8sNodeRecord
|
||||
if masters, ok := d.GetOk("masters"); ok {
|
||||
masterNode = parseNode(masters.([]interface{}))
|
||||
} else {
|
||||
masterNode = nodeMasterDefault()
|
||||
}
|
||||
urlValues.Add("masterNum", strconv.Itoa(masterNode.Num))
|
||||
urlValues.Add("masterCpu", strconv.Itoa(masterNode.Cpu))
|
||||
urlValues.Add("masterRam", strconv.Itoa(masterNode.Ram))
|
||||
urlValues.Add("masterDisk", strconv.Itoa(masterNode.Disk))
|
||||
|
||||
var workerNode K8sNodeRecord
|
||||
if workers, ok := d.GetOk("workers"); ok {
|
||||
workerNode = parseNode(workers.([]interface{}))
|
||||
} else {
|
||||
workerNode = nodeWorkerDefault()
|
||||
}
|
||||
urlValues.Add("workerNum", strconv.Itoa(workerNode.Num))
|
||||
urlValues.Add("workerCpu", strconv.Itoa(workerNode.Cpu))
|
||||
urlValues.Add("workerRam", strconv.Itoa(workerNode.Ram))
|
||||
urlValues.Add("workerDisk", strconv.Itoa(workerNode.Disk))
|
||||
|
||||
//if withLB, ok := d.GetOk("with_lb"); ok {
|
||||
//urlValues.Add("withLB", strconv.FormatBool(withLB.(bool)))
|
||||
//}
|
||||
urlValues.Add("withLB", strconv.FormatBool(true))
|
||||
|
||||
//if extNet, ok := d.GetOk("extnet_id"); ok {
|
||||
//urlValues.Add("extnetId", strconv.Itoa(extNet.(int)))
|
||||
//}
|
||||
urlValues.Add("extnetId", strconv.Itoa(0))
|
||||
|
||||
//if desc, ok := d.GetOk("desc"); ok {
|
||||
//urlValues.Add("desc", desc.(string))
|
||||
//}
|
||||
|
||||
resp, err := controller.decortAPICall("POST", K8sCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
urlValues = &url.Values{}
|
||||
urlValues.Add("auditId", strings.Trim(resp, `"`))
|
||||
|
||||
for {
|
||||
resp, err := controller.decortAPICall("POST", AsyncTaskGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
task := AsyncTask{}
|
||||
if err := json.Unmarshal([]byte(resp), &task); err != nil {
|
||||
return err
|
||||
}
|
||||
log.Debugf("resourceK8sCreate: instance creating - %s", task.Stage)
|
||||
|
||||
if task.Completed {
|
||||
if task.Error != "" {
|
||||
return fmt.Errorf("cannot create k8s instance: %v", task.Error)
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(int(task.Result)))
|
||||
break
|
||||
}
|
||||
|
||||
time.Sleep(time.Second * 10)
|
||||
}
|
||||
|
||||
k8s, err := utilityK8sCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.Set("default_wg_id", k8s.Groups.Workers[0].ID)
|
||||
|
||||
urlValues = &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
kubeconfig, err := controller.decortAPICall("POST", K8sGetConfigAPI, urlValues)
|
||||
if err != nil {
|
||||
log.Warnf("could not get kubeconfig: %v", err)
|
||||
}
|
||||
d.Set("kubeconfig", kubeconfig)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceK8sRead(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceK8sRead: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||
|
||||
k8s, err := utilityK8sCheckPresence(d, m)
|
||||
if k8s == nil {
|
||||
d.SetId("")
|
||||
return err
|
||||
}
|
||||
|
||||
d.Set("name", k8s.Name)
|
||||
d.Set("rg_id", k8s.RgID)
|
||||
d.Set("k8sci_id", k8s.CI)
|
||||
d.Set("wg_name", k8s.Groups.Workers[0].Name)
|
||||
d.Set("masters", nodeToResource(k8s.Groups.Masters))
|
||||
d.Set("workers", nodeToResource(k8s.Groups.Workers[0]))
|
||||
d.Set("default_wg_id", k8s.Groups.Workers[0].ID)
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
kubeconfig, err := controller.decortAPICall("POST", K8sGetConfigAPI, urlValues)
|
||||
if err != nil {
|
||||
log.Warnf("could not get kubeconfig: %v", err)
|
||||
}
|
||||
d.Set("kubeconfig", kubeconfig)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceK8sUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceK8sUpdate: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
|
||||
if d.HasChange("name") {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
|
||||
_, err := controller.decortAPICall("POST", K8sUpdateAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
if d.HasChange("workers") {
|
||||
k8s, err := utilityK8sCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
wg := k8s.Groups.Workers[0]
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
urlValues.Add("workersGroupId", strconv.Itoa(wg.ID))
|
||||
|
||||
newWorkers := parseNode(d.Get("workers").([]interface{}))
|
||||
|
||||
if newWorkers.Num > wg.Num {
|
||||
urlValues.Add("num", strconv.Itoa(newWorkers.Num-wg.Num))
|
||||
_, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
for i := wg.Num - 1; i >= newWorkers.Num; i-- {
|
||||
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
|
||||
_, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceK8sDelete(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||
|
||||
k8s, err := utilityK8sCheckPresence(d, m)
|
||||
if k8s == nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
urlValues.Add("permanently", "true")
|
||||
|
||||
_, err = controller.decortAPICall("POST", K8sDeleteAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceK8sExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
log.Debugf("resourceK8sExists: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
|
||||
|
||||
k8s, err := utilityK8sCheckPresence(d, m)
|
||||
if k8s == nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourceK8sSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "Name of the cluster.",
|
||||
},
|
||||
|
||||
"rg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Resource group ID that this instance belongs to.",
|
||||
},
|
||||
|
||||
"k8sci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "ID of the k8s catalog item to base this instance on.",
|
||||
},
|
||||
|
||||
"wg_name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Name for first worker group created with cluster.",
|
||||
},
|
||||
|
||||
"masters": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: nodeK8sSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Master node(s) configuration.",
|
||||
},
|
||||
|
||||
"workers": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
MaxItems: 1,
|
||||
Elem: &schema.Resource{
|
||||
Schema: nodeK8sSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Worker node(s) configuration.",
|
||||
},
|
||||
|
||||
//"with_lb": {
|
||||
//Type: schema.TypeBool,
|
||||
//Optional: true,
|
||||
//ForceNew: true,
|
||||
//Default: true,
|
||||
//Description: "Create k8s with load balancer if true.",
|
||||
//},
|
||||
|
||||
//"extnet_id": {
|
||||
//Type: schema.TypeInt,
|
||||
//Optional: true,
|
||||
//ForceNew: true,
|
||||
//Default: 0,
|
||||
//Description: "ID of the external network to connect workers to.",
|
||||
//},
|
||||
|
||||
//"desc": {
|
||||
//Type: schema.TypeString,
|
||||
//Optional: true,
|
||||
//Description: "Text description of this instance.",
|
||||
//},
|
||||
|
||||
"default_wg_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "ID of default workers group for this instace.",
|
||||
},
|
||||
|
||||
"kubeconfig": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Kubeconfig for cluster access.",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceK8s() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceK8sCreate,
|
||||
Read: resourceK8sRead,
|
||||
Update: resourceK8sUpdate,
|
||||
Delete: resourceK8sDelete,
|
||||
Exists: resourceK8sExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout20m,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout20m,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: resourceK8sSchemaMake(),
|
||||
}
|
||||
}
|
||||
250
decort/resource_k8s_wg.go
Normal file
250
decort/resource_k8s_wg.go
Normal file
@@ -0,0 +1,250 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
|
||||
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 (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceK8sWgCreate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceK8sWgCreate: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("workerNum", strconv.Itoa(d.Get("num").(int)))
|
||||
urlValues.Add("workerCpu", strconv.Itoa(d.Get("cpu").(int)))
|
||||
urlValues.Add("workerRam", strconv.Itoa(d.Get("ram").(int)))
|
||||
urlValues.Add("workerDisk", strconv.Itoa(d.Get("disk").(int)))
|
||||
|
||||
resp, err := controller.decortAPICall("POST", K8sWgCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(resp)
|
||||
|
||||
// This code is the supposed flow, but at the time of writing it's not yet implemented by the platfom
|
||||
|
||||
//urlValues = &url.Values{}
|
||||
//urlValues.Add("auditId", strings.Trim(resp, `"`))
|
||||
|
||||
//for {
|
||||
//resp, err := controller.decortAPICall("POST", AsyncTaskGetAPI, urlValues)
|
||||
//if err != nil {
|
||||
//return err
|
||||
//}
|
||||
|
||||
//task := AsyncTask{}
|
||||
//if err := json.Unmarshal([]byte(resp), &task); err != nil {
|
||||
//return err
|
||||
//}
|
||||
//log.Debugf("resourceK8sCreate: workers group creating - %s", task.Stage)
|
||||
|
||||
//if task.Completed {
|
||||
//if task.Error != "" {
|
||||
//return fmt.Errorf("cannot create workers group: %v", task.Error)
|
||||
//}
|
||||
|
||||
//d.SetId(strconv.Itoa(int(task.Result)))
|
||||
//break
|
||||
//}
|
||||
|
||||
//time.Sleep(time.Second * 5)
|
||||
//}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceK8sWgRead(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
wg, err := utilityK8sWgCheckPresence(d, m)
|
||||
if wg == nil {
|
||||
d.SetId("")
|
||||
return err
|
||||
}
|
||||
|
||||
d.Set("name", wg.Name)
|
||||
d.Set("num", wg.Num)
|
||||
d.Set("cpu", wg.Cpu)
|
||||
d.Set("ram", wg.Ram)
|
||||
d.Set("disk", wg.Disk)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceK8sWgUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceK8sWgUpdate: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
|
||||
wg, err := utilityK8sWgCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return nil
|
||||
}
|
||||
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
urlValues.Add("workersGroupId", d.Id())
|
||||
|
||||
newNum := d.Get("num").(int)
|
||||
|
||||
if newNum > wg.Num {
|
||||
urlValues.Add("num", strconv.Itoa(newNum-wg.Num))
|
||||
_, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
} else {
|
||||
for i := wg.Num - 1; i >= newNum; i-- {
|
||||
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
|
||||
_, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceK8sWgDelete(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
wg, err := utilityK8sWgCheckPresence(d, m)
|
||||
if wg == nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
urlValues.Add("workersGroupId", strconv.Itoa(wg.ID))
|
||||
|
||||
_, err = controller.decortAPICall("POST", K8sWgDeleteAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceK8sWgExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
log.Debugf("resourceK8sWgExists: called with k8s id %d", d.Get("k8s_id").(int))
|
||||
|
||||
wg, err := utilityK8sWgCheckPresence(d, m)
|
||||
if wg == nil {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourceK8sWgSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"k8s_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "ID of k8s instance.",
|
||||
},
|
||||
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "Name of the worker group.",
|
||||
},
|
||||
|
||||
"num": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 1,
|
||||
Description: "Number of worker nodes to create.",
|
||||
},
|
||||
|
||||
"cpu": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Default: 1,
|
||||
Description: "Worker node CPU count.",
|
||||
},
|
||||
|
||||
"ram": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Default: 1024,
|
||||
Description: "Worker node RAM in MB.",
|
||||
},
|
||||
|
||||
"disk": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
Default: 0,
|
||||
Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceK8sWg() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceK8sWgCreate,
|
||||
Read: resourceK8sWgRead,
|
||||
Update: resourceK8sWgUpdate,
|
||||
Delete: resourceK8sWgDelete,
|
||||
Exists: resourceK8sWgExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout20m,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout20m,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: resourceK8sWgSchemaMake(),
|
||||
}
|
||||
}
|
||||
200
decort/resource_pfw.go
Normal file
200
decort/resource_pfw.go
Normal file
@@ -0,0 +1,200 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
|
||||
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 (
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourcePfwCreate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
urlValues.Add("publicPortStart", strconv.Itoa(d.Get("public_port_start").(int)))
|
||||
urlValues.Add("localBasePort", strconv.Itoa(d.Get("local_base_port").(int)))
|
||||
urlValues.Add("proto", d.Get("proto").(string))
|
||||
|
||||
if portEnd, ok := d.GetOk("public_port_end"); ok {
|
||||
urlValues.Add("publicPortEnd", strconv.Itoa(portEnd.(int)))
|
||||
}
|
||||
|
||||
pfwId, err := controller.decortAPICall("POST", ComputePfwAddAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(fmt.Sprintf("%d-%s", d.Get("compute_id").(int), pfwId))
|
||||
|
||||
pfw, err := utilityPfwCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.Set("local_ip", pfw.LocalIP)
|
||||
if _, ok := d.GetOk("public_port_end"); !ok {
|
||||
d.Set("public_port_end", pfw.PublicPortEnd)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourcePfwRead(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourcePfwRead: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
||||
|
||||
pfw, err := utilityPfwCheckPresence(d, m)
|
||||
if pfw == nil {
|
||||
d.SetId("")
|
||||
return err
|
||||
}
|
||||
|
||||
d.Set("compute_id", pfw.ComputeID)
|
||||
d.Set("public_port_start", pfw.PublicPortStart)
|
||||
d.Set("public_port_end", pfw.PublicPortEnd)
|
||||
d.Set("local_ip", pfw.LocalIP)
|
||||
d.Set("local_base_port", pfw.LocalPort)
|
||||
d.Set("proto", pfw.Protocol)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourcePfwDelete(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourcePfwDelete: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
||||
|
||||
pfw, err := utilityPfwCheckPresence(d, m)
|
||||
if pfw == nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
urlValues.Add("ruleId", strconv.Itoa(pfw.ID))
|
||||
|
||||
_, err = controller.decortAPICall("POST", ComputePfwDelAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourcePfwExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
log.Debugf("resourcePfwExists: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
||||
|
||||
pfw, err := utilityPfwCheckPresence(d, m)
|
||||
if pfw == nil {
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
return false, nil
|
||||
}
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func resourcePfwSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Description: "ID of compute instance.",
|
||||
},
|
||||
|
||||
"public_port_start": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "External start port number for the rule.",
|
||||
},
|
||||
|
||||
"public_port_end": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "End port number (inclusive) for the ranged rule.",
|
||||
},
|
||||
|
||||
"local_ip": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "IP address of compute instance.",
|
||||
},
|
||||
|
||||
"local_base_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "Internal base port number.",
|
||||
},
|
||||
|
||||
"proto": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false),
|
||||
Description: "Network protocol, either 'tcp' or 'udp'.",
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourcePfw() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourcePfwCreate,
|
||||
Read: resourcePfwRead,
|
||||
Delete: resourcePfwDelete,
|
||||
Exists: resourcePfwExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout60s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout60s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: resourcePfwSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -30,6 +30,7 @@ import (
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
||||
@@ -145,7 +146,28 @@ 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))
|
||||
|
||||
do_update := false
|
||||
/* NOTE: we do not allow changing the following attributes of an existing RG via terraform:
|
||||
- def_net_type
|
||||
- ipcidr
|
||||
- ext_net_id
|
||||
- ext_ip
|
||||
|
||||
The following code fragment checks if any of these have been changed and generates error.
|
||||
*/
|
||||
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 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 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)
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
url_values := &url.Values{}
|
||||
@@ -156,7 +178,7 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceResgroupUpdate: name specified - looking for deltas from the old settings.")
|
||||
name_old, _ := d.GetChange("name")
|
||||
if name_old.(string) != name_new.(string) {
|
||||
do_update = true
|
||||
do_general_update = true
|
||||
url_values.Add("name", name_new.(string))
|
||||
}
|
||||
}
|
||||
@@ -169,31 +191,31 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
quotarecord_old, _ := makeQuotaRecord(quota_value_old.([]interface{}))
|
||||
|
||||
if quotarecord_new.Cpu != quotarecord_old.Cpu {
|
||||
do_update = true
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu)
|
||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu))
|
||||
}
|
||||
|
||||
if quotarecord_new.Disk != quotarecord_old.Disk {
|
||||
do_update = true
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.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_update = true
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram)
|
||||
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram))
|
||||
}
|
||||
|
||||
if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic {
|
||||
do_update = true
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic)
|
||||
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.ExtTraffic))
|
||||
}
|
||||
|
||||
if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs {
|
||||
do_update = true
|
||||
do_general_update = true
|
||||
log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs)
|
||||
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs))
|
||||
}
|
||||
@@ -204,12 +226,12 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceResgroupUpdate: description specified - looking for deltas from the old settings.")
|
||||
desc_old, _ := d.GetChange("description")
|
||||
if desc_old.(string) != desc_new.(string) {
|
||||
do_update = true
|
||||
do_general_update = true
|
||||
url_values.Add("desc", desc_new.(string))
|
||||
}
|
||||
}
|
||||
|
||||
if do_update {
|
||||
if do_general_update {
|
||||
log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG")
|
||||
_, err := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values)
|
||||
if err != nil {
|
||||
@@ -237,8 +259,8 @@ func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
url_values := &url.Values{}
|
||||
url_values.Add("rgId", d.Id())
|
||||
url_values.Add("force", "true")
|
||||
url_values.Add("permanently", "true")
|
||||
url_values.Add("force", "1")
|
||||
url_values.Add("permanently", "1")
|
||||
url_values.Add("reason", "Destroyed by DECORT Terraform provider")
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
@@ -294,6 +316,7 @@ func resourceResgroup() *schema.Resource {
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "Unique ID of the account, which this resource group belongs to.",
|
||||
},
|
||||
|
||||
@@ -301,6 +324,7 @@ func resourceResgroup() *schema.Resource {
|
||||
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.",
|
||||
},
|
||||
|
||||
@@ -320,13 +344,13 @@ func resourceResgroup() *schema.Resource {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Default: 0,
|
||||
Description: "ID of the external network, which this resource group will use as default for its computes if def_net_type=PUBLIC",
|
||||
Description: "ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE",
|
||||
},
|
||||
|
||||
"ext_ip": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Description: "IP address on the external netowrk to request, if def_net_type=PUBLIC",
|
||||
Description: "IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0",
|
||||
},
|
||||
|
||||
/* commented out, as in this version of provider we use default Grid ID
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
402
decort/resource_virtual_image.go
Normal file
402
decort/resource_virtual_image.go
Normal file
@@ -0,0 +1,402 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
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 (
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/customdiff"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
log "github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
func resourceVirtualImageCreate(d *schema.ResourceData, m interface{}) error {
|
||||
log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("name", d.Get("name").(string))
|
||||
urlValues.Add("targetId", strconv.Itoa(d.Get("target_id").(int)))
|
||||
|
||||
imageId, err := controller.decortAPICall("POST", imageCreateVirtualAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(imageId)
|
||||
d.Set("image_id", imageId)
|
||||
|
||||
image, err := utilityImageCheckPresence(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
d.SetId(strconv.Itoa(image.ImageId))
|
||||
d.Set("bootable", image.Bootable)
|
||||
//d.Set("image_id", image.ImageId)
|
||||
|
||||
err = resourceImageRead(d, m)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourceVirtualImageSchemaMake() map[string]*schema.Schema {
|
||||
return map[string]*schema.Schema{
|
||||
"name": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
Description: "name of the virtual image to create",
|
||||
},
|
||||
"target_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
Description: "ID of real image to link this virtual image to upon creation",
|
||||
},
|
||||
"history": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"guid": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"timestamp": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
"url": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "URL where to download media from",
|
||||
},
|
||||
"gid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "grid (platform) ID where this template should be create in",
|
||||
},
|
||||
"boot_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Boot type of image bios or uefi",
|
||||
},
|
||||
"image_type": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "Image type linux, windows or other",
|
||||
},
|
||||
"drivers": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
|
||||
},
|
||||
"meta": {
|
||||
Type: schema.TypeList,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
Description: "meta",
|
||||
},
|
||||
"hot_resize": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this machine supports hot resize",
|
||||
},
|
||||
"username": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional username for the image",
|
||||
},
|
||||
"password": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Optional password for the image",
|
||||
},
|
||||
"account_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "AccountId to make the image exclusive",
|
||||
},
|
||||
"username_dl": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "username for upload binary media",
|
||||
},
|
||||
"password_dl": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "password for upload binary media",
|
||||
},
|
||||
"sep_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "storage endpoint provider ID",
|
||||
},
|
||||
"pool_name": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "pool for image create",
|
||||
},
|
||||
"architecture": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
|
||||
},
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "image id",
|
||||
},
|
||||
"permanently": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Whether to completely delete the image",
|
||||
},
|
||||
"bootable": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "Does this image boot OS",
|
||||
},
|
||||
"unc_path": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "unc path",
|
||||
},
|
||||
"link_to": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Description: "",
|
||||
},
|
||||
"status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "status",
|
||||
},
|
||||
"tech_status": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "tech atatus",
|
||||
},
|
||||
"version": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
Description: "version",
|
||||
},
|
||||
"size": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "image size",
|
||||
},
|
||||
"enabled": {
|
||||
Type: schema.TypeBool,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"computeci_id": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
},
|
||||
"guid": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"milestones": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"provider_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"purge_attempts": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"reference_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"res_id": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"res_name": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"rescuecd": {
|
||||
Type: schema.TypeBool,
|
||||
Computed: true,
|
||||
},
|
||||
"reason": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
},
|
||||
"last_modified": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
},
|
||||
"desc": {
|
||||
Type: schema.TypeString,
|
||||
Computed: true,
|
||||
},
|
||||
"enabled_stacks": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"shared_with": {
|
||||
Type: schema.TypeList,
|
||||
Optional: true,
|
||||
Computed: true,
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeInt,
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceVirtualImage() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Create: resourceVirtualImageCreate,
|
||||
Read: resourceImageRead,
|
||||
Update: resourceImageEdit,
|
||||
Delete: resourceImageDelete,
|
||||
Exists: resourceImageExists,
|
||||
|
||||
Importer: &schema.ResourceImporter{
|
||||
State: schema.ImportStatePassthrough,
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout60s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout60s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
CustomizeDiff: customdiff.All(
|
||||
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
|
||||
if old.(bool) != new.(bool) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageChangeEnabled),
|
||||
customdiff.IfValueChange("link_to", func(old, new, meta interface{}) bool {
|
||||
if old.(int) != new.(int) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageLink),
|
||||
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
|
||||
if old.(string) != new.(string) && old.(string) != "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageEditName),
|
||||
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
|
||||
o := old.([]interface{})
|
||||
n := new.([]interface{})
|
||||
|
||||
if len(o) != len(n) {
|
||||
return true
|
||||
} else if len(o) == 0 {
|
||||
return false
|
||||
}
|
||||
count := 0
|
||||
for i, v := range n {
|
||||
if v.(int) == o[i].(int) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageShare),
|
||||
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
|
||||
if old.(int) != new.(int) {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageChangeComputeci),
|
||||
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
|
||||
o := old.([]interface{})
|
||||
n := new.([]interface{})
|
||||
|
||||
if len(o) != len(n) {
|
||||
return true
|
||||
} else if len(o) == 0 {
|
||||
return false
|
||||
}
|
||||
count := 0
|
||||
for i, v := range n {
|
||||
if v.(string) == o[i].(string) {
|
||||
count++
|
||||
}
|
||||
}
|
||||
if count == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}, resourceImageUpdateNodes),
|
||||
),
|
||||
|
||||
Schema: resourceVirtualImageSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -40,32 +40,25 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
|
||||
// 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")
|
||||
|
||||
old_disks := make([]interface{},0,0)
|
||||
if old_set != nil {
|
||||
old_disks = old_set.([]interface{})
|
||||
}
|
||||
|
||||
new_disks := make([]interface{},0,0)
|
||||
if new_set != nil {
|
||||
new_disks = new_set.([]interface{})
|
||||
}
|
||||
|
||||
apiErrCount := 0
|
||||
var lastSavedError error
|
||||
|
||||
if !do_delta {
|
||||
if len(new_disks) < 1 {
|
||||
if new_set.(*schema.Set).Len() < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, disk := range new_disks {
|
||||
for _, disk := range new_set.(*schema.Set).List() {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int)))
|
||||
@@ -86,58 +79,31 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
|
||||
return nil
|
||||
}
|
||||
|
||||
var attach_list, detach_list []int
|
||||
match := false
|
||||
|
||||
for _, oDisk := range old_disks {
|
||||
match = false
|
||||
for _, nDisk := range new_disks {
|
||||
if oDisk.(int) == nDisk.(int) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
detach_list = append(detach_list, oDisk.(int))
|
||||
}
|
||||
}
|
||||
log.Debugf("utilityComputeExtraDisksConfigure: detach list has %d items for Compute ID %s", len(detach_list), d.Id())
|
||||
|
||||
for _, nDisk := range new_disks {
|
||||
match = false
|
||||
for _, oDisk := range old_disks {
|
||||
if nDisk.(int) == oDisk.(int) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
attach_list = append(attach_list, nDisk.(int))
|
||||
}
|
||||
}
|
||||
log.Debugf("utilityComputeExtraDisksConfigure: attach list has %d items for Compute ID %s", len(attach_list), d.Id())
|
||||
|
||||
for _, diskId := range detach_list {
|
||||
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))
|
||||
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.Debugf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId, d.Id(), err)
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
for _, diskId := range attach_list {
|
||||
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))
|
||||
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.Debugf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId, d.Id(), err)
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
@@ -152,39 +118,26 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
|
||||
return nil
|
||||
}
|
||||
|
||||
// TODO: implement do_delta logic
|
||||
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.
|
||||
|
||||
/*
|
||||
argVal, argSet := d.GetOk("network")
|
||||
if !argSet || len(argVal.([]interface{})) < 1 {
|
||||
return nil
|
||||
}
|
||||
net_list := argVal.([]interface{}) // network is ar array of maps; for keys see func networkSubresourceSchemaMake() definition
|
||||
*/
|
||||
|
||||
old_set, new_set := d.GetChange("network")
|
||||
|
||||
oldNets := make([]interface{},0,0)
|
||||
if old_set != nil {
|
||||
oldNets = old_set.([]interface{}) // network is ar array of maps; for keys see func networkSubresourceSchemaMake() definition
|
||||
}
|
||||
|
||||
newNets := make([]interface{},0,0)
|
||||
if new_set != nil {
|
||||
newNets = new_set.([]interface{}) // network is ar array of maps; for keys see func networkSubresourceSchemaMake() definition
|
||||
}
|
||||
|
||||
apiErrCount := 0
|
||||
var lastSavedError error
|
||||
|
||||
if !do_delta {
|
||||
for _, net := range newNets {
|
||||
if new_set.(*schema.Set).Len() < 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, runner := range new_set.(*schema.Set).List() {
|
||||
urlValues := &url.Values{}
|
||||
net_data := net.(map[string]interface{})
|
||||
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)))
|
||||
@@ -208,84 +161,40 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
|
||||
return nil
|
||||
}
|
||||
|
||||
var attachList, detachList []ComputeNetMgmtRecord
|
||||
match := false
|
||||
|
||||
for _, oRunner := range oldNets {
|
||||
match = false
|
||||
oSpecs := oRunner.(map[string]interface{})
|
||||
for _, nRunner := range newNets {
|
||||
nSpecs := nRunner.(map[string]interface{})
|
||||
if oSpecs["net_id"].(int) == nSpecs["net_id"].(int) && oSpecs["net_type"].(string) == nSpecs["net_type"].(string) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
newItem := ComputeNetMgmtRecord{
|
||||
ID: oSpecs["net_id"].(int),
|
||||
Type: oSpecs["net_type"].(string),
|
||||
IPAddress: oSpecs["ip_address"].(string),
|
||||
MAC: oSpecs["mac"].(string),
|
||||
}
|
||||
detachList = append(detachList, newItem)
|
||||
}
|
||||
}
|
||||
log.Debugf("utilityComputeNetworksConfigure: detach list has %d items for Compute ID %s", len(detachList), d.Id())
|
||||
|
||||
for _, nRunner := range newNets {
|
||||
match = false
|
||||
nSpecs := nRunner.(map[string]interface{})
|
||||
for _, oRunner := range oldNets {
|
||||
oSpecs := oRunner.(map[string]interface{})
|
||||
if nSpecs["net_id"].(int) == oSpecs["net_id"].(int) && nSpecs["net_type"].(string) == oSpecs["net_type"].(string) {
|
||||
match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if !match {
|
||||
newItem := ComputeNetMgmtRecord{
|
||||
ID: nSpecs["net_id"].(int),
|
||||
Type: nSpecs["net_type"].(string),
|
||||
}
|
||||
if nSpecs["ip_address"] != nil {
|
||||
newItem.IPAddress = nSpecs["ip_address"].(string)
|
||||
} else {
|
||||
newItem.IPAddress = "" // make sure it is empty, if not coming from the schema
|
||||
}
|
||||
attachList = append(attachList, newItem)
|
||||
}
|
||||
}
|
||||
log.Debugf("utilityComputeNetworksConfigure: attach list has %d items for Compute ID %s", len(attachList), d.Id())
|
||||
|
||||
for _, netRec := range detachList {
|
||||
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", netRec.IPAddress)
|
||||
urlValues.Add("mac", netRec.MAC)
|
||||
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.Debugf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s",
|
||||
netRec.ID, netRec.Type, d.Id(), err)
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
for _, netRec := range attachList {
|
||||
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",netRec.ID))
|
||||
urlValues.Add("netType", netRec.Type)
|
||||
if netRec.IPAddress != "" {
|
||||
urlValues.Add("ipAddr", netRec.IPAddress)
|
||||
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.Debugf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s from Compute ID %s: %s",
|
||||
netRec.ID, netRec.Type, d.Id(), err)
|
||||
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
|
||||
}
|
||||
|
||||
62
decort/utility_grid.go
Normal file
62
decort/utility_grid.go
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityGridCheckPresence(d *schema.ResourceData, m interface{}) (*Grid, error) {
|
||||
grid := &Grid{}
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
if gridId, ok := d.GetOk("grid_id"); ok {
|
||||
urlValues.Add("gridId", strconv.Itoa(gridId.(int)))
|
||||
} else {
|
||||
return nil, errors.New(fmt.Sprintf("grid_id is required"))
|
||||
}
|
||||
|
||||
log.Debugf("utilityGridCheckPresence: load grid")
|
||||
gridRaw, err := controller.decortAPICall("POST", GridGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(gridRaw), grid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return grid, nil
|
||||
}
|
||||
61
decort/utility_grid_list.go
Normal file
61
decort/utility_grid_list.go
Normal file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityGridListCheckPresence(d *schema.ResourceData, m interface{}) (GridList, error) {
|
||||
gridList := GridList{}
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
}
|
||||
|
||||
log.Debugf("utilityGridListCheckPresence: load grid list")
|
||||
gridListRaw, err := controller.decortAPICall("POST", GridListGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(gridListRaw), &gridList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return gridList, nil
|
||||
}
|
||||
62
decort/utility_image.go
Normal file
62
decort/utility_image.go
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||
|
||||
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"
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityImageCheckPresence(d *schema.ResourceData, m interface{}) (*Image, error) {
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
if (strconv.Itoa(d.Get("image_id").(int))) != "0" {
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
} else {
|
||||
urlValues.Add("imageId", d.Id())
|
||||
}
|
||||
|
||||
resp, err := controller.decortAPICall("POST", imageGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
image := &Image{}
|
||||
if err := json.Unmarshal([]byte(resp), image); err != nil {
|
||||
return nil, errors.New(fmt.Sprint("Can not unmarshall data to image: ", resp, " ", image))
|
||||
}
|
||||
|
||||
return image, nil
|
||||
}
|
||||
68
decort/utility_image_list.go
Normal file
68
decort/utility_image_list.go
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityImageListCheckPresence(d *schema.ResourceData, m interface{}) (ImageList, error) {
|
||||
imageList := ImageList{}
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
||||
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
|
||||
}
|
||||
if sharedWith, ok := d.GetOk("shared_with"); ok {
|
||||
urlValues.Add("sharedWith", strconv.Itoa(sharedWith.(int)))
|
||||
}
|
||||
|
||||
if page, ok := d.GetOk("page"); ok {
|
||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
||||
}
|
||||
if size, ok := d.GetOk("size"); ok {
|
||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
||||
}
|
||||
|
||||
log.Debugf("utilityImageListCheckPresence: load image list")
|
||||
imageListRaw, err := controller.decortAPICall("POST", imageListGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(imageListRaw), &imageList)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return imageList, nil
|
||||
}
|
||||
56
decort/utility_image_list_stacks.go
Normal file
56
decort/utility_image_list_stacks.go
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Stanislav Solovev, <spsolovev@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"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityImageListStacksCheckPresence(d *schema.ResourceData, m interface{}) (ImageListStacks, error) {
|
||||
imageListStacks := ImageListStacks{}
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
||||
|
||||
log.Debugf("utilityImageListStacksCheckPresence: load image list")
|
||||
imageListRaw, err := controller.decortAPICall("POST", imageListStacksApi, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
err = json.Unmarshal([]byte(imageListRaw), &imageListStacks)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return imageListStacks, nil
|
||||
}
|
||||
54
decort/utility_k8s.go
Normal file
54
decort/utility_k8s.go
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
|
||||
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"
|
||||
"net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityK8sCheckPresence(d *schema.ResourceData, m interface{}) (*K8sRecord, error) {
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", d.Id())
|
||||
|
||||
resp, err := controller.decortAPICall("POST", K8sGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var k8s K8sRecord
|
||||
if err := json.Unmarshal([]byte(resp), &k8s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &k8s, nil
|
||||
}
|
||||
66
decort/utility_k8s_wg.go
Normal file
66
decort/utility_k8s_wg.go
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
|
||||
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"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityK8sWgCheckPresence(d *schema.ResourceData, m interface{}) (*K8sNodeRecord, error) {
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
||||
|
||||
resp, err := controller.decortAPICall("POST", K8sGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
var k8s K8sRecord
|
||||
if err := json.Unmarshal([]byte(resp), &k8s); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
id, err := strconv.Atoi(d.Id())
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, wg := range k8s.Groups.Workers {
|
||||
if wg.ID == id {
|
||||
return &wg, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
68
decort/utility_pfw.go
Normal file
68
decort/utility_pfw.go
Normal file
@@ -0,0 +1,68 @@
|
||||
/*
|
||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||
|
||||
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"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityPfwCheckPresence(d *schema.ResourceData, m interface{}) (*PfwRecord, error) {
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
resp, err := controller.decortAPICall("POST", ComputePfwListAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if resp == "" {
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
idS := strings.Split(d.Id(), "-")[1]
|
||||
id, err := strconv.Atoi(idS)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var pfws []PfwRecord
|
||||
if err := json.Unmarshal([]byte(resp), &pfws); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for _, pfw := range pfws {
|
||||
if pfw.ID == id {
|
||||
return &pfw, nil
|
||||
}
|
||||
}
|
||||
|
||||
return nil, nil
|
||||
}
|
||||
@@ -28,6 +28,7 @@ import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
@@ -75,6 +76,34 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er
|
||||
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
|
||||
@@ -82,11 +111,11 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er
|
||||
}
|
||||
urlValues.Add("name", vinsName.(string))
|
||||
urlValues.Add("show_all", "false")
|
||||
log.Debugf("utilityVinsCheckPresence: locating ViNS %s", vinsName.(string))
|
||||
log.Debugf("utilityVinsCheckPresence: preparing to locate ViNS name %s", vinsName.(string))
|
||||
|
||||
rgId, rgSet := d.GetOk("rg_id")
|
||||
if rgSet {
|
||||
log.Debugf("utilityVinsCheckPresence: limiting ViNS t search to RG ID %d", rgId.(int))
|
||||
log.Debugf("utilityVinsCheckPresence: limiting ViNS search to RG ID %d", rgId.(int))
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgId.(int)))
|
||||
}
|
||||
|
||||
@@ -133,5 +162,5 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er
|
||||
}
|
||||
}
|
||||
|
||||
return "", fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID", vinsName.(string))
|
||||
return "", fmt.Errorf("Cannot find ViNS name %s. Check name and/or RG ID & Account ID and your access rights", vinsName.(string))
|
||||
}
|
||||
|
||||
37
docs/data-sources/account.md
Normal file
37
docs/data-sources/account.md
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_account Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_account (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- **account_id** (Number) Unique ID of the account. If account ID is specified, then account name is ignored.
|
||||
- **id** (String) The ID of this resource.
|
||||
- **name** (String) Name of the account. Names are case sensitive and unique.
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **status** (String) Current status of the account.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **default** (String)
|
||||
- **read** (String)
|
||||
|
||||
|
||||
45
docs/data-sources/disk.md
Normal file
45
docs/data-sources/disk.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_disk Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_disk (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- **account_id** (Number) ID of the account this disk belongs to. If disk ID is specified, then account ID is ignored.
|
||||
- **disk_id** (Number) ID of the disk to get. If disk ID is specified, then disk name and account ID are ignored.
|
||||
- **id** (String) The ID of this resource.
|
||||
- **name** (String) Name of this disk. NOTE: disk names are NOT unique within an account. If disk ID is specified, disk name is ignored.
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **account_name** (String) Name of the account this disk belongs to. If account ID is specified, account name is ignored.
|
||||
- **description** (String) User-defined text description of this disk.
|
||||
- **image_id** (Number) ID of the image, which this disk was cloned from (valid for disk clones only).
|
||||
- **pool** (String) Pool where this disk is located.
|
||||
- **sep_id** (Number) Storage end-point provider serving this disk.
|
||||
- **sep_type** (String) Type of the storage end-point provider serving this disk.
|
||||
- **size** (Number) Size of the disk in GB.
|
||||
- **type** (String) Type of this disk. E.g. D for data disks, B for boot.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **default** (String)
|
||||
- **read** (String)
|
||||
|
||||
|
||||
43
docs/data-sources/grid.md
Normal file
43
docs/data-sources/grid.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_grid Data Source - terraform-provider-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)
|
||||
|
||||
|
||||
50
docs/data-sources/grid_list.md
Normal file
50
docs/data-sources/grid_list.md
Normal file
@@ -0,0 +1,50 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_grid_list Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_grid_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- **id** (String) The ID of this resource.
|
||||
- **page** (Number) page number
|
||||
- **size** (Number) page size
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **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)
|
||||
|
||||
|
||||
86
docs/data-sources/image.md
Normal file
86
docs/data-sources/image.md
Normal file
@@ -0,0 +1,86 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_image (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **image_id** (Number) image id
|
||||
|
||||
### Optional
|
||||
|
||||
- **id** (String) The ID of this resource.
|
||||
- **shared_with** (List of Number)
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **account_id** (Number) AccountId to make the image exclusive
|
||||
- **architecture** (String) binary architecture of this image, one of X86_64 of PPC64_LE
|
||||
- **boot_type** (String) Boot type of image bios or uefi
|
||||
- **bootable** (Boolean) Does this image boot OS
|
||||
- **computeci_id** (Number)
|
||||
- **desc** (String)
|
||||
- **drivers** (List of String) List of types of compute suitable for image. Example: [ "KVM_X86" ]
|
||||
- **enabled** (Boolean)
|
||||
- **gid** (Number) grid (platform) ID where this template should be create in
|
||||
- **guid** (Number)
|
||||
- **history** (List of Object) (see [below for nested schema](#nestedatt--history))
|
||||
- **hot_resize** (Boolean) Does this machine supports hot resize
|
||||
- **image_type** (String) Image type linux, windows or other
|
||||
- **last_modified** (Number)
|
||||
- **link_to** (Number)
|
||||
- **meta** (List of String) meta
|
||||
- **milestones** (Number)
|
||||
- **name** (String) Name of the rescue disk
|
||||
- **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
|
||||
- **provider_name** (String)
|
||||
- **purge_attempts** (Number)
|
||||
- **reference_id** (String)
|
||||
- **res_id** (String)
|
||||
- **res_name** (String)
|
||||
- **rescuecd** (Boolean)
|
||||
- **sep_id** (Number) storage endpoint provider ID
|
||||
- **size** (Number) image size
|
||||
- **status** (String) status
|
||||
- **tech_status** (String) tech atatus
|
||||
- **unc_path** (String) unc path
|
||||
- **url** (String) URL where to download media from
|
||||
- **username** (String) Optional username for the image
|
||||
- **username_dl** (String) username for upload binary media
|
||||
- **version** (String) version
|
||||
|
||||
<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)
|
||||
|
||||
|
||||
94
docs/data-sources/image_list.md
Normal file
94
docs/data-sources/image_list.md
Normal file
@@ -0,0 +1,94 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image_list Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_image_list (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Optional
|
||||
|
||||
- **id** (String) The ID of this resource.
|
||||
- **page** (Number) page number
|
||||
- **sep_id** (Number) filter images by storage endpoint provider ID
|
||||
- **shared_with** (Number) filter images by account ID availability
|
||||
- **size** (Number) page size
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **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)
|
||||
- **computeci_id** (Number)
|
||||
- **desc** (String)
|
||||
- **drivers** (List of String)
|
||||
- **enabled** (Boolean)
|
||||
- **gid** (Number)
|
||||
- **guid** (Number)
|
||||
- **history** (List of Object) (see [below for nested schema](#nestedobjatt--items--history))
|
||||
- **hot_resize** (Boolean)
|
||||
- **image_id** (Number)
|
||||
- **image_type** (String)
|
||||
- **last_modified** (Number)
|
||||
- **link_to** (Number)
|
||||
- **meta** (List of String)
|
||||
- **milestones** (Number)
|
||||
- **name** (String)
|
||||
- **password** (String)
|
||||
- **password_dl** (String)
|
||||
- **permanently** (Boolean)
|
||||
- **pool_name** (String)
|
||||
- **provider_name** (String)
|
||||
- **purge_attempts** (Number)
|
||||
- **reference_id** (String)
|
||||
- **res_id** (String)
|
||||
- **res_name** (String)
|
||||
- **rescuecd** (Boolean)
|
||||
- **sep_id** (Number)
|
||||
- **shared_with** (List of Number)
|
||||
- **size** (Number)
|
||||
- **status** (String)
|
||||
- **tech_status** (String)
|
||||
- **unc_path** (String)
|
||||
- **url** (String)
|
||||
- **username** (String)
|
||||
- **username_dl** (String)
|
||||
- **version** (String)
|
||||
|
||||
<a id="nestedobjatt--items--history"></a>
|
||||
### Nested Schema for `items.history`
|
||||
|
||||
Read-Only:
|
||||
|
||||
- **guid** (String)
|
||||
- **id** (Number)
|
||||
- **timestamp** (Number)
|
||||
|
||||
|
||||
63
docs/data-sources/image_list_stacks.md
Normal file
63
docs/data-sources/image_list_stacks.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image_list_stacks Data Source - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_image_list_stacks (Data Source)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **image_id** (Number) image id
|
||||
|
||||
### Optional
|
||||
|
||||
- **id** (String) The ID of this resource.
|
||||
- **page** (Number) page number
|
||||
- **size** (Number) page size
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **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)
|
||||
|
||||
|
||||
81
docs/data-sources/kvmvm.md
Normal file
81
docs/data-sources/kvmvm.md
Normal file
@@ -0,0 +1,81 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_kvmvm Data Source - terraform-provider-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.
|
||||
- **id** (String) The ID of this resource.
|
||||
- **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.
|
||||
- **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)
|
||||
|
||||
|
||||
58
docs/data-sources/resgroup.md
Normal file
58
docs/data-sources/resgroup.md
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_resgroup Data Source - terraform-provider-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
|
||||
|
||||
- **id** (String) The ID of this resource.
|
||||
- **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.
|
||||
- **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)
|
||||
|
||||
|
||||
45
docs/data-sources/vins.md
Normal file
45
docs/data-sources/vins.md
Normal file
@@ -0,0 +1,45 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_vins Data Source - terraform-provider-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.
|
||||
- **id** (String) The ID of this resource.
|
||||
- **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).
|
||||
- **ipcidr** (String) Network address used by this ViNS.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **default** (String)
|
||||
- **read** (String)
|
||||
|
||||
|
||||
31
docs/index.md
Normal file
31
docs/index.md
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
# 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.
|
||||
89
docs/resources/cdrom_image.md
Normal file
89
docs/resources/cdrom_image.md
Normal file
@@ -0,0 +1,89 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_cdrom_image Resource - terraform-provider-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
|
||||
- **id** (String) The ID of this resource.
|
||||
- **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))
|
||||
- **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)
|
||||
|
||||
|
||||
40
docs/resources/delete_images.md
Normal file
40
docs/resources/delete_images.md
Normal file
@@ -0,0 +1,40 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_delete_images Resource - terraform-provider-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
|
||||
|
||||
- **id** (String) The ID of this resource.
|
||||
- **permanently** (Boolean) whether to completely delete the images
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **create** (String)
|
||||
- **default** (String)
|
||||
- **delete** (String)
|
||||
- **read** (String)
|
||||
- **update** (String)
|
||||
|
||||
|
||||
51
docs/resources/disk.md
Normal file
51
docs/resources/disk.md
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_disk Resource - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_disk (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **pool** (String) Pool where this disk is located. Cannot be changed for existing disk.
|
||||
- **sep_id** (Number) Storage end-point provider serving this disk. Cannot be changed for existing disk.
|
||||
- **size** (Number) Size of the disk in GB. Note, that existing disks can only be grown in size.
|
||||
|
||||
### Optional
|
||||
|
||||
- **account_id** (Number) ID of the account this disk belongs to.
|
||||
- **description** (String) Optional user-defined text description of this disk.
|
||||
- **disk_id** (Number) ID of the disk to get. If disk ID is specified, then disk name and account ID are ignored.
|
||||
- **id** (String) The ID of this resource.
|
||||
- **name** (String) Name of this disk. NOTE: disk names are NOT unique within an account. If disk ID is specified, disk name is ignored.
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **account_name** (String) Name of the account this disk belongs to.
|
||||
- **image_id** (Number) ID of the image, which this disk was cloned from (if ever cloned).
|
||||
- **sep_type** (String) Type of the storage end-point provider serving this disk.
|
||||
- **type** (String) Type of this disk.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **create** (String)
|
||||
- **default** (String)
|
||||
- **delete** (String)
|
||||
- **read** (String)
|
||||
- **update** (String)
|
||||
|
||||
|
||||
92
docs/resources/image.md
Normal file
92
docs/resources/image.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_image Resource - terraform-provider-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) List of types of compute suitable for image. Example: [ "KVM_X86" ]
|
||||
- **gid** (Number) grid (platform) ID where this template should be create in
|
||||
- **image_type** (String) Image type linux, windows or other
|
||||
- **name** (String) Name of the rescue disk
|
||||
- **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
|
||||
- **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
|
||||
- **id** (String) The ID of this resource.
|
||||
- **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
|
||||
- **reason** (String)
|
||||
- **sep_id** (Number) storage endpoint provider ID
|
||||
- **shared_with** (List of Number)
|
||||
- **sync** (Boolean) Create image from a media identified by URL (in synchronous mode)
|
||||
- **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
|
||||
|
||||
- **desc** (String)
|
||||
- **guid** (Number)
|
||||
- **history** (List of Object) (see [below for nested schema](#nestedatt--history))
|
||||
- **last_modified** (Number)
|
||||
- **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)
|
||||
|
||||
|
||||
70
docs/resources/kubernetes.md
Normal file
70
docs/resources/kubernetes.md
Normal file
@@ -0,0 +1,70 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_k8s Resource - terraform-provider-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
|
||||
|
||||
- **id** (String) The ID of this resource.
|
||||
- **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.
|
||||
- **kubeconfig** (String) Kubeconfig for cluster access.
|
||||
|
||||
<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.
|
||||
|
||||
|
||||
43
docs/resources/kubernetes_wg.md
Normal file
43
docs/resources/kubernetes_wg.md
Normal file
@@ -0,0 +1,43 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_k8s_wg Resource - terraform-provider-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.
|
||||
- **id** (String) The ID of this resource.
|
||||
- **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))
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **create** (String)
|
||||
- **default** (String)
|
||||
- **delete** (String)
|
||||
- **read** (String)
|
||||
- **update** (String)
|
||||
|
||||
|
||||
85
docs/resources/kvmvm.md
Normal file
85
docs/resources/kvmvm.md
Normal file
@@ -0,0 +1,85 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_kvmvm Resource - terraform-provider-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.
|
||||
- **extra_disks** (Set of Number) Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.
|
||||
- **id** (String) The ID of this resource.
|
||||
- **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))
|
||||
- **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.
|
||||
- **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)
|
||||
|
||||
|
||||
46
docs/resources/pfw.md
Normal file
46
docs/resources/pfw.md
Normal file
@@ -0,0 +1,46 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_pfw Resource - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_pfw (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **compute_id** (Number) ID of compute instance.
|
||||
- **local_base_port** (Number) Internal base port number.
|
||||
- **proto** (String) Network protocol, either 'tcp' or 'udp'.
|
||||
- **public_port_start** (Number) External start port number for the rule.
|
||||
|
||||
### Optional
|
||||
|
||||
- **id** (String) The ID of this resource.
|
||||
- **public_port_end** (Number) End port number (inclusive) for the ranged rule.
|
||||
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
|
||||
|
||||
### Read-Only
|
||||
|
||||
- **local_ip** (String) IP address of compute instance.
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **create** (String)
|
||||
- **default** (String)
|
||||
- **delete** (String)
|
||||
- **read** (String)
|
||||
- **update** (String)
|
||||
|
||||
|
||||
63
docs/resources/resgroup.md
Normal file
63
docs/resources/resgroup.md
Normal file
@@ -0,0 +1,63 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_resgroup Resource - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_resgroup (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **account_id** (Number) Unique ID of the account, which this resource group belongs to.
|
||||
- **name** (String) Name of this resource group. Names are case sensitive and unique within the context of a account.
|
||||
|
||||
### Optional
|
||||
|
||||
- **def_net_type** (String) Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.
|
||||
- **description** (String) User-defined text description of this resource group.
|
||||
- **ext_ip** (String) IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0
|
||||
- **ext_net_id** (Number) ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE
|
||||
- **id** (String) The ID of this resource.
|
||||
- **ipcidr** (String) Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE
|
||||
- **quota** (Block List, Max: 1) Quota settings for this resource group. (see [below for nested schema](#nestedblock--quota))
|
||||
- **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).
|
||||
|
||||
<a id="nestedblock--quota"></a>
|
||||
### Nested Schema for `quota`
|
||||
|
||||
Optional:
|
||||
|
||||
- **cpu** (Number) Limit on the total number of CPUs in this resource group.
|
||||
- **disk** (Number) Limit on the total volume of storage resources in this resource group, specified in GB.
|
||||
- **ext_ips** (Number) Limit on the total number of external IP addresses this resource group can use.
|
||||
- **ext_traffic** (Number) Limit on the total ingress network traffic for this resource group, specified in GB.
|
||||
- **gpu_units** (Number) Limit on the total number of virtual GPUs this resource group can use.
|
||||
- **ram** (Number) Limit on the total amount of RAM in this resource group, specified in MB.
|
||||
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **create** (String)
|
||||
- **default** (String)
|
||||
- **delete** (String)
|
||||
- **read** (String)
|
||||
- **update** (String)
|
||||
|
||||
|
||||
48
docs/resources/vins.md
Normal file
48
docs/resources/vins.md
Normal file
@@ -0,0 +1,48 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_vins Resource - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_vins (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **account_id** (Number) ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.
|
||||
- **ext_net_id** (Number) ID of the external network this ViNS is connected to. Pass 0 if no external connection required.
|
||||
- **name** (String) Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.
|
||||
|
||||
### Optional
|
||||
|
||||
- **description** (String) Optional user-defined text description of this ViNS.
|
||||
- **id** (String) The ID of this resource.
|
||||
- **ipcidr** (String) Network address to use by this ViNS. This parameter is only valid when creating new ViNS.
|
||||
- **rg_id** (Number) ID of the resource group, where this ViNS belongs to. Non-zero 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.
|
||||
- **ext_ip_addr** (String) IP address of the external connection (valid for ViNS connected to external network, ignored otherwise).
|
||||
|
||||
<a id="nestedblock--timeouts"></a>
|
||||
### Nested Schema for `timeouts`
|
||||
|
||||
Optional:
|
||||
|
||||
- **create** (String)
|
||||
- **default** (String)
|
||||
- **delete** (String)
|
||||
- **read** (String)
|
||||
- **update** (String)
|
||||
|
||||
|
||||
92
docs/resources/virtual_image.md
Normal file
92
docs/resources/virtual_image.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
# generated by https://github.com/hashicorp/terraform-plugin-docs
|
||||
page_title: "decort_virtual_image Resource - terraform-provider-decort"
|
||||
subcategory: ""
|
||||
description: |-
|
||||
|
||||
---
|
||||
|
||||
# decort_virtual_image (Resource)
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- schema generated by tfplugindocs -->
|
||||
## Schema
|
||||
|
||||
### Required
|
||||
|
||||
- **name** (String) name of the virtual image to create
|
||||
- **target_id** (Number) ID of real image to link this virtual image to upon creation
|
||||
|
||||
### 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
|
||||
- **id** (String) The ID of this resource.
|
||||
- **link_to** (Number)
|
||||
- **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
|
||||
- **reason** (String)
|
||||
- **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)
|
||||
- **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
|
||||
- **guid** (Number)
|
||||
- **history** (List of Object) (see [below for nested schema](#nestedatt--history))
|
||||
- **image_id** (Number) image id
|
||||
- **image_type** (String) Image type linux, windows or other
|
||||
- **last_modified** (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
|
||||
- **url** (String) URL where to download media from
|
||||
- **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)
|
||||
|
||||
|
||||
2
go.mod
2
go.mod
@@ -4,6 +4,8 @@ go 1.15
|
||||
|
||||
require (
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible
|
||||
github.com/google/uuid v1.3.0
|
||||
github.com/hashicorp/terraform-plugin-docs v0.5.1
|
||||
github.com/hashicorp/terraform-plugin-sdk v1.16.0
|
||||
github.com/sirupsen/logrus v1.7.0
|
||||
)
|
||||
|
||||
146
go.sum
146
go.sum
@@ -34,11 +34,26 @@ cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9
|
||||
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
|
||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
|
||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
|
||||
github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
|
||||
github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
|
||||
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
|
||||
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible h1:z4yfnGrZ7netVz+0EDJ0Wi+5VZCSYp4Z0m2dk6cEM60=
|
||||
github.com/Masterminds/sprig v2.22.0+incompatible/go.mod h1:y6hNFY5UBTIWBxnzTeuNhlNS5hqE0NB0E6fgfo2Br3o=
|
||||
github.com/Microsoft/go-winio v0.4.14/go.mod h1:qXqCSQ3Xa7+6tgxaGTIe4Kpcdsi+P8jBhyzoq1bpyYA=
|
||||
github.com/Microsoft/go-winio v0.4.16 h1:FtSW/jqD+l4ba5iPBj9CODVtgfYAD8w2wS923g/cFDk=
|
||||
github.com/Microsoft/go-winio v0.4.16/go.mod h1:XB6nPKklQyQ7GC9LdcBEcBl8PF76WugXOPRXwdLnMv0=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7 h1:YoJbenK9C67SkzkDfmQuVln04ygHj3vjZfd9FL+GmQQ=
|
||||
github.com/ProtonMail/go-crypto v0.0.0-20210428141323-04723f9f07d7/go.mod h1:z4/9nQmJSSwwds7ejkxaJwO37dru3geImFUdJlaLzQo=
|
||||
github.com/acomagu/bufpipe v1.0.3 h1:fxAGrHZTgQ9w5QqVItgzwj235/uYZYgbXitB+dLupOk=
|
||||
github.com/acomagu/bufpipe v1.0.3/go.mod h1:mxdxdup/WdsKVreO5GpW4+M/1CE2sMG4jeGJ2sYmHc4=
|
||||
github.com/agext/levenshtein v1.2.1/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/agext/levenshtein v1.2.2 h1:0S/Yg6LYmFJ5stwQeRp6EeOcCbj7xiqQSdNelsXvaqE=
|
||||
github.com/agext/levenshtein v1.2.2/go.mod h1:JEDfjyjHDjOF/1e4FlBE/PkbqA9OfWu2ki2W0IB5558=
|
||||
github.com/agl/ed25519 v0.0.0-20170116200512-5312a6153412/go.mod h1:WPjqKcmVOxf0XSf3YxCJs6N6AOSrOx3obionmG7T0y0=
|
||||
github.com/alcortesm/tgz v0.0.0-20161220082320-9c5fe88206d7/go.mod h1:6zEj6s6u/ghQa61ZWa/C2Aw3RkjiTBOix7dkqa1VLIs=
|
||||
github.com/andybalholm/crlf v0.0.0-20171020200849-670099aa064f/go.mod h1:k8feO4+kXDxro6ErPXBRTJ/ro2mf0SsFG8s7doP9kJE=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239 h1:kFOfPq6dUM1hTo4JG6LR5AXSUEsOjtdm0kw0FtQtMJA=
|
||||
github.com/anmitsu/go-shlex v0.0.0-20161002113705-648efa622239/go.mod h1:2FmKhYUyUczH0OGQWaF5ceTx0UBShxjsH6f8oGKYe2c=
|
||||
github.com/apparentlymart/go-cidr v1.0.1 h1:NmIwLZ/KdsjIUlhf+/Np40atNXm/+lZ5txfTJ/SpF+U=
|
||||
github.com/apparentlymart/go-cidr v1.0.1/go.mod h1:EBcsNrHc3zQeuaeCeCtQruQm+n9/YjEn/vI25Lg7Gwc=
|
||||
@@ -47,9 +62,12 @@ github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0 h1:MzVXffFU
|
||||
github.com/apparentlymart/go-dump v0.0.0-20190214190832-042adf3cf4a0/go.mod h1:oL81AME2rN47vu18xqj1S1jPIPuN7afo62yKTNn3XMM=
|
||||
github.com/apparentlymart/go-textseg v1.0.0 h1:rRmlIsPEEhUTIKQb7T++Nz/A5Q6C9IuX2wFoYVvnCs0=
|
||||
github.com/apparentlymart/go-textseg v1.0.0/go.mod h1:z96Txxhf3xSFMPmb5X/1W05FF/Nj9VFpLOpjS5yuumk=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0 h1:Y+KvPE1NYz0xl601PVImeQfFyEy6iT90AvPUL1NNfNw=
|
||||
github.com/apparentlymart/go-textseg/v13 v13.0.0/go.mod h1:ZK2fH7c4NqDTLtiYLvIkEghdlcqw7yxLeM89kiTRPUo=
|
||||
github.com/armon/go-radix v0.0.0-20180808171621-7fddfc383310/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-radix v1.0.0 h1:F4z6KzEeeQIMeLFa97iZU6vupzoecKdU5TX24SNppXI=
|
||||
github.com/armon/go-radix v1.0.0/go.mod h1:ufUuZ+zHj4x4TnLV4JWEpy2hxWSpsRywHrMgIH9cCH8=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5 h1:0CwZNZbxp69SHPdPJAN/hZIm0C4OItdklCFmMRWYpio=
|
||||
github.com/armon/go-socks5 v0.0.0-20160902184237-e75332964ef5/go.mod h1:wHh0iHkYZB8zMSxRWpUBQtwG5a7fFgvEO+odwuTv2gs=
|
||||
github.com/aws/aws-sdk-go v1.15.78/go.mod h1:E3/ieXAlvM0XWO57iftYVDLLvQ824smPP3ATZkfNZeM=
|
||||
github.com/aws/aws-sdk-go v1.25.3 h1:uM16hIw9BotjZKMZlX05SN2EFtaWfi/NonPKIARiBLQ=
|
||||
@@ -71,6 +89,7 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
|
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible h1:7qlOGliEKZXTDg6OTjfoBKDXWrumCAMpl/TFQ4/5kLM=
|
||||
github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ=
|
||||
github.com/emirpasic/gods v1.12.0 h1:QAUIPSaCu4G+POclxeqb3F+WPpdKqFGlw36+yOzGlrg=
|
||||
github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3ymbK86o=
|
||||
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
|
||||
@@ -78,12 +97,22 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m
|
||||
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
|
||||
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
|
||||
github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568 h1:BHsljHzVlRcyQhjrss6TZTdY2VfCqZPbv5k3iBFa2ZQ=
|
||||
github.com/flynn/go-shlex v0.0.0-20150515145356-3f9db97f8568/go.mod h1:xEzjJPgXI435gkrCt3MPfRiAkVrwSbHsst4LCFVfpJc=
|
||||
github.com/gliderlabs/ssh v0.2.2 h1:6zsha5zo/TWhRhwqCD3+EarCAgZ2yN28ipRnGPnwkI0=
|
||||
github.com/gliderlabs/ssh v0.2.2/go.mod h1:U7qILu1NlMHj9FlMhZLlkCdDnU1DBEAqr0aevW3Awn0=
|
||||
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
|
||||
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
|
||||
github.com/go-git/go-billy/v5 v5.0.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.2.0/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-billy/v5 v5.3.1 h1:CPiOUAzKtMRvolEKw+bG1PLRpT7D3LIs3/3ey4Aiu34=
|
||||
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.0.1/go.mod h1:m+ICp2rF3jDhFgEZ/8yziagdT1C+ZpZcrJjappBCDSw=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.2.1 h1:n9gGL1Ct/yIw+nfsfr8s4+sbhT+Ncu2SubfXjIWgci8=
|
||||
github.com/go-git/go-git-fixtures/v4 v4.2.1/go.mod h1:K8zd3kDUAykwTdDCr+I0per6Y6vMiRR/nnVTBtavnB0=
|
||||
github.com/go-git/go-git/v5 v5.1.0/go.mod h1:ZKfuPUoY1ZqIG4QG9BDBh3G4gLM5zvPuSJAozQrZuyM=
|
||||
github.com/go-git/go-git/v5 v5.4.2 h1:BXyZu9t0VkbiHtqrsvdq39UDhGJTl1h55VW6CSC4aY4=
|
||||
github.com/go-git/go-git/v5 v5.4.2/go.mod h1:gQ1kArt6d+n+BGd+/B/I74HwRTLhth2+zti4ihgckDc=
|
||||
github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
|
||||
@@ -124,8 +153,9 @@ github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMyw
|
||||
github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
|
||||
github.com/google/go-cmp v0.4.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.4.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.0 h1:/QaMHBdZ26BB3SSst0Iwl10Epc+xhTquomWX0oZEB6w=
|
||||
github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ=
|
||||
github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
|
||||
github.com/google/martian v2.1.0+incompatible h1:/CP5g8u/VJHijgedC/Legn3BAbAaWPgecwXBIDzw5no=
|
||||
github.com/google/martian v2.1.0+incompatible/go.mod h1:9I4somxYTbIHy5NJKHRl3wXiIaQGbYVAs8BPL6v8lEs=
|
||||
github.com/google/martian/v3 v3.0.0 h1:pMen7vLs8nvgEYhywH3KDWJIJTeEr2ULsVWHWYHQyBs=
|
||||
@@ -138,20 +168,25 @@ github.com/google/pprof v0.0.0-20200229191704-1ebb73c60ed3/go.mod h1:ZgVRPoUq/hf
|
||||
github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
|
||||
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
|
||||
github.com/google/uuid v1.1.1 h1:Gkbcsh/GbpXz7lPftLA3P6TYMwjCLYm83jiFQZF/3gY=
|
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
|
||||
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
|
||||
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
|
||||
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
|
||||
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
|
||||
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
|
||||
github.com/hashicorp/go-checkpoint v0.5.0 h1:MFYpPZCnQqQTE18jFwSII6eUQrD/oxMFp3mlgcqk5mU=
|
||||
github.com/hashicorp/go-checkpoint v0.5.0/go.mod h1:7nfLNL10NsxqO4iWuW6tWW0HjZuDrwkBuEQsVcpCOgg=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ=
|
||||
github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48=
|
||||
github.com/hashicorp/go-getter v1.4.0/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY=
|
||||
github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02 h1:l1KB3bHVdvegcIf5upQ5mjcHjs2qsWnKh4Yr9xgIuu8=
|
||||
github.com/hashicorp/go-getter v1.4.2-0.20200106182914-9813cbd4eb02/go.mod h1:7qxyCd8rBfcShwsvxgIguu4KbS3l8bUCwg2Umn7RjeY=
|
||||
github.com/hashicorp/go-getter v1.5.3 h1:NF5+zOlQegim+w/EUhSLh6QhXHmZMEeHLQzllkQ3ROU=
|
||||
github.com/hashicorp/go-getter v1.5.3/go.mod h1:BrrV/1clo8cCYu6mxvboYg+KutTiFnXjMEgDD8+i7ZI=
|
||||
github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI=
|
||||
github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI=
|
||||
github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ=
|
||||
@@ -166,8 +201,9 @@ github.com/hashicorp/go-uuid v1.0.1 h1:fv1ep09latC32wFoVwnqcnKJGnMSdBanPczbHAYm1
|
||||
github.com/hashicorp/go-uuid v1.0.1/go.mod h1:6SBZvOh/SIDV7/2o3Jml5SYk/TvGqwFJ/bN7x4byOro=
|
||||
github.com/hashicorp/go-version v1.1.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.2.1 h1:zEfKbn2+PDgroKdiOzqiE8rsmLqU2uwi5PB5pBJ3TkI=
|
||||
github.com/hashicorp/go-version v1.2.1/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/go-version v1.3.0 h1:McDWVJIU/y+u1BRV06dPaLfLCaT7fUTJLp5r04x7iNw=
|
||||
github.com/hashicorp/go-version v1.3.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/hcl v0.0.0-20170504190234-a4b07c25de5f h1:UdxlrJz4JOnY8W+DbLISwf2B8WXEolNRA8BGCwI9jws=
|
||||
@@ -180,7 +216,13 @@ github.com/hashicorp/logutils v1.0.0/go.mod h1:QIAnNjmIWmVIIkWDTG1z5v++HQmx9WQRO
|
||||
github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8 h1:+RyjwU+Gnd/aTJBPZVDNm903eXVjjqhbaR4Ypx3xYyY=
|
||||
github.com/hashicorp/terraform-config-inspect v0.0.0-20191115094559-17f92b0546e8/go.mod h1:p+ivJws3dpqbp1iP84+npOyAmTTOLMgCzrXd3GSdn/A=
|
||||
github.com/hashicorp/terraform-exec v0.10.0/go.mod h1:tOT8j1J8rP05bZBGWXfMyU3HkLi1LWyqL3Bzsc3CJjo=
|
||||
github.com/hashicorp/terraform-exec v0.15.0 h1:cqjh4d8HYNQrDoEmlSGelHmg2DYDh5yayckvJ5bV18E=
|
||||
github.com/hashicorp/terraform-exec v0.15.0/go.mod h1:H4IG8ZxanU+NW0ZpDRNsvh9f0ul7C0nHP+rUR/CHs7I=
|
||||
github.com/hashicorp/terraform-json v0.5.0/go.mod h1:eAbqb4w0pSlRmdvl8fOyHAi/+8jnkVYN28gJkSJrLhU=
|
||||
github.com/hashicorp/terraform-json v0.13.0 h1:Li9L+lKD1FO5RVFRM1mMMIBDoUHslOniyEi5CM+FWGY=
|
||||
github.com/hashicorp/terraform-json v0.13.0/go.mod h1:y5OdLBCT+rxbwnpxZs9kGL7R9ExU76+cpdY8zHwoazk=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.5.1 h1:WwrUcamix9x0TqfTw/WGHMRqoTe1QPZKaeWJPuFb4lQ=
|
||||
github.com/hashicorp/terraform-plugin-docs v0.5.1/go.mod h1:SQwEgy0/B0UPQ07rNEG1Wpt6E3jvRcCwkVHPNybGgc0=
|
||||
github.com/hashicorp/terraform-plugin-sdk v1.16.0 h1:NrkXMRjHErUPPTHQkZ6JIn6bByiJzGnlJzH1rVdNEuE=
|
||||
github.com/hashicorp/terraform-plugin-sdk v1.16.0/go.mod h1:5sVxrwW6/xzFhZyql+Q9zXCUEJaGWcBIxBbZFLpVXOI=
|
||||
github.com/hashicorp/terraform-plugin-test/v2 v2.1.2/go.mod h1:jerO5mrd+jVNALy8aiq+VZOg/CR8T2T1QR3jd6JKGOI=
|
||||
@@ -189,10 +231,17 @@ github.com/hashicorp/terraform-svchost v0.0.0-20191011084731-65d371908596/go.mod
|
||||
github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
|
||||
github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
|
||||
github.com/huandu/xstrings v1.3.2 h1:L18LIDzqlW6xN2rEkpdV8+oL/IXWJ1APd+vsdYy4Wdw=
|
||||
github.com/huandu/xstrings v1.3.2/go.mod h1:y5/lhBue+AyNmUVz9RLU9xbLR0o4KIIExikq4ovT0aE=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
|
||||
github.com/imdario/mergo v0.3.11/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/imdario/mergo v0.3.12 h1:b6R2BslTbIEToALKP7LxUvijTsNI9TAe80pLWN2g/HU=
|
||||
github.com/imdario/mergo v0.3.12/go.mod h1:jmQim1M+e3UYxmgPu/WyfjB3N3VflVyUjjjwH0dnCYA=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99 h1:BQSFePA1RWJOlocH6Fxy8MmwDt+yVQYULKfN0RoTN8A=
|
||||
github.com/jbenet/go-context v0.0.0-20150711004518-d14ea06fba99/go.mod h1:1lJo3i6rXxKeerYnT8Nvf0QmHCRC1n8sfWVwXF2Frvo=
|
||||
github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI=
|
||||
github.com/jessevdk/go-flags v1.5.0/go.mod h1:Fw0T6WPc1dYxT4mKEZRfG5kJhaTDP9pj1c2EWnYs/m4=
|
||||
github.com/jhump/protoreflect v1.6.0 h1:h5jfMVslIg6l29nsMs0D8Wj17RDVdNYti0vDN/PZZoE=
|
||||
github.com/jhump/protoreflect v1.6.0/go.mod h1:eaTn3RZAmMBcV0fifFvlm6VHNz3wSkYyXYWUh7ymB74=
|
||||
github.com/jmespath/go-jmespath v0.0.0-20160202185014-0b12d6b521d8/go.mod h1:Nht3zPeWKUH0NzdCt2Blrr5ys8VGpn0CEB0cQHVjt7k=
|
||||
@@ -202,10 +251,16 @@ github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1
|
||||
github.com/jstemmer/go-junit-report v0.9.1 h1:6QPYqodiu3GuPL+7mfx+NwDdp2eTkp9IfEUpgAwUN0o=
|
||||
github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20190725054713-01f96b0aa0cd/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351 h1:DowS9hvgyYSX4TO5NpyC606/Z4SxnNYbT+WX27or6Ck=
|
||||
github.com/kevinburke/ssh_config v0.0.0-20201106050909-4977a11b4351/go.mod h1:CT57kijsi8u/K/BOFA39wgDQJ9CxiF4nAY/ojJ6r6mM=
|
||||
github.com/keybase/go-crypto v0.0.0-20161004153544-93f5b35093ba/go.mod h1:ghbZscTyKdM07+Fw3KSi0hcJm+AlEUWj8QLlPtijN/M=
|
||||
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
|
||||
github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
|
||||
github.com/klauspost/compress v1.11.2 h1:MiK62aErc3gIiVEtyzKfeOHgW7atJb5g/KNX5m3c2nQ=
|
||||
github.com/klauspost/compress v1.11.2/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs=
|
||||
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
|
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
|
||||
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
|
||||
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
|
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
|
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
|
||||
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
|
||||
@@ -213,19 +268,25 @@ github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
|
||||
github.com/kylelemons/godebug v0.0.0-20170820004349-d65d576e9348/go.mod h1:B69LEHPfb2qLo0BaaOLcbitczOKLWTsrBG9LczfCD4k=
|
||||
github.com/kylelemons/godebug v1.1.0 h1:RPNrshWIDI6G2gRW9EHilWtl7Z6Sb1BR0xunSBf0SNc=
|
||||
github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
|
||||
github.com/matryer/is v1.2.0 h1:92UTHpy8CDwaJ08GqLDzhhuixiBUUD1p3AU6PHddz4A=
|
||||
github.com/matryer/is v1.2.0/go.mod h1:2fLPjFQM9rhQ15aVEtbuwhJinnOqrmgXPNdZsdwlWXA=
|
||||
github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
|
||||
github.com/mattn/go-colorable v0.1.1 h1:G1f5SKeVxmagw/IyvzvtZE4Gybcc4Tr1tf7I8z0XgOg=
|
||||
github.com/mattn/go-colorable v0.1.1/go.mod h1:FuOcm+DKB9mbwrcAfNl7/TZVBZ6rcnceauSikq3lYCQ=
|
||||
github.com/mattn/go-colorable v0.1.11 h1:nQ+aFkoE2TMGc0b68U2OKSexC+eq46+XwZzWXHRmPYs=
|
||||
github.com/mattn/go-colorable v0.1.11/go.mod h1:u5H1YNBxpqRaxsYJYSkiCWKzEfiAb1Gb520KVy5xxl4=
|
||||
github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
|
||||
github.com/mattn/go-isatty v0.0.5 h1:tHXDdz1cpzGaovsTB+TVB8q90WEokoVmfMqoVcrLUgw=
|
||||
github.com/mattn/go-isatty v0.0.5/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
|
||||
github.com/mattn/go-isatty v0.0.14 h1:yVuAays6BHfxijgZPzw+3Zlu5yQgKGP2/hcQbHb7S9Y=
|
||||
github.com/mattn/go-isatty v0.0.14/go.mod h1:7GGIvUiUoEMVVmxf/4nioHXj79iQHKdU27kJ6hsGG94=
|
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
|
||||
github.com/mitchellh/cli v1.1.1 h1:J64v/xD7Clql+JVKSvkYojLOXu1ibnY9ZjGLwSt/89w=
|
||||
github.com/mitchellh/cli v1.1.1/go.mod h1:xcISNoH86gajksDmfB23e/pu+B+GeFRMYmoHXxx3xhI=
|
||||
github.com/mitchellh/cli v1.1.2 h1:PvH+lL2B7IQ101xQL63Of8yFS2y+aDlsFcsqNc+u/Kw=
|
||||
github.com/mitchellh/cli v1.1.2/go.mod h1:6iaV0fGdElS6dPBx0EApTxHrcWvmJphyh2n8YBLPPZ4=
|
||||
github.com/mitchellh/colorstring v0.0.0-20190213212951-d06e56a500db/go.mod h1:l0dey0ia/Uv7NcFFVbCLtqEBQbrT4OCwCSKTEv6enCw=
|
||||
github.com/mitchellh/copystructure v1.0.0 h1:Laisrj+bAB6b/yJwB5Bt3ITZhGJdqmxquMKeZ+mmkFQ=
|
||||
github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFWgYaq1OVrnRcwhnw=
|
||||
github.com/mitchellh/copystructure v1.2.0 h1:vpKXTN4ewci03Vljg/q9QvCGUDttBOGBIa15WveJJGw=
|
||||
github.com/mitchellh/copystructure v1.2.0/go.mod h1:qLl+cE2AmVv+CoeAwDPye/v+N2HKCj9FbZEVFJRxO9s=
|
||||
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
|
||||
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
|
||||
@@ -239,14 +300,16 @@ github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUb
|
||||
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
|
||||
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
|
||||
github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/mitchellh/reflectwalk v1.0.1 h1:FVzMWA5RllMAKIdUSC8mdWo3XtwoecrH79BY70sEEpE=
|
||||
github.com/mitchellh/reflectwalk v1.0.1/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs=
|
||||
github.com/mitchellh/reflectwalk v1.0.2 h1:G2LzWKi524PWgd3mLHV8Y5k7s6XUvT0Gef6zxSIeXaQ=
|
||||
github.com/mitchellh/reflectwalk v1.0.2/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw=
|
||||
github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno=
|
||||
github.com/oklog/run v1.0.0 h1:Ru7dDtJNOyC66gQ5dQmaCa0qIsAUFY3sFpK1Xk8igrw=
|
||||
github.com/oklog/run v1.0.0/go.mod h1:dlhp/R75TPv97u0XWUtDeV/lRKWPKSdTuV0TZvrmrQA=
|
||||
github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY=
|
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
|
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||
github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
|
||||
@@ -254,9 +317,14 @@ github.com/posener/complete v1.2.1 h1:LrvDIY//XNo65Lq84G/akBuMGlawHvGBABv8f/ZN6D
|
||||
github.com/posener/complete v1.2.1/go.mod h1:6gapUrK/U1TAN7ciCoNRIdVC5sbdBTUh1DKN0g6uH7E=
|
||||
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
|
||||
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
|
||||
github.com/russross/blackfriday v1.6.0 h1:KqfZb0pUVN2lYqZUYRddxF4OR8ZMURnJIG5Y3VRLtww=
|
||||
github.com/russross/blackfriday v1.6.0/go.mod h1:ti0ldHuxg49ri4ksnFxlkCfN+hvslNlmVHqNRXXJNAY=
|
||||
github.com/sebdah/goldie v1.0.0/go.mod h1:jXP4hmWywNEwZzhMuv2ccnqTSFpuq8iyQhtQdkkZBH4=
|
||||
github.com/sergi/go-diff v1.0.0/go.mod h1:0CfEIISq7TuYL3j771MWULgwwjU+GofnZX9QAmXWZgo=
|
||||
github.com/sergi/go-diff v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
|
||||
github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sergi/go-diff v1.2.0 h1:XU+rvMAioB0UC3q1MFrIQy4Vo5/4VsRDQQXHsEya6xQ=
|
||||
github.com/sergi/go-diff v1.2.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM=
|
||||
github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q=
|
||||
github.com/sirupsen/logrus v1.7.0 h1:ShrD1U9pZB12TX0cVy0DtePoCH97K8EtX+mg7ZARUtM=
|
||||
github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0=
|
||||
github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc=
|
||||
@@ -264,25 +332,38 @@ github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTd
|
||||
github.com/spf13/pflag v1.0.2/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
|
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
|
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI=
|
||||
github.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=
|
||||
github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=
|
||||
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
|
||||
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||
github.com/ulikunitz/xz v0.5.5/go.mod h1:2bypXElzHzzJZwzH67Y6wb67pO62Rzfn7BSiF4ABRW8=
|
||||
github.com/ulikunitz/xz v0.5.7 h1:YvTNdFzX6+W5m9msiYg/zpkSURPPtOlzbqYjrFn7Yt4=
|
||||
github.com/ulikunitz/xz v0.5.7/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/ulikunitz/xz v0.5.8 h1:ERv8V6GKqVi23rgu5cj9pVfVzJbOqAY2Ntl88O6c2nQ=
|
||||
github.com/ulikunitz/xz v0.5.8/go.mod h1:nbz6k7qbPmH4IRqmfOplQw/tblSgqTqBwxkY0oWt/14=
|
||||
github.com/vmihailenco/msgpack v3.3.3+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmihailenco/msgpack v4.0.1+incompatible h1:RMF1enSPeKTlXrXdOcqjFUElywVZjjC6pqse21bKbEU=
|
||||
github.com/vmihailenco/msgpack v4.0.1+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12 h1:07s4sz9IReOgdikxLTKNbBdqDMLsjPKXwvCazn8G65U=
|
||||
github.com/vmihailenco/msgpack/v4 v4.3.12/go.mod h1:gborTTJjAo/GWTqqRjrLCn9pgNN+NXzzngzBKDPIqw4=
|
||||
github.com/vmihailenco/tagparser v0.1.1 h1:quXMXlA39OCbd2wAdTsGDlK9RkOk6Wuw+x37wVyIuWY=
|
||||
github.com/vmihailenco/tagparser v0.1.1/go.mod h1:OeAg3pn3UbLjkWt+rN9oFYB6u/cQgqMEUPoW2WPyhdI=
|
||||
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
|
||||
github.com/xanzy/ssh-agent v0.3.0 h1:wUMzuKtKilRgBAD1sUb8gOwwRr2FGoBVumcjoOACClI=
|
||||
github.com/xanzy/ssh-agent v0.3.0/go.mod h1:3s9xbODqPuuhK9JV1R321M/FlMZSBvE5aY6eAcqrDh0=
|
||||
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
|
||||
github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
|
||||
github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s=
|
||||
github.com/zclconf/go-cty v1.2.0/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||
github.com/zclconf/go-cty v1.2.1 h1:vGMsygfmeCl4Xb6OA5U5XVAaQZ69FvoG7X2jUtQujb8=
|
||||
github.com/zclconf/go-cty v1.2.1/go.mod h1:hOPWgoHbaTUnI5k4D2ld+GRpFJSCe6bCM7m1q/N4PQ8=
|
||||
github.com/zclconf/go-cty v1.9.1/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zclconf/go-cty v1.10.0 h1:mp9ZXQeIcN8kAwuqorjH+Q+njbJKjLrvB2yIh4q7U+0=
|
||||
github.com/zclconf/go-cty v1.10.0/go.mod h1:vVKLxnk3puL4qRAv72AO+W99LUD4da90g3uUAzyuvAk=
|
||||
github.com/zclconf/go-cty-debug v0.0.0-20191215020915-b22d67c1ba0b/go.mod h1:ZRKQfBXbGkpdV6QMzT3rU1kSTAnfu1dO8dPKjYprgj8=
|
||||
github.com/zclconf/go-cty-yaml v1.0.1 h1:up11wlgAaDvlAGENcFDnZgkn0qUJurso7k6EpURKNF8=
|
||||
github.com/zclconf/go-cty-yaml v1.0.1/go.mod h1:IP3Ylp0wQpYm50IHK8OZWKMu6sPJIUgKa8XhiVHura0=
|
||||
go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU=
|
||||
@@ -298,8 +379,11 @@ golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8U
|
||||
golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
|
||||
golang.org/x/crypto v0.0.0-20200302210943-78000ba7a073/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
|
||||
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20200820211705-5c72a883971a/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
|
||||
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b h1:7mWr3k41Qtv8XlltBkDkl8LoP3mpSgBW8BUoxtEdbXg=
|
||||
golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
|
||||
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
|
||||
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
|
||||
@@ -359,8 +443,10 @@ golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/
|
||||
golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381 h1:VXak5I6aEWmAXeQjA+QSZzlgNrpq9mjcfDemuexIKsU=
|
||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897 h1:KrsHThm5nFk34YtATK1LsThyGhGbGe1olrte/HInHvs=
|
||||
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
|
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||
@@ -377,6 +463,7 @@ golang.org/x/sync v0.0.0-20200317015054-43a5402ce75a/go.mod h1:RxMgew5VJxzue5/jJ
|
||||
golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190221075227-b4e8571b14e0/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
|
||||
@@ -388,6 +475,7 @@ golang.org/x/sys v0.0.0-20190507160741-ecd444e8653b/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20190606165138-5da285871e9c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190624142023-c5567b49c5d0/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20190916202348-b4ddaad3f8a3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20191204072324-ce4227a45e2e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
@@ -403,14 +491,23 @@ golang.org/x/sys v0.0.0-20200331124033-c3d80250170d/go.mod h1:h1NjWce9XRLGQEsW7w
|
||||
golang.org/x/sys v0.0.0-20200501052902-10377860bb8e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200511232937-7e40ca221e25/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200515095857-1151b9dac4a9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121 h1:rITEj+UZHYC927n8GT97eC3zrpzXdb/voyeOuVKS46o=
|
||||
golang.org/x/sys v0.0.0-20200523222454-059865788121/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210320140829-1e4c9ba3b0c4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210324051608-47abb6519492/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210502180810-71e4cd670f79/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||
golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6 h1:foEbQz/B0Oz6YIqu/69kfXPYeFQAuuMYFkjaqXzl5Wo=
|
||||
golang.org/x/sys v0.0.0-20210927094055-39ccf1dd6fa6/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1 h1:v+OssWQX+hTHEmOBgwxdZxK4zHq3yOs8F9J7mk0PY8E=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
|
||||
golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
|
||||
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/text v0.3.5 h1:i6eZZ+zk0SOf0xgBpEpPD18qWcJda6q1sxt3S0kzyUQ=
|
||||
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
|
||||
golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
|
||||
@@ -536,14 +633,19 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
|
||||
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU=
|
||||
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
|
||||
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q=
|
||||
gopkg.in/cheggaaa/pb.v1 v1.0.27/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
|
||||
gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI=
|
||||
gopkg.in/warnings.v0 v0.1.2 h1:wFXVbFY8DY5/xOe1ECiWdKCzZlxgshcYVNkBHstARME=
|
||||
gopkg.in/warnings.v0 v0.1.2/go.mod h1:jksf8JmL6Qr/oQM2OXTHunEvvTAsrWBLb6OOjuVWRNI=
|
||||
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.2.4 h1:/eiJrUcujPVeJ3xlSWaiNi3uSVmDGBK1pDHUHAnao1I=
|
||||
gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
|
||||
gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
|
||||
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||
honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
|
||||
|
||||
2
main.go
2
main.go
@@ -38,6 +38,8 @@ import (
|
||||
"github.com/rudecs/terraform-provider-decort/decort"
|
||||
)
|
||||
|
||||
//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
|
||||
|
||||
func main() {
|
||||
log.SetLevel(log.DebugLevel)
|
||||
log.Debug("Debug logging enabled")
|
||||
|
||||
29
samples/README.md
Normal file
29
samples/README.md
Normal file
@@ -0,0 +1,29 @@
|
||||
# Примеры применения ресурсов terraform-provider-decort
|
||||
Каждый файл снабжен комментариями, которые кратко описывают возможности и параметры ресурса.
|
||||
Для успешной работы необходим установленный terraform.
|
||||
## Ресурсы в примерах
|
||||
- data:
|
||||
- grid
|
||||
- grid_list
|
||||
- image
|
||||
- image_list
|
||||
- image_list_stacks
|
||||
- resources:
|
||||
- image
|
||||
- virtual_image
|
||||
- cdrom_image
|
||||
- delete_images
|
||||
- k8s
|
||||
- k8s_wg
|
||||
|
||||
## Как пользоваться примерами
|
||||
1. Установить terraform
|
||||
2. Установить terraform-provider-decort с помощью команды `terraform init` (выполняется автоматически), либо вручную.
|
||||
3. Заменить параметр *controller_url* на ваш.
|
||||
4. Заменить параметр *oauth2* на ваш.
|
||||
5. Добавить ключи
|
||||
*DECORT_APP_SECRET* и *DECORT_APP_ID*
|
||||
в качестве переменных окружения, либо
|
||||
можно добавить `app_id` и `app_secret`
|
||||
в блок `provider`,что небезопасно, т.к. данные
|
||||
могут быть похищены при передачи файла.
|
||||
38
samples/data_grid/main.tf
Normal file
38
samples/data_grid/main.tf
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Пример использования
|
||||
Получение data source grid по id
|
||||
*/
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
data "decort_grid" "image" {
|
||||
#id grid для получения информации
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
grid_id = 1
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_grid.image
|
||||
}
|
||||
45
samples/data_grid_list/main.tf
Normal file
45
samples/data_grid_list/main.tf
Normal file
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
Пример использования
|
||||
Получение списка grid
|
||||
|
||||
*/
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
||||
data "decort_grid_list" "gl" {
|
||||
#номер страницы для отображения
|
||||
#опциональный параметр, тип - число
|
||||
#если не задан - выводятся все доступные данные
|
||||
#page = 2
|
||||
|
||||
#размер страницы
|
||||
#опциональный параметр, тип - число
|
||||
#если не задан - выводятся все доступные данные
|
||||
#size = 3
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_grid_list.gl
|
||||
}
|
||||
38
samples/data_image/main.tf
Normal file
38
samples/data_image/main.tf
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
Пример использования
|
||||
Получение образа по id
|
||||
*/
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
data "decort_image" "image" {
|
||||
#id образа
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
image_id = 5912
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_image.image
|
||||
}
|
||||
58
samples/data_image_list/main.tf
Normal file
58
samples/data_image_list/main.tf
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
Пример использования
|
||||
Получение списка образов
|
||||
*/
|
||||
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
data "decort_image_list" "il" {
|
||||
#номер страницы для отображения
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#если не задан - выводятся все доступные данные
|
||||
#page = 2
|
||||
|
||||
#размер страницы
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#если не задан - выводятся все доступные данные
|
||||
#size = 3
|
||||
|
||||
#фильтрация образов по id хранилища
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#если не задан - выволятся все доступные элементы
|
||||
#sep_id = 123
|
||||
|
||||
#фильтрация образов по id доступных аккаунтов
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#если не задан - выволятся все доступные элементы
|
||||
#shared_with = 123
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_image_list.il
|
||||
}
|
||||
49
samples/data_image_list_stacks/main.tf
Normal file
49
samples/data_image_list_stacks/main.tf
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
Пример использования
|
||||
Получение списка stack по id образа
|
||||
*/
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
data "decort_image_list_stacks" "im" {
|
||||
#id образа
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
image_id = 6040
|
||||
|
||||
#номер страницы для отображения информации
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#если не задан - отображается вся доступная информация
|
||||
#page = 2
|
||||
|
||||
#количество отображаемых объектов на странице
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#если не задан - отображается вся доступная информация
|
||||
#size = 3
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = data.decort_image_list_stacks.im
|
||||
}
|
||||
63
samples/resource_delete_images/main.tf
Normal file
63
samples/resource_delete_images/main.tf
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
Пример использования
|
||||
Ресурса delete images
|
||||
Ресурс является служебным
|
||||
Его можно использоваться для быстрого удаления нескольких образов
|
||||
*/
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
resource "decort_delete_images" "my_images" {
|
||||
#массив, содержащий набор id образов для удаления
|
||||
#обязательный параметр
|
||||
#тип - массив чисел
|
||||
image_ids = [6125]
|
||||
|
||||
#параметр удаления
|
||||
#опциональный тип
|
||||
#по-умолчанию - false
|
||||
#тип - булев тип
|
||||
permanently = true
|
||||
|
||||
#причина удаления
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
reason = "test delete"
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = decort_delete_images.my_images
|
||||
}
|
||||
|
||||
/*
|
||||
Применение:
|
||||
1. terraform plan
|
||||
2. terraform apply
|
||||
3. terraform destroy
|
||||
|
||||
|
||||
Примечание:
|
||||
Данный ресурс не поддерживает обновления параметров, поэтому, для переиспользования
|
||||
необходимо удалить старое состояние и повторить шаги выше.
|
||||
*/
|
||||
145
samples/resource_image/main.tf
Normal file
145
samples/resource_image/main.tf
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
Пример использования
|
||||
Ресурса image
|
||||
Ресурс позволяет:
|
||||
1. Создавать образ
|
||||
2. Редактировать образ
|
||||
3. Удалять образ
|
||||
|
||||
*/
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
resource "decort_image" "my_image" {
|
||||
#имя образа
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
#при изменении - изменяет название созданного образа
|
||||
name = "test_image_rename"
|
||||
|
||||
#адрес образа
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
url = "https://colba.decs.online/index.php/s/G3H7AREngzeKGw2/download"
|
||||
|
||||
#grid id образа
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
gid = 212
|
||||
|
||||
#тип загрузки образа
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
#возможные варианты: "bios" или "uefi"
|
||||
boot_type = "bios"
|
||||
|
||||
#тип образа
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
#возможные варианты - "linux", "windows"
|
||||
image_type = "linux"
|
||||
|
||||
#драйвера
|
||||
#обязательный параметр
|
||||
#тип - массив строк
|
||||
#возможные варианты - ["KVM_X86", "SVA_KVM_X86"], ["KVM_X86"], ["SVA_KVM_X86"]
|
||||
drivers = ["KVM_X86", "SVA_KVM_X86"]
|
||||
|
||||
#id аккаунта владельца образа
|
||||
#опциональный параметр
|
||||
#может быть использован как при создании,
|
||||
#так и при редактировании образа
|
||||
#тип данных - число
|
||||
#account_id = 57252
|
||||
|
||||
#имя пользователя и пароль
|
||||
#опциаональные параметры,
|
||||
#могут быть использованы как при создании образа,
|
||||
#так и при его редактировании
|
||||
#тип - строка
|
||||
#username = "Valera"
|
||||
#password = "123"
|
||||
|
||||
#имя пользователя и пароль для загрузки бинарных данных
|
||||
#опциаональные параметры,
|
||||
#могут быть использованы как при создании образа,
|
||||
#так и при его редактировании
|
||||
#тип - строка
|
||||
#username_dl = "Valera1"
|
||||
#password_dl = "1231"
|
||||
|
||||
#id storage endpoint
|
||||
#опциональный параметр, используется при создании
|
||||
#тип - число
|
||||
#sep_id = 1206
|
||||
|
||||
#пул для создания образа
|
||||
#опциональный тип, используется при создании образа
|
||||
#тип - строка
|
||||
#pool_name = "vmstor"
|
||||
|
||||
#архитектура системы образа
|
||||
#опциаональный параметр, используется при создании
|
||||
#тип - строка
|
||||
#доступные значения: "X86_64"
|
||||
#architecture = "X86_64"
|
||||
|
||||
#доступность образа
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - булево значение
|
||||
#enabled = true
|
||||
|
||||
#настройка доступа образа аккаунтам
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - массив чисел
|
||||
#пустой маасив - удаление всех доступов, если они были
|
||||
#shared_with = [28096, 57121]
|
||||
|
||||
#установка computeci
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - число
|
||||
#чтобы сбросить, необходимо передать 0
|
||||
#computeci_id = 1
|
||||
|
||||
#доступные стаки
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - массив строк
|
||||
#для удаления всех доступных стаков, необходимо передать пустой массив
|
||||
#enabled_stacks = ["9"]
|
||||
|
||||
#мгновенное удаление
|
||||
#опциональный параметр, можно использовать перед удалением
|
||||
#тип - булев тип
|
||||
#permanently = true
|
||||
|
||||
#причина удаления
|
||||
#опциональный параметр, можно использовать перед удалением
|
||||
#тип - строка
|
||||
#reason = "test"
|
||||
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = decort_image.my_image
|
||||
}
|
||||
127
samples/resource_image_cdrom/main.tf
Normal file
127
samples/resource_image_cdrom/main.tf
Normal file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
Пример использования
|
||||
Ресурса cdrom image
|
||||
Ресурс позволяет:
|
||||
1. Создавать образ
|
||||
2. Редактировать образ
|
||||
3. Удалять образ
|
||||
|
||||
*/
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
resource "decort_cdrom_image" "my_image" {
|
||||
#имя образа
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
#при изменении - изменяет название созданного образа
|
||||
name = "test_image_rename"
|
||||
|
||||
#адрес образа
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
url = "https://colba.decs.online/index.php/s/G3H7AREngzeKGw2/download"
|
||||
|
||||
#grid id образа
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
gid = 212
|
||||
|
||||
#драйвера
|
||||
#обязательный параметр
|
||||
#тип - массив строк
|
||||
#возможные варианты - ["KVM_X86", "SVA_KVM_X86"], ["KVM_X86"], ["SVA_KVM_X86"]
|
||||
drivers = ["KVM_X86", "SVA_KVM_X86"]
|
||||
|
||||
#id аккаунта владельца образа
|
||||
#опциональный параметр
|
||||
#может быть использован как при создании,
|
||||
#так и при редактировании образа
|
||||
#тип данных - число
|
||||
account_id = 57252
|
||||
|
||||
#имя пользователя и пароль
|
||||
#опциаональные параметры,
|
||||
#могут быть использованы как при создании образа,
|
||||
#так и при его редактировании
|
||||
#тип - строка
|
||||
username = "Valera"
|
||||
password = "123"
|
||||
|
||||
#имя пользователя и пароль для загрузки бинарных данных
|
||||
#опциаональные параметры,
|
||||
#могут быть использованы как при создании образа,
|
||||
#так и при его редактировании
|
||||
#тип - строка
|
||||
#username_dl = "Valera1"
|
||||
#password_dl = "1231"
|
||||
|
||||
#id storage endpoint
|
||||
#опциональный параметр, используется при создании
|
||||
#тип - число
|
||||
#sep_id = 1206
|
||||
|
||||
#пул для создания образа
|
||||
#опциональный тип, используется при создании образа
|
||||
#тип - строка
|
||||
#pool_name = "vmstor"
|
||||
|
||||
#архитектура системы образа
|
||||
#опциаональный параметр, используется при создании
|
||||
#тип - строка
|
||||
#доступные значения: "X86_64"
|
||||
architecture = "X86_64"
|
||||
|
||||
#доступность образа
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - булево значение
|
||||
#enabled = true
|
||||
|
||||
#настройка доступа образа аккаунтам
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - массив чисел
|
||||
#пустой маасив - удаление всех доступов, если они были
|
||||
#shared_with = [28096, 57121]
|
||||
|
||||
#установка computeci
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - число
|
||||
#чтобы сбросить, необходимо передать 0
|
||||
#computeci_id = 1
|
||||
|
||||
#доступные стаки
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - массив строк
|
||||
#для удаления всех доступных стаков, необходимо передать пустой массив
|
||||
#enabled_stacks = ["9"]
|
||||
|
||||
#мгновенное удаление
|
||||
#опциональный параметр, можно использовать перед удалением
|
||||
#тип - булев тип
|
||||
#permanently = true
|
||||
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = decort_cdrom_image.my_image
|
||||
}
|
||||
122
samples/resource_k8s/main.tf
Normal file
122
samples/resource_k8s/main.tf
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
Пример использования
|
||||
Ресурсов k8s cluster
|
||||
Ресурсы позволяет:
|
||||
1. Создавать
|
||||
2. Редактировать
|
||||
3. Удалять
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
source = "terraform.local/local/decort"
|
||||
version = "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
provider "decort" {
|
||||
authenticator = "oauth2"
|
||||
oauth2_url = "https://sso.digitalenergy.online"
|
||||
controller_url = "https://mr4.digitalenergy.online"
|
||||
app_id = ""
|
||||
app_secret = ""
|
||||
}
|
||||
|
||||
|
||||
resource "decort_k8s" "cluster" {
|
||||
#имя кластера
|
||||
#обязательный параметр
|
||||
#при изменении - обновдяет имя кластера
|
||||
#тип - строка
|
||||
name = "tftest"
|
||||
|
||||
#id resource group
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
rg_id = 776
|
||||
|
||||
#id catalogue item
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
k8sci_id = 9
|
||||
|
||||
#имя для первой worker group, созданной в кластере
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
wg_name = "workers"
|
||||
|
||||
#настройка мастер node или nodes
|
||||
#опциональный параметр
|
||||
#максимальное кол-во элементов - 1
|
||||
#тип - список нод
|
||||
masters {
|
||||
#кол-во node
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
num = 1
|
||||
|
||||
#кол-во cpu
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
cpu = 2
|
||||
|
||||
|
||||
#кол-во RAM в Мбайтах
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
ram = 2048
|
||||
|
||||
|
||||
#размер диска в Гбайтах
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
disk = 10
|
||||
}
|
||||
|
||||
#настройка worker node или nodes
|
||||
#опциональный параметр
|
||||
#максимальное кол-во элементов - 1
|
||||
#тип - список нод
|
||||
workers {
|
||||
#кол-во node
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
num = 1
|
||||
|
||||
#кол-во cpu
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
cpu = 2
|
||||
|
||||
#кол-во RAM в Мбайтах
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
ram = 2048
|
||||
|
||||
#размер диска в Гбайтах
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
disk = 10
|
||||
}
|
||||
}
|
||||
|
||||
output "test_cluster" {
|
||||
value = decort_k8s.cluster
|
||||
}
|
||||
|
||||
/*
|
||||
output "kubeconfig"{
|
||||
value = decort_k8s.cluster.kubeconfig
|
||||
}
|
||||
|
||||
*/
|
||||
76
samples/resource_k8s_wg/main.tf
Normal file
76
samples/resource_k8s_wg/main.tf
Normal file
@@ -0,0 +1,76 @@
|
||||
/*
|
||||
Пример использования
|
||||
Ресурсов worker group
|
||||
Ресурсы позволяет:
|
||||
1. Создавать
|
||||
2. Редактировать
|
||||
3. Удалять
|
||||
|
||||
*/
|
||||
|
||||
|
||||
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
source = "terraform.local/local/decort"
|
||||
version = "1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
provider "decort" {
|
||||
authenticator = "oauth2"
|
||||
oauth2_url = "https://sso.digitalenergy.online"
|
||||
controller_url = "https://mr4.digitalenergy.online"
|
||||
app_id = ""
|
||||
app_secret = ""
|
||||
}
|
||||
|
||||
|
||||
resource "decort_k8s_wg" "wg" {
|
||||
#id экземпляра k8s
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
k8s_id = 1234 //это значение должно быть и результат вызова decort_k8s.cluster.id
|
||||
|
||||
#имя worker group
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
name = "workers-2"
|
||||
|
||||
#количество worker node для создания
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#по - умолчанию - 1
|
||||
num = 2
|
||||
|
||||
#количество cpu для 1 worker node
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#по - умолчанию - 1
|
||||
cpu = 1
|
||||
|
||||
#количество RAM для одной worker node в Мбайтах
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#по-умолчанию - 1024
|
||||
ram = 1024
|
||||
|
||||
#размер загрузочного диска для worker node, в Гбайтах
|
||||
#опциональный параметр
|
||||
#тип - число
|
||||
#по - умолчанию - 0
|
||||
#если установлен параметр 0, то размер диска будет равен размеру образа
|
||||
disk = 10
|
||||
}
|
||||
|
||||
|
||||
output "test_wg" {
|
||||
value = decort_k8s_wg.wg
|
||||
}
|
||||
98
samples/resource_virtual_image/main.tf
Normal file
98
samples/resource_virtual_image/main.tf
Normal file
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
Пример использования
|
||||
Ресурса virtual image
|
||||
Ресурс позволяет:
|
||||
1. Создавать образ
|
||||
2. Редактировать образ
|
||||
3. Удалять образ
|
||||
|
||||
*/
|
||||
#Расскомментируйте этот код,
|
||||
#и внесите необходимые правки в версию и путь,
|
||||
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
|
||||
/*
|
||||
terraform {
|
||||
required_providers {
|
||||
decort = {
|
||||
version = "1.1"
|
||||
source = "digitalenergy.online/decort/decort"
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
resource "decort_virtual_image" "my_image" {
|
||||
#имя виртуального образа
|
||||
#обязательный параметр
|
||||
#тип - строка
|
||||
name = "test_vi_im_new_rename"
|
||||
|
||||
#id образа, на основе котрого будет создан виртуальный
|
||||
#обязательный параметр
|
||||
#тип - число
|
||||
target_id = 6125
|
||||
|
||||
#изменение связи виртуального образа
|
||||
#опциональный параметр, используется при редактировании ресурса
|
||||
#тип - число
|
||||
#link_to = 6062
|
||||
|
||||
#id аккаунта владельца образа
|
||||
#опциональный параметр
|
||||
#может быть использован при редактировании образа
|
||||
#тип данных - число
|
||||
#account_id = 57252
|
||||
|
||||
#имя пользователя и пароль
|
||||
#опциаональные параметры,
|
||||
#могут быть использованы при редактировании образа
|
||||
#тип - строка
|
||||
#username = "Valera"
|
||||
#password = "123"
|
||||
|
||||
#доступность образа
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - булево значение
|
||||
#enabled = false
|
||||
|
||||
#настройка доступа образа аккаунтам
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - массив чисел
|
||||
#пустой маасив - удаление всех доступов, если они были
|
||||
#shared_with = [28096, 57121]
|
||||
|
||||
#установка computeci
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - число
|
||||
#чтобы сбросить, необходимо передать 0
|
||||
#computeci_id = 1
|
||||
|
||||
#доступные стаки
|
||||
#опциональный параметр, используется на уже созданном ресурсе
|
||||
#тип - массив строк
|
||||
#для удаления всех доступных стаков, необходимо передать пустой массив
|
||||
#enabled_stacks = ["9"]
|
||||
|
||||
#мгновенное удаление
|
||||
#опциональный параметр, можно использовать перед удалением
|
||||
#тип - булев тип
|
||||
#permanently = true
|
||||
|
||||
#причина удаления
|
||||
#опциональный параметр, можно использовать перед удалением
|
||||
#тип - строка
|
||||
#reason = "test"
|
||||
}
|
||||
|
||||
output "test" {
|
||||
value = decort_virtual_image.my_image
|
||||
}
|
||||
6
terraform-registry-manifest.json
Normal file
6
terraform-registry-manifest.json
Normal file
@@ -0,0 +1,6 @@
|
||||
{
|
||||
"version": 1,
|
||||
"metadata": {
|
||||
"protocol_versions": ["5.0"]
|
||||
}
|
||||
}
|
||||
8
tools/tools.go
Normal file
8
tools/tools.go
Normal file
@@ -0,0 +1,8 @@
|
||||
// +build tools
|
||||
|
||||
package tools
|
||||
|
||||
import (
|
||||
// document generation
|
||||
_ "github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs"
|
||||
)
|
||||
Reference in New Issue
Block a user