Compare commits
163 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| f33b8e3e7d | |||
|
|
5d15e83d56 | ||
| 2c70109d2d | |||
|
|
efe0c88556 | ||
| 5496073a0c | |||
| dc39a6412e | |||
|
|
de8857b1d5 | ||
| 782afe70da | |||
|
|
d6b4752cc7 | ||
| 36879efd58 | |||
|
|
040af43607 | ||
| a59ec3611b | |||
| 6eb6546722 | |||
| 8ad6811e88 | |||
| 6876b25f0e | |||
| db1760cb72 | |||
| 84b7a80e1b | |||
| 8857ed17be | |||
| 91ba361af9 | |||
| f49d9f8860 | |||
| 20050bc169 | |||
| e2ee45ee14 | |||
|
|
294680282e | ||
|
|
2bc0fbae9a | ||
|
|
2453a32d01 | ||
|
|
0602a4b693 | ||
|
|
28b60de115 | ||
|
|
b705ce4aab | ||
|
|
83ca627cea | ||
|
|
739289fbb8 | ||
|
|
c89574c3e6 | ||
|
|
a1e61674c8 | ||
|
|
cb9ff26bb0 | ||
|
|
6932f9d305 | ||
|
|
712f8edf9e | ||
|
|
805ffe1f29 | ||
|
|
bf8d3fb437 | ||
| d7a7eb9cb3 | |||
|
|
b60f32c570 | ||
| 272e385318 | |||
| f731cf246f | |||
| 6365f63fc1 | |||
| 85ce76564f | |||
| 928481d26f | |||
| 0e64974821 | |||
| 371bb0d90f | |||
| caf7213bca | |||
| 9cf150437d | |||
| 523d96189f | |||
|
|
8ca233dd32 | ||
|
|
9bad8a6947 | ||
|
|
e3e7e7bd89 | ||
|
|
b112c5ee22 | ||
|
|
f2f31b939e | ||
|
|
c781ffafaa | ||
|
|
3715db2923 | ||
|
|
f83c8e8a9a | ||
|
|
af82decadd | ||
|
|
f5e0a53364 | ||
|
|
9d1c8eeaa7 | ||
|
|
8516e0419a | ||
|
|
e12afbe1ad | ||
|
|
c0c9dc8131 | ||
|
|
c3bc6ef5da | ||
|
|
4d865ae921 | ||
|
|
a355247845 | ||
|
|
be86069155 | ||
|
|
0adf28daf6 | ||
|
|
9402d6f291 | ||
|
|
cb7e573d26 | ||
|
|
6ef0ad2f93 | ||
|
|
31be0a0b54 | ||
|
|
71ddaa3345 | ||
|
|
775a0b5adb | ||
|
|
1a983e945b | ||
|
|
b152359706 | ||
| a844f6cc30 | |||
|
|
8e6b5a9bab | ||
|
|
cd4695ee68 | ||
|
|
5bd7958f09 | ||
| 8fc9170c9c | |||
|
|
294550f5ce | ||
|
|
ddc6640a32 | ||
|
|
4bc11c5f07 | ||
|
|
2287177302 | ||
|
|
6433bc2954 | ||
|
|
965b6013a6 | ||
|
|
8d530c45ea | ||
|
|
bdcb1ab532 | ||
|
|
818875976c | ||
|
|
e9de5a2840 | ||
|
|
fae22aa484 | ||
| abd1a439eb | |||
|
|
4c4a007a58 | ||
|
|
3275424089 | ||
|
|
f06aa41b96 | ||
|
|
1245dd17f2 | ||
|
|
28ceebecf8 | ||
|
|
2b7f3d45f3 | ||
|
|
0bdd7c3c32 | ||
|
|
44ad5e4fe2 | ||
|
|
628ce3b75c | ||
|
|
020845b48f | ||
|
|
5b4c1f4324 | ||
|
|
fc32db30b6 | ||
|
|
81443a3d02 | ||
|
|
c422910bbe | ||
|
|
e45695e07f | ||
|
|
48cada2cf3 | ||
|
|
7cc359ec59 | ||
|
|
a1d716d566 | ||
|
|
e4be812c68 | ||
|
|
9a7642cf33 | ||
|
|
3613bbea28 | ||
|
|
b49cbe3d55 | ||
|
|
71aff5fa32 | ||
|
|
407e45cd5c | ||
|
|
40b8f93fa2 | ||
|
|
b599e244e8 | ||
|
|
42c4f2e505 | ||
|
|
4b4efec196 | ||
|
|
945e6e08b0 | ||
|
|
efe2b577b0 | ||
|
|
545eac90df | ||
|
|
4e35273d6d | ||
|
|
6f1f18fd0a | ||
|
|
5aa436cfb8 | ||
|
|
4a98b99f1c | ||
|
|
c7b54717a1 | ||
|
|
0609b158c1 | ||
|
|
8d1b13f7b7 | ||
|
|
0be6da1ae1 | ||
|
|
c73a6e0d71 | ||
|
|
95ab4e37c4 | ||
|
|
b70cdcabf6 | ||
|
|
eb22dee25b | ||
|
|
61b8765c82 | ||
|
|
96c4175e74 | ||
|
|
a685a91f86 | ||
|
|
839841aee4 | ||
|
|
9f5b4ab771 | ||
|
|
4a326e9ceb | ||
|
|
a0fbc8dd4f | ||
|
|
9912b04c2a | ||
|
|
d527d9b474 | ||
|
|
5e515daafa | ||
|
|
fa748f6e5d | ||
|
|
c5e35b19f9 | ||
|
|
b5a9987b74 | ||
|
|
103038c0a3 | ||
|
|
f5a606153f | ||
|
|
9a806a8e2c | ||
|
|
56e71c8981 | ||
|
|
424cdcd2b3 | ||
|
|
165bd89fbf | ||
|
|
7fb4223f85 | ||
|
|
8112f328a2 | ||
|
|
5e867706c0 | ||
|
|
2e355d2ede | ||
|
|
b849521780 | ||
|
|
2797a10fcb | ||
|
|
d35fa26eb8 | ||
|
|
83dad0d6b3 |
8
.github/workflows/release.yml
vendored
8
.github/workflows/release.yml
vendored
@@ -2,7 +2,7 @@ name: Release
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
tags:
|
tags:
|
||||||
- 'v*'
|
- '*'
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
release:
|
release:
|
||||||
@@ -17,9 +17,9 @@ jobs:
|
|||||||
run: git fetch --force --tags
|
run: git fetch --force --tags
|
||||||
|
|
||||||
- name: Setup Go
|
- name: Setup Go
|
||||||
uses: actions/setup-go@v2
|
uses: actions/setup-go@v3
|
||||||
with:
|
with:
|
||||||
go-version: 1.17
|
go-version: 1.18
|
||||||
|
|
||||||
- name: Import GPG key
|
- name: Import GPG key
|
||||||
id: import_gpg
|
id: import_gpg
|
||||||
@@ -29,7 +29,7 @@ jobs:
|
|||||||
passphrase: ${{ secrets.PASSPHRASE }}
|
passphrase: ${{ secrets.PASSPHRASE }}
|
||||||
|
|
||||||
- name: Run GoReleaser
|
- name: Run GoReleaser
|
||||||
uses: goreleaser/goreleaser-action@v2
|
uses: goreleaser/goreleaser-action@v3
|
||||||
with:
|
with:
|
||||||
args: release --rm-dist --release-notes CHANGELOG.md
|
args: release --rm-dist --release-notes CHANGELOG.md
|
||||||
env:
|
env:
|
||||||
|
|||||||
4
.gitignore
vendored
4
.gitignore
vendored
@@ -2,3 +2,7 @@ decort/vendor/
|
|||||||
examples/
|
examples/
|
||||||
url_scrapping/
|
url_scrapping/
|
||||||
terraform-provider-decort*
|
terraform-provider-decort*
|
||||||
|
.vscode/
|
||||||
|
.DS_Store
|
||||||
|
vendor/
|
||||||
|
.idea/
|
||||||
@@ -5,7 +5,7 @@ linters:
|
|||||||
- dogsled
|
- dogsled
|
||||||
- errorlint
|
- errorlint
|
||||||
- exportloopref
|
- exportloopref
|
||||||
- gocognit
|
#- gocognit - disabled till better times
|
||||||
- goconst
|
- goconst
|
||||||
- gocyclo
|
- gocyclo
|
||||||
- gosec
|
- gosec
|
||||||
@@ -20,7 +20,7 @@ linters:
|
|||||||
linters-settings:
|
linters-settings:
|
||||||
errcheck:
|
errcheck:
|
||||||
exclude-functions:
|
exclude-functions:
|
||||||
- (*github.com/hashicorp/terraform-plugin-sdk/helper/schema.ResourceData).Set
|
- (*github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema.ResourceData).Set
|
||||||
staticcheck:
|
staticcheck:
|
||||||
go: "1.18"
|
go: "1.18"
|
||||||
checks:
|
checks:
|
||||||
@@ -28,6 +28,8 @@ linters-settings:
|
|||||||
- -SA1019
|
- -SA1019
|
||||||
nestif:
|
nestif:
|
||||||
min-complexity: 7
|
min-complexity: 7
|
||||||
|
gocyclo:
|
||||||
|
min-complexity: 40
|
||||||
|
|
||||||
issues:
|
issues:
|
||||||
max-same-issues: 0
|
max-same-issues: 0
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ before:
|
|||||||
builds:
|
builds:
|
||||||
- env:
|
- env:
|
||||||
- CGO_ENABLED=0
|
- CGO_ENABLED=0
|
||||||
|
main: ./cmd/decort
|
||||||
mod_timestamp: '{{ .CommitTimestamp }}'
|
mod_timestamp: '{{ .CommitTimestamp }}'
|
||||||
flags:
|
flags:
|
||||||
- -trimpath
|
- -trimpath
|
||||||
@@ -15,9 +16,12 @@ builds:
|
|||||||
goarch:
|
goarch:
|
||||||
- amd64
|
- amd64
|
||||||
- '386'
|
- '386'
|
||||||
|
- arm64
|
||||||
ignore:
|
ignore:
|
||||||
- goos: darwin
|
- goos: darwin
|
||||||
goarch: '386'
|
goarch: '386'
|
||||||
|
- goos: windows
|
||||||
|
goarch: arm64
|
||||||
binary: '{{ .ProjectName }}_v{{ .Version }}'
|
binary: '{{ .ProjectName }}_v{{ .Version }}'
|
||||||
archives:
|
archives:
|
||||||
- format: zip
|
- format: zip
|
||||||
|
|||||||
41
CHANGELOG.md
41
CHANGELOG.md
@@ -1,37 +1,8 @@
|
|||||||
### Bug fixes
|
## Version 4.8.5
|
||||||
- changing boot\_disk\_size in kvmvm
|
|
||||||
- downsizing CPU and RAM in kvmvm
|
|
||||||
- pfw recreation if public\_port\_end unspecified
|
|
||||||
- uninformative error message when retrying on 500
|
|
||||||
- hardcoded 3 minute timeout
|
|
||||||
|
|
||||||
### New datasources
|
### Исправлено
|
||||||
- disk\_list
|
|
||||||
- rg\_list
|
|
||||||
- account\_list
|
|
||||||
- account\_computes\_list
|
|
||||||
- account\_disks\_list
|
|
||||||
- account\_vins\_list
|
|
||||||
- account\_audits\_list
|
|
||||||
- account
|
|
||||||
- account\_rg\_list
|
|
||||||
- account\_counsumed\_units
|
|
||||||
- account\_counsumed\_units\_by\_type
|
|
||||||
- account\_reserved\_units
|
|
||||||
- account\_templates\_list
|
|
||||||
- account\_deleted\_list
|
|
||||||
- bservice\_list
|
|
||||||
- bservice\_snapshot\_list
|
|
||||||
- bservice\_deleted\_list
|
|
||||||
- bservice
|
|
||||||
- bservice\_group
|
|
||||||
- extnet\_default
|
|
||||||
- extnet\_list
|
|
||||||
- extnet
|
|
||||||
- extnet\_computes\_list
|
|
||||||
- vins\_list
|
|
||||||
|
|
||||||
### New resources
|
#### kvmvm
|
||||||
- account
|
| Идентификатор<br>задачи | Описание |
|
||||||
- bservice
|
| --- | --- |
|
||||||
- bservice\_group
|
| BATF-1053 | Перезагрузка виртуальной машины при изменении полей `ram` и `cpu` в resources `decort_kvmvm` и `decort_cb_kvmvm` в cloudapi/kvmvm и в cloudbroker/kvmvm |
|
||||||
@@ -1,52 +0,0 @@
|
|||||||
pipeline {
|
|
||||||
agent {
|
|
||||||
kubernetes {
|
|
||||||
yaml '''
|
|
||||||
apiVersion: v1
|
|
||||||
kind: Pod
|
|
||||||
spec:
|
|
||||||
containers:
|
|
||||||
- name: alpine
|
|
||||||
image: alpine:3.15
|
|
||||||
command:
|
|
||||||
- sleep
|
|
||||||
- infinity
|
|
||||||
'''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stages {
|
|
||||||
stage('Dependency check') {
|
|
||||||
environment {
|
|
||||||
DEPCHECKDB = credentials('depcheck-postgres')
|
|
||||||
}
|
|
||||||
steps {
|
|
||||||
container('alpine') {
|
|
||||||
sh 'apk update && apk add openjdk11 java-postgresql-jdbc go'
|
|
||||||
dependencyCheck additionalArguments: '-f JSON -f HTML -n --enableExperimental \
|
|
||||||
-l deplog \
|
|
||||||
--dbDriverName org.postgresql.Driver \
|
|
||||||
--dbDriverPath /usr/share/java/postgresql-jdbc.jar \
|
|
||||||
--dbUser $DEPCHECKDB_USR \
|
|
||||||
--dbPassword $DEPCHECKDB_PSW \
|
|
||||||
--connectionString jdbc:postgresql://postgres-postgresql.postgres/depcheck', odcInstallation: 'depcheck'
|
|
||||||
sh 'cat deplog'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('SonarQube analysis') {
|
|
||||||
environment {
|
|
||||||
SONARSCANNER_HOME = tool 'sonarscanner'
|
|
||||||
}
|
|
||||||
steps {
|
|
||||||
withSonarQubeEnv('sonarqube') {
|
|
||||||
sh '$SONARSCANNER_HOME/bin/sonar-scanner'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
stage('SonarQube quality gate') {
|
|
||||||
steps {
|
|
||||||
waitForQualityGate webhookSecretId: 'sonar-webhook', abortPipeline: true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
2
LICENSE
2
LICENSE
@@ -186,7 +186,7 @@
|
|||||||
same "printed page" as the copyright notice for easier
|
same "printed page" as the copyright notice for easier
|
||||||
identification within third-party archives.
|
identification within third-party archives.
|
||||||
|
|
||||||
Copyright [yyyy] [name of copyright owner]
|
Copyright 2022 Basis LTD
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
|
|||||||
102
Makefile
102
Makefile
@@ -1,39 +1,85 @@
|
|||||||
TEST?=$$(go list ./... | grep -v 'vendor')
|
TEST?=$$(go list ./... | grep -v 'vendor')
|
||||||
HOSTNAME=digitalenergy.online
|
HOSTNAME=basis
|
||||||
NAMESPACE=decort
|
NAMESPACE=decort
|
||||||
NAME=terraform-provider-decort
|
NAME=terraform-provider-decort
|
||||||
#BINARY=terraform-provider-${NAME}
|
BINDIR = ./bin
|
||||||
BINARY=${NAME}.exe
|
ZIPDIR = ./zip
|
||||||
VERSION=0.2
|
BINARY=${NAME}
|
||||||
#OS_ARCH=darwin_amd64
|
WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH}
|
||||||
OS_ARCH=windows_amd64
|
MAINPATH = ./cmd/decort/
|
||||||
|
VERSION=4.8.5
|
||||||
|
OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH)
|
||||||
|
|
||||||
|
FILES = ${BINARY}_${VERSION}_darwin_amd64\
|
||||||
|
${BINARY}_${VERSION}_darwin_arm64\
|
||||||
|
${BINARY}_${VERSION}_freebsd_386\
|
||||||
|
${BINARY}_${VERSION}_freebsd_amd64\
|
||||||
|
${BINARY}_${VERSION}_freebsd_arm\
|
||||||
|
${BINARY}_${VERSION}_linux_386\
|
||||||
|
${BINARY}_${VERSION}_linux_amd64\
|
||||||
|
${BINARY}_${VERSION}_linux_arm\
|
||||||
|
${BINARY}_${VERSION}_linux_arm64\
|
||||||
|
${BINARY}_${VERSION}_openbsd_386\
|
||||||
|
${BINARY}_${VERSION}_openbsd_amd64\
|
||||||
|
${BINARY}_${VERSION}_solaris_amd64\
|
||||||
|
${BINARY}_${VERSION}_windows_386.exe\
|
||||||
|
${BINARY}_${VERSION}_windows_amd64.exe\
|
||||||
|
|
||||||
|
BINS = $(addprefix bin/, $(FILES))
|
||||||
|
|
||||||
default: install
|
default: install
|
||||||
|
|
||||||
build:
|
image:
|
||||||
go build -o ${BINARY}
|
GOOS=linux GOARCH=amd64 go build -o terraform-provider-decort ./cmd/decort/
|
||||||
|
docker build . -t rudecs/tf:3.2.2
|
||||||
|
rm terraform-provider-decort
|
||||||
|
|
||||||
release:
|
lint:
|
||||||
GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64
|
golangci-lint run --timeout 600s
|
||||||
GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386
|
|
||||||
GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64
|
st:
|
||||||
GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm
|
go build -o ${BINARY} ${MAINPATH}
|
||||||
GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386
|
cp ${BINARY} ${WORKPATH}
|
||||||
GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64
|
rm ${BINARY}
|
||||||
GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm
|
|
||||||
GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386
|
build:
|
||||||
GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64
|
go build -o ${BINARY} ${MAINPATH}
|
||||||
GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64
|
|
||||||
GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386
|
release: $(FILES)
|
||||||
GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64
|
|
||||||
|
$(FILES) : $(BINDIR) $(ZIPDIR) $(BINS)
|
||||||
|
zip -r $(ZIPDIR)/$@.zip $(BINDIR)/$@
|
||||||
|
zip -rj $(ZIPDIR)/$@.zip scripts/install.bat scripts/install.sh
|
||||||
|
|
||||||
|
$(BINDIR):
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
$(ZIPDIR):
|
||||||
|
mkdir $@
|
||||||
|
|
||||||
|
$(BINS):
|
||||||
|
GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64 $(MAINPATH)
|
||||||
|
GOOS=darwin GOARCH=arm64 go build -o ./bin/${BINARY}_${VERSION}_darwin_arm64 $(MAINPATH)
|
||||||
|
GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386 $(MAINPATH)
|
||||||
|
GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64 $(MAINPATH)
|
||||||
|
GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm $(MAINPATH)
|
||||||
|
GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386 $(MAINPATH)
|
||||||
|
GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64 $(MAINPATH)
|
||||||
|
GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm $(MAINPATH)
|
||||||
|
GOOS=linux GOARCH=arm64 go build -o ./bin/${BINARY}_${VERSION}_linux_arm64 ${MAINPATH}
|
||||||
|
GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386 $(MAINPATH)
|
||||||
|
GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64 $(MAINPATH)
|
||||||
|
GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64 $(MAINPATH)
|
||||||
|
GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386.exe $(MAINPATH)
|
||||||
|
GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64.exe $(MAINPATH)
|
||||||
|
|
||||||
install: build
|
install: build
|
||||||
mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH}
|
mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH}
|
||||||
mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH}
|
mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH}
|
||||||
|
|
||||||
test:
|
test:
|
||||||
go test -i $(TEST) || exit 1
|
go test -i $(TEST) || exit 1
|
||||||
echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
|
echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
|
||||||
|
|
||||||
testacc:
|
testacc:
|
||||||
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m
|
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m
|
||||||
|
|||||||
246
README.md
246
README.md
@@ -1,69 +1,143 @@
|
|||||||
# terraform-provider-decort
|
# terraform-provider-decort
|
||||||
|
|
||||||
Terraform provider для платформы Digital Energy Cloud Orchestration Technology (DECORT)
|
Terraform provider для платформы Digital Energy Cloud Orchestration Technology (DECORT)
|
||||||
|
|
||||||
Внимание: провайдер версии rc-1.25 разработан для DECORT API 3.7.x.
|
## Соответсвие версий платформы версиям провайдера
|
||||||
Для более старых версий можно использовать:
|
|
||||||
- DECORT API 3.6.x - версия провайдера rc-1.10
|
| Версия DECORT API | Версия провайдера Terraform |
|
||||||
- DECORT API до 3.6.0 - terraform DECS provider (https://github.com/rudecs/terraform-provider-decs)
|
| ------ | ------ |
|
||||||
|
| 4.2.0 | 4.8.x |
|
||||||
|
| 4.1.0 | 4.7.x |
|
||||||
|
| 4.0.0 | 4.6.x |
|
||||||
|
| 3.8.9 | 4.5.x |
|
||||||
|
| 3.8.8 | 4.4.x |
|
||||||
|
| 3.8.7 | 4.3.x |
|
||||||
|
| 3.8.6 | 4.0.x, 4.1.x, 4.2.x |
|
||||||
|
| 3.8.5 | 3.4.x |
|
||||||
|
| 3.8.0 - 3.8.4 | 3.3.1 |
|
||||||
|
| 3.7.x | rc-1.25 |
|
||||||
|
| 3.6.x | rc-1.10 |
|
||||||
|
| до 3.6.0 | [terraform-provider-decs](https://github.com/rudecs/terraform-provider-decs) |
|
||||||
|
|
||||||
|
## Режимы работы
|
||||||
|
|
||||||
|
Провайдер позволяет работать в двух режимах:
|
||||||
|
|
||||||
|
- Режим пользователя,
|
||||||
|
- Режим администратора. <br>
|
||||||
|
Используйте ресурсы `decort_cb_` для администрирования. <br>
|
||||||
|
Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||||
|
|
||||||
## Возможности провайдера
|
## Возможности провайдера
|
||||||
- Работа с Compute instances,
|
|
||||||
- Работа с disks,
|
|
||||||
- Работа с k8s,
|
|
||||||
- Работа с image,
|
|
||||||
- Работа с reource groups,
|
|
||||||
- Работа с VINS,
|
|
||||||
- Работа с pfw,
|
|
||||||
- Работа с accounts,
|
|
||||||
- Работа с snapshots,
|
|
||||||
- Работа с pcidevice,
|
|
||||||
- Работа с sep,
|
|
||||||
- Работа с vgpu,
|
|
||||||
- Работа с bservice,
|
|
||||||
- Работа с extnets.
|
|
||||||
|
|
||||||
Вики проекта: https://github.com/rudecs/terraform-provider-decort/wiki
|
- Режим пользователя:
|
||||||
|
- Работа с accounts,
|
||||||
|
- Работа с audit,
|
||||||
|
- Работа с bservice,
|
||||||
|
- Работа с disks,
|
||||||
|
- Работа с dpdk,
|
||||||
|
- Работа с extnets,
|
||||||
|
- Работа с flipgroups,
|
||||||
|
- Работа с image,
|
||||||
|
- Работа с k8s,
|
||||||
|
- Работа с Compute instances,
|
||||||
|
- Работа с load balancer,
|
||||||
|
- Работа с locations,
|
||||||
|
- Работа с pfw,
|
||||||
|
- Работа с resource groups,
|
||||||
|
- Работа с snapshots,
|
||||||
|
- Работа с stacks,
|
||||||
|
- Работа с VINS.
|
||||||
|
|
||||||
## Начало
|
- Режим администратора:
|
||||||
Старт возможен по двум путям:
|
- Работа с accounts,
|
||||||
1. Установка через собранные пакеты.
|
- Работа с audit,
|
||||||
2. Ручная установка.
|
- Работа с disks,
|
||||||
|
- Работа с dpdk,
|
||||||
|
- Работа с extnets,
|
||||||
|
- Работа с flipgroups,
|
||||||
|
- Работа с grids,
|
||||||
|
- Работа с images,
|
||||||
|
- Работа с k8ci,
|
||||||
|
- Работа с k8s,
|
||||||
|
- Работа с Compute instances,
|
||||||
|
- Работа с load balancer,
|
||||||
|
- Работа с pci device,
|
||||||
|
- Работа с resource groups,
|
||||||
|
- Работа с seps,
|
||||||
|
- Работа с user,
|
||||||
|
- Работа с stacks,
|
||||||
|
- Работа с VINS.
|
||||||
|
|
||||||
### Установка через собранные пакеты.
|
Со списком и описанием функционала всех групп можно ознамоиться на Вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||||
1. Скачайте и установите terraform по ссылке: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
|
|
||||||
2. Создайте файл `main.tf` и добавьте в него следующий блок.
|
## Установка
|
||||||
|
Начиная с версии провайдера `4.3.0` в релизном архиве находятся скрипты-инсталляторы.
|
||||||
|
Чтобы выполнить установку, необходимо:
|
||||||
|
1. Перейти по адресу: https://repository.basistech.ru/BASIS/terraform-provider-decort/releases
|
||||||
|
2. Выбрать необходимую версию провайдера подходящую под операционную систему.
|
||||||
|
3. Скачать архив.
|
||||||
|
4. Распаковать архив.
|
||||||
|
5. Выполнить скрипт установщика, `install.sh` или `install.bat` для Windows.<br/>
|
||||||
|
*Для запуска `install.sh` не забудьте изменить права доступа к файлу*
|
||||||
|
```bash
|
||||||
|
chmod u+x install.sh
|
||||||
|
```
|
||||||
|
6. Дождаться сообщения об успешной установке. Установщик выведет актуальный блок конфигурации провайдера, скопируйте его
|
||||||
|
```bash
|
||||||
|
DECORT provider version 4.3.0 has been successfully installed
|
||||||
|
|
||||||
|
Copy this provider configuration to main.tf file:
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
decort = {
|
||||||
|
version = "4.3.0"
|
||||||
|
source = "basis/decort/decort"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
7. После этого, создайте файл `main.tf` в рабочей директории, которая может находится в любом удобном для пользователя месте.
|
||||||
|
В данном примере, рабочая директория с файлом main.tf находится по пути:
|
||||||
|
```bash
|
||||||
|
~/work/tfdir/main.tf
|
||||||
|
```
|
||||||
|
8. Вставьте в `main.tf` блок конфигурации провайдера, который был выведен на экран установщиком:
|
||||||
|
```terraform
|
||||||
|
terraform {
|
||||||
|
required_providers {
|
||||||
|
decort = {
|
||||||
|
version = "4.3.0"
|
||||||
|
source = "basis/decort/decort"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
9. Добавьте в файл блок с инициализацией провайдера.
|
||||||
```terraform
|
```terraform
|
||||||
provider "decort" {
|
provider "decort" {
|
||||||
authenticator = "oauth2"
|
authenticator = "decs3o"
|
||||||
#controller_url = <DECORT_CONTROLLER_URL>
|
controller_url = "https://mr4.digitalenergy.online"
|
||||||
controller_url = "https://ds1.digitalenergy.online"
|
|
||||||
#oauth2_url = <DECORT_SSO_URL>
|
|
||||||
oauth2_url = "https://sso.digitalenergy.online"
|
oauth2_url = "https://sso.digitalenergy.online"
|
||||||
allow_unverified_ssl = true
|
allow_unverified_ssl = true
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
3. Выполните команду
|
|
||||||
```
|
10. В консоли выполните команду
|
||||||
|
```bash
|
||||||
terraform init
|
terraform init
|
||||||
```
|
```
|
||||||
Провайдер автоматически будет установлен на ваш компьютер из terraform registry.
|
|
||||||
|
|
||||||
### Ручная установка
|
11. В случае успешной установки, Terraform инициализирует провайдер и будет готов к дальнейшей работе.
|
||||||
1. Скачайте и установите Go по ссылке: https://go.dev/dl/
|
|
||||||
2. Скачайте и установите terraform по ссылке: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
|
## Установка из релизов
|
||||||
3. Склонируйте репозиторий с провайдером, выполнив команду:
|
Terraform провайдер DECORT имеет скомпилированные релизные версии, которые расположены по адресу: [Релизы](https://repository.basistech.ru/BASIS/terraform-provider-decort/releases).
|
||||||
```bash
|
Чтобы выполнить установку из релиза, необходимо:
|
||||||
git clone https://github.com/rudecs/terraform-provider-decort.git
|
1. Перейти по адресу: https://repository.basistech.ru/BASIS/terraform-provider-decort/releases
|
||||||
```
|
2. Выбрать необходимую версию провайдера подходящую под операционную систему.
|
||||||
4. Перейдите в скачанную папку с провайдером и выполните команду
|
3. Скачать архив.
|
||||||
```bash
|
4. Распаковать архив.
|
||||||
go build -o terraform-provider-decort
|
5. Полученный файл (в директории `bin/`) необходимо поместить:
|
||||||
```
|
|
||||||
Если вы знаете как устроен _makefile_, то можно изменить в файле `Makefile` параметры под вашу ОС и выполнить команду
|
|
||||||
```bash
|
|
||||||
make build
|
|
||||||
```
|
|
||||||
5. Полученный файл необходимо поместить:
|
|
||||||
Linux:
|
Linux:
|
||||||
```bash
|
```bash
|
||||||
~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target}
|
~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target}
|
||||||
@@ -72,51 +146,81 @@ Windows:
|
|||||||
```powershell
|
```powershell
|
||||||
%APPDATA%\terraform.d\plugins\${host_name}\${namespace}\${type}\${version}\${target}
|
%APPDATA%\terraform.d\plugins\${host_name}\${namespace}\${type}\${version}\${target}
|
||||||
```
|
```
|
||||||
ВНИМАНИЕ: для ОС Windows `%APP_DATA%` является каталогом, в котором будут помещены будущие файлы terraform.
|
|
||||||
Где:
|
Где:
|
||||||
- host_name - имя хоста, держателя провайдера, например, digitalenergy.online
|
- host_name - имя хоста, держателя провайдера, например, basis
|
||||||
- namespace - пространство имен хоста, например decort
|
- namespace - пространство имен хоста, например decort
|
||||||
- type - тип провайдера, может совпадать с пространством имен, например, decort
|
- type - тип провайдера, может совпадать с пространством имен, например, decort
|
||||||
- version - версия провайдера, например 1.2
|
- version - версия провайдера, например 4.3.0
|
||||||
- target - версия ОС, например windows_amd64
|
- target - архитектура операционной системы, например windows_amd64
|
||||||
6. После этого, создайте файл `main.tf`.
|
|
||||||
7. Добавьте в него следующий блок
|
В примере ниже используется путь до провайдера на машине с ОС Linux:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
~/.terraform.d/plugins/basis/decort/decort/4.3.0/linux_amd64/tf-provider
|
||||||
|
^ ^ ^ ^ ^ ^
|
||||||
|
host_name | | | | | |
|
||||||
|
| | | | |
|
||||||
|
namespace | | | | |
|
||||||
|
| | | |
|
||||||
|
type | | | |
|
||||||
|
| | |
|
||||||
|
version | | |
|
||||||
|
| |
|
||||||
|
target | |
|
||||||
|
|
|
||||||
|
исполняемый файл |
|
||||||
|
```
|
||||||
|
|
||||||
|
6. После этого, создайте файл `main.tf` в рабочей директории, которая может находится в любом удобном для пользователя месте.
|
||||||
|
В данном примере, рабочая директория с файлом main.tf находится по пути:
|
||||||
|
```bash
|
||||||
|
~/work/tfdir/main.tf
|
||||||
|
```
|
||||||
|
7. Добавьте в `main.tf` следующий блок
|
||||||
```terraform
|
```terraform
|
||||||
terraform {
|
terraform {
|
||||||
required_providers {
|
required_providers {
|
||||||
decort = {
|
decort = {
|
||||||
version = "1.2"
|
version = "4.3.0"
|
||||||
source = "digitalenergy.online/decort/decort"
|
source = "basis/decort/decort"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
В поле `version` указывается версия провайдера.
|
В поле `version` указывается версия провайдера.
|
||||||
Обязательный параметр
|
<br/>
|
||||||
Тип поля - строка
|
**ВНИМАНИЕ: Версии в блоке и в пути к исполняемому файлу провайдера должны совпадать!**
|
||||||
ВНИМАНИЕ: Версии в блоке и в репозитории, в который был помещен провайдер должны совпадать!
|
|
||||||
|
|
||||||
В поле `source` помещается путь до репозитория с версией вида:
|
В поле `source` помещается путь до репозитория с версией вида:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
${host_name}/${namespace}/${type}
|
${host_name}/${namespace}/${type}
|
||||||
```
|
```
|
||||||
ВНИМАНИЕ: все параметры должны совпадать с путем репозитория, в котором помещен провайдер.
|
|
||||||
|
|
||||||
8. В консоле выполнить команду
|
**ВНИМАНИЕ: Версии в блоке и в пути к исполняемому файлу провайдера должны совпадать!**
|
||||||
|
|
||||||
|
8. Добавьте в файл блок с инициализацией провайдера.
|
||||||
|
```terraform
|
||||||
|
provider "decort" {
|
||||||
|
authenticator = "decs3o"
|
||||||
|
controller_url = "https://mr4.digitalenergy.online"
|
||||||
|
oauth2_url = "https://sso.digitalenergy.online"
|
||||||
|
allow_unverified_ssl = true
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
9. В консоли выполните команду
|
||||||
```bash
|
```bash
|
||||||
terraform init
|
terraform init
|
||||||
```
|
```
|
||||||
|
|
||||||
9. Если все прошло хорошо - ошибок не будет.
|
10. В случае успешной установки, Terraform инициализирует провайдер и будет готов к дальнейшей работе.
|
||||||
|
|
||||||
Более подробно о сборке провайдера можно найти по ссылке: https://learn.hashicorp.com/tutorials/terraform/provider-use?in=terraform/providers
|
|
||||||
|
|
||||||
## Примеры работы
|
## Примеры работы
|
||||||
Примеры работы можно найти:
|
|
||||||
- На вики проекта: https://github.com/rudecs/terraform-provider-decort/wiki
|
|
||||||
- В папке `samples`
|
|
||||||
|
|
||||||
Схемы к terraform'у доступны:
|
Примеры работы можно найти:
|
||||||
- В папке `docs`
|
|
||||||
|
- На вики проекта: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||||
|
- В папке `samples`
|
||||||
|
|
||||||
Хорошей работы!
|
Хорошей работы!
|
||||||
|
|||||||
123
README_EN.md
123
README_EN.md
@@ -1,123 +0,0 @@
|
|||||||
# 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 image,
|
|
||||||
- Work with reource groups,
|
|
||||||
- Work with VINS,
|
|
||||||
- Work with pfw,
|
|
||||||
- Work with accounts,
|
|
||||||
- Work with snapshots,
|
|
||||||
- Work with pcidevice.
|
|
||||||
- Work with sep,
|
|
||||||
- Work with vgpu,
|
|
||||||
- Work with bservice,
|
|
||||||
- Work with extnets.
|
|
||||||
|
|
||||||
This provider supports Import operations on pre-existing resources.
|
|
||||||
|
|
||||||
See user guide at https://github.com/rudecs/terraform-provider-decort/wiki
|
|
||||||
|
|
||||||
|
|
||||||
## Get Started
|
|
||||||
Two ways for starting:
|
|
||||||
1. Installing via binary packages
|
|
||||||
2. Manual installing
|
|
||||||
|
|
||||||
### Installing via binary packages
|
|
||||||
1. Download and install terraform: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
|
|
||||||
2. Create a file `main.tf` and add to it next section.
|
|
||||||
```terraform
|
|
||||||
provider "decort" {
|
|
||||||
authenticator = "oauth2"
|
|
||||||
#controller_url = <DECORT_CONTROLLER_URL>
|
|
||||||
controller_url = "https://ds1.digitalenergy.online"
|
|
||||||
#oauth2_url = <DECORT_SSO_URL>
|
|
||||||
oauth2_url = "https://sso.digitalenergy.online"
|
|
||||||
allow_unverified_ssl = true
|
|
||||||
}
|
|
||||||
```
|
|
||||||
3. Execute next command
|
|
||||||
```
|
|
||||||
terraform init
|
|
||||||
```
|
|
||||||
The Provider will automatically install on your computer from the terrafrom registry.
|
|
||||||
|
|
||||||
### Manual installing
|
|
||||||
1. Download and install Go Programming Language: https://go.dev/dl/
|
|
||||||
2. Download and install terraform: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
|
|
||||||
3. Clone provider's repo:
|
|
||||||
```bash
|
|
||||||
git clone https://github.com/rudecs/terraform-provider-decort.git
|
|
||||||
```
|
|
||||||
4. Change directory to clone provider's and execute next command
|
|
||||||
```bash
|
|
||||||
go build -o terraform-provider-decort
|
|
||||||
```
|
|
||||||
If you have experience with _makefile_, you can change `Makefile`'s paramters and execute next command
|
|
||||||
```bash
|
|
||||||
make build
|
|
||||||
```
|
|
||||||
5. Now move compilled file to:
|
|
||||||
Linux:
|
|
||||||
```bash
|
|
||||||
~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target}
|
|
||||||
```
|
|
||||||
Windows:
|
|
||||||
```powershell
|
|
||||||
%APPDATA%\terraform.d\plugins\${host_name}/${namespace}/${type}/${version}/${target}
|
|
||||||
```
|
|
||||||
NOTE: for Windows OS `%APP_DATA%` is a cataloge, where will place terraform files.
|
|
||||||
Example:
|
|
||||||
- host_name - digitalenergy.online
|
|
||||||
- namespace - decort
|
|
||||||
- type - decort
|
|
||||||
- version - 1.2
|
|
||||||
- target - windows_amd64
|
|
||||||
6. After all, create a file `main.tf`.
|
|
||||||
7. Add to the file next code section
|
|
||||||
```terraform
|
|
||||||
terraform {
|
|
||||||
required_providers {
|
|
||||||
decort = {
|
|
||||||
version = "1.2"
|
|
||||||
source = "digitalenergy.online/decort/decort"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
```
|
|
||||||
`version`- field for provider's version
|
|
||||||
Required
|
|
||||||
String
|
|
||||||
Note: Versions in code section and in a repository must be equal!
|
|
||||||
|
|
||||||
`source` - path to repository with provider's version
|
|
||||||
```bash
|
|
||||||
${host_name}/${namespace}/${type}
|
|
||||||
```
|
|
||||||
NOTE: all paramters must be equal to the repository path!
|
|
||||||
|
|
||||||
8. Execute command in your terminal
|
|
||||||
```bash
|
|
||||||
terraform init
|
|
||||||
```
|
|
||||||
|
|
||||||
9. If everything all right - you got green message in your terminal!
|
|
||||||
|
|
||||||
More details about the provider's building process: https://learn.hashicorp.com/tutorials/terraform/provider-use?in=terraform/providers
|
|
||||||
|
|
||||||
## Examples and Samples
|
|
||||||
- Examples: https://github.com/rudecs/terraform-provider-decort/wiki
|
|
||||||
- Samples: see in repository `samples`
|
|
||||||
|
|
||||||
Terraform schemas in:
|
|
||||||
- See in repository `docs`
|
|
||||||
|
|
||||||
Good work!
|
|
||||||
@@ -1,6 +1,10 @@
|
|||||||
/*
|
/*
|
||||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
||||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
Authors:
|
||||||
|
Petr Krutov, <petr.krutov@digitalenergy.online>
|
||||||
|
Stanislav Solovev, <spsolovev@digitalenergy.online>
|
||||||
|
Kasim Baybikov, <kmbaybikov@basistech.ru>
|
||||||
|
Tim Tkachev, <tvtkachev@basistech.ru>
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
you may not use this file except in compliance with the License.
|
you may not use this file except in compliance with the License.
|
||||||
@@ -19,12 +23,12 @@ limitations under the License.
|
|||||||
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
|
||||||
Orchestration Technology) with Terraform by Hashicorp.
|
Orchestration Technology) with Terraform by Hashicorp.
|
||||||
|
|
||||||
Source code: https://github.com/rudecs/terraform-provider-decort
|
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
|
||||||
|
|
||||||
Please see README.md to learn where to place source code so that it
|
Please see README.md to learn where to place source code so that it
|
||||||
builds seamlessly.
|
builds seamlessly.
|
||||||
|
|
||||||
Documentation: https://github.com/rudecs/terraform-provider-decort/wiki
|
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package main
|
package main
|
||||||
@@ -32,10 +36,10 @@ package main
|
|||||||
import (
|
import (
|
||||||
log "github.com/sirupsen/logrus"
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/plugin"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/terraform"
|
"github.com/hashicorp/terraform-plugin-sdk/v2/plugin"
|
||||||
|
|
||||||
"github.com/rudecs/terraform-provider-decort/decort"
|
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/provider"
|
||||||
)
|
)
|
||||||
|
|
||||||
//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
|
//go:generate go run github.com/hashicorp/terraform-plugin-docs/cmd/tfplugindocs
|
||||||
@@ -45,8 +49,8 @@ func main() {
|
|||||||
log.Debug("Debug logging enabled")
|
log.Debug("Debug logging enabled")
|
||||||
|
|
||||||
plugin.Serve(&plugin.ServeOpts{
|
plugin.Serve(&plugin.ServeOpts{
|
||||||
ProviderFunc: func() terraform.ResourceProvider {
|
ProviderFunc: func() *schema.Provider {
|
||||||
return decort.Provider()
|
return provider.Provider()
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -1,43 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
// LimitMaxVinsPerResgroup set maximum number of VINs instances per Resource Group
|
|
||||||
const LimitMaxVinsPerResgroup=4
|
|
||||||
|
|
||||||
// MaxSshKeysPerCompute sets maximum number of user:ssh_key pairs to authorize when creating new compute
|
|
||||||
const MaxSshKeysPerCompute=12
|
|
||||||
|
|
||||||
// MaxExtraDisksPerCompute sets maximum number of extra disks that can be added when creating new compute
|
|
||||||
const MaxExtraDisksPerCompute=12
|
|
||||||
|
|
||||||
// MaxNetworksPerCompute sets maximum number of vNICs per compute
|
|
||||||
const MaxNetworksPerCompute=8
|
|
||||||
|
|
||||||
// MaxCpusPerCompute sets maximum number of vCPUs per compute
|
|
||||||
const MaxCpusPerCompute=128
|
|
||||||
|
|
||||||
// MinRamPerCompute sets minimum amount of RAM per compute in MB
|
|
||||||
const MinRamPerCompute=128
|
|
||||||
@@ -1,408 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"crypto/tls"
|
|
||||||
"fmt"
|
|
||||||
"io/ioutil"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
// "time"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/dgrijalva/jwt-go"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
// 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
|
|
||||||
)
|
|
||||||
|
|
||||||
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
|
|
||||||
}
|
|
||||||
|
|
||||||
func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
|
|
||||||
// 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
|
|
||||||
// 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,
|
|
||||||
// which is a DECORT authentication mode aware wrapper around standard HTTP requests.
|
|
||||||
|
|
||||||
ret_config := &ControllerCfg{
|
|
||||||
controller_url: d.Get("controller_url").(string),
|
|
||||||
auth_mode_code: MODE_UNDEF,
|
|
||||||
legacy_user: d.Get("user").(string),
|
|
||||||
legacy_password: d.Get("password").(string),
|
|
||||||
legacy_sid: "",
|
|
||||||
jwt: d.Get("jwt").(string),
|
|
||||||
app_id: d.Get("app_id").(string),
|
|
||||||
app_secret: d.Get("app_secret").(string),
|
|
||||||
oauth2_url: d.Get("oauth2_url").(string),
|
|
||||||
decort_username: "",
|
|
||||||
}
|
|
||||||
|
|
||||||
allow_unverified_ssl := d.Get("allow_unverified_ssl").(bool)
|
|
||||||
|
|
||||||
if ret_config.controller_url == "" {
|
|
||||||
return nil, fmt.Errorf("Empty DECORT cloud controller URL provided.")
|
|
||||||
}
|
|
||||||
|
|
||||||
// this should have already been done by StateFunc defined in Schema, but we want to be sure
|
|
||||||
ret_config.auth_mode_txt = strings.ToLower(d.Get("authenticator").(string))
|
|
||||||
|
|
||||||
switch ret_config.auth_mode_txt {
|
|
||||||
case "jwt":
|
|
||||||
if ret_config.jwt == "" {
|
|
||||||
return nil, fmt.Errorf("Authenticator mode 'jwt' specified but no JWT provided.")
|
|
||||||
}
|
|
||||||
ret_config.auth_mode_code = MODE_JWT
|
|
||||||
case "oauth2":
|
|
||||||
if ret_config.oauth2_url == "" {
|
|
||||||
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no OAuth2 URL provided.")
|
|
||||||
}
|
|
||||||
if ret_config.app_id == "" {
|
|
||||||
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no Application ID provided.")
|
|
||||||
}
|
|
||||||
if ret_config.app_secret == "" {
|
|
||||||
return nil, fmt.Errorf("Authenticator mode 'oauth2' specified but no Secret ID provided.")
|
|
||||||
}
|
|
||||||
ret_config.auth_mode_code = MODE_OAUTH2
|
|
||||||
case "legacy":
|
|
||||||
//
|
|
||||||
ret_config.legacy_user = d.Get("user").(string)
|
|
||||||
if ret_config.legacy_user == "" {
|
|
||||||
return nil, fmt.Errorf("Authenticator mode 'legacy' specified but no user provided.")
|
|
||||||
}
|
|
||||||
ret_config.legacy_password = d.Get("password").(string)
|
|
||||||
if ret_config.legacy_password == "" {
|
|
||||||
return nil, fmt.Errorf("Authenticator mode 'legacy' specified but no password provided.")
|
|
||||||
}
|
|
||||||
ret_config.auth_mode_code = MODE_LEGACY
|
|
||||||
default:
|
|
||||||
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}} //nolint:gosec
|
|
||||||
ret_config.cc_client = &http.Client{
|
|
||||||
Transport: transCfg,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
ret_config.cc_client = &http.Client{}
|
|
||||||
}
|
|
||||||
|
|
||||||
switch ret_config.auth_mode_code {
|
|
||||||
case MODE_LEGACY:
|
|
||||||
ok, err := ret_config.validateLegacyUser()
|
|
||||||
if !ok {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
ret_config.decort_username = ret_config.legacy_user
|
|
||||||
case MODE_JWT:
|
|
||||||
//
|
|
||||||
ok, err := ret_config.validateJWT("")
|
|
||||||
if !ok {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
case MODE_OAUTH2:
|
|
||||||
// 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
|
|
||||||
// OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user")
|
|
||||||
// and JWT issuer name (claim "iss")
|
|
||||||
parser := jwt.Parser{}
|
|
||||||
token, _, err := parser.ParseUnverified(ret_config.jwt, jwt.MapClaims{})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if claims, ok := token.Claims.(jwt.MapClaims); ok {
|
|
||||||
var tbuf bytes.Buffer
|
|
||||||
tbuf.WriteString(claims["username"].(string))
|
|
||||||
tbuf.WriteString("@")
|
|
||||||
tbuf.WriteString(claims["iss"].(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.")
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
// FYI, this should never happen due to all above checks, but we want to be fool proof
|
|
||||||
return nil, fmt.Errorf("Unknown authenticator mode code %d provided.", ret_config.auth_mode_code)
|
|
||||||
}
|
|
||||||
|
|
||||||
// All checks passed successfully, credentials corresponding to the selected authenticator mode
|
|
||||||
// obtained and validated.
|
|
||||||
return ret_config, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *ControllerCfg) getDecortUsername() string {
|
|
||||||
return config.decort_username
|
|
||||||
}
|
|
||||||
|
|
||||||
func (config *ControllerCfg) getOAuth2JWT() (string, error) {
|
|
||||||
// Obtain JWT from the Oauth2 provider using application ID and application secret provided in config.
|
|
||||||
if config.auth_mode_code == MODE_UNDEF {
|
|
||||||
return "", fmt.Errorf("getOAuth2JWT method called for undefined authorization mode.")
|
|
||||||
}
|
|
||||||
if config.auth_mode_code != MODE_OAUTH2 {
|
|
||||||
return "", fmt.Errorf("getOAuth2JWT method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
|
||||||
}
|
|
||||||
|
|
||||||
params := url.Values{}
|
|
||||||
params.Add("grant_type", "client_credentials")
|
|
||||||
params.Add("client_id", config.app_id)
|
|
||||||
params.Add("client_secret", config.app_secret)
|
|
||||||
params.Add("response_type", "id_token")
|
|
||||||
params.Add("validity", "3600")
|
|
||||||
params_str := params.Encode()
|
|
||||||
|
|
||||||
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)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
// fmt.Println("response Status:", resp.Status)
|
|
||||||
// fmt.Println("response Headers:", resp.Header)
|
|
||||||
// fmt.Println("response Headers:", req.URL)
|
|
||||||
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
|
|
||||||
resp.StatusCode, req.URL, config.app_id, params_str)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
responseData, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// validation successful - store JWT in the corresponding field of the ControllerCfg structure
|
|
||||||
config.jwt = strings.TrimSpace(string(responseData))
|
|
||||||
|
|
||||||
return config.jwt, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
if jwt == "" {
|
|
||||||
if config.jwt == "" {
|
|
||||||
return false, fmt.Errorf("validateJWT method called, but no meaningful JWT provided.")
|
|
||||||
}
|
|
||||||
jwt = config.jwt
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.oauth2_url == "" {
|
|
||||||
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)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q.",
|
|
||||||
resp.StatusCode, req.URL)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
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.
|
|
||||||
*/
|
|
||||||
if config.auth_mode_code == MODE_UNDEF {
|
|
||||||
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode.")
|
|
||||||
}
|
|
||||||
if config.auth_mode_code != MODE_LEGACY {
|
|
||||||
return false, fmt.Errorf("validateLegacyUser method called for incompatible authorization mode %q.", config.auth_mode_txt)
|
|
||||||
}
|
|
||||||
|
|
||||||
params := url.Values{}
|
|
||||||
params.Add("username", config.legacy_user)
|
|
||||||
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))
|
|
||||||
if err != nil {
|
|
||||||
return false, 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)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q.",
|
|
||||||
resp.StatusCode, config.legacy_user, config.controller_url)
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
responseData, err := ioutil.ReadAll(resp.Body)
|
|
||||||
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) { //nolint:unparam
|
|
||||||
// This is a convenience wrapper around standard HTTP request methods that is aware of the
|
|
||||||
// authorization mode for which the provider was initialized and compiles request accordingly.
|
|
||||||
|
|
||||||
if config.cc_client == nil {
|
|
||||||
// this should never happen if ClientConfig was properly called prior to decortAPICall
|
|
||||||
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))
|
|
||||||
//
|
|
||||||
// Or:
|
|
||||||
//
|
|
||||||
// params := url.Values{}
|
|
||||||
// params.Add("machineId", "2638")
|
|
||||||
// params.Add("username", "u")
|
|
||||||
// params.Add("password", "b")
|
|
||||||
// req, _ := http.NewRequest(method, url, strings.NewReader(params.Encode()))
|
|
||||||
//
|
|
||||||
|
|
||||||
if config.auth_mode_code == MODE_UNDEF {
|
|
||||||
return "", fmt.Errorf("decortAPICall method called for unknown authorization mode.")
|
|
||||||
}
|
|
||||||
|
|
||||||
if config.auth_mode_code == MODE_LEGACY {
|
|
||||||
url_values.Add("authkey", config.legacy_sid)
|
|
||||||
}
|
|
||||||
params_str := url_values.Encode()
|
|
||||||
|
|
||||||
req, err := http.NewRequest(method, config.controller_url+api_name, strings.NewReader(params_str))
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
|
|
||||||
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
|
|
||||||
req.Header.Set("Accept", "application/json")
|
|
||||||
|
|
||||||
if config.auth_mode_code == MODE_OAUTH2 || config.auth_mode_code == MODE_JWT {
|
|
||||||
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", config.jwt))
|
|
||||||
}
|
|
||||||
|
|
||||||
var resp *http.Response
|
|
||||||
var body []byte
|
|
||||||
for i := 0; i < 5; i++ {
|
|
||||||
resp, err = config.cc_client.Do(req)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
body, err = ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
resp.Body.Close()
|
|
||||||
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, body)
|
|
||||||
|
|
||||||
if resp.StatusCode == http.StatusOK {
|
|
||||||
return string(body), nil
|
|
||||||
} else {
|
|
||||||
if resp.StatusCode == http.StatusInternalServerError {
|
|
||||||
log.Warnf("got 500, retrying %d/5", i+1)
|
|
||||||
time.Sleep(time.Second * 5)
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %q with request Body %q. Respone:\n%s",
|
|
||||||
resp.StatusCode, req.URL, params_str, body)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", 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)
|
|
||||||
}
|
|
||||||
@@ -1,417 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceAccountRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
acc, err := utilityAccountCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("dc_location", acc.DCLocation)
|
|
||||||
d.Set("resources", flattenAccResources(acc.Resources))
|
|
||||||
d.Set("ckey", acc.CKey)
|
|
||||||
d.Set("meta", flattenMeta(acc.Meta))
|
|
||||||
d.Set("acl", flattenAccAcl(acc.Acl))
|
|
||||||
d.Set("company", acc.Company)
|
|
||||||
d.Set("companyurl", acc.CompanyUrl)
|
|
||||||
d.Set("created_by", acc.CreatedBy)
|
|
||||||
d.Set("created_time", acc.CreatedTime)
|
|
||||||
d.Set("deactivation_time", acc.DeactiovationTime)
|
|
||||||
d.Set("deleted_by", acc.DeletedBy)
|
|
||||||
d.Set("deleted_time", acc.DeletedTime)
|
|
||||||
d.Set("displayname", acc.DisplayName)
|
|
||||||
d.Set("guid", acc.GUID)
|
|
||||||
d.Set("account_id", acc.ID)
|
|
||||||
d.Set("account_name", acc.Name)
|
|
||||||
d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits))
|
|
||||||
d.Set("send_access_emails", acc.SendAccessEmails)
|
|
||||||
d.Set("service_account", acc.ServiceAccount)
|
|
||||||
d.Set("status", acc.Status)
|
|
||||||
d.Set("updated_time", acc.UpdatedTime)
|
|
||||||
d.Set("version", acc.Version)
|
|
||||||
d.Set("vins", acc.Vins)
|
|
||||||
d.Set("vinses", acc.Vinses)
|
|
||||||
d.Set("computes", flattenAccComputes(acc.Computes))
|
|
||||||
d.Set("machines", flattenAccMachines(acc.Machines))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenAccComputes(acs Computes) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"started": acs.Started,
|
|
||||||
"stopped": acs.Stopped,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenAccMachines(ams Machines) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"running": ams.Running,
|
|
||||||
"halted": ams.Halted,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenAccAcl(acls []AccountAclRecord) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, acls := range acls {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"can_be_deleted": acls.CanBeDeleted,
|
|
||||||
"explicit": acls.IsExplicit,
|
|
||||||
"guid": acls.Guid,
|
|
||||||
"right": acls.Rights,
|
|
||||||
"status": acls.Status,
|
|
||||||
"type": acls.Type,
|
|
||||||
"user_group_id": acls.UgroupID,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenAccResources(r Resources) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"current": flattenAccResource(r.Current),
|
|
||||||
"reserved": flattenAccResource(r.Reserved),
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenAccResource(r Resource) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"cpu": r.CPU,
|
|
||||||
"disksize": r.Disksize,
|
|
||||||
"extips": r.Extips,
|
|
||||||
"exttraffic": r.Exttraffic,
|
|
||||||
"gpu": r.GPU,
|
|
||||||
"ram": r.RAM,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAccountSchemaMake() map[string]*schema.Schema {
|
|
||||||
res := map[string]*schema.Schema{
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"dc_location": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"resources": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"current": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disksize": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"extips": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"exttraffic": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"reserved": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disksize": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"extips": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"exttraffic": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"acl": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"can_be_deleted": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"explicit": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"right": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"user_group_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"company": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"companyurl": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deactivation_time": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"displayname": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"resource_limits": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"cu_c": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_d": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_i": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_m": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_np": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gpu_units": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"send_access_emails": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"service_account": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"version": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"vins": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"computes": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"started": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"stopped": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"machines": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"halted": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"running": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"vinses": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAccount() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceAccountRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceAccountSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceAccountDeletedListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
accountDeletedList, err := utilityAccountDeletedListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", flattenAccountList(accountDeletedList))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAccountDeletedList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceAccountDeletedListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceAccountListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,119 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func flattenAccountDisksList(adl AccountDisksList) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, ad := range adl {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"disk_id": ad.ID,
|
|
||||||
"disk_name": ad.Name,
|
|
||||||
"pool": ad.Pool,
|
|
||||||
"sep_id": ad.SepId,
|
|
||||||
"size_max": ad.SizeMax,
|
|
||||||
"type": ad.Type,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAccountDisksListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
accountDisksList, err := utilityAccountDisksListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", flattenAccountDisksList(accountDisksList))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAccountDisksListSchemaMake() map[string]*schema.Schema {
|
|
||||||
res := map[string]*schema.Schema{
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "ID of the account",
|
|
||||||
},
|
|
||||||
"items": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Search Result",
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"disk_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disk_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"pool": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"size_max": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAccountDisksList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceAccountDisksListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceAccountDisksListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,306 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func flattenAccountList(al AccountCloudApiList) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, acc := range al {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"acl": flattenRgAcl(acc.Acl),
|
|
||||||
"created_time": acc.CreatedTime,
|
|
||||||
"deleted_time": acc.DeletedTime,
|
|
||||||
"account_id": acc.ID,
|
|
||||||
"account_name": acc.Name,
|
|
||||||
"status": acc.Status,
|
|
||||||
"updated_time": acc.UpdatedTime,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
/*uncomment for cloudbroker
|
|
||||||
func flattenAccountList(al AccountList) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, acc := range al {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"dc_location": acc.DCLocation,
|
|
||||||
"ckey": acc.CKey,
|
|
||||||
"meta": flattenMeta(acc.Meta),
|
|
||||||
|
|
||||||
"acl": flattenRgAcl(acc.Acl),
|
|
||||||
|
|
||||||
"company": acc.Company,
|
|
||||||
"companyurl": acc.CompanyUrl,
|
|
||||||
"created_by": acc.CreatedBy,
|
|
||||||
|
|
||||||
"created_time": acc.CreatedTime,
|
|
||||||
|
|
||||||
"deactivation_time": acc.DeactiovationTime,
|
|
||||||
"deleted_by": acc.DeletedBy,
|
|
||||||
|
|
||||||
"deleted_time": acc.DeletedTime,
|
|
||||||
|
|
||||||
"displayname": acc.DisplayName,
|
|
||||||
"guid": acc.GUID,
|
|
||||||
|
|
||||||
"account_id": acc.ID,
|
|
||||||
"account_name": acc.Name,
|
|
||||||
|
|
||||||
"resource_limits": flattenRgResourceLimits(acc.ResourceLimits),
|
|
||||||
"send_access_emails": acc.SendAccessEmails,
|
|
||||||
"service_account": acc.ServiceAccount,
|
|
||||||
|
|
||||||
"status": acc.Status,
|
|
||||||
"updated_time": acc.UpdatedTime,
|
|
||||||
|
|
||||||
"version": acc.Version,
|
|
||||||
"vins": acc.Vins,
|
|
||||||
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
func dataSourceAccountListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
accountList, err := utilityAccountListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", flattenAccountList(accountList))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAccountListSchemaMake() map[string]*schema.Schema {
|
|
||||||
res := 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,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
/*uncomment for cloudbroker
|
|
||||||
"dc_location": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},*/
|
|
||||||
"acl": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"explicit": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"right": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"user_group_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
/*uncomment for cloudbroker
|
|
||||||
"company": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"companyurl": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
"created_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
/*uncomment for cloudbroker
|
|
||||||
"deactivation_time": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
"deleted_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
/*uncomment for cloudbroker
|
|
||||||
"displayname": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
/*uncomment for cloudbroker
|
|
||||||
"resource_limits": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"cu_c": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_d": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_i": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_m": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_np": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gpu_units": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"send_access_emails": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"service_account": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
/*uncomment for cloudbroker
|
|
||||||
"version": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"vins": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceAccountList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceAccountListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceAccountListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceBasicServiceDeletedListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
basicServiceDeletedList, err := utilityBasicServiceDeletedListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", flattenBasicServiceList(basicServiceDeletedList))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceBasicServiceDeletedList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceBasicServiceDeletedListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceBasicServiceListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,372 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Parse list of all disks from API compute/get into a list of "extra disks" attached to this compute
|
|
||||||
// Extra disks are all compute disks but a boot disk.
|
|
||||||
func parseComputeDisksToExtraDisks(disks []DiskRecord) []interface{} {
|
|
||||||
// this return value will be used to d.Set("extra_disks",) item of dataSourceCompute schema,
|
|
||||||
// which is a simple list of integer disk IDs excluding boot disk ID
|
|
||||||
length := len(disks)
|
|
||||||
log.Debugf("parseComputeDisksToExtraDisks: called for %d disks", length)
|
|
||||||
|
|
||||||
if length == 0 || (length == 1 && disks[0].Type == "B") {
|
|
||||||
// the disk list is empty (which is kind of strange - diskless compute?), or
|
|
||||||
// there is only one disk in the list and it is a boot disk;
|
|
||||||
// as we skip boot disks, the result will be of 0 length anyway
|
|
||||||
return make([]interface{}, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
result := make([]interface{}, length-1)
|
|
||||||
idx := 0
|
|
||||||
for _, value := range disks {
|
|
||||||
if value.Type == "B" {
|
|
||||||
// skip boot disk when iterating over the list of disks
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
result[idx] = value.ID
|
|
||||||
idx++
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseBootDiskSize(disks []DiskRecord) int {
|
|
||||||
// this return value will be used to d.Set("boot_disk_size",) item of dataSourceCompute schema
|
|
||||||
if len(disks) == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, value := range disks {
|
|
||||||
if value.Type == "B" {
|
|
||||||
return value.SizeMax
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseBootDiskId(disks []DiskRecord) uint {
|
|
||||||
// this return value will be used to d.Set("boot_disk_id",) item of dataSourceCompute schema
|
|
||||||
if len(disks) == 0 {
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, value := range disks {
|
|
||||||
if value.Type == "B" {
|
|
||||||
return value.ID
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func findBootDisk(disks []DiskRecord) (*DiskRecord, error) {
|
|
||||||
for _, d := range disks {
|
|
||||||
if d.Type == "B" {
|
|
||||||
return &d, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, errors.New("boot disk not found")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Parse the list of interfaces from compute/get response into a list of networks
|
|
||||||
// attached to this compute
|
|
||||||
func parseComputeInterfacesToNetworks(ifaces []InterfaceRecord) []interface{} {
|
|
||||||
// return value will be used to d.Set("network") item of dataSourceCompute schema
|
|
||||||
length := len(ifaces)
|
|
||||||
log.Debugf("parseComputeInterfacesToNetworks: called for %d ifaces", length)
|
|
||||||
|
|
||||||
result := []interface{}{}
|
|
||||||
|
|
||||||
for _, value := range ifaces {
|
|
||||||
elem := make(map[string]interface{})
|
|
||||||
// Keys in this map should correspond to the Schema definition
|
|
||||||
// as returned by networkSubresourceSchemaMake()
|
|
||||||
elem["net_id"] = value.NetID
|
|
||||||
elem["net_type"] = value.NetType
|
|
||||||
elem["ip_address"] = value.IPAddress
|
|
||||||
elem["mac"] = value.MAC
|
|
||||||
|
|
||||||
// log.Debugf(" element %d: net_id=%d, net_type=%s", i, value.NetID, value.NetType)
|
|
||||||
|
|
||||||
result = append(result, elem)
|
|
||||||
}
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenCompute(d *schema.ResourceData, compFacts string) error {
|
|
||||||
// This function expects that compFacts string contains response from API compute/get,
|
|
||||||
// i.e. detailed information about compute instance.
|
|
||||||
//
|
|
||||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
|
||||||
// from resourceComputeExists(...) method
|
|
||||||
model := ComputeGetResp{}
|
|
||||||
log.Debugf("flattenCompute: ready to unmarshal string %s", compFacts)
|
|
||||||
err := json.Unmarshal([]byte(compFacts), &model)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("flattenCompute: ID %d, RG ID %d", model.ID, model.RgID)
|
|
||||||
|
|
||||||
d.SetId(fmt.Sprintf("%d", model.ID))
|
|
||||||
// d.Set("compute_id", model.ID) - we should NOT set compute_id in the schema here: if it was set - it is already set, if it wasn't - we shouldn't
|
|
||||||
d.Set("name", model.Name)
|
|
||||||
d.Set("rg_id", model.RgID)
|
|
||||||
d.Set("rg_name", model.RgName)
|
|
||||||
d.Set("account_id", model.AccountID)
|
|
||||||
d.Set("account_name", model.AccountName)
|
|
||||||
d.Set("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
|
|
||||||
d.Set("image_id", model.ImageID)
|
|
||||||
d.Set("description", model.Desc)
|
|
||||||
d.Set("cloud_init", "applied") // NOTE: for existing compute we hard-code this value as an indicator for DiffSuppress fucntion
|
|
||||||
// d.Set("status", model.Status)
|
|
||||||
// d.Set("tech_status", model.TechStatus)
|
|
||||||
|
|
||||||
if model.TechStatus == "STARTED" {
|
|
||||||
d.Set("started", true)
|
|
||||||
} else {
|
|
||||||
d.Set("started", false)
|
|
||||||
}
|
|
||||||
|
|
||||||
bootDisk, err := findBootDisk(model.Disks)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("boot_disk_size", bootDisk.SizeMax)
|
|
||||||
d.Set("boot_disk_id", bootDisk.ID) // we may need boot disk ID in resize operations
|
|
||||||
d.Set("sep_id", bootDisk.SepID)
|
|
||||||
d.Set("pool", bootDisk.Pool)
|
|
||||||
|
|
||||||
if len(model.Disks) > 0 {
|
|
||||||
log.Debugf("flattenCompute: calling parseComputeDisksToExtraDisks for %d disks", len(model.Disks))
|
|
||||||
if err = d.Set("extra_disks", parseComputeDisksToExtraDisks(model.Disks)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(model.Interfaces) > 0 {
|
|
||||||
log.Debugf("flattenCompute: calling parseComputeInterfacesToNetworks for %d interfaces", len(model.Interfaces))
|
|
||||||
if err = d.Set("network", parseComputeInterfacesToNetworks(model.Interfaces)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(model.OsUsers) > 0 {
|
|
||||||
log.Debugf("flattenCompute: calling parseOsUsers for %d logins", len(model.OsUsers))
|
|
||||||
if err = d.Set("os_users", parseOsUsers(model.OsUsers)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceComputeRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
|
||||||
if compFacts == "" {
|
|
||||||
// if empty string is returned from utilityComputeCheckPresence then there is no
|
|
||||||
// such Compute and err tells so - just return it to the calling party
|
|
||||||
d.SetId("") // ensure ID is empty
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return flattenCompute(d, compFacts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceCompute() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceComputeRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Name of this compute instance. NOTE: this parameter is case sensitive.",
|
|
||||||
},
|
|
||||||
|
|
||||||
// TODO: consider removing compute_id from the schema, as it not practical to call this data provider if
|
|
||||||
// corresponding compute ID is already known
|
|
||||||
"compute_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "ID of the compute instance. If ID is specified, name and resource group ID are ignored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "ID of the resource group where this compute instance is located.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"rg_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the resource group where this compute instance is located.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the account this compute instance belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the account this compute instance belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"driver": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Hardware architecture of this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Number of CPUs allocated for this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Amount of RAM in MB allocated for this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"image_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the OS image this compute instance is based on.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"image_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the OS image this compute instance is based on.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"boot_disk_size": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "This compute instance boot disk size in GB.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"boot_disk_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "This compute instance boot disk ID.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"extra_disks": {
|
|
||||||
Type: schema.TypeSet,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: MaxExtraDisksPerCompute,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "IDs of the extra disk(s) attached to this compute.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
"disks": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: dataSourceDiskSchemaMake(), // ID, type, name, size, account ID, SEP ID, SEP type, pool, status, tech status, compute ID, image ID
|
|
||||||
},
|
|
||||||
Description: "Detailed specification for all disks attached to this compute instance (including bood disk).",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
"network": {
|
|
||||||
Type: schema.TypeSet,
|
|
||||||
Optional: true,
|
|
||||||
MaxItems: MaxNetworksPerCompute,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: networkSubresourceSchemaMake(),
|
|
||||||
},
|
|
||||||
Description: "Network connection(s) for this compute.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"os_users": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: osUsersSubresourceSchemaMake(),
|
|
||||||
},
|
|
||||||
Description: "Guest OS users provisioned on this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "User-defined text description of this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"cloud_init": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Placeholder for cloud_init parameters.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"started": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: true,
|
|
||||||
Description: "Is compute started.",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,201 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
// "net/url"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
func flattenDisk(d *schema.ResourceData, disk_facts string) error {
|
|
||||||
// This function expects disk_facts string to contain a response from disks/get API
|
|
||||||
//
|
|
||||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
|
||||||
// from resourceDiskExists(...) method. Use utilityDiskCheckPresence instead.
|
|
||||||
|
|
||||||
log.Debugf("flattenDisk: ready to unmarshal string %s", disk_facts)
|
|
||||||
|
|
||||||
model := DiskRecord{}
|
|
||||||
|
|
||||||
err := json.Unmarshal([]byte(disk_facts), &model)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("flattenDisk: disk ID %d, disk AccountID %d", model.ID, model.AccountID)
|
|
||||||
|
|
||||||
d.SetId(fmt.Sprintf("%d", model.ID))
|
|
||||||
// d.Set("disk_id", model.ID) - we should NOT update disk_id in the schema. If it was set - it is already set, if it wasn't - we shouldn't
|
|
||||||
d.Set("name", model.Name)
|
|
||||||
d.Set("account_id", model.AccountID)
|
|
||||||
d.Set("account_name", model.AccountName)
|
|
||||||
d.Set("size", model.SizeMax)
|
|
||||||
// d.Set("sizeUsed", model.SizeUsed)
|
|
||||||
d.Set("type", model.Type)
|
|
||||||
d.Set("image_id", model.ImageID)
|
|
||||||
d.Set("sep_id", model.SepID)
|
|
||||||
d.Set("sep_type", model.SepType)
|
|
||||||
d.Set("pool", model.Pool)
|
|
||||||
// d.Set("compute_id", model.ComputeID)
|
|
||||||
|
|
||||||
d.Set("description", model.Desc)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceDiskRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
disk_facts, err := utilityDiskCheckPresence(d, m)
|
|
||||||
if disk_facts == "" {
|
|
||||||
// if empty string is returned from utilityDiskCheckPresence then there is no
|
|
||||||
// such Disk and err tells so - just return it to the calling party
|
|
||||||
d.SetId("") // ensure ID is empty
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return flattenDisk(d, disk_facts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceDiskSchemaMake() map[string]*schema.Schema {
|
|
||||||
rets := map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Name of this disk. NOTE: disk names are NOT unique within an account. If disk ID is specified, disk name is ignored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"disk_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "ID of the disk to get. If disk ID is specified, then disk name and account ID are ignored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "ID of the account this disk belongs to. If disk ID is specified, then account ID is ignored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
// The rest of the data source Disk schema are all computed
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Storage end-point provider serving this disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"pool": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Pool where this disk is located.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"size": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Size of the disk in GB.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Type of this disk. E.g. D for data disks, B for boot.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "User-defined text description of this disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the account this disk belongs to. If account ID is specified, account name is ignored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"image_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the image, which this disk was cloned from (valid for disk clones only).",
|
|
||||||
},
|
|
||||||
|
|
||||||
"sep_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Type of the storage end-point provider serving this disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
"snapshots": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource {
|
|
||||||
Schema: snapshotSubresourceSchemaMake(),
|
|
||||||
},
|
|
||||||
Description: "List of user-created snapshots for this disk."
|
|
||||||
},
|
|
||||||
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Current model status of this disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"tech_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Current technical status of this disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"compute_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the compute instance where this disk is attached to, or 0 for unattached disk.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
return rets
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceDisk() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceDiskRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceDiskSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,391 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func flattenDiskList(dl DisksListResp) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, disk := range dl {
|
|
||||||
diskAcl, _ := json.Marshal(disk.Acl)
|
|
||||||
diskIotune, _ := json.Marshal(disk.IOTune)
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"account_id": disk.AccountID,
|
|
||||||
"account_name": disk.AccountName,
|
|
||||||
"acl": string(diskAcl),
|
|
||||||
"boot_partition": disk.BootPartition,
|
|
||||||
"compute_id": disk.ComputeID,
|
|
||||||
"compute_name": disk.ComputeName,
|
|
||||||
"created_time": disk.CreatedTime,
|
|
||||||
"deleted_time": disk.DeletedTime,
|
|
||||||
"desc": disk.Desc,
|
|
||||||
"destruction_time": disk.DestructionTime,
|
|
||||||
"devicename": disk.DeviceName,
|
|
||||||
"disk_path": disk.DiskPath,
|
|
||||||
"gid": disk.GridID,
|
|
||||||
"guid": disk.GUID,
|
|
||||||
"disk_id": disk.ID,
|
|
||||||
"image_id": disk.ImageID,
|
|
||||||
"images": disk.Images,
|
|
||||||
"iotune": string(diskIotune),
|
|
||||||
"iqn": disk.IQN,
|
|
||||||
"login": disk.Login,
|
|
||||||
"machine_id": disk.MachineId,
|
|
||||||
"machine_name": disk.MachineName,
|
|
||||||
"milestones": disk.Milestones,
|
|
||||||
"name": disk.Name,
|
|
||||||
"order": disk.Order,
|
|
||||||
"params": disk.Params,
|
|
||||||
"parent_id": disk.ParentId,
|
|
||||||
"passwd": disk.Passwd,
|
|
||||||
"pci_slot": disk.PciSlot,
|
|
||||||
"pool": disk.Pool,
|
|
||||||
"purge_attempts": disk.PurgeAttempts,
|
|
||||||
"purge_time": disk.PurgeTime,
|
|
||||||
"reality_device_number": disk.RealityDeviceNumber,
|
|
||||||
"reference_id": disk.ReferenceId,
|
|
||||||
"res_id": disk.ResID,
|
|
||||||
"res_name": disk.ResName,
|
|
||||||
"role": disk.Role,
|
|
||||||
"sep_id": disk.SepID,
|
|
||||||
"sep_type": disk.SepType,
|
|
||||||
"size_max": disk.SizeMax,
|
|
||||||
"size_used": disk.SizeUsed,
|
|
||||||
"snapshots": flattendDiskSnapshotList(disk.Snapshots),
|
|
||||||
"status": disk.Status,
|
|
||||||
"tech_status": disk.TechStatus,
|
|
||||||
"type": disk.Type,
|
|
||||||
"vmid": disk.VMID,
|
|
||||||
"update_by": disk.UpdateBy,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattendDiskSnapshotList(sl SnapshotRecordList) []interface{} {
|
|
||||||
res := make([]interface{}, 0)
|
|
||||||
for _, snapshot := range sl {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"guid": snapshot.Guid,
|
|
||||||
"label": snapshot.Label,
|
|
||||||
"res_id": snapshot.ResId,
|
|
||||||
"snap_set_guid": snapshot.SnapSetGuid,
|
|
||||||
"snap_set_time": snapshot.SnapSetTime,
|
|
||||||
"timestamp": snapshot.TimeStamp,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceDiskListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
diskList, err := utilityDiskListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", flattenDiskList(diskList))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceDiskListSchemaMake() map[string]*schema.Schema {
|
|
||||||
res := map[string]*schema.Schema{
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "ID of the account the disks belong to",
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "type of the disks",
|
|
||||||
},
|
|
||||||
"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: map[string]*schema.Schema{
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"acl": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"boot_partition": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"compute_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"compute_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"desc": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"destruction_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"devicename": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disk_path": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disk_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"image_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"images": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"iotune": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"iqn": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"login": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"machine_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"machine_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"milestones": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"order": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"params": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"parent_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"passwd": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"pci_slot": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"pool": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"purge_attempts": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"purge_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"reality_device_number": {
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
"role": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"sep_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"size_max": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"size_used": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"snapshots": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"label": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"res_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"snap_set_guid": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"snap_set_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"tech_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"vmid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"update_by": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceDiskList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceDiskListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceDiskListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,112 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func flattenExtnetList(el ExtnetList) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, e := range el {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"net_id": e.ID,
|
|
||||||
"ipcidr": e.IPCidr,
|
|
||||||
"name": e.Name,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceExtnetListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
extnetList, err := utilityExtnetListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", flattenExtnetList(extnetList))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceExtnetListSchemaMake() map[string]*schema.Schema {
|
|
||||||
res := map[string]*schema.Schema{
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "filter by account 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: map[string]*schema.Schema{
|
|
||||||
"net_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"ipcidr": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceExtnetList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceExtnetListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceExtnetListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
/*
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
|
|
||||||
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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,128 +0,0 @@
|
|||||||
/*
|
|
||||||
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,311 +0,0 @@
|
|||||||
/*
|
|
||||||
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 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)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceImageRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
image, err := utilityImageCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId(strconv.Itoa(image.Guid))
|
|
||||||
flattenImage(d, image)
|
|
||||||
|
|
||||||
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,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceImage() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceImageRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceImageSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,140 +0,0 @@
|
|||||||
/*
|
|
||||||
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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,182 +0,0 @@
|
|||||||
/*
|
|
||||||
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(_ *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,128 +0,0 @@
|
|||||||
/*
|
|
||||||
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 dataSourcePcideviceRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
pcidevice, err := utilityPcideviceCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("ckey", pcidevice.CKey)
|
|
||||||
d.Set("meta", flattenMeta(pcidevice.Meta))
|
|
||||||
d.Set("compute_id", pcidevice.Computeid)
|
|
||||||
d.Set("description", pcidevice.Description)
|
|
||||||
d.Set("guid", pcidevice.Guid)
|
|
||||||
d.Set("hw_path", pcidevice.HwPath)
|
|
||||||
d.Set("rg_id", pcidevice.RgID)
|
|
||||||
d.Set("name", pcidevice.Name)
|
|
||||||
d.Set("stack_id", pcidevice.StackID)
|
|
||||||
d.Set("status", pcidevice.Status)
|
|
||||||
d.Set("system_name", pcidevice.SystemName)
|
|
||||||
|
|
||||||
d.SetId(strconv.Itoa(d.Get("device_id").(int)))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourcePcideviceSchemaMake() map[string]*schema.Schema {
|
|
||||||
rets := map[string]*schema.Schema{
|
|
||||||
"device_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
},
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"compute_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"hw_path": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"stack_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"system_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return rets
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourcePcidevice() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourcePcideviceRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourcePcideviceSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
/*
|
|
||||||
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 flattenPcideviceList(pl PcideviceList) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, item := range pl {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"ckey": item.CKey,
|
|
||||||
"meta": flattenMeta(item.Meta),
|
|
||||||
"compute_id": item.Computeid,
|
|
||||||
"description": item.Description,
|
|
||||||
"guid": item.Guid,
|
|
||||||
"hw_path": item.HwPath,
|
|
||||||
"device_id": item.ID,
|
|
||||||
"rg_id": item.RgID,
|
|
||||||
"name": item.Name,
|
|
||||||
"stack_id": item.StackID,
|
|
||||||
"status": item.Status,
|
|
||||||
"system_name": item.SystemName,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourcePcideviceListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
pcideviceList, err := utilityPcideviceListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("items", flattenPcideviceList(pcideviceList))
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourcePcideviceItem() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"compute_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"hw_path": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"device_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"stack_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"system_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourcePcideviceListSchemaMake() map[string]*schema.Schema {
|
|
||||||
rets := map[string]*schema.Schema{
|
|
||||||
"items": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Description: "pcidevice list",
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: dataSourcePcideviceItem(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return rets
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourcePcideviceList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourcePcideviceListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourcePcideviceListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,188 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
func flattenResgroup(d *schema.ResourceData, rg_facts string) error {
|
|
||||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
|
||||||
// from resourceRsgroupExists(...) method
|
|
||||||
// log.Debugf("%s", rg_facts)
|
|
||||||
log.Debugf("flattenResgroup: ready to decode response body from API")
|
|
||||||
details := ResgroupGetResp{}
|
|
||||||
err := json.Unmarshal([]byte(rg_facts), &details)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("flattenResgroup: decoded RG name %q / ID %d, account ID %d",
|
|
||||||
details.Name, details.ID, details.AccountID)
|
|
||||||
|
|
||||||
d.SetId(fmt.Sprintf("%d", details.ID))
|
|
||||||
d.Set("rg_id", details.ID)
|
|
||||||
d.Set("name", details.Name)
|
|
||||||
d.Set("account_name", details.AccountName)
|
|
||||||
d.Set("account_id", details.AccountID)
|
|
||||||
// d.Set("grid_id", details.GridID)
|
|
||||||
d.Set("description", details.Desc)
|
|
||||||
d.Set("status", details.Status)
|
|
||||||
d.Set("def_net_type", details.DefaultNetType)
|
|
||||||
d.Set("def_net_id", details.DefaultNetID)
|
|
||||||
/*
|
|
||||||
d.Set("vins", details.Vins)
|
|
||||||
d.Set("computes", details.Computes)
|
|
||||||
*/
|
|
||||||
|
|
||||||
log.Debugf("flattenResgroup: calling flattenQuota()")
|
|
||||||
if err = d.Set("quota", parseQuota(details.Quota)); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceResgroupRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
|
||||||
if rg_facts == "" {
|
|
||||||
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
|
||||||
// such resource group and err tells so - just return it to the calling party
|
|
||||||
d.SetId("") // ensure ID is empty in this case
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return flattenResgroup(d, rg_facts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceResgroup() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceResgroupRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Name of the resource group. Names are case sensitive and unique within the context of an account.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Unique ID of the resource group. If this ID is specified, then resource group name is ignored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the account, which this resource group belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "Unique ID of the account, which this resource group belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "User-defined text description of this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/* commented out, as in this version of provider we use default Grid ID
|
|
||||||
"grid_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Unique ID of the grid, where this resource group is deployed.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
"quota": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: quotaRgSubresourceSchemaMake(), // this is a dictionary
|
|
||||||
},
|
|
||||||
Description: "Quota settings for this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"def_net_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Type of the default network for this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"def_net_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the default network for this resource group (if any).",
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Current status of this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"vins": {
|
|
||||||
Type: schema.TypeList, // this is a list of ints
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: LimitMaxVinsPerResgroup,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "List of VINs deployed in this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"computes": {
|
|
||||||
Type: schema.TypeList, //t his is a list of ints
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "List of computes deployed in this resource group.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,314 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func flattenRgList(rgl ResgroupListResp) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, rg := range rgl {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"account_id": rg.AccountID,
|
|
||||||
"account_name": rg.AccountName,
|
|
||||||
"acl": flattenRgAcl(rg.ACLs),
|
|
||||||
"created_by": rg.CreatedBy,
|
|
||||||
"created_time": rg.CreatedTime,
|
|
||||||
"def_net_id": rg.DefaultNetID,
|
|
||||||
"def_net_type": rg.DefaultNetType,
|
|
||||||
"deleted_by": rg.DeletedBy,
|
|
||||||
"deleted_time": rg.DeletedTime,
|
|
||||||
"desc": rg.Decsription,
|
|
||||||
"gid": rg.GridID,
|
|
||||||
"guid": rg.GUID,
|
|
||||||
"rg_id": rg.ID,
|
|
||||||
"lock_status": rg.LockStatus,
|
|
||||||
"milestones": rg.Milestones,
|
|
||||||
"name": rg.Name,
|
|
||||||
"register_computes": rg.RegisterComputes,
|
|
||||||
"resource_limits": flattenRgResourceLimits(rg.ResourceLimits),
|
|
||||||
"secret": rg.Secret,
|
|
||||||
"status": rg.Status,
|
|
||||||
"updated_by": rg.UpdatedBy,
|
|
||||||
"updated_time": rg.UpdatedTime,
|
|
||||||
"vins": rg.Vins,
|
|
||||||
"vms": rg.Computes,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenRgAcl(rgAcls []AccountAclRecord) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, rgAcl := range rgAcls {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"explicit": rgAcl.IsExplicit,
|
|
||||||
"guid": rgAcl.Guid,
|
|
||||||
"right": rgAcl.Rights,
|
|
||||||
"status": rgAcl.Status,
|
|
||||||
"type": rgAcl.Type,
|
|
||||||
"user_group_id": rgAcl.UgroupID,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenRgResourceLimits(rl ResourceLimits) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"cu_c": rl.CUC,
|
|
||||||
"cu_d": rl.CUD,
|
|
||||||
"cu_i": rl.CUI,
|
|
||||||
"cu_m": rl.CUM,
|
|
||||||
"cu_np": rl.CUNP,
|
|
||||||
"gpu_units": rl.GpuUnits,
|
|
||||||
}
|
|
||||||
res = append(res, temp)
|
|
||||||
|
|
||||||
return res
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceRgListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
rgList, err := utilityRgListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", flattenRgList(rgList))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceRgListSchemaMake() map[string]*schema.Schema {
|
|
||||||
res := map[string]*schema.Schema{
|
|
||||||
"includedeleted": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "included deleted resource groups",
|
|
||||||
},
|
|
||||||
"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: map[string]*schema.Schema{
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"acl": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"explicit": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"right": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"user_group_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"created_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"def_net_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"def_net_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"desc": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"lock_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"milestones": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"register_computes": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"resource_limits": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"cu_c": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_d": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_i": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_m": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_np": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gpu_units": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"secret": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"vins": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"vms": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceRgList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceRgListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceRgListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,145 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceSepRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
desSep, err := utilitySepCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
d.Set("ckey", desSep.Ckey)
|
|
||||||
d.Set("meta", flattenMeta(desSep.Meta))
|
|
||||||
d.Set("consumed_by", desSep.ConsumedBy)
|
|
||||||
d.Set("desc", desSep.Desc)
|
|
||||||
d.Set("gid", desSep.Gid)
|
|
||||||
d.Set("guid", desSep.Guid)
|
|
||||||
d.Set("sep_id", desSep.Id)
|
|
||||||
d.Set("milestones", desSep.Milestones)
|
|
||||||
d.Set("name", desSep.Name)
|
|
||||||
d.Set("obj_status", desSep.ObjStatus)
|
|
||||||
d.Set("provided_by", desSep.ProvidedBy)
|
|
||||||
d.Set("tech_status", desSep.TechStatus)
|
|
||||||
d.Set("type", desSep.Type)
|
|
||||||
data, _ := json.Marshal(desSep.Config)
|
|
||||||
d.Set("config", string(data))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepCSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "sep type des id",
|
|
||||||
},
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"consumed_by": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"desc": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"milestones": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"obj_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"provided_by": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"tech_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSep() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceSepRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceSepCSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceSepConfigRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
sepConfig, err := utilitySepConfigCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
data, _ := json.Marshal(sepConfig)
|
|
||||||
d.Set("config", string(data))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepConfigSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "storage endpoint provider ID",
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "sep config json string",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepConfig() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceSepConfigRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceSepConfigSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
/*
|
|
||||||
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 dataSourceSepConsumptionRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
sepCons, err := utilitySepConsumptionCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
d.Set("type", sepCons.Type)
|
|
||||||
d.Set("total", flattenSepConsumption(sepCons.Total))
|
|
||||||
d.Set("by_pool", flattenSepConsumptionPools(sepCons.ByPool))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenSepConsumptionPools(mp map[string]SepConsumptionInd) []map[string]interface{} {
|
|
||||||
sh := make([]map[string]interface{}, 0)
|
|
||||||
for k, v := range mp {
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"name": k,
|
|
||||||
"disk_count": v.DiskCount,
|
|
||||||
"disk_usage": v.DiskUsage,
|
|
||||||
"snapshot_count": v.SnapshotCount,
|
|
||||||
"snapshot_usage": v.SnapshotUsage,
|
|
||||||
"usage": v.Usage,
|
|
||||||
"usage_limit": v.UsageLimit,
|
|
||||||
}
|
|
||||||
sh = append(sh, temp)
|
|
||||||
}
|
|
||||||
return sh
|
|
||||||
}
|
|
||||||
|
|
||||||
func flattenSepConsumption(sc SepConsumptionTotal) []map[string]interface{} {
|
|
||||||
sh := make([]map[string]interface{}, 0)
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"capacity_limit": sc.CapacityLimit,
|
|
||||||
"disk_count": sc.DiskCount,
|
|
||||||
"disk_usage": sc.DiskUsage,
|
|
||||||
"snapshot_count": sc.SnapshotCount,
|
|
||||||
"snapshot_usage": sc.SnapshotUsage,
|
|
||||||
"usage": sc.Usage,
|
|
||||||
"usage_limit": sc.UsageLimit,
|
|
||||||
}
|
|
||||||
sh = append(sh, temp)
|
|
||||||
return sh
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepConsumptionSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "sep id",
|
|
||||||
},
|
|
||||||
"by_pool": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "pool name",
|
|
||||||
},
|
|
||||||
"disk_count": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "number of disks",
|
|
||||||
},
|
|
||||||
"disk_usage": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "disk usage",
|
|
||||||
},
|
|
||||||
"snapshot_count": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "number of snapshots",
|
|
||||||
},
|
|
||||||
"snapshot_usage": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "snapshot usage",
|
|
||||||
},
|
|
||||||
"usage": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "usage",
|
|
||||||
},
|
|
||||||
"usage_limit": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "usage limit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Description: "consumption divided by pool",
|
|
||||||
},
|
|
||||||
"total": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"capacity_limit": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disk_count": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "number of disks",
|
|
||||||
},
|
|
||||||
"disk_usage": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "disk usage",
|
|
||||||
},
|
|
||||||
"snapshot_count": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "number of snapshots",
|
|
||||||
},
|
|
||||||
"snapshot_usage": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "snapshot usage",
|
|
||||||
},
|
|
||||||
"usage": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "usage",
|
|
||||||
},
|
|
||||||
"usage_limit": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "usage limit",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
Description: "total consumption",
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "sep type",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepConsumption() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceSepConsumptionRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceSepConsumptionSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,82 +0,0 @@
|
|||||||
/*
|
|
||||||
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 dataSourceSepDiskListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
sepDiskList, err := utilitySepDiskListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", sepDiskList)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepDiskListSchemaMake() map[string]*schema.Schema {
|
|
||||||
rets := map[string]*schema.Schema{
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "storage endpoint provider ID",
|
|
||||||
},
|
|
||||||
"pool_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "pool name",
|
|
||||||
},
|
|
||||||
"items": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Description: "sep disk list",
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return rets
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepDiskList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceSepDiskListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceSepDiskListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,180 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func flattenSepList(sl SepList) []map[string]interface{} {
|
|
||||||
res := make([]map[string]interface{}, 0)
|
|
||||||
for _, item := range sl {
|
|
||||||
data, _ := json.Marshal(item.Config)
|
|
||||||
temp := map[string]interface{}{
|
|
||||||
"ckey": item.Ckey,
|
|
||||||
"meta": flattenMeta(item.Meta),
|
|
||||||
"consumed_by": item.ConsumedBy,
|
|
||||||
"desc": item.Desc,
|
|
||||||
"gid": item.Gid,
|
|
||||||
"guid": item.Guid,
|
|
||||||
"sep_id": item.Id,
|
|
||||||
"milestones": item.Milestones,
|
|
||||||
"name": item.Name,
|
|
||||||
"obj_status": item.ObjStatus,
|
|
||||||
"provided_by": item.ProvidedBy,
|
|
||||||
"tech_status": item.TechStatus,
|
|
||||||
"type": item.Type,
|
|
||||||
"config": string(data),
|
|
||||||
}
|
|
||||||
|
|
||||||
res = append(res, temp)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepListRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
sepList, err := utilitySepListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
d.Set("items", flattenSepList(sepList))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepListSchemaMake() 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: "sep list",
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: dataSourceSepShortSchemaMake(),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return rets
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepShortSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"consumed_by": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"desc": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"milestones": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"obj_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"provided_by": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"tech_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepList() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceSepListRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceSepListSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,80 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func dataSourceSepPoolRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
sepPool, err := utilitySepPoolCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
data, _ := json.Marshal(sepPool)
|
|
||||||
d.Set("pool", string(data))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepPoolSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "storage endpoint provider ID",
|
|
||||||
},
|
|
||||||
"pool_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "pool name",
|
|
||||||
},
|
|
||||||
"pool": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceSepPool() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceSepPoolRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: dataSourceSepPoolSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,171 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2020-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
|
||||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
// "net/url"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
// vins_facts is a response string from API vins/get
|
|
||||||
func flattenVins(d *schema.ResourceData, vins_facts string) error {
|
|
||||||
// NOTE: this function modifies ResourceData argument - as such it should never be called
|
|
||||||
// from resourceVinsExists(...) method
|
|
||||||
// log.Debugf("flattenVins: ready to decode response body from API %s", vins_facts)
|
|
||||||
vinsRecord := VinsRecord{}
|
|
||||||
err := json.Unmarshal([]byte(vins_facts), &vinsRecord)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("flattenVins: decoded ViNS name:ID %s:%d, account ID %d, RG ID %d",
|
|
||||||
vinsRecord.Name, vinsRecord.ID, vinsRecord.AccountID, vinsRecord.RgID)
|
|
||||||
|
|
||||||
d.SetId(fmt.Sprintf("%d", vinsRecord.ID))
|
|
||||||
d.Set("name", vinsRecord.Name)
|
|
||||||
d.Set("account_id", vinsRecord.AccountID)
|
|
||||||
d.Set("account_name", vinsRecord.AccountName)
|
|
||||||
d.Set("rg_id", vinsRecord.RgID)
|
|
||||||
d.Set("description", vinsRecord.Desc)
|
|
||||||
d.Set("ipcidr", vinsRecord.IPCidr)
|
|
||||||
|
|
||||||
noExtNetConnection := true
|
|
||||||
for _, value := range vinsRecord.VNFs {
|
|
||||||
if value.Type == "GW" {
|
|
||||||
log.Debugf("flattenVins: discovered GW VNF ID %d in ViNS ID %d", value.ID, vinsRecord.ID)
|
|
||||||
extNetID, idOk := value.Config["ext_net_id"] // NOTE: unknown numbers are unmarshalled to float64. This is by design!
|
|
||||||
extNetIP, ipOk := value.Config["ext_net_ip"]
|
|
||||||
if idOk && ipOk {
|
|
||||||
log.Debugf("flattenVins: ViNS ext_net_id=%d, ext_net_ip=%s", int(extNetID.(float64)), extNetIP.(string))
|
|
||||||
d.Set("ext_ip_addr", extNetIP.(string))
|
|
||||||
d.Set("ext_net_id", int(extNetID.(float64)))
|
|
||||||
} else {
|
|
||||||
return fmt.Errorf("Failed to unmarshal VNF GW Config - structure is invalid.")
|
|
||||||
}
|
|
||||||
noExtNetConnection = false
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if noExtNetConnection {
|
|
||||||
d.Set("ext_ip_addr", "")
|
|
||||||
d.Set("ext_net_id", 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("flattenVins: EXTRA CHECK - schema rg_id=%d, ext_net_id=%d", d.Get("rg_id").(int), d.Get("ext_net_id").(int))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceVinsRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
vinsFacts, err := utilityVinsCheckPresence(d, m)
|
|
||||||
if vinsFacts == "" {
|
|
||||||
// if empty string is returned from utilityVinsCheckPresence then there is no
|
|
||||||
// such ViNS and err tells so - just return it to the calling party
|
|
||||||
d.SetId("") // ensure ID is empty in this case
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return flattenVins(d, vinsFacts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func dataSourceVins() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Read: dataSourceVinsRead,
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
"vins_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Unique ID of the resource group, where this ViNS is belongs to (for ViNS created at resource group level, 0 otherwise).",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Unique ID of the account, which this ViNS belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
// the rest of attributes are computed
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the account, which this ViNS belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "User-defined text description of this ViNS.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ext_ip_addr": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "IP address of the external connection (valid for ViNS connected to external network, empty string otherwise).",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ext_net_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the external network this ViNS is connected to (-1 means no external connection).",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ipcidr": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Network address used by this ViNS.",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
1486
decort/models_api.go
1486
decort/models_api.go
File diff suppressed because it is too large
Load Diff
@@ -1,98 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
|
||||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
|
|
||||||
func nodeMasterDefault() K8sNodeRecord {
|
|
||||||
return K8sNodeRecord{
|
|
||||||
Num: 1,
|
|
||||||
Cpu: 2,
|
|
||||||
Ram: 2048,
|
|
||||||
Disk: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeWorkerDefault() K8sNodeRecord {
|
|
||||||
return K8sNodeRecord{
|
|
||||||
Num: 1,
|
|
||||||
Cpu: 1,
|
|
||||||
Ram: 1024,
|
|
||||||
Disk: 0,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func parseNode(nodeList []interface{}) K8sNodeRecord {
|
|
||||||
node := nodeList[0].(map[string]interface{})
|
|
||||||
|
|
||||||
return K8sNodeRecord{
|
|
||||||
Num: node["num"].(int),
|
|
||||||
Cpu: node["cpu"].(int),
|
|
||||||
Ram: node["ram"].(int),
|
|
||||||
Disk: node["disk"].(int),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeToResource(node K8sNodeRecord) []interface{} {
|
|
||||||
mp := make(map[string]interface{})
|
|
||||||
|
|
||||||
mp["num"] = node.Num
|
|
||||||
mp["cpu"] = node.Cpu
|
|
||||||
mp["ram"] = node.Ram
|
|
||||||
mp["disk"] = node.Disk
|
|
||||||
|
|
||||||
return []interface{}{mp}
|
|
||||||
}
|
|
||||||
|
|
||||||
func nodeK8sSubresourceSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"num": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "Number of nodes to create.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "Node CPU count.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "Node RAM in MB.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"disk": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "Node boot disk size in GB.",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,196 +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 (
|
|
||||||
"fmt"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/terraform"
|
|
||||||
)
|
|
||||||
|
|
||||||
func Provider() *schema.Provider {
|
|
||||||
return &schema.Provider{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"authenticator": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
StateFunc: stateFuncToLower,
|
|
||||||
ValidateFunc: validation.StringInSlice([]string{"oauth2", "legacy", "jwt"}, true), // ignore case while validating
|
|
||||||
Description: "Authentication mode to use when connecting to DECORT cloud API. Should be one of 'oauth2', 'legacy' or 'jwt'.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"oauth2_url": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
StateFunc: stateFuncToLower,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_OAUTH2_URL", nil),
|
|
||||||
Description: "OAuth2 application URL in 'oauth2' authentication mode.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"controller_url": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
StateFunc: stateFuncToLower,
|
|
||||||
Description: "URL of DECORT Cloud controller to use. API calls will be directed to this URL.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"user": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_USER", nil),
|
|
||||||
Description: "User name for DECORT cloud API operations in 'legacy' authentication mode.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"password": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_PASSWORD", nil),
|
|
||||||
Description: "User password for DECORT cloud API operations in 'legacy' authentication mode.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"app_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_ID", nil),
|
|
||||||
Description: "Application ID to access DECORT cloud API in 'oauth2' authentication mode.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"app_secret": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_APP_SECRET", nil),
|
|
||||||
Description: "Application secret to access DECORT cloud API in 'oauth2' authentication mode.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"jwt": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
DefaultFunc: schema.EnvDefaultFunc("DECORT_JWT", nil),
|
|
||||||
Description: "JWT to access DECORT cloud API in 'jwt' authentication mode.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"allow_unverified_ssl": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "If true, DECORT API will not verify SSL certificates. Use this with caution and in trusted environments only!",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
ResourcesMap: map[string]*schema.Resource{
|
|
||||||
"decort_resgroup": resourceResgroup(),
|
|
||||||
"decort_kvmvm": resourceCompute(),
|
|
||||||
"decort_disk": resourceDisk(),
|
|
||||||
"decort_vins": resourceVins(),
|
|
||||||
"decort_pfw": resourcePfw(),
|
|
||||||
"decort_k8s": resourceK8s(),
|
|
||||||
"decort_k8s_wg": resourceK8sWg(),
|
|
||||||
"decort_image": resourceImage(),
|
|
||||||
"decort_virtual_image": resourceVirtualImage(),
|
|
||||||
"decort_cdrom_image": resourceCDROMImage(),
|
|
||||||
"decort_delete_images": resourceDeleteImages(),
|
|
||||||
"decort_snapshot": resourceSnapshot(),
|
|
||||||
"decort_pcidevice": resourcePcidevice(),
|
|
||||||
"decort_sep": resourceSep(),
|
|
||||||
"decort_sep_config": resourceSepConfig(),
|
|
||||||
"decort_account": resourceAccount(),
|
|
||||||
"decort_bservice": resourceBasicService(),
|
|
||||||
"decort_bservice_group": resourceBasicServiceGroup(),
|
|
||||||
},
|
|
||||||
|
|
||||||
DataSourcesMap: map[string]*schema.Resource{
|
|
||||||
"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_snapshot_list": dataSourceSnapshotList(),
|
|
||||||
"decort_vgpu": dataSourceVGPU(),
|
|
||||||
"decort_pcidevice": dataSourcePcidevice(),
|
|
||||||
"decort_pcidevice_list": dataSourcePcideviceList(),
|
|
||||||
"decort_sep_list": dataSourceSepList(),
|
|
||||||
"decort_sep": dataSourceSep(),
|
|
||||||
"decort_sep_consumption": dataSourceSepConsumption(),
|
|
||||||
"decort_sep_disk_list": dataSourceSepDiskList(),
|
|
||||||
"decort_sep_config": dataSourceSepConfig(),
|
|
||||||
"decort_sep_pool": dataSourceSepPool(),
|
|
||||||
"decort_disk_list": dataSourceDiskList(),
|
|
||||||
"decort_rg_list": dataSourceRgList(),
|
|
||||||
"decort_account_list": dataSourceAccountList(),
|
|
||||||
"decort_account_computes_list": dataSourceAccountComputesList(),
|
|
||||||
"decort_account_disks_list": dataSourceAccountDisksList(),
|
|
||||||
"decort_account_vins_list": dataSourceAccountVinsList(),
|
|
||||||
"decort_account_audits_list": dataSourceAccountAuditsList(),
|
|
||||||
"decort_account_rg_list": dataSourceAccountRGList(),
|
|
||||||
"decort_account_consumed_units": dataSourceAccountConsumedUnits(),
|
|
||||||
"decort_account_consumed_units_by_type": dataSourceAccountConsumedUnitsByType(),
|
|
||||||
"decort_account_reserved_units": dataSourceAccountReservedUnits(),
|
|
||||||
"decort_account_templates_list": dataSourceAccountTemplatessList(),
|
|
||||||
"decort_account_deleted_list": dataSourceAccountDeletedList(),
|
|
||||||
"decort_account_flipgroups_list": dataSourceAccountFlipGroupsList(),
|
|
||||||
"decort_bservice_list": dataSourceBasicServiceList(),
|
|
||||||
"decort_bservice": dataSourceBasicService(),
|
|
||||||
"decort_bservice_snapshot_list": dataSourceBasicServiceSnapshotList(),
|
|
||||||
"decort_bservice_group": dataSourceBasicServiceGroup(),
|
|
||||||
"decort_bservice_deleted_list": dataSourceBasicServiceDeletedList(),
|
|
||||||
"decort_extnet_list": dataSourceExtnetList(),
|
|
||||||
"decort_extnet_computes_list": dataSourceExtnetComputesList(),
|
|
||||||
"decort_extnet": dataSourceExtnet(),
|
|
||||||
"decort_extnet_default": dataSourceExtnetDefault(),
|
|
||||||
"decort_vins_list": dataSourceVinsList(),
|
|
||||||
// "decort_pfw": dataSourcePfw(),
|
|
||||||
},
|
|
||||||
|
|
||||||
ConfigureFunc: providerConfigure,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func stateFuncToLower(argval interface{}) string {
|
|
||||||
return strings.ToLower(argval.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
func stateFuncToUpper(argval interface{}) string {
|
|
||||||
return strings.ToUpper(argval.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
func providerConfigure(d *schema.ResourceData) (interface{}, error) {
|
|
||||||
decsController, err := ControllerConfigure(d)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
// initialize global default Grid ID - it will be needed to create some resource types, e.g. disks
|
|
||||||
gridId, err := decsController.utilityLocationGetDefaultGridID()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if gridId == 0 {
|
|
||||||
return nil, fmt.Errorf("providerConfigure: invalid default Grid ID = 0")
|
|
||||||
}
|
|
||||||
|
|
||||||
return decsController, nil
|
|
||||||
}
|
|
||||||
@@ -1,794 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceAccountCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceAccountCreate")
|
|
||||||
|
|
||||||
if accountId, ok := d.GetOk("account_id"); ok {
|
|
||||||
if exists, err := resourceAccountExists(d, m); exists {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId(strconv.Itoa(accountId.(int)))
|
|
||||||
err = resourceAccountRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("provided account id does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("name", d.Get("account_name").(string))
|
|
||||||
urlValues.Add("username", d.Get("username").(string))
|
|
||||||
|
|
||||||
if emailaddress, ok := d.GetOk("emailaddress"); ok {
|
|
||||||
urlValues.Add("emailaddress", emailaddress.(string))
|
|
||||||
}
|
|
||||||
if sendAccessEmails, ok := d.GetOk("send_access_emails"); ok {
|
|
||||||
urlValues.Add("sendAccessEmails", strconv.FormatBool(sendAccessEmails.(bool)))
|
|
||||||
}
|
|
||||||
if resLimits, ok := d.GetOk("resource_limits"); ok {
|
|
||||||
resLimit := resLimits.([]interface{})[0]
|
|
||||||
resLimitConv := resLimit.(map[string]interface{})
|
|
||||||
if resLimitConv["cu_m"] != nil {
|
|
||||||
maxMemCap := int(resLimitConv["cu_m"].(float64))
|
|
||||||
if maxMemCap == 0 {
|
|
||||||
urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if resLimitConv["cu_d"] != nil {
|
|
||||||
maxDiskCap := int(resLimitConv["cu_d"].(float64))
|
|
||||||
if maxDiskCap == 0 {
|
|
||||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if resLimitConv["cu_c"] != nil {
|
|
||||||
maxCPUCap := int(resLimitConv["cu_c"].(float64))
|
|
||||||
if maxCPUCap == 0 {
|
|
||||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if resLimitConv["cu_i"] != nil {
|
|
||||||
maxNumPublicIP := int(resLimitConv["cu_i"].(float64))
|
|
||||||
if maxNumPublicIP == 0 {
|
|
||||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if resLimitConv["cu_np"] != nil {
|
|
||||||
maxNP := int(resLimitConv["cu_np"].(float64))
|
|
||||||
if maxNP == 0 {
|
|
||||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if resLimitConv["gpu_units"] != nil {
|
|
||||||
gpuUnits := int(resLimitConv["gpu_units"].(float64))
|
|
||||||
if gpuUnits == 0 {
|
|
||||||
urlValues.Add("gpu_units", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("gpu_units", strconv.Itoa(gpuUnits))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
accountId, err := controller.decortAPICall("POST", accountCreateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(accountId)
|
|
||||||
d.Set("account_id", accountId)
|
|
||||||
|
|
||||||
err = resourceAccountRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAccountRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceAccountRead")
|
|
||||||
|
|
||||||
acc, err := utilityAccountCheckPresence(d, m)
|
|
||||||
if acc == nil {
|
|
||||||
d.SetId("")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("dc_location", acc.DCLocation)
|
|
||||||
d.Set("resources", flattenAccResources(acc.Resources))
|
|
||||||
d.Set("ckey", acc.CKey)
|
|
||||||
d.Set("meta", flattenMeta(acc.Meta))
|
|
||||||
d.Set("acl", flattenAccAcl(acc.Acl))
|
|
||||||
d.Set("company", acc.Company)
|
|
||||||
d.Set("companyurl", acc.CompanyUrl)
|
|
||||||
d.Set("created_by", acc.CreatedBy)
|
|
||||||
d.Set("created_time", acc.CreatedTime)
|
|
||||||
d.Set("deactivation_time", acc.DeactiovationTime)
|
|
||||||
d.Set("deleted_by", acc.DeletedBy)
|
|
||||||
d.Set("deleted_time", acc.DeletedTime)
|
|
||||||
d.Set("displayname", acc.DisplayName)
|
|
||||||
d.Set("guid", acc.GUID)
|
|
||||||
d.Set("account_id", acc.ID)
|
|
||||||
d.Set("account_name", acc.Name)
|
|
||||||
d.Set("resource_limits", flattenRgResourceLimits(acc.ResourceLimits))
|
|
||||||
d.Set("send_access_emails", acc.SendAccessEmails)
|
|
||||||
d.Set("service_account", acc.ServiceAccount)
|
|
||||||
d.Set("status", acc.Status)
|
|
||||||
d.Set("updated_time", acc.UpdatedTime)
|
|
||||||
d.Set("version", acc.Version)
|
|
||||||
d.Set("vins", acc.Vins)
|
|
||||||
d.Set("vinses", acc.Vinses)
|
|
||||||
d.Set("computes", flattenAccComputes(acc.Computes))
|
|
||||||
d.Set("machines", flattenAccMachines(acc.Machines))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAccountDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceAccountDelete")
|
|
||||||
|
|
||||||
account, err := utilityAccountCheckPresence(d, m)
|
|
||||||
if account == nil {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
|
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", accountDeleteAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId("")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAccountExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
log.Debugf("resourceAccountExists")
|
|
||||||
|
|
||||||
account, err := utilityAccountCheckPresence(d, m)
|
|
||||||
if account == nil {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAccountEdit(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceAccountEdit")
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
if d.HasChange("enable") {
|
|
||||||
api := accountDisableAPI
|
|
||||||
enable := d.Get("enable").(bool)
|
|
||||||
if enable {
|
|
||||||
api = accountEnableAPI
|
|
||||||
}
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", api, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("account_name") {
|
|
||||||
urlValues.Add("name", d.Get("account_name").(string))
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
_, err := c.decortAPICall("POST", accountUpdateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
if d.HasChange("resource_limits") {
|
|
||||||
resLimit := d.Get("resource_limits").([]interface{})[0]
|
|
||||||
resLimitConv := resLimit.(map[string]interface{})
|
|
||||||
|
|
||||||
if resLimitConv["cu_m"] != nil {
|
|
||||||
maxMemCap := int(resLimitConv["cu_m"].(float64))
|
|
||||||
if maxMemCap == 0 {
|
|
||||||
urlValues.Add("maxMemoryCapacity", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxMemoryCapacity", strconv.Itoa(maxMemCap))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if resLimitConv["cu_d"] != nil {
|
|
||||||
maxDiskCap := int(resLimitConv["cu_d"].(float64))
|
|
||||||
if maxDiskCap == 0 {
|
|
||||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxVDiskCapacity", strconv.Itoa(maxDiskCap))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if resLimitConv["cu_c"] != nil {
|
|
||||||
maxCPUCap := int(resLimitConv["cu_c"].(float64))
|
|
||||||
if maxCPUCap == 0 {
|
|
||||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxCPUCapacity", strconv.Itoa(maxCPUCap))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if resLimitConv["cu_i"] != nil {
|
|
||||||
maxNumPublicIP := int(resLimitConv["cu_i"].(float64))
|
|
||||||
if maxNumPublicIP == 0 {
|
|
||||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxNumPublicIP", strconv.Itoa(maxNumPublicIP))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if resLimitConv["cu_np"] != nil {
|
|
||||||
maxNP := int(resLimitConv["cu_np"].(float64))
|
|
||||||
if maxNP == 0 {
|
|
||||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("maxNetworkPeerTransfer", strconv.Itoa(maxNP))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
if resLimitConv["gpu_units"] != nil {
|
|
||||||
gpuUnits := int(resLimitConv["gpu_units"].(float64))
|
|
||||||
if gpuUnits == 0 {
|
|
||||||
urlValues.Add("gpu_units", strconv.Itoa(-1))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("gpu_units", strconv.Itoa(gpuUnits))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
_, err := c.decortAPICall("POST", accountUpdateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("send_access_emails") {
|
|
||||||
urlValues.Add("sendAccessEmails", strconv.FormatBool(d.Get("send_access_emails").(bool)))
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
_, err := c.decortAPICall("POST", accountUpdateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("restore") {
|
|
||||||
restore := d.Get("restore").(bool)
|
|
||||||
if restore {
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
_, err := c.decortAPICall("POST", accountRestoreAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("users") {
|
|
||||||
deletedUsers := make([]interface{}, 0)
|
|
||||||
addedUsers := make([]interface{}, 0)
|
|
||||||
updatedUsers := make([]interface{}, 0)
|
|
||||||
|
|
||||||
old, new := d.GetChange("users")
|
|
||||||
oldConv := old.([]interface{})
|
|
||||||
newConv := new.([]interface{})
|
|
||||||
for _, el := range oldConv {
|
|
||||||
if !isContainsUser(newConv, el) {
|
|
||||||
deletedUsers = append(deletedUsers, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, el := range newConv {
|
|
||||||
if !isContainsUser(oldConv, el) {
|
|
||||||
addedUsers = append(addedUsers, el)
|
|
||||||
} else {
|
|
||||||
if isChangedUser(oldConv, el) {
|
|
||||||
updatedUsers = append(updatedUsers, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(deletedUsers) > 0 {
|
|
||||||
for _, user := range deletedUsers {
|
|
||||||
userConv := user.(map[string]interface{})
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
urlValues.Add("userId", userConv["user_id"].(string))
|
|
||||||
urlValues.Add("recursivedelete", strconv.FormatBool(userConv["recursive_delete"].(bool)))
|
|
||||||
_, err := c.decortAPICall("POST", accountDeleteUserAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(addedUsers) > 0 {
|
|
||||||
for _, user := range addedUsers {
|
|
||||||
userConv := user.(map[string]interface{})
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
urlValues.Add("userId", userConv["user_id"].(string))
|
|
||||||
urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string)))
|
|
||||||
_, err := c.decortAPICall("POST", accountAddUserAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(updatedUsers) > 0 {
|
|
||||||
for _, user := range updatedUsers {
|
|
||||||
userConv := user.(map[string]interface{})
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
urlValues.Add("userId", userConv["user_id"].(string))
|
|
||||||
urlValues.Add("accesstype", strings.ToUpper(userConv["access_type"].(string)))
|
|
||||||
_, err := c.decortAPICall("POST", accountUpdateUserAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isContainsUser(els []interface{}, el interface{}) bool {
|
|
||||||
for _, elOld := range els {
|
|
||||||
elOldConv := elOld.(map[string]interface{})
|
|
||||||
elConv := el.(map[string]interface{})
|
|
||||||
if elOldConv["user_id"].(string) == elConv["user_id"].(string) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func isChangedUser(els []interface{}, el interface{}) bool {
|
|
||||||
for _, elOld := range els {
|
|
||||||
elOldConv := elOld.(map[string]interface{})
|
|
||||||
elConv := el.(map[string]interface{})
|
|
||||||
if elOldConv["user_id"].(string) == elConv["user_id"].(string) &&
|
|
||||||
(!strings.EqualFold(elOldConv["access_type"].(string), elConv["access_type"].(string)) ||
|
|
||||||
elOldConv["recursive_delete"].(bool) != elConv["recursive_delete"].(bool)) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAccountSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "account name",
|
|
||||||
},
|
|
||||||
"username": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "username of owner the account",
|
|
||||||
},
|
|
||||||
"emailaddress": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "email",
|
|
||||||
},
|
|
||||||
"send_access_emails": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: true,
|
|
||||||
Description: "if true send emails when a user is granted access to resources",
|
|
||||||
},
|
|
||||||
"users": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"user_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"access_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"recursive_delete": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"restore": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Description: "restore a deleted account",
|
|
||||||
},
|
|
||||||
"permanently": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "whether to completely delete the account",
|
|
||||||
},
|
|
||||||
"enable": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Description: "enable/disable account",
|
|
||||||
},
|
|
||||||
"resource_limits": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"cu_c": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_d": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_i": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_m": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"cu_np": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gpu_units": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"dc_location": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"resources": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"current": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disksize": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"extips": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"exttraffic": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"reserved": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disksize": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"extips": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"exttraffic": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"acl": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"can_be_deleted": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"explicit": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"right": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"user_group_id": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"company": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"companyurl": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deactivation_time": {
|
|
||||||
Type: schema.TypeFloat,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"displayname": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"service_account": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"version": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"vins": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"computes": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"started": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"stopped": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"machines": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"halted": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"running": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"vinses": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceAccount() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceAccountCreate,
|
|
||||||
Read: resourceAccountRead,
|
|
||||||
Update: resourceAccountEdit,
|
|
||||||
Delete: resourceAccountDelete,
|
|
||||||
Exists: resourceAccountExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout60s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout60s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceAccountSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,554 +0,0 @@
|
|||||||
/*
|
|
||||||
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/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceBasicServiceCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceBasicServiceCreate")
|
|
||||||
|
|
||||||
if serviceId, ok := d.GetOk("service_id"); ok {
|
|
||||||
if exists, err := resourceBasicServiceExists(d, m); exists {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(strconv.Itoa(serviceId.(int)))
|
|
||||||
d.Set("service_id", strconv.Itoa(serviceId.(int)))
|
|
||||||
err = resourceBasicServiceRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId(id.String())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("provided service id does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("name", d.Get("service_name").(string))
|
|
||||||
urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int)))
|
|
||||||
|
|
||||||
if sshKey, ok := d.GetOk("ssh_key"); ok {
|
|
||||||
urlValues.Add("sshKey", sshKey.(string))
|
|
||||||
}
|
|
||||||
if sshUser, ok := d.GetOk("ssh_user"); ok {
|
|
||||||
urlValues.Add("sshUser", sshUser.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
serviceId, err := controller.decortAPICall("POST", bserviceCreateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(serviceId)
|
|
||||||
d.Set("service_id", serviceId)
|
|
||||||
|
|
||||||
err = resourceBasicServiceRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceBasicServiceRead")
|
|
||||||
|
|
||||||
bs, err := utilityBasicServiceCheckPresence(d, m)
|
|
||||||
if bs == nil {
|
|
||||||
d.SetId("")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("account_id", bs.AccountId)
|
|
||||||
d.Set("account_name", bs.AccountName)
|
|
||||||
d.Set("base_domain", bs.BaseDomain)
|
|
||||||
d.Set("computes", flattenBasicServiceComputes(bs.Computes))
|
|
||||||
d.Set("cpu_total", bs.CPUTotal)
|
|
||||||
d.Set("created_by", bs.CreatedBy)
|
|
||||||
d.Set("created_time", bs.CreatedTime)
|
|
||||||
d.Set("deleted_by", bs.DeletedBy)
|
|
||||||
d.Set("deleted_time", bs.DeletedTime)
|
|
||||||
d.Set("disk_total", bs.DiskTotal)
|
|
||||||
d.Set("gid", bs.GID)
|
|
||||||
d.Set("groups", bs.Groups)
|
|
||||||
d.Set("groups_name", bs.GroupsName)
|
|
||||||
d.Set("guid", bs.GUID)
|
|
||||||
d.Set("milestones", bs.Milestones)
|
|
||||||
d.Set("service_name", bs.Name)
|
|
||||||
d.Set("service_id", bs.ID)
|
|
||||||
d.Set("parent_srv_id", bs.ParentSrvId)
|
|
||||||
d.Set("parent_srv_type", bs.ParentSrvType)
|
|
||||||
d.Set("ram_total", bs.RamTotal)
|
|
||||||
d.Set("rg_id", bs.RGID)
|
|
||||||
d.Set("rg_name", bs.RGName)
|
|
||||||
d.Set("snapshots", flattenBasicServiceSnapshots(bs.Snapshots))
|
|
||||||
d.Set("ssh_key", bs.SSHKey)
|
|
||||||
d.Set("ssh_user", bs.SSHUser)
|
|
||||||
d.Set("status", bs.Status)
|
|
||||||
d.Set("tech_status", bs.TechStatus)
|
|
||||||
d.Set("updated_by", bs.UpdatedBy)
|
|
||||||
d.Set("updated_time", bs.UpdatedTime)
|
|
||||||
d.Set("user_managed", bs.UserManaged)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceBasicServiceDelete")
|
|
||||||
|
|
||||||
bs, err := utilityBasicServiceCheckPresence(d, m)
|
|
||||||
if bs == nil {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
|
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", bserviceDeleteAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId("")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
log.Debugf("resourceBasicServiceExists")
|
|
||||||
|
|
||||||
bservice, err := utilityBasicServiceCheckPresence(d, m)
|
|
||||||
if bservice == nil {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceEdit(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceBasicServiceEdit")
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
if d.HasChange("enable") {
|
|
||||||
api := bserviceDisableAPI
|
|
||||||
enable := d.Get("enable").(bool)
|
|
||||||
if enable {
|
|
||||||
api = bserviceEnableAPI
|
|
||||||
}
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", api, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("restore") {
|
|
||||||
restore := d.Get("restore").(bool)
|
|
||||||
if restore {
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
_, err := c.decortAPICall("POST", bserviceRestoreAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("start") {
|
|
||||||
api := bserviceStopAPI
|
|
||||||
start := d.Get("start").(bool)
|
|
||||||
if start {
|
|
||||||
api = bserviceStartAPI
|
|
||||||
}
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", api, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("snapshots") {
|
|
||||||
deletedSnapshots := make([]interface{}, 0)
|
|
||||||
addedSnapshots := make([]interface{}, 0)
|
|
||||||
updatedSnapshots := make([]interface{}, 0)
|
|
||||||
|
|
||||||
old, new := d.GetChange("snapshots")
|
|
||||||
oldConv := old.([]interface{})
|
|
||||||
newConv := new.([]interface{})
|
|
||||||
for _, el := range oldConv {
|
|
||||||
if !isContainsSnapshot(newConv, el) {
|
|
||||||
deletedSnapshots = append(deletedSnapshots, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, el := range newConv {
|
|
||||||
if !isContainsSnapshot(oldConv, el) {
|
|
||||||
addedSnapshots = append(addedSnapshots, el)
|
|
||||||
} else {
|
|
||||||
if isRollback(oldConv, el) {
|
|
||||||
updatedSnapshots = append(updatedSnapshots, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(deletedSnapshots) > 0 {
|
|
||||||
for _, snapshot := range deletedSnapshots {
|
|
||||||
snapshotConv := snapshot.(map[string]interface{})
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("label", snapshotConv["label"].(string))
|
|
||||||
_, err := c.decortAPICall("POST", bserviceSnapshotDeleteAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(addedSnapshots) > 0 {
|
|
||||||
for _, snapshot := range addedSnapshots {
|
|
||||||
snapshotConv := snapshot.(map[string]interface{})
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("label", snapshotConv["label"].(string))
|
|
||||||
_, err := c.decortAPICall("POST", bserviceSnapshotCreateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(updatedSnapshots) > 0 {
|
|
||||||
for _, snapshot := range updatedSnapshots {
|
|
||||||
snapshotConv := snapshot.(map[string]interface{})
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("label", snapshotConv["label"].(string))
|
|
||||||
_, err := c.decortAPICall("POST", bserviceSnapshotRollbackAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isContainsSnapshot(els []interface{}, el interface{}) bool {
|
|
||||||
for _, elOld := range els {
|
|
||||||
elOldConv := elOld.(map[string]interface{})
|
|
||||||
elConv := el.(map[string]interface{})
|
|
||||||
if elOldConv["guid"].(string) == elConv["guid"].(string) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func isRollback(els []interface{}, el interface{}) bool {
|
|
||||||
for _, elOld := range els {
|
|
||||||
elOldConv := elOld.(map[string]interface{})
|
|
||||||
elConv := el.(map[string]interface{})
|
|
||||||
if elOldConv["guid"].(string) == elConv["guid"].(string) &&
|
|
||||||
elOldConv["rollback"].(bool) != elConv["rollback"].(bool) &&
|
|
||||||
elConv["rollback"].(bool) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"service_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "Name of the service",
|
|
||||||
},
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "ID of the Resource Group where this service will be placed",
|
|
||||||
},
|
|
||||||
"ssh_key": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Description: "SSH key to deploy for the specified user. Same key will be deployed to all computes of the service.",
|
|
||||||
},
|
|
||||||
"ssh_user": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Description: "name of the user to deploy SSH key for. Pass empty string if no SSH key deployment is required",
|
|
||||||
},
|
|
||||||
"permanently": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately",
|
|
||||||
},
|
|
||||||
"enable": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "if set to False, Basic service will be deleted to recycle bin. Otherwise destroyed immediately",
|
|
||||||
},
|
|
||||||
"restore": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "Restores BasicService instance",
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "Start service. Starting a service technically means starting computes from all service groups according to group relations",
|
|
||||||
},
|
|
||||||
"service_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"base_domain": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"computes": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"compgroup_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"compgroup_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"compgroup_role": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
|
|
||||||
"cpu_total": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"disk_total": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"groups": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"groups_name": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"milestones": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"parent_srv_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"parent_srv_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"ram_total": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"rg_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"snapshots": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Optional: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"label": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"rollback": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"valid": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"tech_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"user_managed": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicService() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceBasicServiceCreate,
|
|
||||||
Read: resourceBasicServiceRead,
|
|
||||||
Update: resourceBasicServiceEdit,
|
|
||||||
Delete: resourceBasicServiceDelete,
|
|
||||||
Exists: resourceBasicServiceExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout60s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout60s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceBasicServiceSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,661 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceBasicServiceGroupCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceBasicServiceGroupCreate")
|
|
||||||
|
|
||||||
if compgroupId, ok := d.GetOk("compgroup_id"); ok {
|
|
||||||
if _, ok := d.GetOk("service_id"); ok {
|
|
||||||
if exists, err := resourceBasicServiceGroupExists(d, m); exists {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(strconv.Itoa(compgroupId.(int)))
|
|
||||||
d.Set("compgroup_id", strconv.Itoa(compgroupId.(int)))
|
|
||||||
err = resourceBasicServiceGroupRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId(id.String())
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("provided compgroup id does not exist")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("name", d.Get("compgroup_name").(string))
|
|
||||||
|
|
||||||
urlValues.Add("count", strconv.Itoa(d.Get("comp_count").(int)))
|
|
||||||
urlValues.Add("cpu", strconv.Itoa(d.Get("cpu").(int)))
|
|
||||||
urlValues.Add("ram", strconv.Itoa(d.Get("ram").(int)))
|
|
||||||
urlValues.Add("disk", strconv.Itoa(d.Get("disk").(int)))
|
|
||||||
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
|
|
||||||
urlValues.Add("driver", strings.ToUpper(d.Get("driver").(string)))
|
|
||||||
|
|
||||||
if role, ok := d.GetOk("role"); ok {
|
|
||||||
urlValues.Add("role", role.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if timeoutStart, ok := d.GetOk("timeout_start"); ok {
|
|
||||||
urlValues.Add("timeoutStart", strconv.Itoa(timeoutStart.(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if vinses, ok := d.GetOk("vinses"); ok {
|
|
||||||
vs := vinses.([]interface{})
|
|
||||||
temp := ""
|
|
||||||
l := len(vs)
|
|
||||||
for i, v := range vs {
|
|
||||||
s := strconv.Itoa(v.(int))
|
|
||||||
if i != (l - 1) {
|
|
||||||
s += ","
|
|
||||||
}
|
|
||||||
temp = temp + s
|
|
||||||
}
|
|
||||||
temp = "[" + temp + "]"
|
|
||||||
urlValues.Add("vinses", temp)
|
|
||||||
}
|
|
||||||
if extnets, ok := d.GetOk("extnets"); ok {
|
|
||||||
es := extnets.([]interface{})
|
|
||||||
temp := ""
|
|
||||||
l := len(es)
|
|
||||||
for i, e := range es {
|
|
||||||
s := strconv.Itoa(e.(int))
|
|
||||||
if i != (l - 1) {
|
|
||||||
s += ","
|
|
||||||
}
|
|
||||||
temp = temp + s
|
|
||||||
}
|
|
||||||
temp = "[" + temp + "]"
|
|
||||||
urlValues.Add("extnets", temp)
|
|
||||||
}
|
|
||||||
|
|
||||||
compgroupId, err := controller.decortAPICall("POST", bserviceGroupAddAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(compgroupId)
|
|
||||||
d.Set("compgroup_id", compgroupId)
|
|
||||||
|
|
||||||
err = resourceBasicServiceGroupRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceGroupRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceBasicServiceGroupRead")
|
|
||||||
|
|
||||||
bsg, err := utilityBasicServiceGroupCheckPresence(d, m)
|
|
||||||
if bsg == nil {
|
|
||||||
d.SetId("")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("account_id", bsg.AccountId)
|
|
||||||
d.Set("account_name", bsg.AccountName)
|
|
||||||
d.Set("computes", flattenBSGroupComputes(bsg.Computes))
|
|
||||||
d.Set("consistency", bsg.Consistency)
|
|
||||||
d.Set("cpu", bsg.CPU)
|
|
||||||
d.Set("created_by", bsg.CreatedBy)
|
|
||||||
d.Set("created_time", bsg.CreatedTime)
|
|
||||||
d.Set("deleted_by", bsg.DeletedBy)
|
|
||||||
d.Set("deleted_time", bsg.DeletedTime)
|
|
||||||
d.Set("disk", bsg.Disk)
|
|
||||||
d.Set("driver", bsg.Driver)
|
|
||||||
d.Set("extnets", bsg.Extnets)
|
|
||||||
d.Set("gid", bsg.GID)
|
|
||||||
d.Set("guid", bsg.GUID)
|
|
||||||
d.Set("image_id", bsg.ImageId)
|
|
||||||
d.Set("milestones", bsg.Milestones)
|
|
||||||
d.Set("compgroup_name", bsg.Name)
|
|
||||||
d.Set("compgroup_id", bsg.ID)
|
|
||||||
d.Set("parents", bsg.Parents)
|
|
||||||
d.Set("ram", bsg.RAM)
|
|
||||||
d.Set("rg_id", bsg.RGID)
|
|
||||||
d.Set("rg_name", bsg.RGName)
|
|
||||||
d.Set("role", bsg.Role)
|
|
||||||
d.Set("sep_id", bsg.SepId)
|
|
||||||
d.Set("seq_no", bsg.SeqNo)
|
|
||||||
d.Set("status", bsg.Status)
|
|
||||||
d.Set("tech_status", bsg.TechStatus)
|
|
||||||
d.Set("timeout_start", bsg.TimeoutStart)
|
|
||||||
d.Set("updated_by", bsg.UpdatedBy)
|
|
||||||
d.Set("updated_time", bsg.UpdatedTime)
|
|
||||||
d.Set("vinses", bsg.Vinses)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceGroupDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceBasicServiceGroupDelete")
|
|
||||||
|
|
||||||
bsg, err := utilityBasicServiceGroupCheckPresence(d, m)
|
|
||||||
if bsg == nil {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", bserviceGroupRemoveAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId("")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceGroupExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
log.Debugf("resourceBasicServiceGroupExists")
|
|
||||||
|
|
||||||
bserviceGroup, err := utilityBasicServiceGroupCheckPresence(d, m)
|
|
||||||
if bserviceGroup == nil {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceGroupEdit(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceBasicServiceGroupEdit")
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
if d.HasChange("comp_count") {
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
urlValues.Add("count", strconv.Itoa(d.Get("comp_count").(int)))
|
|
||||||
urlValues.Add("mode", strings.ToUpper(d.Get("mode").(string)))
|
|
||||||
_, err := c.decortAPICall("POST", bserviceGroupResizeAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("start") {
|
|
||||||
api := bserviceGroupStopAPI
|
|
||||||
start := d.Get("start").(bool)
|
|
||||||
if start {
|
|
||||||
api = bserviceGroupStartAPI
|
|
||||||
} else {
|
|
||||||
urlValues.Add("force", strconv.FormatBool(d.Get("force_stop").(bool)))
|
|
||||||
}
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", api, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChanges("compgroup_name", "ram", "cpu", "disk", "role") {
|
|
||||||
urlValues.Add("name", d.Get("compgroup_name").(string))
|
|
||||||
urlValues.Add("cpu", strconv.Itoa(d.Get("cpu").(int)))
|
|
||||||
urlValues.Add("ram", strconv.Itoa(d.Get("ram").(int)))
|
|
||||||
urlValues.Add("disk", strconv.Itoa(d.Get("disk").(int)))
|
|
||||||
urlValues.Add("role", d.Get("role").(string))
|
|
||||||
urlValues.Add("force", strconv.FormatBool(d.Get("force_update").(bool)))
|
|
||||||
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", bserviceGroupUpdateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("extnets") {
|
|
||||||
extnets := d.Get("extnets").([]interface{})
|
|
||||||
temp := ""
|
|
||||||
l := len(extnets)
|
|
||||||
for i, e := range extnets {
|
|
||||||
s := strconv.Itoa(e.(int))
|
|
||||||
if i != (l - 1) {
|
|
||||||
s += ",\n"
|
|
||||||
} else {
|
|
||||||
s += "\n"
|
|
||||||
}
|
|
||||||
temp = temp + s
|
|
||||||
}
|
|
||||||
temp = "[" + temp + "]"
|
|
||||||
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
urlValues.Add("extnets", temp)
|
|
||||||
_, err := c.decortAPICall("POST", bserviceGroupUpdateExtnetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("vinses") {
|
|
||||||
vinses := d.Get("vinses").([]interface{})
|
|
||||||
temp := ""
|
|
||||||
l := len(vinses)
|
|
||||||
for i, v := range vinses {
|
|
||||||
s := strconv.Itoa(v.(int))
|
|
||||||
if i != (l - 1) {
|
|
||||||
s += ",\n"
|
|
||||||
} else {
|
|
||||||
s += "\n"
|
|
||||||
}
|
|
||||||
temp = temp + s
|
|
||||||
}
|
|
||||||
temp = "[" + temp + "]"
|
|
||||||
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
urlValues.Add("vinses", temp)
|
|
||||||
_, err := c.decortAPICall("POST", bserviceGroupUpdateVinsAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("parents") {
|
|
||||||
deletedParents := make([]interface{}, 0)
|
|
||||||
addedParents := make([]interface{}, 0)
|
|
||||||
|
|
||||||
old, new := d.GetChange("parents")
|
|
||||||
oldConv := old.([]interface{})
|
|
||||||
newConv := new.([]interface{})
|
|
||||||
for _, el := range oldConv {
|
|
||||||
if !isContainsParent(newConv, el) {
|
|
||||||
deletedParents = append(deletedParents, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for _, el := range newConv {
|
|
||||||
if !isContainsParent(oldConv, el) {
|
|
||||||
addedParents = append(addedParents, el)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(deletedParents) > 0 {
|
|
||||||
for _, parent := range deletedParents {
|
|
||||||
parentConv := parent.(int)
|
|
||||||
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
urlValues.Add("parentId", strconv.Itoa(parentConv))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", bserviceGroupParentRemoveAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(addedParents) > 0 {
|
|
||||||
for _, parent := range addedParents {
|
|
||||||
parentConv := parent.(int)
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
urlValues.Add("parentId", strconv.Itoa(parentConv))
|
|
||||||
_, err := c.decortAPICall("POST", bserviceGroupParentAddAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if d.HasChange("remove_computes") {
|
|
||||||
rcs := d.Get("remove_computes").([]interface{})
|
|
||||||
if len(rcs) > 0 {
|
|
||||||
for _, rc := range rcs {
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
urlValues.Add("computeId", strconv.Itoa(rc.(int)))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", bserviceGroupComputeRemoveAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func isContainsParent(els []interface{}, el interface{}) bool {
|
|
||||||
for _, elOld := range els {
|
|
||||||
elOldConv := elOld.(int)
|
|
||||||
elConv := el.(int)
|
|
||||||
if elOldConv == elConv {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceGroupSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"service_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "ID of the Basic Service to add a group to",
|
|
||||||
},
|
|
||||||
"compgroup_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "name of the Compute Group to add",
|
|
||||||
},
|
|
||||||
"comp_count": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "computes number. Defines how many computes must be there in the group",
|
|
||||||
},
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "compute CPU number. All computes in the group have the same CPU count",
|
|
||||||
},
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "compute RAM volume in MB. All computes in the group have the same RAM volume",
|
|
||||||
},
|
|
||||||
"disk": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "compute boot disk size in GB",
|
|
||||||
},
|
|
||||||
"image_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "OS image ID to create computes from",
|
|
||||||
},
|
|
||||||
"driver": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "compute driver like a KVM_X86, KVM_PPC, etc.",
|
|
||||||
},
|
|
||||||
"role": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Description: "group role tag. Can be empty string, does not have to be unique",
|
|
||||||
},
|
|
||||||
"timeout_start": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Description: "time of Compute Group readiness",
|
|
||||||
},
|
|
||||||
"extnets": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "list of external networks to connect computes to",
|
|
||||||
},
|
|
||||||
"vinses": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "list of ViNSes to connect computes to",
|
|
||||||
},
|
|
||||||
"mode": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Default: "RELATIVE",
|
|
||||||
ValidateFunc: validation.StringInSlice([]string{"RELATIVE", "ABSOLUTE"}, false),
|
|
||||||
Description: "(RELATIVE;ABSOLUTE) either delta or absolute value of computes",
|
|
||||||
},
|
|
||||||
"start": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "Start the specified Compute Group within BasicService",
|
|
||||||
},
|
|
||||||
"force_stop": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "force stop Compute Group",
|
|
||||||
},
|
|
||||||
"force_update": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "force resize Compute Group",
|
|
||||||
},
|
|
||||||
"parents": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"remove_computes": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"compgroup_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"computes": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"ip_addresses": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"os_users": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"login": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"password": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"consistency": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"created_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"deleted_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"gid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"milestones": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"rg_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"seq_no": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"tech_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_by": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"updated_time": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceBasicServiceGroup() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceBasicServiceGroupCreate,
|
|
||||||
Read: resourceBasicServiceGroupRead,
|
|
||||||
Update: resourceBasicServiceGroupEdit,
|
|
||||||
Delete: resourceBasicServiceGroupDelete,
|
|
||||||
Exists: resourceBasicServiceGroupExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout60s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout60s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceBasicServiceGroupSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,434 +0,0 @@
|
|||||||
/*
|
|
||||||
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 {
|
|
||||||
return old.(bool) != new.(bool)
|
|
||||||
}, resourceImageChangeEnabled),
|
|
||||||
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
|
|
||||||
return old.(string) != new.(string) && old.(string) != ""
|
|
||||||
}, 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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 0
|
|
||||||
}, resourceImageShare),
|
|
||||||
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
|
|
||||||
return old.(int) != new.(int)
|
|
||||||
}, 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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 0
|
|
||||||
}, resourceImageUpdateNodes),
|
|
||||||
),
|
|
||||||
|
|
||||||
Schema: resourceCDROMImageSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,570 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
func cloudInitDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
|
|
||||||
if oldVal == "" && newVal != "applied" {
|
|
||||||
// if old value for "cloud_init" resource is empty string, it means that we are creating new compute
|
|
||||||
// and there is a chance that the user will want custom cloud init parameters - so we check if
|
|
||||||
// cloud_init is explicitly set in TF file by making sure that its new value is different from "applied",
|
|
||||||
// which is a reserved key word.
|
|
||||||
log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal)
|
|
||||||
return false // there is a difference between stored and new value
|
|
||||||
}
|
|
||||||
log.Debugf("cloudInitDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal)
|
|
||||||
return true // suppress difference
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceComputeCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
// we assume all mandatory parameters it takes to create a comptue instance are properly
|
|
||||||
// specified - we rely on schema "Required" attributes to let Terraform validate them for us
|
|
||||||
|
|
||||||
log.Debugf("resourceComputeCreate: called for Compute name %q, RG ID %d", d.Get("name").(string), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
// create basic Compute (i.e. without extra disks and network connections - those will be attached
|
|
||||||
// by subsequent individual API calls).
|
|
||||||
// creating Compute is a multi-step workflow, which may fail at some step, so we use "partial" feature of Terraform
|
|
||||||
d.Partial(true)
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("rgId", fmt.Sprintf("%d", d.Get("rg_id").(int)))
|
|
||||||
urlValues.Add("name", d.Get("name").(string))
|
|
||||||
urlValues.Add("cpu", fmt.Sprintf("%d", d.Get("cpu").(int)))
|
|
||||||
urlValues.Add("ram", fmt.Sprintf("%d", d.Get("ram").(int)))
|
|
||||||
urlValues.Add("imageId", fmt.Sprintf("%d", d.Get("image_id").(int)))
|
|
||||||
urlValues.Add("bootDisk", fmt.Sprintf("%d", d.Get("boot_disk_size").(int)))
|
|
||||||
urlValues.Add("netType", "NONE") // at the 1st step create isolated compute
|
|
||||||
urlValues.Add("start", "0") // at the 1st step create compute in a stopped state
|
|
||||||
|
|
||||||
argVal, argSet := d.GetOk("description")
|
|
||||||
if argSet {
|
|
||||||
urlValues.Add("desc", argVal.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
if sepID, ok := d.GetOk("sep_id"); ok {
|
|
||||||
urlValues.Add("sepId", strconv.Itoa(sepID.(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if pool, ok := d.GetOk("pool"); ok {
|
|
||||||
urlValues.Add("pool", pool.(string))
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
sshKeysVal, sshKeysSet := d.GetOk("ssh_keys")
|
|
||||||
if sshKeysSet {
|
|
||||||
// process SSH Key settings and set API values accordingly
|
|
||||||
log.Debugf("resourceComputeCreate: calling makeSshKeysArgString to setup SSH keys for guest login(s)")
|
|
||||||
urlValues.Add("userdata", makeSshKeysArgString(sshKeysVal.([]interface{})))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
computeCreateAPI := KvmX86CreateAPI
|
|
||||||
driver := d.Get("driver").(string)
|
|
||||||
if driver == "KVM_PPC" {
|
|
||||||
computeCreateAPI = KvmPPCCreateAPI
|
|
||||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM PowerPC")
|
|
||||||
} else { // note that we do not validate arch value for explicit "KVM_X86" here
|
|
||||||
log.Debugf("resourceComputeCreate: creating Compute of type KVM VM x86")
|
|
||||||
}
|
|
||||||
|
|
||||||
argVal, argSet = d.GetOk("cloud_init")
|
|
||||||
if argSet {
|
|
||||||
// userdata must not be empty string and must not be a reserved keyword "applied"
|
|
||||||
userdata := argVal.(string)
|
|
||||||
if userdata != "" && userdata != "applied" {
|
|
||||||
urlValues.Add("userdata", userdata)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
apiResp, err := controller.decortAPICall("POST", computeCreateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Compute create API returns ID of the new Compute instance on success
|
|
||||||
|
|
||||||
d.SetId(apiResp) // update ID of the resource to tell Terraform that the resource exists, albeit partially
|
|
||||||
compId, _ := strconv.Atoi(apiResp)
|
|
||||||
d.SetPartial("name")
|
|
||||||
d.SetPartial("description")
|
|
||||||
d.SetPartial("cpu")
|
|
||||||
d.SetPartial("ram")
|
|
||||||
d.SetPartial("image_id")
|
|
||||||
d.SetPartial("boot_disk_size")
|
|
||||||
/*
|
|
||||||
if sshKeysSet {
|
|
||||||
d.SetPartial("ssh_keys")
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
log.Debugf("resourceComputeCreate: new simple Compute ID %d, name %s created", compId, d.Get("name").(string))
|
|
||||||
|
|
||||||
// Configure data disks if any
|
|
||||||
extraDisksOk := true
|
|
||||||
argVal, argSet = d.GetOk("extra_disks")
|
|
||||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
|
||||||
// urlValues.Add("desc", argVal.(string))
|
|
||||||
log.Debugf("resourceComputeCreate: calling utilityComputeExtraDisksConfigure to attach %d extra disk(s)", argVal.(*schema.Set).Len())
|
|
||||||
err = controller.utilityComputeExtraDisksConfigure(d, false) // do_delta=false, as we are working on a new compute
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("resourceComputeCreate: error when attaching extra disk(s) to a new Compute ID %d: %v", compId, err)
|
|
||||||
extraDisksOk = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if extraDisksOk {
|
|
||||||
d.SetPartial("extra_disks")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Configure external networks if any
|
|
||||||
netsOk := true
|
|
||||||
argVal, argSet = d.GetOk("network")
|
|
||||||
if argSet && argVal.(*schema.Set).Len() > 0 {
|
|
||||||
log.Debugf("resourceComputeCreate: calling utilityComputeNetworksConfigure to attach %d network(s)", argVal.(*schema.Set).Len())
|
|
||||||
err = controller.utilityComputeNetworksConfigure(d, false) // do_delta=false, as we are working on a new compute
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("resourceComputeCreate: error when attaching networks to a new Compute ID %d: %s", compId, err)
|
|
||||||
netsOk = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if netsOk {
|
|
||||||
// there were no errors reported when configuring networks
|
|
||||||
d.SetPartial("network")
|
|
||||||
}
|
|
||||||
|
|
||||||
if extraDisksOk && netsOk {
|
|
||||||
// if there were no errors in setting any of the subresources, we may leave Partial mode
|
|
||||||
d.Partial(false)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note bene: we created compute in a STOPPED state (this is required to properly attach 1st network interface),
|
|
||||||
// now we need to start it before we report the sequence complete
|
|
||||||
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)
|
|
||||||
if _, err := controller.decortAPICall("POST", ComputeStartAPI, reqValues); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("resourceComputeCreate: new Compute ID %d, name %s creation sequence complete", compId, d.Get("name").(string))
|
|
||||||
|
|
||||||
// We may reuse dataSourceComputeRead here as we maintain similarity
|
|
||||||
// between Compute resource and Compute data source schemas
|
|
||||||
// Compute read function will also update resource ID on success, so that Terraform
|
|
||||||
// will know the resource exists
|
|
||||||
return dataSourceComputeRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceComputeRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceComputeRead: called for Compute name %s, RG ID %d",
|
|
||||||
d.Get("name").(string), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
|
||||||
if compFacts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// Compute with such name and RG ID was not found
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
if err = flattenCompute(d, compFacts); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("resourceComputeRead: after flattenCompute: Compute ID %s, name %q, RG ID %d",
|
|
||||||
d.Id(), d.Get("name").(string), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceComputeUpdate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceComputeUpdate: called for Compute ID %s / name %s, RGID %d",
|
|
||||||
d.Id(), d.Get("name").(string), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
/*
|
|
||||||
1. Resize CPU/RAM
|
|
||||||
2. Resize (grow) boot disk
|
|
||||||
3. Update extra disks
|
|
||||||
4. Update networks
|
|
||||||
5. Start/stop
|
|
||||||
*/
|
|
||||||
|
|
||||||
// 1. Resize CPU/RAM
|
|
||||||
params := &url.Values{}
|
|
||||||
doUpdate := false
|
|
||||||
params.Add("computeId", d.Id())
|
|
||||||
|
|
||||||
d.Partial(true)
|
|
||||||
|
|
||||||
oldCpu, newCpu := d.GetChange("cpu")
|
|
||||||
if oldCpu.(int) != newCpu.(int) {
|
|
||||||
params.Add("cpu", fmt.Sprintf("%d", newCpu.(int)))
|
|
||||||
doUpdate = true
|
|
||||||
} else {
|
|
||||||
params.Add("cpu", "0") // no change to CPU allocation
|
|
||||||
}
|
|
||||||
|
|
||||||
oldRam, newRam := d.GetChange("ram")
|
|
||||||
if oldRam.(int) != newRam.(int) {
|
|
||||||
params.Add("ram", fmt.Sprintf("%d", newRam.(int)))
|
|
||||||
doUpdate = true
|
|
||||||
} else {
|
|
||||||
params.Add("ram", "0")
|
|
||||||
}
|
|
||||||
|
|
||||||
if doUpdate {
|
|
||||||
log.Debugf("resourceComputeUpdate: changing CPU %d -> %d and/or RAM %d -> %d",
|
|
||||||
oldCpu.(int), newCpu.(int),
|
|
||||||
oldRam.(int), newRam.(int))
|
|
||||||
params.Add("force", "true")
|
|
||||||
_, err := controller.decortAPICall("POST", ComputeResizeAPI, params)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetPartial("cpu")
|
|
||||||
d.SetPartial("ram")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 2. Resize (grow) Boot disk
|
|
||||||
oldSize, newSize := d.GetChange("boot_disk_size")
|
|
||||||
if oldSize.(int) < newSize.(int) {
|
|
||||||
bdsParams := &url.Values{}
|
|
||||||
bdsParams.Add("diskId", fmt.Sprintf("%d", d.Get("boot_disk_id").(int)))
|
|
||||||
bdsParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
|
||||||
log.Debugf("resourceComputeUpdate: compute ID %s, boot disk ID %d resize %d -> %d",
|
|
||||||
d.Id(), d.Get("boot_disk_id").(int), oldSize.(int), newSize.(int))
|
|
||||||
_, err := controller.decortAPICall("POST", DisksResizeAPI, bdsParams)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetPartial("boot_disk_size")
|
|
||||||
} else if oldSize.(int) > newSize.(int) {
|
|
||||||
log.Warnf("resourceComputeUpdate: compute ID %s - shrinking boot disk is not allowed", d.Id())
|
|
||||||
}
|
|
||||||
|
|
||||||
// 3. Calculate and apply changes to data disks
|
|
||||||
err := controller.utilityComputeExtraDisksConfigure(d, true) // pass do_delta = true to apply changes, if any
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
d.SetPartial("extra_disks")
|
|
||||||
}
|
|
||||||
|
|
||||||
// 4. Calculate and apply changes to network connections
|
|
||||||
err = controller.utilityComputeNetworksConfigure(d, true) // pass do_delta = true to apply changes, if any
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
} else {
|
|
||||||
d.SetPartial("network")
|
|
||||||
}
|
|
||||||
|
|
||||||
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
|
|
||||||
// between Compute resource and Compute data source schemas
|
|
||||||
return dataSourceComputeRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceComputeDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
// NOTE: this function destroys target Compute instance "permanently", so
|
|
||||||
// there is no way to restore it.
|
|
||||||
// If compute being destroyed has some extra disks attached, they are
|
|
||||||
// detached from the compute
|
|
||||||
log.Debugf("resourceComputeDelete: called for Compute name %s, RG ID %d",
|
|
||||||
d.Get("name").(string), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
|
||||||
if compFacts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// the target Compute does not exist - in this case according to Terraform best practice
|
|
||||||
// we exit from Destroy method without error
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
model := ComputeGetResp{}
|
|
||||||
log.Debugf("resourceComputeDelete: ready to unmarshal string %s", compFacts)
|
|
||||||
err = json.Unmarshal([]byte(compFacts), &model)
|
|
||||||
if err == nil && len(model.Disks) > 0 {
|
|
||||||
// prepare to detach data disks from compute - do it only if compFacts unmarshalled
|
|
||||||
// properly and the resulting model contains non-empty Disks list
|
|
||||||
for _, diskFacts := range model.Disks {
|
|
||||||
if diskFacts.Type == "B" {
|
|
||||||
// boot disk is never detached on compute delete
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("resourceComputeDelete: ready to detach data disk ID %d from compute ID %s", diskFacts.ID, d.Id())
|
|
||||||
|
|
||||||
detachParams := &url.Values{}
|
|
||||||
detachParams.Add("computeId", d.Id())
|
|
||||||
detachParams.Add("diskId", fmt.Sprintf("%d", diskFacts.ID))
|
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", ComputeDiskDetachAPI, detachParams)
|
|
||||||
if err != nil {
|
|
||||||
// We do not fail compute deletion on data disk detach errors
|
|
||||||
log.Errorf("resourceComputeDelete: error when detaching Disk ID %d: %s", diskFacts.ID, err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
params := &url.Values{}
|
|
||||||
params.Add("computeId", d.Id())
|
|
||||||
params.Add("permanently", "1")
|
|
||||||
// TODO: this is for the upcoming API update - params.Add("detachdisks", "1")
|
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", ComputeDeleteAPI, params)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceComputeExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
|
||||||
log.Debugf("resourceComputeExist: called for Compute name %s, RG ID %d",
|
|
||||||
d.Get("name").(string), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
compFacts, err := utilityComputeCheckPresence(d, m)
|
|
||||||
if compFacts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceCompute() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceComputeCreate,
|
|
||||||
Read: resourceComputeRead,
|
|
||||||
Update: resourceComputeUpdate,
|
|
||||||
Delete: resourceComputeDelete,
|
|
||||||
Exists: resourceComputeExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout180s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout180s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "Name of this compute. Compute names are case sensitive and must be unique in the resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validation.IntAtLeast(1),
|
|
||||||
Description: "ID of the resource group where this compute should be deployed.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"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.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validation.IntBetween(1, MaxCpusPerCompute),
|
|
||||||
Description: "Number of CPUs to allocate to this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validation.IntAtLeast(MinRamPerCompute),
|
|
||||||
Description: "Amount of RAM in MB to allocate to this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"image_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validation.IntAtLeast(1),
|
|
||||||
Description: "ID of the OS image to base this compute instance on.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"boot_disk_size": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "This compute instance boot disk size in GB. Make sure it is large enough to accomodate selected OS image.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "ID of SEP to create bootDisk on. Uses image's sepId if not set.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"pool": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "Pool to use if sepId is set, can be also empty if needed to be chosen by system.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"extra_disks": {
|
|
||||||
Type: schema.TypeSet,
|
|
||||||
Optional: true,
|
|
||||||
MaxItems: MaxExtraDisksPerCompute,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "Optional list of IDs of extra disks to attach to this compute. You may specify several extra disks.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"network": {
|
|
||||||
Type: schema.TypeSet,
|
|
||||||
Optional: true,
|
|
||||||
MaxItems: MaxNetworksPerCompute,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: networkSubresourceSchemaMake(),
|
|
||||||
},
|
|
||||||
Description: "Optional network connection(s) for this compute. You may specify several network blocks, one for each connection.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
"ssh_keys": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
MaxItems: MaxSshKeysPerCompute,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: sshSubresourceSchemaMake(),
|
|
||||||
},
|
|
||||||
Description: "SSH keys to authorize on this compute instance.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Optional text description of this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"cloud_init": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Default: "applied",
|
|
||||||
DiffSuppressFunc: cloudInitDiffSupperss,
|
|
||||||
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
|
|
||||||
},
|
|
||||||
|
|
||||||
// The rest are Compute properties, which are "computed" once it is created
|
|
||||||
"rg_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the resource group where this compute instance is located.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the account this compute instance belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the account this compute instance belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"boot_disk_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "This compute instance boot disk ID.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"os_users": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: osUsersSubresourceSchemaMake(),
|
|
||||||
},
|
|
||||||
Description: "Guest OS users provisioned on this compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"started": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: true,
|
|
||||||
Description: "Is compute started.",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,131 +0,0 @@
|
|||||||
/*
|
|
||||||
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(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,332 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
// "encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceDiskCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceDiskCreate: called for Disk name %q, Account ID %d", d.Get("name").(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
// accountId, gid, name, description, size, type, sep_id, pool
|
|
||||||
urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
|
||||||
urlValues.Add("gid", fmt.Sprintf("%d", DefaultGridID)) // we use default Grid ID, which was obtained along with DECORT Controller init
|
|
||||||
urlValues.Add("name", d.Get("name").(string))
|
|
||||||
urlValues.Add("size", fmt.Sprintf("%d", d.Get("size").(int)))
|
|
||||||
urlValues.Add("type", "D") // NOTE: only disks of Data type are managed via plugin
|
|
||||||
|
|
||||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(sepId.(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
if poolName, ok := d.GetOk("pool"); ok {
|
|
||||||
urlValues.Add("pool", poolName.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
argVal, argSet := d.GetOk("description")
|
|
||||||
if argSet {
|
|
||||||
urlValues.Add("description", argVal.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
apiResp, err := controller.decortAPICall("POST", DisksCreateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(apiResp) // update ID of the resource to tell Terraform that the disk resource exists
|
|
||||||
diskId, _ := strconv.Atoi(apiResp)
|
|
||||||
|
|
||||||
log.Debugf("resourceDiskCreate: new Disk ID / name %d / %s creation sequence complete", diskId, d.Get("name").(string))
|
|
||||||
|
|
||||||
// We may reuse dataSourceDiskRead here as we maintain similarity
|
|
||||||
// between Disk resource and Disk data source schemas
|
|
||||||
// Disk resource read function will also update resource ID on success, so that Terraform
|
|
||||||
// will know the resource exists (however, we already did it a few lines before)
|
|
||||||
return dataSourceDiskRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceDiskRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
diskFacts, err := utilityDiskCheckPresence(d, m)
|
|
||||||
if diskFacts == "" {
|
|
||||||
// if empty string is returned from utilityDiskCheckPresence then there is no
|
|
||||||
// such Disk and err tells so - just return it to the calling party
|
|
||||||
d.SetId("") // ensure ID is empty
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return flattenDisk(d, diskFacts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceDiskUpdate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
// Update will only change the following attributes of the disk:
|
|
||||||
// - Size; to keep data safe, shrinking disk is not allowed.
|
|
||||||
// - Name
|
|
||||||
//
|
|
||||||
// Attempt to change disk type will throw an error and mark disk
|
|
||||||
// resource as partially updated
|
|
||||||
log.Debugf("resourceDiskUpdate: called for Disk ID / name %s / %s, Account ID %d",
|
|
||||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
d.Partial(true)
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
oldSize, newSize := d.GetChange("size")
|
|
||||||
if oldSize.(int) < newSize.(int) {
|
|
||||||
log.Debugf("resourceDiskUpdate: resizing disk ID %s - %d GB -> %d GB",
|
|
||||||
d.Id(), oldSize.(int), newSize.(int))
|
|
||||||
sizeParams := &url.Values{}
|
|
||||||
sizeParams.Add("diskId", d.Id())
|
|
||||||
sizeParams.Add("size", fmt.Sprintf("%d", newSize.(int)))
|
|
||||||
_, err := controller.decortAPICall("POST", DisksResizeAPI, sizeParams)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetPartial("size")
|
|
||||||
} else if oldSize.(int) > newSize.(int) {
|
|
||||||
return fmt.Errorf("resourceDiskUpdate: Disk ID %s - reducing disk size is not allowed", d.Id())
|
|
||||||
}
|
|
||||||
|
|
||||||
oldName, newName := d.GetChange("name")
|
|
||||||
if oldName.(string) != newName.(string) {
|
|
||||||
log.Debugf("resourceDiskUpdate: renaming disk ID %d - %s -> %s",
|
|
||||||
d.Get("disk_id").(int), oldName.(string), newName.(string))
|
|
||||||
renameParams := &url.Values{}
|
|
||||||
renameParams.Add("diskId", d.Id())
|
|
||||||
renameParams.Add("name", newName.(string))
|
|
||||||
_, err := controller.decortAPICall("POST", DisksRenameAPI, renameParams)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetPartial("name")
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
NOTE: plugin will manage disks of type "Data" only, and type cannot be changed once disk is created
|
|
||||||
|
|
||||||
oldType, newType := d.GetChange("type")
|
|
||||||
if oldType.(string) != newType.(string) {
|
|
||||||
return fmt.Errorf("resourceDiskUpdate: Disk ID %s - changing type of existing disk not allowed", d.Id())
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
d.Partial(false)
|
|
||||||
|
|
||||||
// we may reuse dataSourceDiskRead here as we maintain similarity
|
|
||||||
// between Compute resource and Compute data source schemas
|
|
||||||
return dataSourceDiskRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceDiskDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
// NOTE: this function tries to detach and destroy target Disk "permanently", so
|
|
||||||
// there is no way to restore it.
|
|
||||||
// If, however, the disk is attached to a compute, the method will
|
|
||||||
// fail (by failing the underpinning DECORt API call, which is issued with detach=false)
|
|
||||||
log.Debugf("resourceDiskDelete: called for Disk ID / name %d / %s, Account ID %d",
|
|
||||||
d.Get("disk_id").(int), d.Get("name").(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
diskFacts, err := utilityDiskCheckPresence(d, m)
|
|
||||||
if diskFacts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// the specified Disk does not exist - in this case according to Terraform best practice
|
|
||||||
// we exit from Destroy method without error
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
params := &url.Values{}
|
|
||||||
params.Add("diskId", d.Id())
|
|
||||||
// NOTE: we are not force-detaching disk from a compute (if attached) thus protecting
|
|
||||||
// data that may be on that disk from destruction.
|
|
||||||
// However, this may change in the future, as TF state management logic may want
|
|
||||||
// to delete disk resource BEFORE it is detached from compute instance, and, while
|
|
||||||
// perfectly OK from data preservation viewpoint, this is breaking expected TF workflow
|
|
||||||
// in the eyes of an experienced TF user
|
|
||||||
params.Add("detach", "0")
|
|
||||||
params.Add("permanently", "1")
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
_, err = controller.decortAPICall("POST", DisksDeleteAPI, params)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceDiskExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
|
||||||
log.Debugf("resourceDiskExists: called for Disk ID / name %d / %s, Account ID %d",
|
|
||||||
d.Get("disk_id").(int), d.Get("name").(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
diskFacts, err := utilityDiskCheckPresence(d, m)
|
|
||||||
if diskFacts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceDiskSchemaMake() map[string]*schema.Schema {
|
|
||||||
rets := map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "Name of this disk. NOTE: disk names are NOT unique within an account. If disk ID is specified, disk name is ignored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"disk_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "ID of the disk to get. If disk ID is specified, then disk name and account ID are ignored.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "ID of the account this disk belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "Storage end-point provider serving this disk. Cannot be changed for existing disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"pool": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "Pool where this disk is located. Cannot be changed for existing disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"size": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validation.IntAtLeast(1),
|
|
||||||
Description: "Size of the disk in GB. Note, that existing disks can only be grown in size.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/* We moved "type" attribute to computed attributes section, as plugin manages disks of only
|
|
||||||
one type - "D", e.g. data disks.
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Default: "D",
|
|
||||||
StateFunc: stateFuncToUpper,
|
|
||||||
ValidateFunc: validation.StringInSlice([]string{"B", "D"}, false),
|
|
||||||
Description: "Optional type of this disk. Defaults to D, i.e. data disk. Cannot be changed for existing disks.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Default: "Disk resource managed by Terraform",
|
|
||||||
Description: "Optional user-defined text description of this disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
// The rest of the attributes are all computed
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the account this disk belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"image_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the image, which this disk was cloned from (if ever cloned).",
|
|
||||||
},
|
|
||||||
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Type of this disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"sep_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Type of the storage end-point provider serving this disk.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
"snapshots": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource {
|
|
||||||
Schema: snapshotSubresourceSchemaMake(),
|
|
||||||
},
|
|
||||||
Description: "List of user-created snapshots for this disk."
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
return rets
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceDisk() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceDiskCreate,
|
|
||||||
Read: resourceDiskRead,
|
|
||||||
Update: resourceDiskUpdate,
|
|
||||||
Delete: resourceDiskDelete,
|
|
||||||
Exists: resourceDiskExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout180s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout180s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceDiskSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,722 +0,0 @@
|
|||||||
/*
|
|
||||||
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 := ""
|
|
||||||
if isSync := d.Get("sync").(bool); !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 {
|
|
||||||
return old.(bool) != new.(bool)
|
|
||||||
}, resourceImageChangeEnabled),
|
|
||||||
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
|
|
||||||
return old.(string) != new.(string) && old.(string) != ""
|
|
||||||
}, 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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 0
|
|
||||||
}, resourceImageShare),
|
|
||||||
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
|
|
||||||
return old.(int) != new.(int)
|
|
||||||
}, 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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 0
|
|
||||||
}, 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
|
|
||||||
}
|
|
||||||
@@ -1,393 +0,0 @@
|
|||||||
/*
|
|
||||||
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)))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("extnetId", "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("lbId", strconv.Itoa(k8s.LbID))
|
|
||||||
|
|
||||||
resp, err = controller.decortAPICall("POST", LbGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var lb LbRecord
|
|
||||||
if err := json.Unmarshal([]byte(resp), &lb); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.Set("extnet_id", lb.ExtNetID)
|
|
||||||
d.Set("lb_ip", lb.PrimaryNode.FrontendIP)
|
|
||||||
|
|
||||||
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("lbId", strconv.Itoa(k8s.LbID))
|
|
||||||
|
|
||||||
resp, err := controller.decortAPICall("POST", LbGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
var lb LbRecord
|
|
||||||
if err := json.Unmarshal([]byte(resp), &lb); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.Set("extnet_id", lb.ExtNetID)
|
|
||||||
d.Set("lb_ip", lb.PrimaryNode.FrontendIP)
|
|
||||||
|
|
||||||
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))
|
|
||||||
if _, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for i := wg.Num - 1; i >= newWorkers.Num; i-- {
|
|
||||||
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
|
|
||||||
if _, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues); 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,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
|
|
||||||
},
|
|
||||||
|
|
||||||
//"desc": {
|
|
||||||
//Type: schema.TypeString,
|
|
||||||
//Optional: true,
|
|
||||||
//Description: "Text description of this instance.",
|
|
||||||
//},
|
|
||||||
|
|
||||||
"lb_ip": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "IP address of default load balancer.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"default_wg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of default workers group for this instace.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"kubeconfig": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Kubeconfig for cluster access.",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceK8s() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceK8sCreate,
|
|
||||||
Read: resourceK8sRead,
|
|
||||||
Update: resourceK8sUpdate,
|
|
||||||
Delete: resourceK8sDelete,
|
|
||||||
Exists: resourceK8sExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout20m,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout20m,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceK8sSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,248 +0,0 @@
|
|||||||
/*
|
|
||||||
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 err
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
|
||||||
urlValues.Add("workersGroupId", d.Id())
|
|
||||||
|
|
||||||
if newNum := d.Get("num").(int); newNum > wg.Num {
|
|
||||||
urlValues.Add("num", strconv.Itoa(newNum-wg.Num))
|
|
||||||
_, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
for i := wg.Num - 1; i >= newNum; i-- {
|
|
||||||
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
|
|
||||||
_, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceK8sWgDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int))
|
|
||||||
|
|
||||||
wg, err := utilityK8sWgCheckPresence(d, m)
|
|
||||||
if wg == nil {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
|
|
||||||
urlValues.Add("workersGroupId", strconv.Itoa(wg.ID))
|
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", K8sWgDeleteAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceK8sWgExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
log.Debugf("resourceK8sWgExists: called with k8s id %d", d.Get("k8s_id").(int))
|
|
||||||
|
|
||||||
wg, err := utilityK8sWgCheckPresence(d, m)
|
|
||||||
if wg == nil {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceK8sWgSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"k8s_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "ID of k8s instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "Name of the worker group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"num": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Default: 1,
|
|
||||||
Description: "Number of worker nodes to create.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"cpu": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Default: 1,
|
|
||||||
Description: "Worker node CPU count.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ram": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Default: 1024,
|
|
||||||
Description: "Worker node RAM in MB.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"disk": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Default: 0,
|
|
||||||
Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceK8sWg() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceK8sWgCreate,
|
|
||||||
Read: resourceK8sWgRead,
|
|
||||||
Update: resourceK8sWgUpdate,
|
|
||||||
Delete: resourceK8sWgDelete,
|
|
||||||
Exists: resourceK8sWgExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout20m,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout20m,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceK8sWgSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,263 +0,0 @@
|
|||||||
/*
|
|
||||||
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/schema"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourcePcideviceCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourcePcideviceCreate: called for pcidevice %s", d.Get("name").(string))
|
|
||||||
|
|
||||||
if deviceId, ok := d.GetOk("device_id"); ok {
|
|
||||||
if exists, err := resourcePcideviceExists(d, m); exists {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId(strconv.Itoa(deviceId.(int)))
|
|
||||||
err = resourcePcideviceRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("provided device id does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("name", d.Get("name").(string))
|
|
||||||
urlValues.Add("hwPath", d.Get("hw_path").(string))
|
|
||||||
urlValues.Add("rgId", strconv.Itoa(d.Get("rg_id").(int)))
|
|
||||||
urlValues.Add("stackId", strconv.Itoa(d.Get("stack_id").(int)))
|
|
||||||
|
|
||||||
if description, ok := d.GetOk("description"); ok {
|
|
||||||
urlValues.Add("description", description.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
pcideviceId, err := controller.decortAPICall("POST", pcideviceCreateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(pcideviceId)
|
|
||||||
d.Set("device_id", pcideviceId)
|
|
||||||
|
|
||||||
err = resourcePcideviceRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePcideviceRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
pcidevice, err := utilityPcideviceCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(strconv.Itoa(pcidevice.ID))
|
|
||||||
d.Set("ckey", pcidevice.CKey)
|
|
||||||
d.Set("meta", flattenMeta(pcidevice.Meta))
|
|
||||||
d.Set("compute_id", pcidevice.Computeid)
|
|
||||||
d.Set("description", pcidevice.Description)
|
|
||||||
d.Set("guid", pcidevice.Guid)
|
|
||||||
d.Set("hw_path", pcidevice.HwPath)
|
|
||||||
d.Set("device_id", pcidevice.ID)
|
|
||||||
d.Set("rg_id", pcidevice.RgID)
|
|
||||||
d.Set("name", pcidevice.Name)
|
|
||||||
d.Set("stack_id", pcidevice.StackID)
|
|
||||||
d.Set("status", pcidevice.Status)
|
|
||||||
d.Set("system_name", pcidevice.SystemName)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePcideviceDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourcePcideviceDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("deviceId", d.Id())
|
|
||||||
urlValues.Add("force", strconv.FormatBool(d.Get("force").(bool)))
|
|
||||||
|
|
||||||
_, err := controller.decortAPICall("POST", pcideviceDeleteAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId("")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePcideviceExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
pcidevice, err := utilityPcideviceCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if pcidevice == nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePcideviceEdit(d *schema.ResourceData, m interface{}) error {
|
|
||||||
if d.HasChange("enable") {
|
|
||||||
state := d.Get("enable").(bool)
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
api := ""
|
|
||||||
|
|
||||||
urlValues.Add("deviceId", strconv.Itoa(d.Get("device_id").(int)))
|
|
||||||
|
|
||||||
if state {
|
|
||||||
api = pcideviceEnableAPI
|
|
||||||
} else {
|
|
||||||
api = pcideviceDisableAPI
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", api, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := resourcePcideviceRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePcideviceSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"compute_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Description: "description, just for information",
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"hw_path": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "PCI address of the device",
|
|
||||||
},
|
|
||||||
"device_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "Name of Device",
|
|
||||||
},
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "Resource GROUP",
|
|
||||||
},
|
|
||||||
"stack_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "stackId",
|
|
||||||
},
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"system_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"force": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "Force delete",
|
|
||||||
},
|
|
||||||
"enable": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "Enable pci device",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePcidevice() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourcePcideviceCreate,
|
|
||||||
Read: resourcePcideviceRead,
|
|
||||||
Update: resourcePcideviceEdit,
|
|
||||||
Delete: resourcePcideviceDelete,
|
|
||||||
Exists: resourcePcideviceExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout60s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout60s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourcePcideviceSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,201 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
|
||||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourcePfwCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int))
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
|
||||||
urlValues.Add("publicPortStart", strconv.Itoa(d.Get("public_port_start").(int)))
|
|
||||||
urlValues.Add("localBasePort", strconv.Itoa(d.Get("local_base_port").(int)))
|
|
||||||
urlValues.Add("proto", d.Get("proto").(string))
|
|
||||||
|
|
||||||
if portEnd, ok := d.GetOk("public_port_end"); ok {
|
|
||||||
urlValues.Add("publicPortEnd", strconv.Itoa(portEnd.(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pfwId, err := controller.decortAPICall("POST", ComputePfwAddAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(fmt.Sprintf("%d-%s", d.Get("compute_id").(int), pfwId))
|
|
||||||
|
|
||||||
pfw, err := utilityPfwCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("local_ip", pfw.LocalIP)
|
|
||||||
if _, ok := d.GetOk("public_port_end"); !ok {
|
|
||||||
d.Set("public_port_end", pfw.PublicPortEnd)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePfwRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourcePfwRead: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
|
||||||
|
|
||||||
pfw, err := utilityPfwCheckPresence(d, m)
|
|
||||||
if pfw == nil {
|
|
||||||
d.SetId("")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("compute_id", pfw.ComputeID)
|
|
||||||
d.Set("public_port_start", pfw.PublicPortStart)
|
|
||||||
d.Set("public_port_end", pfw.PublicPortEnd)
|
|
||||||
d.Set("local_ip", pfw.LocalIP)
|
|
||||||
d.Set("local_base_port", pfw.LocalPort)
|
|
||||||
d.Set("proto", pfw.Protocol)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePfwDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourcePfwDelete: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
|
||||||
|
|
||||||
pfw, err := utilityPfwCheckPresence(d, m)
|
|
||||||
if pfw == nil {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
|
||||||
urlValues.Add("ruleId", strconv.Itoa(pfw.ID))
|
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", ComputePfwDelAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePfwExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
log.Debugf("resourcePfwExists: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
|
|
||||||
|
|
||||||
pfw, err := utilityPfwCheckPresence(d, m)
|
|
||||||
if pfw == nil {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePfwSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"compute_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "ID of compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"public_port_start": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validation.IntBetween(1, 65535),
|
|
||||||
Description: "External start port number for the rule.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"public_port_end": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validation.IntBetween(1, 65535),
|
|
||||||
Description: "End port number (inclusive) for the ranged rule.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"local_ip": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "IP address of compute instance.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"local_base_port": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validation.IntBetween(1, 65535),
|
|
||||||
Description: "Internal base port number.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"proto": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false),
|
|
||||||
Description: "Network protocol, either 'tcp' or 'udp'.",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourcePfw() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourcePfwCreate,
|
|
||||||
Read: resourcePfwRead,
|
|
||||||
Delete: resourcePfwDelete,
|
|
||||||
Exists: resourcePfwExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout60s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout60s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourcePfwSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,430 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2019-2021 Digital Energy Cloud Solutions. All Rights Reserved.
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
// First validate that we have all parameters required to create the new Resource Group
|
|
||||||
|
|
||||||
// Valid account ID is required to create new resource group
|
|
||||||
// obtain Account ID by account name - it should not be zero on success
|
|
||||||
|
|
||||||
rg_name, arg_set := d.GetOk("name")
|
|
||||||
if !arg_set {
|
|
||||||
return fmt.Errorf("Cannot create new RG: missing name.")
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Current version of provider works with default grid id (same is true for disk resources)
|
|
||||||
grid_id, arg_set := d.GetOk("grid_id")
|
|
||||||
if !arg_set {
|
|
||||||
return fmt.Errorf("Cannot create new RG %q in account ID %d: missing Grid ID.",
|
|
||||||
rg_name.(string), validated_account_id)
|
|
||||||
}
|
|
||||||
if grid_id.(int) < 1 {
|
|
||||||
grid_id = DefaultGridID
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
// all required parameters are set in the schema - we can continue with RG creation
|
|
||||||
log.Debugf("resourceResgroupCreate: called for RG name %s, account ID %d",
|
|
||||||
rg_name.(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
// quota settings are optional
|
|
||||||
set_quota := false
|
|
||||||
var quota_record QuotaRecord
|
|
||||||
arg_value, arg_set := d.GetOk("quota")
|
|
||||||
if arg_set {
|
|
||||||
log.Debugf("resourceResgroupCreate: setting Quota on RG requested")
|
|
||||||
quota_record = makeQuotaRecord(arg_value.([]interface{}))
|
|
||||||
set_quota = true
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
log.Debugf("resourceResgroupCreate: called by user %q for RG name %s, account ID %d",
|
|
||||||
controller.getDecortUsername(),
|
|
||||||
rg_name.(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
url_values := &url.Values{}
|
|
||||||
url_values.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
|
||||||
url_values.Add("name", rg_name.(string))
|
|
||||||
url_values.Add("gid", fmt.Sprintf("%d", DefaultGridID)) // use default Grid ID, similar to disk resource mgmt convention
|
|
||||||
url_values.Add("owner", controller.getDecortUsername())
|
|
||||||
|
|
||||||
// pass quota values as set
|
|
||||||
if set_quota {
|
|
||||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quota_record.Cpu))
|
|
||||||
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quota_record.Disk))
|
|
||||||
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quota_record.Ram)) // RAM quota is float; this may change in the future
|
|
||||||
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quota_record.ExtTraffic))
|
|
||||||
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quota_record.ExtIPs))
|
|
||||||
// url_values.Add("???", fmt.Sprintf("%d", quota_record.GpuUnits))
|
|
||||||
}
|
|
||||||
|
|
||||||
// parse and handle network settings
|
|
||||||
def_net_type, arg_set := d.GetOk("def_net_type")
|
|
||||||
if arg_set {
|
|
||||||
url_values.Add("def_net", def_net_type.(string)) // NOTE: in API default network type is set by "def_net" parameter
|
|
||||||
}
|
|
||||||
|
|
||||||
ipcidr, arg_set := d.GetOk("ipcidr")
|
|
||||||
if arg_set {
|
|
||||||
url_values.Add("ipcidr", ipcidr.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
ext_net_id, arg_set := d.GetOk("ext_net_id")
|
|
||||||
if arg_set {
|
|
||||||
url_values.Add("extNetId", fmt.Sprintf("%d", ext_net_id.(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
ext_ip, arg_set := d.GetOk("ext_ip")
|
|
||||||
if arg_set {
|
|
||||||
url_values.Add("extIp", ext_ip.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
api_resp, err := controller.decortAPICall("POST", ResgroupCreateAPI, url_values)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(api_resp) // rg/create API returns ID of the newly creted resource group on success
|
|
||||||
// rg.ID, _ = strconv.Atoi(api_resp)
|
|
||||||
if !set_quota {
|
|
||||||
resp, err := utilityResgroupCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
rg := ResgroupGetResp{}
|
|
||||||
if err := json.Unmarshal([]byte(resp), &rg); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("quota", parseQuota(rg.Quota))
|
|
||||||
}
|
|
||||||
|
|
||||||
// re-read newly created RG to make sure schema contains complete and up to date set of specifications
|
|
||||||
return resourceResgroupRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceResgroupRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceResgroupRead: called for RG name %s, account ID %d",
|
|
||||||
d.Get("name").(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
|
||||||
if rg_facts == "" {
|
|
||||||
// if empty string is returned from utilityResgroupCheckPresence then there is no
|
|
||||||
// such resource group and err tells so - just return it to the calling party
|
|
||||||
d.SetId("") // ensure ID is empty
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return flattenResgroup(d, rg_facts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceResgroupUpdate: called for RG name %s, account ID %d",
|
|
||||||
d.Get("name").(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
/* NOTE: we do not allow changing the following attributes of an existing RG via terraform:
|
|
||||||
- def_net_type
|
|
||||||
- ipcidr
|
|
||||||
- ext_net_id
|
|
||||||
- ext_ip
|
|
||||||
|
|
||||||
The following code fragment checks if any of these have been changed and generates error.
|
|
||||||
*/
|
|
||||||
for _, attr := range []string{"def_net_type", "ipcidr", "ext_ip"} {
|
|
||||||
attr_new, attr_old := d.GetChange("def_net_type")
|
|
||||||
if attr_new.(string) != attr_old.(string) {
|
|
||||||
return fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing %s for existing RG is not allowed", d.Id(), attr)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attr_new, attr_old := d.GetChange("ext_net_id")
|
|
||||||
if attr_new.(int) != attr_old.(int) {
|
|
||||||
return fmt.Errorf("resourceResgroupUpdate: RG ID %s: changing ext_net_id for existing RG is not allowed", d.Id())
|
|
||||||
}
|
|
||||||
|
|
||||||
do_general_update := false // will be true if general RG update is necessary (API rg/update)
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
url_values := &url.Values{}
|
|
||||||
url_values.Add("rgId", d.Id())
|
|
||||||
|
|
||||||
name_new, name_set := d.GetOk("name")
|
|
||||||
if name_set {
|
|
||||||
log.Debugf("resourceResgroupUpdate: name specified - looking for deltas from the old settings.")
|
|
||||||
name_old, _ := d.GetChange("name")
|
|
||||||
if name_old.(string) != name_new.(string) {
|
|
||||||
do_general_update = true
|
|
||||||
url_values.Add("name", name_new.(string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
quota_value, quota_set := d.GetOk("quota")
|
|
||||||
if quota_set {
|
|
||||||
log.Debugf("resourceResgroupUpdate: quota specified - looking for deltas from the old quota.")
|
|
||||||
quotarecord_new := makeQuotaRecord(quota_value.([]interface{}))
|
|
||||||
quota_value_old, _ := d.GetChange("quota") // returns old as 1st, new as 2nd return value
|
|
||||||
quotarecord_old := makeQuotaRecord(quota_value_old.([]interface{}))
|
|
||||||
|
|
||||||
if quotarecord_new.Cpu != quotarecord_old.Cpu {
|
|
||||||
do_general_update = true
|
|
||||||
log.Debugf("resourceResgroupUpdate: Cpu diff %d <- %d", quotarecord_new.Cpu, quotarecord_old.Cpu)
|
|
||||||
url_values.Add("maxCPUCapacity", fmt.Sprintf("%d", quotarecord_new.Cpu))
|
|
||||||
}
|
|
||||||
|
|
||||||
if quotarecord_new.Disk != quotarecord_old.Disk {
|
|
||||||
do_general_update = true
|
|
||||||
log.Debugf("resourceResgroupUpdate: Disk diff %d <- %d", quotarecord_new.Disk, quotarecord_old.Disk)
|
|
||||||
url_values.Add("maxVDiskCapacity", fmt.Sprintf("%d", quotarecord_new.Disk))
|
|
||||||
}
|
|
||||||
|
|
||||||
if quotarecord_new.Ram != quotarecord_old.Ram { // NB: quota on RAM is stored as float32, in units of MB
|
|
||||||
do_general_update = true
|
|
||||||
log.Debugf("resourceResgroupUpdate: Ram diff %f <- %f", quotarecord_new.Ram, quotarecord_old.Ram)
|
|
||||||
url_values.Add("maxMemoryCapacity", fmt.Sprintf("%f", quotarecord_new.Ram))
|
|
||||||
}
|
|
||||||
|
|
||||||
if quotarecord_new.ExtTraffic != quotarecord_old.ExtTraffic {
|
|
||||||
do_general_update = true
|
|
||||||
log.Debugf("resourceResgroupUpdate: ExtTraffic diff %d <- %d", quotarecord_new.ExtTraffic, quotarecord_old.ExtTraffic)
|
|
||||||
url_values.Add("maxNetworkPeerTransfer", fmt.Sprintf("%d", quotarecord_new.ExtTraffic))
|
|
||||||
}
|
|
||||||
|
|
||||||
if quotarecord_new.ExtIPs != quotarecord_old.ExtIPs {
|
|
||||||
do_general_update = true
|
|
||||||
log.Debugf("resourceResgroupUpdate: ExtIPs diff %d <- %d", quotarecord_new.ExtIPs, quotarecord_old.ExtIPs)
|
|
||||||
url_values.Add("maxNumPublicIP", fmt.Sprintf("%d", quotarecord_new.ExtIPs))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
desc_new, desc_set := d.GetOk("description")
|
|
||||||
if desc_set {
|
|
||||||
log.Debugf("resourceResgroupUpdate: description specified - looking for deltas from the old settings.")
|
|
||||||
desc_old, _ := d.GetChange("description")
|
|
||||||
if desc_old.(string) != desc_new.(string) {
|
|
||||||
do_general_update = true
|
|
||||||
url_values.Add("desc", desc_new.(string))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if do_general_update {
|
|
||||||
log.Debugf("resourceResgroupUpdate: detected delta between new and old RG specs - updating the RG")
|
|
||||||
_, err := controller.decortAPICall("POST", ResgroupUpdateAPI, url_values)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
log.Debugf("resourceResgroupUpdate: no difference between old and new state - no update on the RG will be done")
|
|
||||||
}
|
|
||||||
|
|
||||||
return resourceResgroupRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceResgroupDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
// NOTE: this method forcibly destroys target resource group with flag "permanently", so there is no way to
|
|
||||||
// restore the destroyed resource group as well all Computes & VINSes that existed in it
|
|
||||||
log.Debugf("resourceResgroupDelete: called for RG name %s, account ID %d",
|
|
||||||
d.Get("name").(string), d.Get("account_id").(int))
|
|
||||||
|
|
||||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
|
||||||
if rg_facts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// the target RG does not exist - in this case according to Terraform best practice
|
|
||||||
// we exit from Destroy method without error
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
url_values := &url.Values{}
|
|
||||||
url_values.Add("rgId", d.Id())
|
|
||||||
url_values.Add("force", "1")
|
|
||||||
url_values.Add("permanently", "1")
|
|
||||||
url_values.Add("reason", "Destroyed by DECORT Terraform provider")
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
_, err = controller.decortAPICall("POST", ResgroupDeleteAPI, url_values)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceResgroupExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
// Reminder: according to Terraform rules, this function should NOT modify ResourceData argument
|
|
||||||
rg_facts, err := utilityResgroupCheckPresence(d, m)
|
|
||||||
if rg_facts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceResgroup() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceResgroupCreate,
|
|
||||||
Read: resourceResgroupRead,
|
|
||||||
Update: resourceResgroupUpdate,
|
|
||||||
Delete: resourceResgroupDelete,
|
|
||||||
Exists: resourceResgroupExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout180s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout180s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "Name of this resource group. Names are case sensitive and unique within the context of a account.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validation.IntAtLeast(1),
|
|
||||||
Description: "Unique ID of the account, which this resource group belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"def_net_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Default: "PRIVATE",
|
|
||||||
ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false),
|
|
||||||
Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"def_net_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "ID of the default network for this resource group (if any).",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ipcidr": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Address of the netowrk inside the private network segment (aka ViNS) if def_net_type=PRIVATE",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ext_net_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Default: 0,
|
|
||||||
Description: "ID of the external network for default ViNS. Pass 0 if def_net_type=PUBLIC or no external connection required for the defult ViNS when def_net_type=PRIVATE",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ext_ip": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "IP address on the external netowrk to request when def_net_type=PRIVATE and ext_net_id is not 0",
|
|
||||||
},
|
|
||||||
|
|
||||||
/* commented out, as in this version of provider we use default Grid ID
|
|
||||||
"grid_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Default: 0, // if 0 is passed, default Grid ID will be used
|
|
||||||
// DefaultFunc: utilityResgroupGetDefaultGridID,
|
|
||||||
ForceNew: true, // change of Grid ID will require new RG
|
|
||||||
Description: "Unique ID of the grid, where this resource group is deployed.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
"quota": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: 1,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: quotaRgSubresourceSchemaMake(),
|
|
||||||
},
|
|
||||||
Description: "Quota settings for this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Description: "User-defined text description of this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the account, which this resource group belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/*
|
|
||||||
"status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Current status of this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"vins": {
|
|
||||||
Type: schema.TypeList, // this is a list of ints
|
|
||||||
Computed: true,
|
|
||||||
MaxItems: LimitMaxVinsPerResgroup,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "List of VINs deployed in this resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"computes": {
|
|
||||||
Type: schema.TypeList, // this is a list of ints
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "List of computes deployed in this resource group.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,548 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/customdiff"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceSepCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepCreate: called for sep %s", d.Get("name").(string))
|
|
||||||
|
|
||||||
if sepId, ok := d.GetOk("sep_id"); ok {
|
|
||||||
if exists, err := resourceSepExists(d, m); exists {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId(strconv.Itoa(sepId.(int)))
|
|
||||||
err = resourceSepRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("provided sep id does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("name", d.Get("name").(string))
|
|
||||||
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
|
|
||||||
urlValues.Add("sep_type", d.Get("type").(string))
|
|
||||||
|
|
||||||
if desc, ok := d.GetOk("desc"); ok {
|
|
||||||
urlValues.Add("description", desc.(string))
|
|
||||||
}
|
|
||||||
if configString, ok := d.GetOk("config"); ok {
|
|
||||||
urlValues.Add("config", configString.(string))
|
|
||||||
}
|
|
||||||
if enable, ok := d.GetOk("enable"); ok {
|
|
||||||
urlValues.Add("enable", strconv.FormatBool(enable.(bool)))
|
|
||||||
}
|
|
||||||
|
|
||||||
tstr := d.Get("consumed_by").([]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("consumer_nids", temp)
|
|
||||||
|
|
||||||
tstr = d.Get("provided_by").([]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("provider_nids", temp)
|
|
||||||
|
|
||||||
sepId, err := controller.decortAPICall("POST", sepCreateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(sepId)
|
|
||||||
d.Set("sep_id", sepId)
|
|
||||||
|
|
||||||
err = resourceSepRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(id.String())
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepRead: called for %s id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
|
||||||
|
|
||||||
sep, err := utilitySepCheckPresence(d, m)
|
|
||||||
if sep == nil {
|
|
||||||
d.SetId("")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("ckey", sep.Ckey)
|
|
||||||
d.Set("meta", flattenMeta(sep.Meta))
|
|
||||||
d.Set("consumed_by", sep.ConsumedBy)
|
|
||||||
d.Set("desc", sep.Desc)
|
|
||||||
d.Set("gid", sep.Gid)
|
|
||||||
d.Set("guid", sep.Guid)
|
|
||||||
d.Set("sep_id", sep.Id)
|
|
||||||
d.Set("milestones", sep.Milestones)
|
|
||||||
d.Set("name", sep.Name)
|
|
||||||
d.Set("obj_status", sep.ObjStatus)
|
|
||||||
d.Set("provided_by", sep.ProvidedBy)
|
|
||||||
d.Set("tech_status", sep.TechStatus)
|
|
||||||
d.Set("type", sep.Type)
|
|
||||||
data, _ := json.Marshal(sep.Config)
|
|
||||||
d.Set("config", string(data))
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepDelete: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
|
||||||
|
|
||||||
sepDes, err := utilitySepCheckPresence(d, m)
|
|
||||||
if sepDes == nil {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
|
|
||||||
_, err = controller.decortAPICall("POST", sepDeleteAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId("")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
log.Debugf("resourceSepExists: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
|
||||||
|
|
||||||
sepDes, err := utilitySepCheckPresence(d, m)
|
|
||||||
if sepDes == nil {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepEdit(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepEdit: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
if d.HasChange("decommission") {
|
|
||||||
decommission := d.Get("decommission").(bool)
|
|
||||||
if decommission {
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
urlValues.Add("clear_physically", strconv.FormatBool(d.Get("clear_physically").(bool)))
|
|
||||||
_, err := c.decortAPICall("POST", sepDecommissionAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
if d.HasChange("upd_capacity_limit") {
|
|
||||||
updCapacityLimit := d.Get("upd_capacity_limit").(bool)
|
|
||||||
if updCapacityLimit {
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
_, err := c.decortAPICall("POST", sepUpdateCapacityLimitAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
if d.HasChange("config") {
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
urlValues.Add("config", d.Get("config").(string))
|
|
||||||
_, err := c.decortAPICall("POST", sepConfigValidateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = c.decortAPICall("POST", sepConfigInsertAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
if d.HasChange("field_edit") {
|
|
||||||
fieldConfig := d.Get("field_edit").([]interface{})
|
|
||||||
field := fieldConfig[0].(map[string]interface{})
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
urlValues.Add("field_name", field["field_name"].(string))
|
|
||||||
urlValues.Add("field_value", field["field_value"].(string))
|
|
||||||
urlValues.Add("field_type", field["field_type"].(string))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", sepConfigFieldEditAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
if err := resourceSepRead(d, m); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepChangeEnabled(d *schema.ResourceDiff, m interface{}) error {
|
|
||||||
var api string
|
|
||||||
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
if d.Get("enable").(bool) {
|
|
||||||
api = sepEnableAPI
|
|
||||||
} else {
|
|
||||||
api = sepDisableAPI
|
|
||||||
}
|
|
||||||
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 resourceSepUpdateNodes(d *schema.ResourceDiff, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepUpdateNodes: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
t1, t2 := d.GetChange("consumed_by")
|
|
||||||
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
|
|
||||||
consumedIds := make([]interface{}, 0)
|
|
||||||
temp := ""
|
|
||||||
api := ""
|
|
||||||
|
|
||||||
if d1, d2 := t1.([]interface{}), t2.([]interface{}); len(d1) > len(d2) {
|
|
||||||
for _, n := range d2 {
|
|
||||||
if !findElInt(d1, n) {
|
|
||||||
consumedIds = append(consumedIds, n)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
api = sepDelConsumerNodesAPI
|
|
||||||
} else {
|
|
||||||
consumedIds = d.Get("consumed_by").([]interface{})
|
|
||||||
api = sepAddConsumerNodesAPI
|
|
||||||
}
|
|
||||||
|
|
||||||
l := len(consumedIds)
|
|
||||||
for i, consumedId := range consumedIds {
|
|
||||||
s := strconv.Itoa(consumedId.(int))
|
|
||||||
if i != (l - 1) {
|
|
||||||
s += ","
|
|
||||||
}
|
|
||||||
temp = temp + s
|
|
||||||
}
|
|
||||||
temp = "[" + temp + "]"
|
|
||||||
urlValues.Add("consumer_nids", temp)
|
|
||||||
_, err := c.decortAPICall("POST", api, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func findElInt(sl []interface{}, el interface{}) bool {
|
|
||||||
for _, e := range sl {
|
|
||||||
if e.(int) == el.(int) {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepUpdateProviders(d *schema.ResourceDiff, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepUpdateProviders: called for %s, id: %d", d.Get("name").(string), d.Get("sep_id").(int))
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
providerIds := d.Get("provided_by").([]interface{})
|
|
||||||
temp := ""
|
|
||||||
l := len(providerIds)
|
|
||||||
for i, providerId := range providerIds {
|
|
||||||
s := strconv.Itoa(providerId.(int))
|
|
||||||
if i != (l - 1) {
|
|
||||||
s += ","
|
|
||||||
}
|
|
||||||
temp = temp + s
|
|
||||||
}
|
|
||||||
temp = "[" + temp + "]"
|
|
||||||
urlValues.Add("provider_nids", temp)
|
|
||||||
_, err := c.decortAPICall("POST", sepAddProviderNodesAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Description: "sep type des id",
|
|
||||||
},
|
|
||||||
"upd_capacity_limit": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "Update SEP capacity limit",
|
|
||||||
},
|
|
||||||
"decommission": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "unlink everything that exists from SEP",
|
|
||||||
},
|
|
||||||
"clear_physically": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: true,
|
|
||||||
Description: "clear disks and images physically",
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Description: "sep config string",
|
|
||||||
},
|
|
||||||
"ckey": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"meta": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeString,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"consumed_by": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "list of consumer nodes IDs",
|
|
||||||
},
|
|
||||||
"desc": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Optional: true,
|
|
||||||
Description: "sep description",
|
|
||||||
},
|
|
||||||
"gid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
Description: "grid (platform) ID",
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"milestones": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "SEP name",
|
|
||||||
},
|
|
||||||
"obj_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"provided_by": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
Description: "list of provider nodes IDs",
|
|
||||||
},
|
|
||||||
"tech_status": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
Description: "type of storage",
|
|
||||||
},
|
|
||||||
"enable": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "enable SEP after creation",
|
|
||||||
},
|
|
||||||
"field_edit": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
MaxItems: 1,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"field_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"field_value": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"field_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSep() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceSepCreate,
|
|
||||||
Read: resourceSepRead,
|
|
||||||
Update: resourceSepEdit,
|
|
||||||
Delete: resourceSepDelete,
|
|
||||||
Exists: resourceSepExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout60s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout60s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceSepSchemaMake(),
|
|
||||||
|
|
||||||
CustomizeDiff: customdiff.All(
|
|
||||||
customdiff.IfValueChange("enable", func(old, new, meta interface{}) bool {
|
|
||||||
return old.(bool) != new.(bool)
|
|
||||||
}, resourceSepChangeEnabled),
|
|
||||||
customdiff.IfValueChange("consumed_by", 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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 0
|
|
||||||
}, resourceSepUpdateNodes),
|
|
||||||
customdiff.IfValueChange("provided_by", 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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 0
|
|
||||||
}, resourceSepUpdateProviders),
|
|
||||||
),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,195 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/google/uuid"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceSepConfigCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepConfigCreate: called for sep id %d", d.Get("sep_id").(int))
|
|
||||||
|
|
||||||
if _, ok := d.GetOk("sep_id"); ok {
|
|
||||||
if exists, err := resourceSepConfigExists(d, m); exists {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
id := uuid.New()
|
|
||||||
d.SetId(id.String())
|
|
||||||
err = resourceSepConfigRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
return errors.New("provided sep id config does not exist")
|
|
||||||
}
|
|
||||||
|
|
||||||
return resourceSepConfigRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepConfigRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepConfigRead: called for sep id: %d", d.Get("sep_id").(int))
|
|
||||||
|
|
||||||
sepConfig, err := utilitySepConfigCheckPresence(d, m)
|
|
||||||
if sepConfig == nil {
|
|
||||||
d.SetId("")
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
data, _ := json.Marshal(sepConfig)
|
|
||||||
d.Set("config", string(data))
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepConfigDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
d.SetId("")
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepConfigExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
log.Debugf("resourceSepConfigExists: called for sep id: %d", d.Get("sep_id").(int))
|
|
||||||
|
|
||||||
sepDesConfig, err := utilitySepConfigCheckPresence(d, m)
|
|
||||||
if sepDesConfig == nil {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepConfigEdit(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSepConfigEdit: called for sep id: %d", d.Get("sep_id").(int))
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
if d.HasChange("config") {
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
urlValues.Add("config", d.Get("config").(string))
|
|
||||||
_, err := c.decortAPICall("POST", sepConfigValidateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
_, err = c.decortAPICall("POST", sepConfigInsertAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues = &url.Values{}
|
|
||||||
if d.HasChange("field_edit") {
|
|
||||||
fieldConfig := d.Get("field_edit").([]interface{})
|
|
||||||
field := fieldConfig[0].(map[string]interface{})
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
urlValues.Add("field_name", field["field_name"].(string))
|
|
||||||
urlValues.Add("field_value", field["field_value"].(string))
|
|
||||||
urlValues.Add("field_type", field["field_type"].(string))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", sepConfigFieldEditAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
err := resourceSepConfigRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepConfigSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"sep_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"config": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
},
|
|
||||||
"field_edit": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
MaxItems: 1,
|
|
||||||
Optional: true,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Resource{
|
|
||||||
Schema: map[string]*schema.Schema{
|
|
||||||
"field_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"field_value": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
"field_type": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSepConfig() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceSepConfigCreate,
|
|
||||||
Read: resourceSepConfigRead,
|
|
||||||
Update: resourceSepConfigEdit,
|
|
||||||
Delete: resourceSepConfigDelete,
|
|
||||||
Exists: resourceSepConfigExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout60s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout60s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceSepConfigSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,203 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/customdiff"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
|
||||||
|
|
||||||
func resourceSnapshotCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSnapshotCreate: called for snapshot %s", d.Get("label").(string))
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("label", d.Get("label").(string))
|
|
||||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
|
||||||
|
|
||||||
snapshotId, err := controller.decortAPICall("POST", snapshotCreateAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
snapshotId = strings.ReplaceAll(snapshotId, "\"", "")
|
|
||||||
|
|
||||||
d.SetId(snapshotId)
|
|
||||||
d.Set("guid", snapshotId)
|
|
||||||
|
|
||||||
err = resourceSnapshotRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSnapshotRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
snapshot, err := utilitySnapshotCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Set("timestamp", snapshot.Timestamp)
|
|
||||||
d.Set("guid", snapshot.Guid)
|
|
||||||
d.Set("disks", snapshot.Disks)
|
|
||||||
d.Set("label", snapshot.Label)
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSnapshotDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceSnapshotDelete: called for %s, id: %s", d.Get("label").(string), d.Id())
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
|
||||||
urlValues.Add("label", d.Get("label").(string))
|
|
||||||
|
|
||||||
_, err := controller.decortAPICall("POST", snapshotDeleteAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
d.SetId("")
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSnapshotExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
snapshot, err := utilitySnapshotCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
if snapshot == nil {
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSnapshotEdit(d *schema.ResourceData, m interface{}) error {
|
|
||||||
err := resourceSnapshotRead(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSnapshotRollback(d *schema.ResourceDiff, m interface{}) error {
|
|
||||||
c := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
|
||||||
urlValues.Add("label", d.Get("label").(string))
|
|
||||||
|
|
||||||
_, err := c.decortAPICall("POST", snapshotRollbackAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSnapshotSchemaMake() map[string]*schema.Schema {
|
|
||||||
return map[string]*schema.Schema{
|
|
||||||
"compute_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "ID of the compute instance to create snapshot for.",
|
|
||||||
},
|
|
||||||
"label": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Description: "text label for snapshot. Must be unique among this compute snapshots.",
|
|
||||||
},
|
|
||||||
"rollback": {
|
|
||||||
Type: schema.TypeBool,
|
|
||||||
Optional: true,
|
|
||||||
Default: false,
|
|
||||||
Description: "is rollback the snapshot",
|
|
||||||
},
|
|
||||||
"disks": {
|
|
||||||
Type: schema.TypeList,
|
|
||||||
Computed: true,
|
|
||||||
Elem: &schema.Schema{
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"guid": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "guid of the snapshot",
|
|
||||||
},
|
|
||||||
"timestamp": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Computed: true,
|
|
||||||
Description: "timestamp",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceSnapshot() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceSnapshotCreate,
|
|
||||||
Read: resourceSnapshotRead,
|
|
||||||
Update: resourceSnapshotEdit,
|
|
||||||
Delete: resourceSnapshotDelete,
|
|
||||||
Exists: resourceSnapshotExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout60s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout60s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
CustomizeDiff: customdiff.All(
|
|
||||||
customdiff.IfValueChange("rollback", func(old, new, meta interface{}) bool {
|
|
||||||
o := old.(bool)
|
|
||||||
if o != new.(bool) && !o {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return false
|
|
||||||
}, resourceSnapshotRollback),
|
|
||||||
),
|
|
||||||
|
|
||||||
Schema: resourceSnapshotSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,321 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
// "encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
func ipcidrDiffSupperss(key, oldVal, newVal string, d *schema.ResourceData) bool {
|
|
||||||
if oldVal == "" && newVal != "" {
|
|
||||||
// if old value for "ipcidr" resource is empty string, it means that we are creating new ViNS
|
|
||||||
// and there is a chance that the user will want specific IP address range for this ViNS -
|
|
||||||
// check if "ipcidr" is explicitly set in TF file to a non-empty string.
|
|
||||||
log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=FALSE", key, oldVal, newVal)
|
|
||||||
return false // there is a difference between stored and new value
|
|
||||||
}
|
|
||||||
log.Debugf("ipcidrDiffSupperss: key=%s, oldVal=%q, newVal=%q -> suppress=TRUE", key, oldVal, newVal)
|
|
||||||
return true // suppress difference
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceVinsCreate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceVinsCreate: called for ViNS name %s, Account ID %d, RG ID %d",
|
|
||||||
d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
apiToCall := VinsCreateInAccountAPI
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("name", d.Get("name").(string))
|
|
||||||
|
|
||||||
argVal, argSet := d.GetOk("rg_id")
|
|
||||||
if argSet && argVal.(int) > 0 {
|
|
||||||
apiToCall = VinsCreateInRgAPI
|
|
||||||
urlValues.Add("rgId", fmt.Sprintf("%d", argVal.(int)))
|
|
||||||
} else {
|
|
||||||
// RG ID either not set at all or set to 0 - user may want ViNS at account level
|
|
||||||
argVal, argSet = d.GetOk("account_id")
|
|
||||||
if !argSet || argVal.(int) <= 0 {
|
|
||||||
// No valid Account ID (and no RG ID either) - cannot create ViNS
|
|
||||||
return fmt.Errorf("resourceVinsCreate: ViNS name %s - no valid account and/or resource group ID specified", d.Id())
|
|
||||||
}
|
|
||||||
urlValues.Add("accountId", fmt.Sprintf("%d", argVal.(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
argVal, argSet = d.GetOk("ext_net_id") // NB: even if ext_net_id value is explicitly set to 0, argSet = false anyway
|
|
||||||
if argSet {
|
|
||||||
if argVal.(int) > 0 {
|
|
||||||
// connect to specific external network
|
|
||||||
urlValues.Add("extNetId", fmt.Sprintf("%d", argVal.(int)))
|
|
||||||
/*
|
|
||||||
Commented out, as we've made "ext_net_ip" parameter non-configurable via Terraform!
|
|
||||||
|
|
||||||
// in case of specific ext net connection user may also want a particular IP address
|
|
||||||
argVal, argSet = d.GetOk("ext_net_ip")
|
|
||||||
if argSet && argVal.(string) != "" {
|
|
||||||
urlValues.Add("extIp", argVal.(string))
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
} else {
|
|
||||||
// ext_net_id is set to a negative value - connect to default external network
|
|
||||||
// no particular IP address selection in this case
|
|
||||||
urlValues.Add("extNetId", "0")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
argVal, argSet = d.GetOk("ipcidr")
|
|
||||||
if argSet && argVal.(string) != "" {
|
|
||||||
log.Debugf("resourceVinsCreate: ipcidr is set to %s", argVal.(string))
|
|
||||||
urlValues.Add("ipcidr", argVal.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
argVal, argSet = d.GetOk("description")
|
|
||||||
if argSet {
|
|
||||||
urlValues.Add("desc", argVal.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
apiResp, err := controller.decortAPICall("POST", apiToCall, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetId(apiResp) // update ID of the resource to tell Terraform that the ViNS resource exists
|
|
||||||
vinsId, _ := strconv.Atoi(apiResp)
|
|
||||||
|
|
||||||
log.Debugf("resourceVinsCreate: new ViNS ID / name %d / %s creation sequence complete", vinsId, d.Get("name").(string))
|
|
||||||
|
|
||||||
// We may reuse dataSourceVinsRead here as we maintain similarity
|
|
||||||
// between ViNS resource and ViNS data source schemas
|
|
||||||
// ViNS resource read function will also update resource ID on success, so that Terraform
|
|
||||||
// will know the resource exists (however, we already did it a few lines before)
|
|
||||||
return dataSourceVinsRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceVinsRead(d *schema.ResourceData, m interface{}) error {
|
|
||||||
vinsFacts, err := utilityVinsCheckPresence(d, m)
|
|
||||||
if vinsFacts == "" {
|
|
||||||
// if empty string is returned from utilityVinsCheckPresence then there is no
|
|
||||||
// such ViNS and err tells so - just return it to the calling party
|
|
||||||
d.SetId("") // ensure ID is empty
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return flattenVins(d, vinsFacts)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceVinsUpdate(d *schema.ResourceData, m interface{}) error {
|
|
||||||
|
|
||||||
log.Debugf("resourceVinsUpdate: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d",
|
|
||||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
|
|
||||||
d.Partial(true)
|
|
||||||
|
|
||||||
// 1. Handle external network connection change
|
|
||||||
oldExtNetId, newExtNedId := d.GetChange("ext_net_id")
|
|
||||||
if oldExtNetId.(int) != newExtNedId.(int) {
|
|
||||||
log.Debugf("resourceVinsUpdate: changing ViNS ID %s - ext_net_id %d -> %d", d.Id(), oldExtNetId.(int), newExtNedId.(int))
|
|
||||||
|
|
||||||
extnetParams := &url.Values{}
|
|
||||||
extnetParams.Add("vinsId", d.Id())
|
|
||||||
|
|
||||||
if oldExtNetId.(int) > 0 {
|
|
||||||
// there was preexisting external net connection - disconnect ViNS
|
|
||||||
_, err := controller.decortAPICall("POST", VinsExtNetDisconnectAPI, extnetParams)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if newExtNedId.(int) > 0 {
|
|
||||||
// new external network connection requested - connect ViNS
|
|
||||||
extnetParams.Add("netId", fmt.Sprintf("%d", newExtNedId.(int)))
|
|
||||||
_, err := controller.decortAPICall("POST", VinsExtNetConnectAPI, extnetParams)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
d.SetPartial("ext_net_id")
|
|
||||||
}
|
|
||||||
|
|
||||||
d.Partial(false)
|
|
||||||
|
|
||||||
// we may reuse dataSourceVinsRead here as we maintain similarity
|
|
||||||
// between Compute resource and Compute data source schemas
|
|
||||||
return dataSourceVinsRead(d, m)
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceVinsDelete(d *schema.ResourceData, m interface{}) error {
|
|
||||||
log.Debugf("resourceVinsDelete: called for ViNS ID / name %s / %s, Account ID %d, RG ID %d",
|
|
||||||
d.Id(), d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
vinsFacts, err := utilityVinsCheckPresence(d, m)
|
|
||||||
if vinsFacts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
// the specified ViNS does not exist - in this case according to Terraform best practice
|
|
||||||
// we exit from Destroy method without error
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
params := &url.Values{}
|
|
||||||
params.Add("vinsId", d.Id())
|
|
||||||
params.Add("force", "1") // disconnect all computes before deleting ViNS
|
|
||||||
params.Add("permanently", "1") // delete ViNS immediately bypassing recycle bin
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
_, err = controller.decortAPICall("POST", VinsDeleteAPI, params)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceVinsExists(d *schema.ResourceData, m interface{}) (bool, error) {
|
|
||||||
// Reminder: according to Terraform rules, this function should not modify its ResourceData argument
|
|
||||||
log.Debugf("resourceVinsExists: called for ViNS name %s, Account ID %d, RG ID %d",
|
|
||||||
d.Get("name").(string), d.Get("account_id").(int), d.Get("rg_id").(int))
|
|
||||||
|
|
||||||
vinsFacts, err := utilityVinsCheckPresence(d, m)
|
|
||||||
if vinsFacts == "" {
|
|
||||||
if err != nil {
|
|
||||||
return false, err
|
|
||||||
}
|
|
||||||
return false, nil
|
|
||||||
}
|
|
||||||
return true, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceVinsSchemaMake() map[string]*schema.Schema {
|
|
||||||
rets := map[string]*schema.Schema{
|
|
||||||
"name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validation.StringIsNotEmpty,
|
|
||||||
Description: "Name of the ViNS. Names are case sensitive and unique within the context of an account or resource group.",
|
|
||||||
},
|
|
||||||
|
|
||||||
/* we do not need ViNS ID as an argument because if we already know this ID, it is not practical to call resource provider.
|
|
||||||
Resource Import will work anyway, as it obtains the ID of ViNS to be imported through another mechanism.
|
|
||||||
"vins_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
Description: "Unique ID of the ViNS. If ViNS ID is specified, then ViNS name, rg_id and account_id are ignored.",
|
|
||||||
},
|
|
||||||
*/
|
|
||||||
|
|
||||||
"rg_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Optional: true,
|
|
||||||
ForceNew: true,
|
|
||||||
Default: 0,
|
|
||||||
Description: "ID of the resource group, where this ViNS belongs to. Non-zero for ViNS created at resource group level, 0 otherwise.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"account_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ForceNew: true,
|
|
||||||
ValidateFunc: validation.IntAtLeast(1),
|
|
||||||
Description: "ID of the account, which this ViNS belongs to. For ViNS created at account level, resource group ID is 0.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ext_net_id": {
|
|
||||||
Type: schema.TypeInt,
|
|
||||||
Required: true,
|
|
||||||
ValidateFunc: validation.IntAtLeast(0),
|
|
||||||
Description: "ID of the external network this ViNS is connected to. Pass 0 if no external connection required.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ipcidr": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
DiffSuppressFunc: ipcidrDiffSupperss,
|
|
||||||
Description: "Network address to use by this ViNS. This parameter is only valid when creating new ViNS.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"description": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Optional: true,
|
|
||||||
Default: "",
|
|
||||||
Description: "Optional user-defined text description of this ViNS.",
|
|
||||||
},
|
|
||||||
|
|
||||||
// the rest of attributes are computed
|
|
||||||
"account_name": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "Name of the account, which this ViNS belongs to.",
|
|
||||||
},
|
|
||||||
|
|
||||||
"ext_ip_addr": {
|
|
||||||
Type: schema.TypeString,
|
|
||||||
Computed: true,
|
|
||||||
Description: "IP address of the external connection (valid for ViNS connected to external network, ignored otherwise).",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
return rets
|
|
||||||
}
|
|
||||||
|
|
||||||
func resourceVins() *schema.Resource {
|
|
||||||
return &schema.Resource{
|
|
||||||
SchemaVersion: 1,
|
|
||||||
|
|
||||||
Create: resourceVinsCreate,
|
|
||||||
Read: resourceVinsRead,
|
|
||||||
Update: resourceVinsUpdate,
|
|
||||||
Delete: resourceVinsDelete,
|
|
||||||
Exists: resourceVinsExists,
|
|
||||||
|
|
||||||
Importer: &schema.ResourceImporter{
|
|
||||||
State: schema.ImportStatePassthrough,
|
|
||||||
},
|
|
||||||
|
|
||||||
Timeouts: &schema.ResourceTimeout{
|
|
||||||
Create: &Timeout180s,
|
|
||||||
Read: &Timeout30s,
|
|
||||||
Update: &Timeout180s,
|
|
||||||
Delete: &Timeout60s,
|
|
||||||
Default: &Timeout60s,
|
|
||||||
},
|
|
||||||
|
|
||||||
Schema: resourceVinsSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,384 +0,0 @@
|
|||||||
/*
|
|
||||||
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 {
|
|
||||||
return old.(bool) != new.(bool)
|
|
||||||
}, resourceImageChangeEnabled),
|
|
||||||
customdiff.IfValueChange("link_to", func(old, new, meta interface{}) bool {
|
|
||||||
return old.(int) != new.(int)
|
|
||||||
}, resourceImageLink),
|
|
||||||
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
|
|
||||||
return old.(string) != new.(string) && old.(string) != ""
|
|
||||||
}, 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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 0
|
|
||||||
}, resourceImageShare),
|
|
||||||
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
|
|
||||||
return old.(int) != new.(int)
|
|
||||||
}, 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++
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return count == 0
|
|
||||||
}, resourceImageUpdateNodes),
|
|
||||||
),
|
|
||||||
|
|
||||||
Schema: resourceVirtualImageSchemaMake(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountCheckPresence(d *schema.ResourceData, m interface{}) (*AccountWithResources, error) {
|
|
||||||
account := &AccountWithResources{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
if (strconv.Itoa(d.Get("account_id").(int))) != "0" {
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("accountId", d.Id())
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountCheckPresence: load account")
|
|
||||||
accountRaw, err := controller.decortAPICall("POST", accountGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountRaw), &account)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return account, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountAuditsListCheckPresence(d *schema.ResourceData, m interface{}) (AccountAuditsList, error) {
|
|
||||||
accountAuditsList := AccountAuditsList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountAuditsListCheckPresence: load account list")
|
|
||||||
accountAuditsListRaw, err := controller.decortAPICall("POST", accountAuditsAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountAuditsListRaw), &accountAuditsList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountAuditsList, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountComputesListCheckPresence(d *schema.ResourceData, m interface{}) (AccountComputesList, error) {
|
|
||||||
accountComputesList := AccountComputesList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountComputesListCheckPresence: load account list")
|
|
||||||
accountComputesListRaw, err := controller.decortAPICall("POST", accountListComputesAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountComputesListRaw), &accountComputesList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountComputesList, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountConsumedUnitsCheckPresence(d *schema.ResourceData, m interface{}) (*ResourceLimits, error) {
|
|
||||||
accountConsumedUnits := &ResourceLimits{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountConsumedUnitsCheckPresence: load account list")
|
|
||||||
accountConsumedUnitsRaw, err := controller.decortAPICall("POST", accountGetConsumedUnitsAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountConsumedUnitsRaw), accountConsumedUnits)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountConsumedUnits, nil
|
|
||||||
}
|
|
||||||
@@ -1,55 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func utilityAccountConsumedUnitsByTypeCheckPresence(d *schema.ResourceData, m interface{}) (float64, error) {
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
urlValues.Add("cutype", strings.ToUpper(d.Get("cu_type").(string)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountConsumedUnitsByTypeCheckPresence")
|
|
||||||
resultRaw, err := controller.decortAPICall("POST", accountGetConsumedUnitsByTypeAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
result, err := strconv.ParseFloat(resultRaw, 64)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return result, nil
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountDeletedListCheckPresence(d *schema.ResourceData, m interface{}) (AccountCloudApiList, error) {
|
|
||||||
accountDeletedList := AccountCloudApiList{}
|
|
||||||
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("utilityAccountDeletedListCheckPresence: load")
|
|
||||||
accountDeletedListRaw, err := controller.decortAPICall("POST", accountListDeletedAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountDeletedListRaw), &accountDeletedList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountDeletedList, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountDisksListCheckPresence(d *schema.ResourceData, m interface{}) (AccountDisksList, error) {
|
|
||||||
accountDisksList := AccountDisksList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountDisksListCheckPresence: load account list")
|
|
||||||
accountDisksListRaw, err := controller.decortAPICall("POST", accountListDisksAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountDisksListRaw), &accountDisksList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountDisksList, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountFlipGroupsListCheckPresence(d *schema.ResourceData, m interface{}) (AccountFlipGroupsList, error) {
|
|
||||||
accountFlipGroupsList := AccountFlipGroupsList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountFlipGroupsListCheckPresence")
|
|
||||||
accountFlipGroupsListRaw, err := controller.decortAPICall("POST", accountListFlipGroupsAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountFlipGroupsListRaw), &accountFlipGroupsList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountFlipGroupsList, nil
|
|
||||||
}
|
|
||||||
@@ -1,89 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountListCheckPresence(d *schema.ResourceData, m interface{}) (AccountCloudApiList, error) {
|
|
||||||
accountList := AccountCloudApiList{}
|
|
||||||
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("utilityAccountListCheckPresence: load account list")
|
|
||||||
accountListRaw, err := controller.decortAPICall("POST", accountListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountListRaw), &accountList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountList, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
/*uncomment for cloudbroker
|
|
||||||
func utilityAccountListCheckPresence(d *schema.ResourceData, m interface{}) (AccountList, error) {
|
|
||||||
accountList := AccountList{}
|
|
||||||
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("utilityAccountListCheckPresence: load account list")
|
|
||||||
accountListRaw, err := controller.decortAPICall("POST", accountListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountListRaw), &accountList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountList, nil
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountReservedUnitsCheckPresence(d *schema.ResourceData, m interface{}) (*ResourceLimits, error) {
|
|
||||||
accountReservedUnits := &ResourceLimits{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountReservedUnitsCheckPresence: load units")
|
|
||||||
accountReservedUnitsRaw, err := controller.decortAPICall("POST", accountGetReservedUnitsAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountReservedUnitsRaw), accountReservedUnits)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountReservedUnits, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountRGListCheckPresence(d *schema.ResourceData, m interface{}) (AccountRGList, error) {
|
|
||||||
accountRGList := AccountRGList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountRGListCheckPresence: load account list")
|
|
||||||
accountRGListRaw, err := controller.decortAPICall("POST", accountListRGAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountRGListRaw), &accountRGList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountRGList, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountTemplatesListCheckPresence(d *schema.ResourceData, m interface{}) (AccountTemplatesList, error) {
|
|
||||||
accountTemplatesList := AccountTemplatesList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountTemplatesListCheckPresence: load")
|
|
||||||
accountTemplatesListRaw, err := controller.decortAPICall("POST", accountListTemplatesAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountTemplatesListRaw), &accountTemplatesList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountTemplatesList, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityAccountVinsListCheckPresence(d *schema.ResourceData, m interface{}) (AccountVinsList, error) {
|
|
||||||
accountVinsList := AccountVinsList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityAccountVinsListCheckPresence: load account list")
|
|
||||||
accountVinsListRaw, err := controller.decortAPICall("POST", accountListVinsAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(accountVinsListRaw), &accountVinsList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return accountVinsList, nil
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityBasicServiceDeletedListCheckPresence(d *schema.ResourceData, m interface{}) (BasicServiceList, error) {
|
|
||||||
basicServiceDeletedList := BasicServiceList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
if accountId, ok := d.GetOk("account_id"); ok {
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
|
||||||
}
|
|
||||||
if rgId, ok := d.GetOk("rg_id"); ok {
|
|
||||||
urlValues.Add("rgId", strconv.Itoa(rgId.(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("utilityBasicServiceDeletedListCheckPresence")
|
|
||||||
basicServiceDeletedListRaw, err := controller.decortAPICall("POST", bserviceListDeletedAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(basicServiceDeletedListRaw), &basicServiceDeletedList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return basicServiceDeletedList, nil
|
|
||||||
}
|
|
||||||
@@ -1,60 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityBasicServiceCheckPresence(d *schema.ResourceData, m interface{}) (*BasicServiceExtend, error) {
|
|
||||||
bservice := &BasicServiceExtend{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
if (strconv.Itoa(d.Get("service_id").(int))) != "0" {
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("serviceId", d.Id())
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityBasicServiceCheckPresence")
|
|
||||||
bserviceRaw, err := controller.decortAPICall("POST", bserviceGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(bserviceRaw), &bservice)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bservice, nil
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityBasicServiceGroupCheckPresence(d *schema.ResourceData, m interface{}) (*BasicServiceGroup, error) {
|
|
||||||
bserviceGroup := &BasicServiceGroup{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(d.Get("service_id").(int)))
|
|
||||||
if (strconv.Itoa(d.Get("compgroup_id").(int))) != "0" {
|
|
||||||
urlValues.Add("compgroupId", strconv.Itoa(d.Get("compgroup_id").(int)))
|
|
||||||
} else {
|
|
||||||
urlValues.Add("compgroupId", d.Id())
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityBasicServiceGroupCheckPresence")
|
|
||||||
bserviceGroupRaw, err := controller.decortAPICall("POST", bserviceGroupGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(bserviceGroupRaw), &bserviceGroup)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return bserviceGroup, nil
|
|
||||||
}
|
|
||||||
@@ -1,67 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityBasicServiceListCheckPresence(d *schema.ResourceData, m interface{}) (BasicServiceList, error) {
|
|
||||||
basicServiceList := BasicServiceList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
if accountId, ok := d.GetOk("account_id"); ok {
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
|
||||||
}
|
|
||||||
if rgId, ok := d.GetOk("rg_id"); ok {
|
|
||||||
urlValues.Add("rgId", strconv.Itoa(rgId.(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("utilityBasicServiceListCheckPresence")
|
|
||||||
basicServiceListRaw, err := controller.decortAPICall("POST", bserviceListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(basicServiceListRaw), &basicServiceList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return basicServiceList, nil
|
|
||||||
}
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityBasicServiceSnapshotListCheckPresence(d *schema.ResourceData, m interface{}) (BasicServiceSnapshots, error) {
|
|
||||||
basicServiceSnapshotList := BasicServiceSnapshots{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
if serviceId, ok := d.GetOk("service_id"); ok {
|
|
||||||
urlValues.Add("serviceId", strconv.Itoa(serviceId.(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityBasicServiceSnapshotListCheckPresence")
|
|
||||||
basicServiceSnapshotListRaw, err := controller.decortAPICall("POST", bserviceSnapshotListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(basicServiceSnapshotListRaw), &basicServiceSnapshotList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return basicServiceSnapshotList, nil
|
|
||||||
}
|
|
||||||
@@ -1,298 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
func (ctrl *ControllerCfg) utilityComputeExtraDisksConfigure(d *schema.ResourceData, do_delta bool) error {
|
|
||||||
// d is filled with data according to computeResource schema, so extra disks config is retrieved via "extra_disks" key
|
|
||||||
// If do_delta is true, this function will identify changes between new and existing specs for extra disks and try to
|
|
||||||
// update compute configuration accordingly
|
|
||||||
// Otherwise it will apply whatever is found in the new set of "extra_disks" right away.
|
|
||||||
// Primary use of do_delta=false is when calling this function from compute Create handler.
|
|
||||||
|
|
||||||
// Note that this function will not abort on API errors, but will continue to configure (attach / detach) other individual
|
|
||||||
// disks via atomic API calls. However, it will not retry failed manipulation on the same disk.
|
|
||||||
log.Debugf("utilityComputeExtraDisksConfigure: called for Compute ID %s with do_delta = %t", d.Id(), do_delta)
|
|
||||||
|
|
||||||
// NB: as of rc-1.25 "extra_disks" are TypeSet with the elem of TypeInt
|
|
||||||
old_set, new_set := d.GetChange("extra_disks")
|
|
||||||
|
|
||||||
apiErrCount := 0
|
|
||||||
var lastSavedError error
|
|
||||||
|
|
||||||
if !do_delta {
|
|
||||||
if new_set.(*schema.Set).Len() < 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, disk := range new_set.(*schema.Set).List() {
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("computeId", d.Id())
|
|
||||||
urlValues.Add("diskId", fmt.Sprintf("%d", disk.(int)))
|
|
||||||
_, err := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
// failed to attach extra disk - partial resource update
|
|
||||||
apiErrCount++
|
|
||||||
lastSavedError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if apiErrCount > 0 {
|
|
||||||
log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when attaching disks to Compute ID %s. Last error was: %s",
|
|
||||||
apiErrCount, d.Id(), lastSavedError)
|
|
||||||
return lastSavedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
|
|
||||||
log.Debugf("utilityComputeExtraDisksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
|
|
||||||
for _, diskId := range detach_set.List() {
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("computeId", d.Id())
|
|
||||||
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
|
||||||
_, err := ctrl.decortAPICall("POST", ComputeDiskDetachAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
// failed to detach disk - there will be partial resource update
|
|
||||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to detach disk ID %d from Compute ID %s: %s", diskId.(int), d.Id(), err)
|
|
||||||
apiErrCount++
|
|
||||||
lastSavedError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
|
|
||||||
log.Debugf("utilityComputeExtraDisksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
|
|
||||||
for _, diskId := range attach_set.List() {
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
urlValues.Add("computeId", d.Id())
|
|
||||||
urlValues.Add("diskId", fmt.Sprintf("%d", diskId.(int)))
|
|
||||||
_, err := ctrl.decortAPICall("POST", ComputeDiskAttachAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
// failed to attach disk - there will be partial resource update
|
|
||||||
log.Errorf("utilityComputeExtraDisksConfigure: failed to attach disk ID %d to Compute ID %s: %s", diskId.(int), d.Id(), err)
|
|
||||||
apiErrCount++
|
|
||||||
lastSavedError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if apiErrCount > 0 {
|
|
||||||
log.Errorf("utilityComputeExtraDisksConfigure: there were %d error(s) when managing disks of Compute ID %s. Last error was: %s",
|
|
||||||
apiErrCount, d.Id(), lastSavedError)
|
|
||||||
return lastSavedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ctrl *ControllerCfg) utilityComputeNetworksConfigure(d *schema.ResourceData, do_delta bool) error {
|
|
||||||
// "d" is filled with data according to computeResource schema, so extra networks config is retrieved via "network" key
|
|
||||||
// If do_delta is true, this function will identify changes between new and existing specs for network and try to
|
|
||||||
// update compute configuration accordingly
|
|
||||||
// Otherwise it will apply whatever is found in the new set of "network" right away.
|
|
||||||
// Primary use of do_delta=false is when calling this function from compute Create handler.
|
|
||||||
|
|
||||||
old_set, new_set := d.GetChange("network")
|
|
||||||
|
|
||||||
apiErrCount := 0
|
|
||||||
var lastSavedError error
|
|
||||||
|
|
||||||
if !do_delta {
|
|
||||||
if new_set.(*schema.Set).Len() < 1 {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, runner := range new_set.(*schema.Set).List() {
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
net_data := runner.(map[string]interface{})
|
|
||||||
urlValues.Add("computeId", d.Id())
|
|
||||||
urlValues.Add("netType", net_data["net_type"].(string))
|
|
||||||
urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
|
|
||||||
ipaddr, ipSet := net_data["ip_address"] // "ip_address" key is optional
|
|
||||||
if ipSet {
|
|
||||||
urlValues.Add("ipAddr", ipaddr.(string))
|
|
||||||
}
|
|
||||||
_, err := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
// failed to attach network - partial resource update
|
|
||||||
apiErrCount++
|
|
||||||
lastSavedError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if apiErrCount > 0 {
|
|
||||||
log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s",
|
|
||||||
apiErrCount, d.Id(), lastSavedError)
|
|
||||||
return lastSavedError
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
detach_set := old_set.(*schema.Set).Difference(new_set.(*schema.Set))
|
|
||||||
log.Debugf("utilityComputeNetworksConfigure: detach set has %d items for Compute ID %s", detach_set.Len(), d.Id())
|
|
||||||
for _, runner := range detach_set.List() {
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
net_data := runner.(map[string]interface{})
|
|
||||||
urlValues.Add("computeId", d.Id())
|
|
||||||
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
|
||||||
urlValues.Add("mac", net_data["mac"].(string))
|
|
||||||
_, err := ctrl.decortAPICall("POST", ComputeNetDetachAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
// failed to detach this network - there will be partial resource update
|
|
||||||
log.Errorf("utilityComputeNetworksConfigure: failed to detach net ID %d of type %s from Compute ID %s: %s",
|
|
||||||
net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err)
|
|
||||||
apiErrCount++
|
|
||||||
lastSavedError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
attach_set := new_set.(*schema.Set).Difference(old_set.(*schema.Set))
|
|
||||||
log.Debugf("utilityComputeNetworksConfigure: attach set has %d items for Compute ID %s", attach_set.Len(), d.Id())
|
|
||||||
for _, runner := range attach_set.List() {
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
net_data := runner.(map[string]interface{})
|
|
||||||
urlValues.Add("computeId", d.Id())
|
|
||||||
urlValues.Add("netId", fmt.Sprintf("%d", net_data["net_id"].(int)))
|
|
||||||
urlValues.Add("netType", net_data["net_type"].(string))
|
|
||||||
if net_data["ip_address"].(string) != "" {
|
|
||||||
urlValues.Add("ipAddr", net_data["ip_address"].(string))
|
|
||||||
}
|
|
||||||
_, err := ctrl.decortAPICall("POST", ComputeNetAttachAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
// failed to attach this network - there will be partial resource update
|
|
||||||
log.Errorf("utilityComputeNetworksConfigure: failed to attach net ID %d of type %s to Compute ID %s: %s",
|
|
||||||
net_data["net_id"].(int), net_data["net_type"].(string), d.Id(), err)
|
|
||||||
apiErrCount++
|
|
||||||
lastSavedError = err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if apiErrCount > 0 {
|
|
||||||
log.Errorf("utilityComputeNetworksConfigure: there were %d error(s) when managing networks of Compute ID %s. Last error was: %s",
|
|
||||||
apiErrCount, d.Id(), lastSavedError)
|
|
||||||
return lastSavedError
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func utilityComputeCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
|
||||||
// This function tries to locate Compute by one of the following approaches:
|
|
||||||
// - if compute_id is specified - locate by compute ID
|
|
||||||
// - if compute_name is specified - locate by a combination of compute name and resource
|
|
||||||
// group ID
|
|
||||||
//
|
|
||||||
// If succeeded, it returns non-empty string that contains JSON formatted facts about the
|
|
||||||
// Compute as returned by compute/get API call.
|
|
||||||
// Otherwise it returns empty string and meaningful error.
|
|
||||||
//
|
|
||||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
|
||||||
// method for resource's Exists method.
|
|
||||||
//
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
// make it possible to use "read" & "check presence" functions with compute ID set so
|
|
||||||
// that Import of Compute resource is possible
|
|
||||||
idSet := false
|
|
||||||
theId, err := strconv.Atoi(d.Id())
|
|
||||||
if err != nil || theId <= 0 {
|
|
||||||
computeId, argSet := d.GetOk("compute_id") // NB: compute_id is NOT present in computeResource schema!
|
|
||||||
if argSet {
|
|
||||||
theId = computeId.(int)
|
|
||||||
idSet = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
idSet = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if idSet {
|
|
||||||
// compute ID is specified, try to get compute instance straight by this ID
|
|
||||||
log.Debugf("utilityComputeCheckPresence: locating compute by its ID %d", theId)
|
|
||||||
urlValues.Add("computeId", fmt.Sprintf("%d", theId))
|
|
||||||
computeFacts, err := controller.decortAPICall("POST", ComputeGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return computeFacts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID was not set in the schema upon entering this function - work through Compute name
|
|
||||||
// and RG ID
|
|
||||||
computeName, argSet := d.GetOk("name")
|
|
||||||
if !argSet {
|
|
||||||
return "", fmt.Errorf("Cannot locate compute instance if name is empty and no compute ID specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
rgId, argSet := d.GetOk("rg_id")
|
|
||||||
if !argSet {
|
|
||||||
return "", fmt.Errorf("Cannot locate compute by name %s if no resource group ID is set", computeName.(string))
|
|
||||||
}
|
|
||||||
|
|
||||||
urlValues.Add("rgId", fmt.Sprintf("%d", rgId))
|
|
||||||
apiResp, err := controller.decortAPICall("POST", RgListComputesAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityComputeCheckPresence: ready to unmarshal string %s", apiResp)
|
|
||||||
|
|
||||||
computeList := RgListComputesResp{}
|
|
||||||
err = json.Unmarshal([]byte(apiResp), &computeList)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// log.Printf("%#v", computeList)
|
|
||||||
log.Debugf("utilityComputeCheckPresence: traversing decoded JSON of length %d", len(computeList))
|
|
||||||
for index, item := range computeList {
|
|
||||||
// need to match Compute by name, skip Computes with the same name in DESTROYED satus
|
|
||||||
if item.Name == computeName.(string) && item.Status != "DESTROYED" {
|
|
||||||
log.Debugf("utilityComputeCheckPresence: index %d, matched name %s", index, item.Name)
|
|
||||||
// we found the Compute we need - now get detailed information via compute/get API
|
|
||||||
cgetValues := &url.Values{}
|
|
||||||
cgetValues.Add("computeId", fmt.Sprintf("%d", item.ID))
|
|
||||||
apiResp, err = controller.decortAPICall("POST", ComputeGetAPI, cgetValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return apiResp, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", nil // there should be no error if Compute does not exist
|
|
||||||
}
|
|
||||||
@@ -1,137 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func utilityDiskCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
|
||||||
// This function tries to locate Disk by one of the following algorithms depending on
|
|
||||||
// the parameters passed:
|
|
||||||
// - if disk ID is specified -> by disk ID
|
|
||||||
// - if disk name is specifeid -> by disk name and either account ID or account name
|
|
||||||
//
|
|
||||||
// NOTE: disk names are not unique, so the first occurence of this name in the account will
|
|
||||||
// be returned. There is no such ambiguity when locating disk by its ID.
|
|
||||||
//
|
|
||||||
// If succeeded, it returns non empty string that contains JSON formatted facts about the disk
|
|
||||||
// as returned by disks/get API call.
|
|
||||||
// Otherwise it returns empty string and meaningful error.
|
|
||||||
//
|
|
||||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
|
||||||
// method for resource's Exists method.
|
|
||||||
//
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
// make it possible to use "read" & "check presence" functions with disk ID set so
|
|
||||||
// that Import of preexisting Disk resource is possible
|
|
||||||
idSet := false
|
|
||||||
theId, err := strconv.Atoi(d.Id())
|
|
||||||
if err != nil || theId <= 0 {
|
|
||||||
diskId, argSet := d.GetOk("disk_id")
|
|
||||||
if argSet {
|
|
||||||
theId = diskId.(int)
|
|
||||||
idSet = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
idSet = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if idSet {
|
|
||||||
// disk ID is specified, try to get disk instance straight by this ID
|
|
||||||
log.Debugf("utilityDiskCheckPresence: locating disk by its ID %d", theId)
|
|
||||||
urlValues.Add("diskId", fmt.Sprintf("%d", theId))
|
|
||||||
diskFacts, err := controller.decortAPICall("POST", DisksGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return diskFacts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID or disk_di was not set in the schema upon entering this function - rely on Disk name
|
|
||||||
// and Account ID to find the disk
|
|
||||||
diskName, argSet := d.GetOk("name")
|
|
||||||
if !argSet {
|
|
||||||
// no disk ID and no disk name - we cannot locate disk in this case
|
|
||||||
return "", fmt.Errorf("Cannot locate disk if name is empty and no disk ID specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid account ID is required to locate disks
|
|
||||||
// obtain Account ID by account name - it should not be zero on success
|
|
||||||
|
|
||||||
urlValues.Add("accountId", fmt.Sprintf("%d", d.Get("account_id").(int)))
|
|
||||||
diskFacts, err := controller.decortAPICall("POST", DisksListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityDiskCheckPresence: ready to unmarshal string %s", diskFacts)
|
|
||||||
|
|
||||||
disksList := DisksListResp{}
|
|
||||||
err = json.Unmarshal([]byte(diskFacts), &disksList)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
// log.Printf("%#v", vm_list)
|
|
||||||
log.Debugf("utilityDiskCheckPresence: traversing decoded JSON of length %d", len(disksList))
|
|
||||||
for index, item := range disksList {
|
|
||||||
// need to match disk by name, return the first match
|
|
||||||
if item.Name == diskName.(string) && item.Status != "DESTROYED" {
|
|
||||||
log.Debugf("utilityDiskCheckPresence: index %d, matched disk name %q", index, item.Name)
|
|
||||||
// we found the disk we need - not get detailed information via API call to disks/get
|
|
||||||
/*
|
|
||||||
// TODO: this may not be optimal as it initiates one extra call to the DECORT controller
|
|
||||||
// in spite of the fact that we already have all required information about the disk in
|
|
||||||
// item variable
|
|
||||||
//
|
|
||||||
get_urlValues := &url.Values{}
|
|
||||||
get_urlValues.Add("diskId", fmt.Sprintf("%d", item.ID))
|
|
||||||
diskFacts, err = controller.decortAPICall("POST", DisksGetAPI, get_urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return diskFacts, nil
|
|
||||||
*/
|
|
||||||
reencodedItem, err := json.Marshal(item)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return string(reencodedItem[:]), nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", nil // there should be no error if disk does not exist
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func utilityDiskListCheckPresence(d *schema.ResourceData, m interface{}) (DisksListResp, error) {
|
|
||||||
diskList := DisksListResp{}
|
|
||||||
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)))
|
|
||||||
}
|
|
||||||
if diskType, ok := d.GetOk("type"); ok {
|
|
||||||
urlValues.Add("type", strings.ToUpper(diskType.(string)))
|
|
||||||
}
|
|
||||||
if accountId, ok := d.GetOk("accountId"); ok {
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityDiskListCheckPresence: load grid list")
|
|
||||||
diskListRaw, err := controller.decortAPICall("POST", DisksListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(diskListRaw), &diskList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return diskList, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityExtnetCheckPresence(d *schema.ResourceData, m interface{}) (*ExtnetDetailed, error) {
|
|
||||||
extnet := &ExtnetDetailed{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("net_id", strconv.Itoa(d.Get("net_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityExtnetCheckPresence")
|
|
||||||
extnetRaw, err := controller.decortAPICall("POST", extnetGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(extnetRaw), &extnet)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return extnet, nil
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityExtnetComputesListCheckPresence(d *schema.ResourceData, m interface{}) (ExtnetComputesList, error) {
|
|
||||||
extnetComputesList := ExtnetComputesList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilityExtnetComputesListCheckPresence")
|
|
||||||
extnetComputesListRaw, err := controller.decortAPICall("POST", extnetListComputesAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(extnetComputesListRaw), &extnetComputesList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return extnetComputesList, nil
|
|
||||||
}
|
|
||||||
@@ -1,46 +0,0 @@
|
|||||||
/*
|
|
||||||
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 (
|
|
||||||
"net/url"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func utilityExtnetDefaultCheckPresence(_ *schema.ResourceData, m interface{}) (string, error) {
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
log.Debugf("utilityExtnetDefaultCheckPresence")
|
|
||||||
res, err := controller.decortAPICall("POST", extnetGetDefaultAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return res, nil
|
|
||||||
}
|
|
||||||
@@ -1,64 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityExtnetListCheckPresence(d *schema.ResourceData, m interface{}) (ExtnetList, error) {
|
|
||||||
extnetList := ExtnetList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
if accountId, ok := d.GetOk("account_id"); ok {
|
|
||||||
urlValues.Add("accountId", strconv.Itoa(accountId.(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("utilityExtnetListCheckPresence")
|
|
||||||
extnetListRaw, err := controller.decortAPICall("POST", extnetListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(extnetListRaw), &extnetList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return extnetList, nil
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
"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("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
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,62 +0,0 @@
|
|||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,56 +0,0 @@
|
|||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,66 +0,0 @@
|
|||||||
/*
|
|
||||||
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
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
|
||||||
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
var DefaultGridID int
|
|
||||||
|
|
||||||
func (controller *ControllerCfg) utilityLocationGetDefaultGridID() (int, error) {
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
log.Debug("utilityLocationGetDefaultGridID: retrieving locations list")
|
|
||||||
apiResp, err := controller.decortAPICall("POST", LocationsListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
locList := LocationsListResp{}
|
|
||||||
err = json.Unmarshal([]byte(apiResp), &locList)
|
|
||||||
if err != nil {
|
|
||||||
return 0, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(locList) == 0 {
|
|
||||||
DefaultGridID = 0
|
|
||||||
return 0, fmt.Errorf("utilityLocationGetDefaultGridID: retrieved 0 length locations list")
|
|
||||||
}
|
|
||||||
|
|
||||||
DefaultGridID = locList[0].GridID
|
|
||||||
log.Debugf("utilityLocationGetDefaultGridID: default location GridID %d, name %s", DefaultGridID, locList[0].Name)
|
|
||||||
|
|
||||||
return DefaultGridID, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityPcideviceCheckPresence(d *schema.ResourceData, m interface{}) (*Pcidevice, error) {
|
|
||||||
pcideviceList, err := utilityPcideviceListCheckPresence(d, m)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
pcideviceId := 0
|
|
||||||
if (d.Get("device_id").(int)) != 0 {
|
|
||||||
pcideviceId = d.Get("device_id").(int)
|
|
||||||
} else {
|
|
||||||
id, _ := strconv.Atoi(d.Id())
|
|
||||||
pcideviceId = id
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pd := range pcideviceList {
|
|
||||||
if pd.ID == pcideviceId {
|
|
||||||
return &pd, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
@@ -1,50 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func utilityPcideviceListCheckPresence(_ *schema.ResourceData, m interface{}) (PcideviceList, error) {
|
|
||||||
pcideviceList := PcideviceList{}
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
pcideviceListRaw, err := controller.decortAPICall("POST", pcideviceListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(pcideviceListRaw), &pcideviceList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return pcideviceList, nil
|
|
||||||
}
|
|
||||||
@@ -1,68 +0,0 @@
|
|||||||
/*
|
|
||||||
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
|
|
||||||
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
|
|
||||||
|
|
||||||
Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
you may not use this file except in compliance with the License.
|
|
||||||
You may obtain a copy of the License at
|
|
||||||
|
|
||||||
http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
|
|
||||||
Unless required by applicable law or agreed to in writing, software
|
|
||||||
distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
See the License for the specific language governing permissions and
|
|
||||||
limitations under the License.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func utilityPfwCheckPresence(d *schema.ResourceData, m interface{}) (*PfwRecord, error) {
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
|
|
||||||
resp, err := controller.decortAPICall("POST", ComputePfwListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp == "" {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
idS := strings.Split(d.Id(), "-")[1]
|
|
||||||
id, err := strconv.Atoi(idS)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var pfws []PfwRecord
|
|
||||||
if err := json.Unmarshal([]byte(resp), &pfws); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, pfw := range pfws {
|
|
||||||
if pfw.ID == id {
|
|
||||||
return &pfw, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
@@ -1,131 +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.
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
|
|
||||||
Technology platfom.
|
|
||||||
|
|
||||||
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package decort
|
|
||||||
|
|
||||||
import (
|
|
||||||
"encoding/json"
|
|
||||||
"fmt"
|
|
||||||
"net/url"
|
|
||||||
"strconv"
|
|
||||||
|
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
// "github.com/hashicorp/terraform-plugin-sdk/helper/validation"
|
|
||||||
)
|
|
||||||
|
|
||||||
// On success this function returns a string, as returned by API rg/get, which could be unmarshalled
|
|
||||||
// into ResgroupGetResp structure
|
|
||||||
func utilityResgroupCheckPresence(d *schema.ResourceData, m interface{}) (string, error) {
|
|
||||||
// This function tries to locate resource group by one of the following algorithms depending
|
|
||||||
// on the parameters passed:
|
|
||||||
// - if resource group ID is specified -> by RG ID
|
|
||||||
// - if resource group name is specifeid -> by RG name and either account ID or account name
|
|
||||||
//
|
|
||||||
// If succeeded, it returns non empty string that contains JSON formatted facts about the
|
|
||||||
// resource group as returned by rg/get API call.
|
|
||||||
// Otherwise it returns empty string and a meaningful error.
|
|
||||||
//
|
|
||||||
// NOTE: As our provider always deletes RGs permanently, there is no "restore" method and
|
|
||||||
// consequently we are not interested in matching RGs in DELETED state. Hence, we call
|
|
||||||
// .../rg/list API with includedeleted=false
|
|
||||||
//
|
|
||||||
// This function does not modify its ResourceData argument, so it is safe to use it as core
|
|
||||||
// method for the Terraform resource Exists method.
|
|
||||||
//
|
|
||||||
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
// make it possible to use "read" & "check presence" functions with RG ID set so
|
|
||||||
// that Import of RG resource is possible
|
|
||||||
idSet := false
|
|
||||||
theId, err := strconv.Atoi(d.Id())
|
|
||||||
if err != nil || theId <= 0 {
|
|
||||||
rgId, argSet := d.GetOk("rg_id")
|
|
||||||
if argSet {
|
|
||||||
theId = rgId.(int)
|
|
||||||
idSet = true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
idSet = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if idSet {
|
|
||||||
// go straight for the RG by its ID
|
|
||||||
log.Debugf("utilityResgroupCheckPresence: locating RG by its ID %d", theId)
|
|
||||||
urlValues.Add("rgId", fmt.Sprintf("%d", theId))
|
|
||||||
rgFacts, err := controller.decortAPICall("POST", ResgroupGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
return rgFacts, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
rgName, argSet := d.GetOk("name")
|
|
||||||
if !argSet {
|
|
||||||
// no RG ID and no RG name - we cannot locate resource group in this case
|
|
||||||
return "", fmt.Errorf("Cannot check resource group presence if name is empty and no resource group ID specified")
|
|
||||||
}
|
|
||||||
|
|
||||||
// Valid account ID is required to locate a resource group
|
|
||||||
// obtain Account ID by account name - it should not be zero on success
|
|
||||||
|
|
||||||
urlValues.Add("includedeleted", "false")
|
|
||||||
apiResp, err := controller.decortAPICall("POST", ResgroupListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
// log.Debugf("%s", apiResp)
|
|
||||||
log.Debugf("utilityResgroupCheckPresence: ready to decode response body from %s", ResgroupListAPI)
|
|
||||||
model := ResgroupListResp{}
|
|
||||||
err = json.Unmarshal([]byte(apiResp), &model)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityResgroupCheckPresence: traversing decoded Json of length %d", len(model))
|
|
||||||
for index, item := range model {
|
|
||||||
// match by RG name & account ID
|
|
||||||
if item.Name == rgName.(string) && item.AccountID == d.Get("account_id").(int) {
|
|
||||||
log.Debugf("utilityResgroupCheckPresence: match RG name %s / ID %d, account ID %d at index %d",
|
|
||||||
item.Name, item.ID, item.AccountID, index)
|
|
||||||
|
|
||||||
// not all required information is returned by rg/list API, so we need to initiate one more
|
|
||||||
// call to rg/get to obtain extra data to complete Resource population.
|
|
||||||
// Namely, we need resource quota settings
|
|
||||||
reqValues := &url.Values{}
|
|
||||||
reqValues.Add("rgId", fmt.Sprintf("%d", item.ID))
|
|
||||||
apiResp, err := controller.decortAPICall("POST", ResgroupGetAPI, reqValues)
|
|
||||||
if err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return apiResp, nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return "", fmt.Errorf("Cannot find RG name %s owned by account ID %d", rgName, d.Get("account_id").(int))
|
|
||||||
}
|
|
||||||
@@ -1,65 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilityRgListCheckPresence(d *schema.ResourceData, m interface{}) (ResgroupListResp, error) {
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
rgList := ResgroupListResp{}
|
|
||||||
|
|
||||||
if size, ok := d.GetOk("size"); ok {
|
|
||||||
urlValues.Add("size", strconv.Itoa(size.(int)))
|
|
||||||
}
|
|
||||||
if page, ok := d.GetOk("page"); ok {
|
|
||||||
urlValues.Add("page", strconv.Itoa(page.(int)))
|
|
||||||
}
|
|
||||||
if includedeleted, ok := d.GetOk("includedeleted"); ok {
|
|
||||||
urlValues.Add("includedeleted", strconv.FormatBool(includedeleted.(bool)))
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilityRgListCheckPresence: load rg list")
|
|
||||||
rgListRaw, err := controller.decortAPICall("POST", ResgroupListAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(rgListRaw), &rgList)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return rgList, nil
|
|
||||||
}
|
|
||||||
@@ -1,61 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilitySepCheckPresence(d *schema.ResourceData, m interface{}) (*Sep, error) {
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
sep := &Sep{}
|
|
||||||
|
|
||||||
if d.Get("sep_id").(int) == 0 {
|
|
||||||
urlValues.Add("sep_id", d.Id())
|
|
||||||
} else {
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Debugf("utilitySepCheckPresence: load sep")
|
|
||||||
sepRaw, err := controller.decortAPICall("POST", sepGetAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(sepRaw), sep)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return sep, nil
|
|
||||||
}
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
/*
|
|
||||||
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 utilitySepConfigCheckPresence(d *schema.ResourceData, m interface{}) (SepConfig, error) {
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
sepConfig := SepConfig{}
|
|
||||||
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
|
|
||||||
log.Debugf("utilitySepConfigCheckPresence: load sep config")
|
|
||||||
sepConfigRaw, err := controller.decortAPICall("POST", sepGetConfigAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(sepConfigRaw), &sepConfig)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return sepConfig, nil
|
|
||||||
}
|
|
||||||
@@ -1,54 +0,0 @@
|
|||||||
/*
|
|
||||||
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"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
|
||||||
)
|
|
||||||
|
|
||||||
func utilitySepConsumptionCheckPresence(d *schema.ResourceData, m interface{}) (*SepConsumption, error) {
|
|
||||||
controller := m.(*ControllerCfg)
|
|
||||||
urlValues := &url.Values{}
|
|
||||||
|
|
||||||
sepCons := &SepConsumption{}
|
|
||||||
|
|
||||||
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
|
|
||||||
|
|
||||||
sepConsRaw, err := controller.decortAPICall("POST", sepConsumptionAPI, urlValues)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
err = json.Unmarshal([]byte(sepConsRaw), sepCons)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return sepCons, nil
|
|
||||||
}
|
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user