Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9d15af9259 | ||
|
|
8cf4680ce1 | ||
|
|
bf1afc66dd | ||
|
|
d9c10c0d9c | ||
|
|
f28588fea5 | ||
|
|
3e72f72d15 | ||
|
|
bf179b9d12 | ||
|
|
9379289e58 | ||
|
|
edf7728cb5 | ||
|
|
95cd7cb820 | ||
|
|
06c0578fa6 | ||
|
|
1bf17c23c8 | ||
|
|
668d57cd3b | ||
|
|
fef6040cc6 | ||
|
|
d0165918c3 | ||
|
|
dfeb9a9165 | ||
|
|
e0dcd053c5 | ||
|
|
ab070b73cb | ||
|
|
80a4b70db8 | ||
|
|
28db919ffa | ||
|
|
3164793f69 | ||
|
|
5db588e5dc |
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
|
||||
16
CHANGELOG.md
Normal file
16
CHANGELOG.md
Normal file
@@ -0,0 +1,16 @@
|
||||
## 2.0
|
||||
|
||||
### New data sources
|
||||
- image
|
||||
- image\_list
|
||||
- grid
|
||||
- grid\_list
|
||||
- image\_list\_stacks
|
||||
|
||||
### New resources
|
||||
- image
|
||||
- virtual\_image
|
||||
- cdrom\_image
|
||||
- delete\_images
|
||||
- k8s
|
||||
- k8s\_wg
|
||||
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,55 +1,114 @@
|
||||
# terraform-provider-decort
|
||||
Terraform provider for Digital Energy Cloud Orchestration Technology (DECORT) platform
|
||||
Terraform provider для платформы Digital Energy Cloud Orchestration Technology (DECORT)
|
||||
|
||||
NOTE: provider rc-1.40 is designed for DECORT API 3.7.x. For older API versions please use:
|
||||
- DECORT API 3.6.x versions - provider version rc-1.10
|
||||
- DECORT API versions prior to 3.6.0 - Terraform DECS provider (https://github.com/rudecs/terraform-provider-decs)
|
||||
Внимание: провайдер версии 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, virtual network segments and resource
|
||||
groups in DECORT platform, as well as query the platform for information about existing resources.
|
||||
This provider supports Import operations on pre-existing resources.
|
||||
## Возможности провайдера
|
||||
- Работа с 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
|
||||
```
|
||||
|
||||
6. Build Terraform DECORT provider:
|
||||
```
|
||||
cd $GOPKG/src/github.com/terraform-provider-decort
|
||||
go build -o terraform-provider-decort
|
||||
```
|
||||
Хорошей работы!
|
||||
|
||||
115
README_EN.md
Normal file
115
README_EN.md
Normal file
@@ -0,0 +1,115 @@
|
||||
# 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: in repository `samples`
|
||||
|
||||
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
|
||||
@@ -132,15 +131,15 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
||||
}
|
||||
ret_config.auth_mode_code = MODE_LEGACY
|
||||
default:
|
||||
return nil, fmt.Errorf("Unknown authenticator mode %s provided.", ret_config.auth_mode_txt)
|
||||
return nil, fmt.Errorf("Unknown authenticator mode %q provided.", ret_config.auth_mode_txt)
|
||||
}
|
||||
|
||||
if allow_unverified_ssl {
|
||||
log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!")
|
||||
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true},}
|
||||
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
|
||||
}
|
||||
|
||||
@@ -205,7 +204,7 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
||||
return "", fmt.Errorf("getOAuth2JWT method called for undefined authorization mode.")
|
||||
}
|
||||
if config.auth_mode_code != MODE_OAUTH2 {
|
||||
return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %s.", config.auth_mode_txt)
|
||||
return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -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 %s for APP_ID %s, request Body %s",
|
||||
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 %s.",
|
||||
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,16 +288,16 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
|
||||
|
||||
func (config *ControllerCfg) validateLegacyUser() (bool, error) {
|
||||
/*
|
||||
Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls
|
||||
to DECORT controller.
|
||||
If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any
|
||||
reason, the method will return false and error.
|
||||
Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls
|
||||
to DECORT controller.
|
||||
If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any
|
||||
reason, the method will return false and error.
|
||||
*/
|
||||
if config.auth_mode_code == MODE_UNDEF {
|
||||
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode.")
|
||||
}
|
||||
if config.auth_mode_code != MODE_LEGACY {
|
||||
return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %s.", config.auth_mode_txt)
|
||||
return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
||||
}
|
||||
|
||||
params := url.Values{}
|
||||
@@ -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,40 +313,38 @@ 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 %s against %s.",
|
||||
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)
|
||||
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error, hrc int) {
|
||||
// This is a convenience wrapper around standard HTTP request methods that is aware of the
|
||||
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
|
||||
// authorization mode for which the provider was initialized and compiles request accordingly.
|
||||
|
||||
hrc = 0 // HTTP Response Code
|
||||
|
||||
if config.cc_client == nil {
|
||||
// this should never happen if ClientConfig was properly called prior to decortAPICall
|
||||
return "", fmt.Errorf("decortAPICall method called with unconfigured DECORT cloud controller HTTP client."), 0
|
||||
// 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))
|
||||
//
|
||||
@@ -361,7 +358,7 @@ func (config *ControllerCfg) decortAPICall(method string, api_name string, url_v
|
||||
//
|
||||
|
||||
if config.auth_mode_code == MODE_UNDEF {
|
||||
return "", fmt.Errorf("decortAPICall method called for unknown authorization mode."), 0
|
||||
return "", fmt.Errorf("decortAPICall method called for unknown authorization mode.")
|
||||
}
|
||||
|
||||
if config.auth_mode_code == MODE_LEGACY {
|
||||
@@ -369,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, 0
|
||||
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, 0
|
||||
return "", err
|
||||
}
|
||||
defer resp.Body.Close()
|
||||
|
||||
if resp.StatusCode == http.StatusOK {
|
||||
tmp_body, err := ioutil.ReadAll(resp.Body)
|
||||
if err != nil {
|
||||
return "", err, resp.StatusCode
|
||||
}
|
||||
json_resp := Jo2JSON(string(tmp_body))
|
||||
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, json_resp)
|
||||
return json_resp, nil, resp.StatusCode
|
||||
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 %s with request Body %s",
|
||||
resp.StatusCode, req.URL, params_str), resp.StatusCode
|
||||
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %q with request Body %q. Respone:\n%s",
|
||||
resp.StatusCode, req.URL, params_str, body)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
if resp.StatusCode == StatusServiceUnavailable {
|
||||
return nil, fmt.Errorf("decortAPICall method called for incompatible authorization mode %s.", config.auth_mode_txt), resp.StatusCode
|
||||
}
|
||||
if resp.StatusCode == StatusServiceUnavailable {
|
||||
return nil, fmt.Errorf("decortAPICall method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
||||
}
|
||||
*/
|
||||
|
||||
return "", err, resp.StatusCode
|
||||
}
|
||||
|
||||
|
||||
@@ -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,7 +63,7 @@ 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
|
||||
@@ -70,18 +71,18 @@ func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
||||
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 := []interface{}{}
|
||||
|
||||
if length == 0 {
|
||||
@@ -90,10 +91,10 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
|
||||
|
||||
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
|
||||
@@ -112,11 +113,11 @@ func parseComputeDisks(disks []DiskRecord) []interface{} {
|
||||
// elem["status"] = value.Status
|
||||
// elem["tech_status"] = value.TechStatus
|
||||
elem["compute_id"] = value.ComputeID
|
||||
|
||||
|
||||
result = append(result, elem)
|
||||
}
|
||||
|
||||
return result
|
||||
return result
|
||||
}
|
||||
|
||||
func parseBootDiskSize(disks []DiskRecord) int {
|
||||
@@ -131,7 +132,7 @@ func parseBootDiskSize(disks []DiskRecord) int {
|
||||
}
|
||||
}
|
||||
|
||||
return 0
|
||||
return 0
|
||||
}
|
||||
|
||||
func parseBootDiskId(disks []DiskRecord) uint {
|
||||
@@ -146,10 +147,10 @@ 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
|
||||
@@ -172,14 +173,40 @@ func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
||||
result = append(result, elem)
|
||||
}
|
||||
|
||||
return result
|
||||
return result
|
||||
}
|
||||
|
||||
/*
|
||||
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []map[string]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 := make([]map[string]interface{}, length, length)
|
||||
|
||||
for i, 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[i] = elem
|
||||
}
|
||||
|
||||
return result
|
||||
}
|
||||
*/
|
||||
|
||||
// NOTE: this function is retained for historical purposes and actually not used as of rc-1.10
|
||||
func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
|
||||
// return value was designed to d.Set("interfaces",) item of dataSourceCompute schema
|
||||
// However, this item was excluded from the schema as it is not directly
|
||||
// managed through Terraform
|
||||
// managed through Terraform
|
||||
length := len(ifaces)
|
||||
log.Debugf("parseComputeInterfaces: called for %d ifaces", length)
|
||||
|
||||
@@ -211,7 +238,7 @@ func parseComputeInterfaces(ifaces []InterfaceRecord) []map[string]interface{} {
|
||||
result[i] = elem
|
||||
}
|
||||
|
||||
return result
|
||||
return result
|
||||
}
|
||||
|
||||
func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||
@@ -236,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
|
||||
@@ -248,6 +275,12 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
||||
// 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 {
|
||||
@@ -334,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.",
|
||||
@@ -377,24 +410,24 @@ func dataSourceCompute() *schema.Resource {
|
||||
},
|
||||
|
||||
"extra_disks": {
|
||||
Type: schema.TypeSet,
|
||||
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": {
|
||||
@@ -408,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": {
|
||||
@@ -439,24 +472,31 @@ func dataSourceCompute() *schema.Resource {
|
||||
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.",
|
||||
},
|
||||
*/
|
||||
},
|
||||
}
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
@@ -1,144 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
// "hash/fnv"
|
||||
log "github.com/sirupsen/logrus"
|
||||
// "net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
|
||||
func flattenPfw(d *schema.ResourceData, pfwFacts string) error {
|
||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
||||
// from resourcePfwExists(...) method
|
||||
pfwRecord := ComputePfwListResp{}
|
||||
err := json.Unmarshal([]byte(pfwFacts), &pfwRecord)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("flattenPfw: decoded %d PFW rules for compute ID %s on ViNS ID %d",
|
||||
len(pfwRecord.Rules), pfwRecord.Header.VinsID, pfwRecord.Header.VinsID)
|
||||
|
||||
/*
|
||||
Here it gets a little bit interesting.
|
||||
Unlike compute or disk, port forwaring rules are NOT represented by any cloud
|
||||
platform resource, which might have had a unique ID. They are just a subset of
|
||||
rules in the list maintained by the corresponding ViNS instance. However,
|
||||
Terraform needs a unique ID for each resource it manages so that it could be
|
||||
stored in the state file and retrieved for use.
|
||||
|
||||
Therefore we need to make up an ID and supply it to Terraform in a standard
|
||||
way (i.e. by calling d.SetId(...)).
|
||||
|
||||
Fortunately, a combination of Compute ID and ViNS ID with GW VNF, where this
|
||||
compute is plugged in, makes a unique string, so we use it as an ID for
|
||||
the PFW ruleset.
|
||||
|
||||
The following few lines are legacy from the first attempt to make an ID
|
||||
as a hash of concatenated Compute ID & ViNS ID, but it did not work as
|
||||
expected for a number of reasons, which explanation is not a primary
|
||||
intent of the comment in the source code.
|
||||
|
||||
combo := fmt.Sprintf("%d:%d", compId.(int), pfwRecord.ViNS.VinsID)
|
||||
hasher := fnv.New32a()
|
||||
hasher.Write([]byte(combo))
|
||||
d.SetId(fmt.Sprintf("%d", hasher.Sum32()))
|
||||
*/
|
||||
// set ID of this PFW rule set as "compute_id:vins_id"
|
||||
d.SetId(fmt.Sprintf("%d:%d", pfwRecord.Header.ComputeID, pfwRecord.Header.VinsID))
|
||||
log.Debugf("flattenPfw: PFW rule set ID %s", d.Id())
|
||||
d.Set("compute_id", pfwRecord.Header.ComputeID)
|
||||
d.Set("vins_id", pfwRecord.Header.VinsID)
|
||||
|
||||
pfwRulesList := []interface{}{}
|
||||
for _, runner := range pfwRecord.Rules {
|
||||
rule := map[string]interface{}{
|
||||
"pub_port_start": runner.PublicPortStart,
|
||||
"pub_port_end": runner.PublicPortEnd,
|
||||
"local_port": runner.LocalPort,
|
||||
"proto": runner.Protocol,
|
||||
"rule_id": runner.ID,
|
||||
}
|
||||
pfwRulesList = append(pfwRulesList, rule)
|
||||
}
|
||||
if err = d.Set("rule", pfwRulesList); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func dataSourcePfwRead(d *schema.ResourceData, m interface{}) error {
|
||||
pfwFacts, err := utilityPfwCheckPresence(d, m)
|
||||
if pfwFacts == "" {
|
||||
// if empty string is returned from dataSourcePfwRead then we got no
|
||||
// PFW rules. It could also be because there was some error, which
|
||||
// is indicated by non-nil err value
|
||||
d.SetId("") // ensure ID is empty in this case anyway
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenPfw(d, pfwFacts)
|
||||
}
|
||||
|
||||
func dataSourcePfw() *schema.Resource {
|
||||
return &schema.Resource{
|
||||
SchemaVersion: 1,
|
||||
|
||||
Read: dataSourcePfwRead,
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Read: &Timeout30s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the compute instance to configure port forwarding rules for.",
|
||||
},
|
||||
|
||||
"vins_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the ViNS to configure port forwarding rules on. Compute must be already plugged into this ViNS and ViNS must have external network connection.",
|
||||
},
|
||||
|
||||
// TODO: consider making "rule" attribute Required with MinItems = 1
|
||||
"rule": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: rulesSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Port forwarding rule. You may specify several rules, one in each such block.",
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
@@ -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 Timeout10m = time.Minute * 10
|
||||
|
||||
//
|
||||
// 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,22 +191,23 @@ 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"
|
||||
@@ -271,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"
|
||||
@@ -302,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"`
|
||||
@@ -325,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"`
|
||||
@@ -355,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"`
|
||||
@@ -376,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"`
|
||||
}
|
||||
|
||||
//
|
||||
@@ -446,20 +452,7 @@ type AccountsListResp []AccountRecord
|
||||
//
|
||||
// structures related to /cloudapi/portforwarding/list API
|
||||
//
|
||||
// Note the specifics of compute/pfwList response in API 3.7.x (this may be changed in the future):
|
||||
// 1) if there are no PFW rules and compute is not connected to any PFW-able ViNS
|
||||
// the response will be empty string
|
||||
// 2) if there are no PFW rules but compute is connected to a PFW-able ViNS
|
||||
// the response will contain a list with a single element - prefix (see PfwPrefixRecord)
|
||||
// 3) if there are port forwarding rules, the response will contain a list which starts
|
||||
// with prefix (see PfwPrefixRecord) and then followed by one or more rule records
|
||||
// (see PfwRuleRecord)
|
||||
type PfwPrefixRecord struct {
|
||||
VinsID int `json:"vinsId"`
|
||||
VinsName string `json:"vinsName"`
|
||||
ComputeID int `json:"computeId"`
|
||||
}
|
||||
type PfwRuleRecord struct {
|
||||
type PfwRecord struct {
|
||||
ID int `json:"id"`
|
||||
LocalIP string `json:"localIp"`
|
||||
LocalPort int `json:"localPort"`
|
||||
@@ -469,13 +462,10 @@ type PfwRuleRecord struct {
|
||||
ComputeID int `json:"vmId"`
|
||||
}
|
||||
|
||||
type ComputePfwListResp struct {
|
||||
Header PfwPrefixRecord `json:"header"`
|
||||
Rules []PfwRuleRecord `json:"rules"`
|
||||
}
|
||||
|
||||
const ComputePfwListAPI = "/restmachine/cloudapi/compute/pfwList"
|
||||
|
||||
type ComputePfwListResp []PfwRecord
|
||||
|
||||
const ComputePfwAddAPI = "/restmachine/cloudapi/compute/pfwAdd"
|
||||
|
||||
const ComputePfwDelAPI = "/restmachine/cloudapi/compute/pfwDel"
|
||||
@@ -484,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"
|
||||
@@ -528,52 +519,52 @@ 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"
|
||||
@@ -586,15 +577,106 @@ 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
|
||||
@@ -608,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
|
||||
|
||||
99
decort/node_subresource.go
Normal file
99
decort/node_subresource.go
Normal file
@@ -0,0 +1,99 @@
|
||||
/*
|
||||
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["id"] = node.ID
|
||||
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,21 +99,31 @@ 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_pfw": dataSourcePfw(),
|
||||
"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(),
|
||||
},
|
||||
|
||||
ConfigureFunc: providerConfigure,
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
@@ -50,15 +50,15 @@ func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) b
|
||||
}
|
||||
|
||||
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)))
|
||||
@@ -68,32 +68,32 @@ 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", "0") // 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")
|
||||
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)
|
||||
@@ -101,8 +101,8 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
urlValues.Add("userdata", userdata)
|
||||
}
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", computeCreateAPI, urlValues)
|
||||
|
||||
apiResp, err := controller.decortAPICall("POST", computeCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -117,16 +117,16 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
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")
|
||||
argVal, argSet = d.GetOk("extra_disks")
|
||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||
// urlValues.Add("desc", argVal.(string))
|
||||
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
|
||||
@@ -142,8 +142,8 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
// Configure external networks if any
|
||||
netsOk := true
|
||||
argVal, argSet = d.GetOk("network")
|
||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
||||
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 {
|
||||
@@ -161,23 +161,25 @@ func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
||||
d.Partial(false)
|
||||
}
|
||||
|
||||
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
|
||||
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
|
||||
// now we need to start it before we report the sequence complete
|
||||
reqValues := &url.Values{}
|
||||
reqValues.Add("computeId", fmt.Sprintf("%d", compId))
|
||||
log.Debugf("resourceComputeCreate: starting Compute ID %d after completing its resource configuration", compId)
|
||||
apiResp, err, _ = controller.decortAPICall("POST", ComputeStartAPI, reqValues)
|
||||
if err != nil {
|
||||
return err
|
||||
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 {
|
||||
@@ -186,7 +188,6 @@ func resourceComputeRead(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
||||
if compFacts == "" {
|
||||
d.SetId("")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -210,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
|
||||
@@ -231,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)))
|
||||
@@ -242,9 +244,9 @@ 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))
|
||||
_, err, _ := controller.decortAPICall("POST", ComputeResizeAPI, params)
|
||||
oldCpu.(int), newCpu.(int),
|
||||
oldRam.(int), newRam.(int))
|
||||
_, err := controller.decortAPICall("POST", ComputeResizeAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -252,15 +254,15 @@ 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))
|
||||
_, err, _ := controller.decortAPICall("POST", DisksResizeAPI, params)
|
||||
d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int))
|
||||
_, err := controller.decortAPICall("POST", DisksResizeAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -285,17 +287,32 @@ 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.
|
||||
// If compute being destroyed has some extra disks attached, they are
|
||||
// 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))
|
||||
@@ -313,7 +330,7 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
||||
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
|
||||
// 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" {
|
||||
@@ -327,7 +344,7 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
||||
detachParams.Add("computeId", d.Id())
|
||||
detachParams.Add("diskId", fmt.Sprintf("%d", diskFacts.ID))
|
||||
|
||||
_, err, _ = controller.decortAPICall("POST", ComputeDiskDetachAPI, detachParams)
|
||||
_, 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)
|
||||
@@ -339,8 +356,8 @@ func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
||||
params.Add("computeId", d.Id())
|
||||
params.Add("permanently", "1")
|
||||
// TODO: this is for the upcoming API update - params.Add("detachdisks", "1")
|
||||
|
||||
_, err, _ = controller.decortAPICall("POST", ComputeDeleteAPI, params)
|
||||
|
||||
_, err = controller.decortAPICall("POST", ComputeDeleteAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -399,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": {
|
||||
@@ -423,16 +440,16 @@ func resourceCompute() *schema.Resource {
|
||||
},
|
||||
|
||||
"image_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ForceNew: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the OS image to base this compute instance on.",
|
||||
Description: "ID of the OS image to base this compute instance on.",
|
||||
},
|
||||
|
||||
"boot_disk_size": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
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.",
|
||||
},
|
||||
|
||||
@@ -457,15 +474,15 @@ func resourceCompute() *schema.Resource {
|
||||
},
|
||||
|
||||
/*
|
||||
"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": {
|
||||
@@ -474,13 +491,12 @@ func resourceCompute() *schema.Resource {
|
||||
Description: "Optional text description of this compute instance.",
|
||||
},
|
||||
|
||||
|
||||
"cloud_init": {
|
||||
Type: schema.TypeString,
|
||||
Optional: true,
|
||||
Default: "applied",
|
||||
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.",
|
||||
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
|
||||
@@ -517,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(),
|
||||
}
|
||||
}
|
||||
@@ -55,7 +55,7 @@ func resourceDiskCreate(d *schema.ResourceData, m interface{}) error {
|
||||
urlValues.Add("description", argVal.(string))
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", DisksCreateAPI, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", DisksCreateAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -105,7 +105,7 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
sizeParams := &url.Values{}
|
||||
sizeParams.Add("diskId", d.Id())
|
||||
sizeParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
||||
_, err, _ := controller.decortAPICall("POST", DisksResizeAPI, sizeParams)
|
||||
_, err := controller.decortAPICall("POST", DisksResizeAPI, sizeParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -121,7 +121,7 @@ func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
renameParams := &url.Values{}
|
||||
renameParams.Add("diskId", d.Id())
|
||||
renameParams.Add("name", newName.(string))
|
||||
_, err, _ := controller.decortAPICall("POST", DisksRenameAPI, renameParams)
|
||||
_, err := controller.decortAPICall("POST", DisksRenameAPI, renameParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -171,7 +171,7 @@ func resourceDiskDelete(d *schema.ResourceData, m interface{}) error {
|
||||
params.Add("permanently", "1")
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
_, err, _ = controller.decortAPICall("POST", DisksDeleteAPI, params)
|
||||
_, err = controller.decortAPICall("POST", DisksDeleteAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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: &Timeout10m,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout10m,
|
||||
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: &Timeout10m,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout10m,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: resourceK8sWgSchemaMake(),
|
||||
}
|
||||
}
|
||||
@@ -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>
|
||||
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.
|
||||
@@ -15,158 +15,171 @@ 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"
|
||||
log "github.com/sirupsen/logrus"
|
||||
"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 {
|
||||
compId := d.Get("compute_id")
|
||||
|
||||
rules_set, ok := d.GetOk("rule")
|
||||
if !ok || rules_set.(*schema.Set).Len() == 0 {
|
||||
log.Debugf("resourcePfwCreate: empty new PFW rules set requested for compute ID %d - nothing to create", compId.(int))
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debugf("resourcePfwCreate: ready to setup %d PFW rules for compute ID %d",
|
||||
rules_set.(*schema.Set).Len(), compId.(int))
|
||||
log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
apiErrCount := 0
|
||||
var lastSavedError error
|
||||
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))
|
||||
|
||||
for _, runner := range rules_set.(*schema.Set).List() {
|
||||
rule := runner.(map[string]interface{})
|
||||
params := &url.Values{}
|
||||
params.Add("computeId", fmt.Sprintf("%d", compId.(int)))
|
||||
params.Add("publicPortStart", fmt.Sprintf("%d", rule["pub_port_start"].(int)))
|
||||
params.Add("publicPortEnd", fmt.Sprintf("%d", rule["pub_port_end"].(int)))
|
||||
params.Add("localBasePort", fmt.Sprintf("%d", rule["local_port"].(int)))
|
||||
params.Add("proto", rule["proto"].(string))
|
||||
log.Debugf("resourcePfwCreate: ready to add rule %d:%d -> %d %s for Compute ID %d",
|
||||
rule["pub_port_start"].(int),rule["pub_port_end"].(int),
|
||||
rule["local_port"].(int), rule["proto"].(string),
|
||||
compId.(int))
|
||||
_, err, _ := controller.decortAPICall("POST", ComputePfwAddAPI, params)
|
||||
if err != nil {
|
||||
log.Errorf("resourcePfwCreate: error adding rule %d:%d -> %d %s for Compute ID %d: %s",
|
||||
rule["pub_port_start"].(int),rule["pub_port_end"].(int),
|
||||
rule["local_port"].(int), rule["proto"].(string),
|
||||
compId.(int),
|
||||
err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
if apiErrCount > 0 {
|
||||
log.Errorf("resourcePfwCreate: there were %d error(s) adding PFW rules to Compute ID %s. Last error was: %s",
|
||||
apiErrCount, compId.(int), lastSavedError)
|
||||
return lastSavedError
|
||||
if portEnd, ok := d.GetOk("public_port_end"); ok {
|
||||
urlValues.Add("publicPortEnd", strconv.Itoa(portEnd.(int)))
|
||||
}
|
||||
|
||||
return resourcePfwRead(d, m)
|
||||
}
|
||||
|
||||
func resourcePfwRead(d *schema.ResourceData, m interface{}) error {
|
||||
pfwFacts, err := utilityPfwCheckPresence(d, m)
|
||||
if pfwFacts == "" {
|
||||
// if empty string is returned from dataSourcePfwRead then we got no
|
||||
// PFW rules. It could also be because there was some error, which
|
||||
// is indicated by non-nil err value
|
||||
d.SetId("") // ensure ID is empty in this case anyway
|
||||
pfwId, err := controller.decortAPICall("POST", ComputePfwAddAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return flattenPfw(d, pfwFacts)
|
||||
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 resourcePfwUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
// TODO: update not implemented yet
|
||||
compId := d.Get("compute_id")
|
||||
return fmt.Errorf("resourcePfwUpdate: method is not implemented yet (Compute ID %d)", compId.(int))
|
||||
|
||||
// return resourcePfwRead(d, m)
|
||||
func 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 {
|
||||
compId := d.Get("compute_id")
|
||||
log.Debugf("resourcePfwDelete: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
||||
|
||||
rules_set, ok := d.GetOk("rule")
|
||||
if !ok || rules_set.(*schema.Set).Len() == 0 {
|
||||
log.Debugf("resourcePfwDelete: no PFW rules defined for compute ID %d - nothing to delete", compId.(int))
|
||||
pfw, err := utilityPfwCheckPresence(d, m)
|
||||
if pfw == nil {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Debugf("resourcePfwDelete: ready to delete %d PFW rules from compute ID %d",
|
||||
rules_set.(*schema.Set).Len(), compId.(int))
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
apiErrCount := 0
|
||||
var lastSavedError error
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
||||
urlValues.Add("ruleId", strconv.Itoa(pfw.ID))
|
||||
|
||||
for _, runner := range rules_set.(*schema.Set).List() {
|
||||
rule := runner.(map[string]interface{})
|
||||
params := &url.Values{}
|
||||
params.Add("computeId", fmt.Sprintf("%d", compId.(int)))
|
||||
params.Add("ruleId", fmt.Sprintf("%d", rule["rule_id"].(int)))
|
||||
log.Debugf("resourcePfwCreate: ready to delete rule ID%s (%d:%d -> %d %s) from Compute ID %d",
|
||||
rule["rule_id"].(int),
|
||||
rule["pub_port_start"].(int),rule["pub_port_end"].(int),
|
||||
rule["local_port"].(int), rule["proto"].(string),
|
||||
compId.(int))
|
||||
_, err, _ := controller.decortAPICall("POST", ComputePfwDelAPI, params)
|
||||
if err != nil {
|
||||
log.Errorf("resourcePfwDelete: error deleting rule ID %d (%d:%d -> %d %s) from Compute ID %d: %s",
|
||||
rule["rule_id"].(int),
|
||||
rule["pub_port_start"].(int),rule["pub_port_end"].(int),
|
||||
rule["local_port"].(int), rule["proto"].(string),
|
||||
compId.(int),
|
||||
err)
|
||||
apiErrCount++
|
||||
lastSavedError = err
|
||||
}
|
||||
}
|
||||
|
||||
if apiErrCount > 0 {
|
||||
log.Errorf("resourcePfwDelete: there were %d error(s) when deleting PFW rules from Compute ID %s. Last error was: %s",
|
||||
apiErrCount, compId.(int), lastSavedError)
|
||||
return lastSavedError
|
||||
_, err = controller.decortAPICall("POST", ComputePfwDelAPI, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func resourcePfwExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
||||
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
||||
log.Debugf("resourcePfwExists: called for Compute ID %d", d.Get("compute_id").(int))
|
||||
log.Debugf("resourcePfwExists: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
||||
|
||||
pfwFacts, err := utilityPfwCheckPresence(d, m)
|
||||
if pfwFacts == "" {
|
||||
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,
|
||||
Update: resourcePfwUpdate,
|
||||
Delete: resourcePfwDelete,
|
||||
Exists: resourcePfwExists,
|
||||
|
||||
@@ -175,38 +188,13 @@ func resourcePfw() *schema.Resource {
|
||||
},
|
||||
|
||||
Timeouts: &schema.ResourceTimeout{
|
||||
Create: &Timeout180s,
|
||||
Create: &Timeout60s,
|
||||
Read: &Timeout30s,
|
||||
Update: &Timeout180s,
|
||||
Update: &Timeout60s,
|
||||
Delete: &Timeout60s,
|
||||
Default: &Timeout60s,
|
||||
},
|
||||
|
||||
Schema: map[string]*schema.Schema{
|
||||
"compute_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the compute instance to configure port forwarding rules for.",
|
||||
},
|
||||
|
||||
"vins_id": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntAtLeast(1),
|
||||
Description: "ID of the ViNS to configure port forwarding rules on. Compute must be already plugged into this ViNS and ViNS must have external network connection.",
|
||||
},
|
||||
|
||||
// TODO: consider making "rule" attribute Required with MinItems = 1 to prevent
|
||||
// empty PFW list definition
|
||||
"rule": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Elem: &schema.Resource{
|
||||
Schema: rulesSubresourceSchemaMake(),
|
||||
},
|
||||
Description: "Port forwarding rule. You may specify several rules, one in each such block.",
|
||||
},
|
||||
},
|
||||
Schema: resourcePfwSchemaMake(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
||||
url_values.Add("extIp", ext_ip.(string))
|
||||
}
|
||||
|
||||
api_resp, err, _ := controller.decortAPICall("POST", ResgroupCreateAPI, url_values)
|
||||
api_resp, err := controller.decortAPICall("POST", ResgroupCreateAPI, url_values)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -233,7 +233,7 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
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)
|
||||
_, err := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -264,7 +264,7 @@ func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error {
|
||||
url_values.Add("reason", "Destroyed by DECORT Terraform provider")
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
_, err, _ = controller.decortAPICall("POST", ResgroupDeleteAPI, url_values)
|
||||
_, err = controller.decortAPICall("POST", ResgroupDeleteAPI, url_values)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -106,7 +106,7 @@ func resourceVinsCreate(d *schema.ResourceData, m interface{}) error {
|
||||
urlValues.Add("desc", argVal.(string))
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", apiToCall, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", apiToCall, urlValues)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -154,7 +154,7 @@ func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
|
||||
if oldExtNetId.(int) > 0 {
|
||||
// there was preexisting external net connection - disconnect ViNS
|
||||
_, err, _ := controller.decortAPICall("POST", VinsExtNetDisconnectAPI, extnetParams)
|
||||
_, err := controller.decortAPICall("POST", VinsExtNetDisconnectAPI, extnetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -163,7 +163,7 @@ func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error {
|
||||
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)
|
||||
_, err := controller.decortAPICall("POST", VinsExtNetConnectAPI, extnetParams)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -196,7 +196,7 @@ func resourceVinsDelete(d *schema.ResourceData, m interface{}) error {
|
||||
params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
_, err, _ = controller.decortAPICall("POST", VinsDeleteAPI, params)
|
||||
_, err = controller.decortAPICall("POST", VinsDeleteAPI, params)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
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(),
|
||||
}
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*
|
||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
package decort
|
||||
|
||||
import (
|
||||
|
||||
// "encoding/json"
|
||||
// "fmt"
|
||||
// "bytes"
|
||||
// log "github.com/sirupsen/logrus"
|
||||
// "net/url"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
||||
)
|
||||
|
||||
// This is rules subresource of PFW resource used
|
||||
// when creating/managing port forwarding rules for a compute connected
|
||||
// to the corresponding network
|
||||
|
||||
func rulesSubresourceSchemaMake() map[string]*schema.Schema {
|
||||
rets := map[string]*schema.Schema{
|
||||
"pub_port_start": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "Port number on the external interface. For a ranged rule it set the starting port number.",
|
||||
},
|
||||
|
||||
"pub_port_end": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "End port number on the external interface for a ranged rule. Set it equal to start port for a single port rule.",
|
||||
},
|
||||
|
||||
"local_port": {
|
||||
Type: schema.TypeInt,
|
||||
Required: true,
|
||||
ValidateFunc: validation.IntBetween(1, 65535),
|
||||
Description: "Port number on the local interface.",
|
||||
},
|
||||
|
||||
"proto": {
|
||||
Type: schema.TypeString,
|
||||
Required: true,
|
||||
StateFunc: stateFuncToLower,
|
||||
ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false),
|
||||
Description: "Protocol for this rule. Could be either tcp or udp.",
|
||||
},
|
||||
|
||||
// the rest are computed
|
||||
|
||||
"rule_id": {
|
||||
Type: schema.TypeInt,
|
||||
Computed: true,
|
||||
Description: "Rule ID as assigned by the cloud platform.",
|
||||
},
|
||||
|
||||
}
|
||||
return rets
|
||||
}
|
||||
@@ -44,7 +44,7 @@ func utilityAccountCheckPresence(d *schema.ResourceData, m interface{}) (string,
|
||||
// get Account right away by its ID
|
||||
log.Debugf("utilityAccountCheckPresence: locating Account by its ID %d", accId.(int))
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", accId.(int)))
|
||||
apiResp, err, _ := controller.decortAPICall("POST", AccountsGetAPI, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", AccountsGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -57,7 +57,7 @@ func utilityAccountCheckPresence(d *schema.ResourceData, m interface{}) (string,
|
||||
return "", fmt.Errorf("Cannot check account presence if name is empty and no account ID specified")
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", AccountsListAPI, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", AccountsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -131,7 +131,7 @@ func utilityGetAccountIdBySchema(d *schema.ResourceData, m interface{}) (int, er
|
||||
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
apiResp, err, _ := controller.decortAPICall("POST", AccountsListAPI, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", AccountsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -62,7 +62,7 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int)))
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
|
||||
_, err := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to attach extra disk - partial resource update
|
||||
apiErrCount++
|
||||
@@ -85,7 +85,7 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeDiskDetachAPI, urlValues)
|
||||
_, err := ctrl.decortAPICall("POST", ComputeDiskDetachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to detach disk - there will be partial resource update
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||
@@ -100,7 +100,7 @@ func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceD
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
|
||||
_, err := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to attach disk - there will be partial resource update
|
||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err)
|
||||
@@ -145,7 +145,7 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
|
||||
if ipSet {
|
||||
urlValues.Add("ipAddr", ipaddr.(string))
|
||||
}
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
|
||||
_, err := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to attach network - partial resource update
|
||||
apiErrCount++
|
||||
@@ -169,7 +169,7 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
|
||||
urlValues.Add("computeId", d.Id())
|
||||
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
||||
urlValues.Add("mac", net_data["mac"].(string))
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeNetDetachAPI, urlValues)
|
||||
_, err := ctrl.decortAPICall("POST", ComputeNetDetachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to detach this network - there will be partial resource update
|
||||
log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s",
|
||||
@@ -190,7 +190,7 @@ func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceDat
|
||||
if net_data["ip_address"].(string) != "" {
|
||||
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
||||
}
|
||||
_, err, _ := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
|
||||
_, err := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
|
||||
if err != nil {
|
||||
// failed to attach this network - there will be partial resource update
|
||||
log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s",
|
||||
@@ -244,7 +244,7 @@ func utilityComputeCheckPresence(d *schema.ResourceData, m interface{}) (string,
|
||||
// compute ID is specified, try to get compute instance straight by this ID
|
||||
log.Debugf("utilityComputeCheckPresence: locating compute by its ID %d", theId)
|
||||
urlValues.Add("computeId", fmt.Sprintf("%d", theId))
|
||||
computeFacts, err, _ := controller.decortAPICall("POST", ComputeGetAPI, urlValues)
|
||||
computeFacts, err := controller.decortAPICall("POST", ComputeGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -264,7 +264,7 @@ func utilityComputeCheckPresence(d *schema.ResourceData, m interface{}) (string,
|
||||
}
|
||||
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgId))
|
||||
apiResp, err, _ := controller.decortAPICall("POST", RgListComputesAPI, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", RgListComputesAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -286,7 +286,7 @@ func utilityComputeCheckPresence(d *schema.ResourceData, m interface{}) (string,
|
||||
// we found the Compute we need - now get detailed information via compute/get API
|
||||
cgetValues := &url.Values{}
|
||||
cgetValues.Add("computeId", fmt.Sprintf("%d", item.ID))
|
||||
apiResp, err, _ = controller.decortAPICall("POST", ComputeGetAPI, cgetValues)
|
||||
apiResp, err = controller.decortAPICall("POST", ComputeGetAPI, cgetValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -75,7 +75,7 @@ func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, er
|
||||
// disk ID is specified, try to get disk instance straight by this ID
|
||||
log.Debugf("utilityDiskCheckPresence: locating disk by its ID %d", theId)
|
||||
urlValues.Add("diskId", fmt.Sprintf("%d", theId))
|
||||
diskFacts, err, _ := controller.decortAPICall("POST", DisksGetAPI, urlValues)
|
||||
diskFacts, err := controller.decortAPICall("POST", DisksGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -98,7 +98,7 @@ func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, er
|
||||
}
|
||||
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", validatedAccountId))
|
||||
diskFacts, err, _ := controller.decortAPICall("POST", DisksListAPI, urlValues)
|
||||
diskFacts, err := controller.decortAPICall("POST", DisksListAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", 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
|
||||
}
|
||||
@@ -41,7 +41,7 @@ func (controller *ControllerCfg) utilityLocationGetDefaultGridID() (int, error)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
log.Debug("utilityLocationGetDefaultGridID: retrieving locations list")
|
||||
apiResp, err, _ := controller.decortAPICall("POST", LocationsListAPI, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", LocationsListAPI, urlValues)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/*
|
||||
Copyright (c) 2020-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: 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.
|
||||
@@ -26,183 +26,43 @@ package decort
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net/url"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
log "github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
)
|
||||
|
||||
func utilityPfwCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
||||
//
|
||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
||||
// method for the Terraform resource Exists method.
|
||||
//
|
||||
|
||||
// The string returned by this method mimics response of an imaginary API that will
|
||||
// report PFW rules (if any) as following:
|
||||
// {
|
||||
// "header": {
|
||||
// "computeId": <int>,
|
||||
// "vinsId": <int>,
|
||||
// },
|
||||
// "rules": [
|
||||
// {
|
||||
// "id": <int>,
|
||||
// "localPort": <int>,
|
||||
// "protocol": <int>,
|
||||
// "publicPortStart": <int>,
|
||||
// "publicPortEnd": <int>,
|
||||
// "vmId": <int>,
|
||||
// },
|
||||
// {
|
||||
// ...
|
||||
// },
|
||||
// ],
|
||||
// }
|
||||
// This response unmarshalls into ComputePfwListResp structure.
|
||||
// NOTE: If there are no rules for this compute, an empty string is returned along with err=nil
|
||||
//
|
||||
|
||||
func utilityPfwCheckPresence(d *schema.ResourceData, m interface{}) (*PfwRecord, error) {
|
||||
controller := m.(*ControllerCfg)
|
||||
urlValues := &url.Values{}
|
||||
|
||||
var compId, vinsId int
|
||||
|
||||
// PFW resource ID is a combination of compute_id and vins_id separated by ":"
|
||||
// See a note in "flattenPfw" method explaining the rationale behind this approach.
|
||||
if d.Id() != "" {
|
||||
log.Debugf("utilityPfwCheckPresence: setting context from PFW ID %s", d.Id())
|
||||
idParts := strings.SplitN(d.Id(), ":", 2)
|
||||
compId, _ = strconv.Atoi(idParts[0])
|
||||
vinsId, _ = strconv.Atoi(idParts[1])
|
||||
log.Debugf("utilityPfwCheckPresence: extracted Compute ID %d, ViNS %d", compId, vinsId)
|
||||
if compId <= 0 || vinsId <= 0 {
|
||||
return "", fmt.Errorf("Ivalid context from d.Id %s", d.Id())
|
||||
}
|
||||
} else {
|
||||
scId, cSet := d.GetOk("compute_id")
|
||||
svId, vSet := d.GetOk("vins_id")
|
||||
if cSet || vSet {
|
||||
log.Debugf("utilityPfwCheckPresence: setting Compute ID from schema")
|
||||
compId = scId.(int)
|
||||
vinsId = svId.(int)
|
||||
log.Debugf("utilityPfwCheckPresence: extracted Compute ID %d, ViNS %d", compId, vinsId)
|
||||
} else {
|
||||
return "", fmt.Errorf("Cannot get context to check PFW rules neither from PFW ID nor from schema")
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
log.Debugf("utilityPfwCheckPresence: preparing to get PFW rules for Compute ID %d on ViNS ID %d", compId, vinsId)
|
||||
|
||||
urlValues.Add("computeId", fmt.Sprintf("%d", compId))
|
||||
apiResp, err, respCode := controller.decortAPICall("POST", ComputePfwListAPI, urlValues)
|
||||
if respCode == 500 {
|
||||
// this is workaround for API 3.7.0 "feature" - will be removed in one of the future versions
|
||||
log.Errorf("utilityPfwCheckPresence: Compute ID %d has no PFW and no connection to PFW-ready ViNS", compId)
|
||||
return "", nil
|
||||
}
|
||||
if err != nil {
|
||||
|
||||
return "", err
|
||||
}
|
||||
|
||||
pfwListResp := ComputePfwListResp{}
|
||||
|
||||
// Note the specifics of compute/pfwList response in API 3.7.x (this may be changed in the future):
|
||||
// 1) if there are no PFW rules and compute is not connected to any PFW-able ViNS
|
||||
// the response will be empty string (or HTTP error code 500)
|
||||
// 2) if there are no PFW rules but compute is connected to a PFW-able ViNS
|
||||
// the response will contain a list with a single element - prefix (see PfwPrefixRecord)
|
||||
// 3) if there are port forwarding rules, the response will contain a list which starts
|
||||
// with prefix (see PfwPrefixRecord) and then followed by one or more rule records
|
||||
// (see PfwRuleRecord)
|
||||
//
|
||||
// EXTRA NOTE: in API 3.7.0 and the likes pfwList returns HTTP response code 500 for a compute
|
||||
// that is not connected to any PFW-able ViNS - need to implement temporary workaround
|
||||
|
||||
if apiResp == "" {
|
||||
// No port forward rules defined for this compute
|
||||
return "", nil
|
||||
}
|
||||
|
||||
log.Debugf("utilityPfwCheckPresence: ready to split API response string %s", apiResp)
|
||||
|
||||
twoParts := strings.SplitN(apiResp, "},", 2)
|
||||
if len(twoParts) < 1 || len(twoParts) > 2 {
|
||||
// Case: invalid format of API response
|
||||
log.Errorf("utilityPfwCheckPresence: non-empty pfwList response for compute ID %d failed to split properly", compId)
|
||||
return "", fmt.Errorf("Non-empty pfwList response failed to split properly")
|
||||
}
|
||||
|
||||
if len(twoParts) == 1 {
|
||||
// Case: compute is connected to a PWF-ready ViNS but has no PFW rules defined
|
||||
log.Debugf("utilityPfwCheckPresence: compute ID %d is connected to PFW-ready ViNS but has no PFW rules", compId)
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Case: compute is connected to a PFW ready ViNS and has some PFW rule
|
||||
prefixResp := strings.TrimSuffix(strings.TrimPrefix(twoParts[0], "["), ",") + "}"
|
||||
log.Debugf("utilityPfwCheckPresence: ready to unmarshal prefix part %s", prefixResp)
|
||||
err = json.Unmarshal([]byte(prefixResp), &pfwListResp.Header)
|
||||
if err != nil {
|
||||
log.Errorf("utilityPfwCheckPresence: failed to unmarshal prefix part of API response: %s", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
rulesResp := "[" + twoParts[1]
|
||||
log.Debugf("utilityPfwCheckPresence: ready to unmarshal rules part %s", rulesResp)
|
||||
err = json.Unmarshal([]byte(rulesResp), &pfwListResp.Rules)
|
||||
if err != nil {
|
||||
log.Errorf("utilityPfwCheckPresence: failed to unmarshal rules part of API response: %s", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
log.Debugf("utilityPfwCheckPresence: successfully read %d port forward rules for Compute ID %d",
|
||||
len(pfwListResp.Rules), compId)
|
||||
|
||||
if len(pfwListResp.Rules) == 0 {
|
||||
// this compute technically can have rules, but no rules are currently defined
|
||||
return "", nil
|
||||
}
|
||||
|
||||
// Now we can double check that the PFWs we've got do belong to the compute & ViNS specified in the
|
||||
// PFW definition. Do so by reading compute details and comparing NatableVinsID value with the
|
||||
// specified ViNS ID
|
||||
//
|
||||
// We may reuse urlValues here, as it already contains computeId field (see initialization above)
|
||||
apiResp, err, _ = controller.decortAPICall("POST", ComputeGetAPI, urlValues)
|
||||
if err != nil || apiResp == "" {
|
||||
log.Errorf("utilityPfwCheckPresence: failed to get Compute ID %d details", compId)
|
||||
return "", err
|
||||
}
|
||||
compFacts := ComputeGetResp{}
|
||||
err = json.Unmarshal([]byte(rulesResp), &apiResp)
|
||||
if err != nil {
|
||||
log.Errorf("utilityPfwCheckPresence: failed to unmarshal compute details for ID %d: %s", compId, err)
|
||||
return "", err
|
||||
}
|
||||
if compFacts.NatableVinsID <= 0 {
|
||||
log.Errorf("utilityPfwCheckPresence: compute ID %d is not connected to a NAT-able ViNS", compId)
|
||||
return "", fmt.Errorf("Compute ID %d is not connected to a NAT-able ViNS", compId)
|
||||
}
|
||||
if compFacts.NatableVinsID != vinsId {
|
||||
log.Errorf("utilityPfwCheckPresence: ViNS ID mismatch for PFW rules on compute ID %d: actual %d, required %d",
|
||||
compId, compFacts.NatableVinsID, vinsId)
|
||||
return "", fmt.Errorf("ViNS ID mismatch for PFW rules on compute ID %d: actual %d, required %d",
|
||||
compId, compFacts.NatableVinsID, vinsId)
|
||||
}
|
||||
|
||||
// reconstruct API response string to return
|
||||
pfwListResp.Header.ComputeID = compId
|
||||
pfwListResp.Header.VinsID = compFacts.NatableVinsID
|
||||
reencodedItem, err := json.Marshal(pfwListResp)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return string(reencodedItem[:]), nil
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ import (
|
||||
func (ctrl *ControllerCfg) utilityResgroupConfigGet(rgid int) (*ResgroupGetResp, error) {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgid))
|
||||
rgFacts, err, _ := ctrl.decortAPICall("POST", ResgroupGetAPI, urlValues)
|
||||
rgFacts, err := ctrl.decortAPICall("POST", ResgroupGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -109,7 +109,7 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
|
||||
// go straight for the RG by its ID
|
||||
log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId)
|
||||
urlValues.Add("rgId", fmt.Sprintf("%d", theId))
|
||||
rgFacts, err, _ := controller.decortAPICall("POST", ResgroupGetAPI, urlValues)
|
||||
rgFacts, err := controller.decortAPICall("POST", ResgroupGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -130,7 +130,7 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
|
||||
}
|
||||
|
||||
urlValues.Add("includedeleted", "false")
|
||||
apiResp, err, _ := controller.decortAPICall("POST", ResgroupListAPI, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", ResgroupListAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -154,7 +154,7 @@ func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string
|
||||
// Namely, we need resource quota settings
|
||||
reqValues := &url.Values{}
|
||||
reqValues.Add("rgId", fmt.Sprintf("%d", item.ID))
|
||||
apiResp, err, _ := controller.decortAPICall("POST", ResgroupGetAPI, reqValues)
|
||||
apiResp, err := controller.decortAPICall("POST", ResgroupGetAPI, reqValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ import (
|
||||
func (ctrl *ControllerCfg) utilityVinsConfigGet(vinsid int) (*VinsRecord, error) {
|
||||
urlValues := &url.Values{}
|
||||
urlValues.Add("vinsId", fmt.Sprintf("%d", vinsid))
|
||||
vinsFacts, err, _ := ctrl.decortAPICall("POST", VinsGetAPI, urlValues)
|
||||
vinsFacts, err := ctrl.decortAPICall("POST", VinsGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -94,7 +94,7 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er
|
||||
// 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)
|
||||
vinsFacts, err := controller.decortAPICall("POST", VinsGetAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -125,7 +125,7 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er
|
||||
urlValues.Add("accountId", fmt.Sprintf("%d", accountId.(int)))
|
||||
}
|
||||
|
||||
apiResp, err, _ := controller.decortAPICall("POST", VinsSearchAPI, urlValues)
|
||||
apiResp, err := controller.decortAPICall("POST", VinsSearchAPI, urlValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -154,7 +154,7 @@ func utilityVinsCheckPresence(d *schema.ResourceData, m interface{}) (string, er
|
||||
// manage ViNS, so we have to get detailed info by calling API vins/get
|
||||
rqValues := &url.Values{}
|
||||
rqValues.Add("vinsId", fmt.Sprintf("%d",item.ID))
|
||||
vinsGetResp, err, _ := controller.decortAPICall("POST", VinsGetAPI, rqValues)
|
||||
vinsGetResp, err := controller.decortAPICall("POST", VinsGetAPI, rqValues)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
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")
|
||||
|
||||
27
samples/README.md
Normal file
27
samples/README.md
Normal file
@@ -0,0 +1,27 @@
|
||||
# Примеры применения ресурсов terraform-provider-decort
|
||||
Каждый файл снабжен комментариями, которые кратко описывают возможности и параметры ресурса.
|
||||
Для успешной работы необходим установленный terraform.
|
||||
## Ресурсы в примерах
|
||||
- data:
|
||||
- grid
|
||||
- grid_list
|
||||
- image
|
||||
- image_list
|
||||
- image_list_stacks
|
||||
- resources:
|
||||
- image
|
||||
- virtual_image
|
||||
- cdrom_image
|
||||
- delete_images
|
||||
|
||||
## Как пользоваться примерами
|
||||
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
|
||||
}
|
||||
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