Compare commits

...

50 Commits

Author SHA1 Message Date
kjubybot
ffbcce9897 updated changelog, enabled experimental features in depchek; v2.2.0 ready 2022-05-13 16:33:24 +03:00
kjubybot
efe79ee85a disabled depcheck database update 2022-05-13 13:46:14 +03:00
stSolo
42c91e1549 Add sample for vgpu data, edit readme files 2022-05-05 11:26:12 +03:00
Petr Krutov
6bc61fb856 Merge branch 'fix/rg_quotas' into '2.2'
fixed rg recreation when quota is not specified

See merge request rudecs/terraform-provider-decort!9
2022-05-05 11:09:24 +03:00
Petr Krutov
dbf61d4da1 Merge branch 'feature/vgpu-datasource' into '2.2'
added vgpu datasource

See merge request rudecs/terraform-provider-decort!8
2022-05-05 11:06:14 +03:00
Petr Krutov
c5953387ae Merge branch '2.2' into 'feature/vgpu-datasource'
# Conflicts:
#   decort/models_api.go
#   decort/provider.go
2022-05-05 11:05:39 +03:00
Petr Krutov
bc6789f755 Merge branch '2.2/feature/pcidevice' into '2.1'
2.2/feature/pcidevice

See merge request rudecs/terraform-provider-decort!5
2022-05-05 10:59:47 +03:00
Petr Krutov
0aee28ed2e Merge branch '2.1' into '2.2/feature/pcidevice'
# Conflicts:
#   README.md
#   README_EN.md
#   decort/models_api.go
#   decort/provider.go
#   samples/README.md
2022-05-05 10:58:58 +03:00
Petr Krutov
98c4dfe0af Merge branch '2.2/feature/sep' into '2.1'
2.2/feature/sep

See merge request rudecs/terraform-provider-decort!6
2022-05-05 10:52:37 +03:00
stSolo
0fd620eeff Fix pcidevice sample 2022-05-05 10:27:12 +03:00
stSolo
2f2fa2a544 Add resource, data, samples 2022-05-04 20:56:56 +03:00
stSolo
9af980964a Add all data and des resource 2022-04-25 12:52:38 +03:00
stSolo
c110239225 Add models, data source 2022-04-12 14:59:34 +03:00
kjubybot
413fb4b82b fixed rg recreation when quota is not specified 2022-04-11 14:07:50 +03:00
kjubybot
b2e1004dbe added vgpu datasource 2022-04-08 12:34:27 +03:00
stSolo
594c876364 Add pcidevice resource, data 2022-04-07 16:39:08 +03:00
kjubybot
8a716edac3 updated changelog 2022-04-04 12:33:50 +03:00
kjubybot
cda317f4db updated docs 2022-04-04 12:28:54 +03:00
kjubybot
299d606df0 added Jenkinsfile and sonar-project.properties for SAST analysis 2022-04-04 12:19:40 +03:00
stSolo
3cd8c2e618 Rename data_snapshot_list => data_source_snapshot_list 2022-03-30 20:01:31 +03:00
stSolo
efea1af92a Update readme files 2022-03-30 19:22:03 +03:00
Petr Krutov
77d8d2e921 Merge branch 'feature/k8s_extnet' into '2.1'
added extnet_id parameter to k8s; added read-only parameter lb_ip to k8s

See merge request rudecs/terraform-provider-decort!4
2022-03-30 17:20:54 +03:00
Petr Krutov
f1ec6d776a Merge branch 'feature/retry_on_fail' into '2.1'
controller: added request retry on 500

See merge request rudecs/terraform-provider-decort!3
2022-03-30 17:19:58 +03:00
Petr Krutov
ff64840b13 Merge branch 'features/snapshot' into '2.1'
Features/snapshot

See merge request rudecs/terraform-provider-decort!2
2022-03-30 17:13:16 +03:00
Stanislav Solovev
13e6849328 Features/snapshot 2022-03-30 17:13:16 +03:00
kjubybot
964e85c34a controller: added request retry on 500 2022-03-30 09:33:34 +03:00
kjubybot
92d96b13c6 added extnet_id parameter to k8s; added read-only parameter lb_ip to k8s 2022-03-29 17:58:58 +03:00
kjubybot
94f222fe19 k8s: fixed state import; k8s, k8s_wg: increased create/update timeouts 2022-03-29 17:45:59 +03:00
kjubybot
a3da44f2ad k8s, k8s_wg: single worker add/delete support; github actions support 2022-03-28 16:05:29 +03:00
stSolo
ef7fa62e79 Fix README files 2022-03-25 18:48:03 +03:00
stSolo
4bb75fe0d7 Add samples for k8s, k8s_wg, edit README files 2022-03-25 18:45:37 +03:00
kjubybot
8cf4680ce1 Fixed kubeconfig reading 2022-03-23 11:46:38 +03:00
kjubybot
bf1afc66dd Fixed asyncs tasks parsing; Applied k8s API changes; Updated docs 2022-03-23 11:40:51 +03:00
stSolo
d9c10c0d9c Add samples repo, rename README.md to README_EN.md, add README.md (RU Version), update README files 2022-03-22 19:16:16 +03:00
stSolo
f28588fea5 Add samples repo, rename README.md to README_EN.md, add README.md (RU Version), update README files 2022-03-22 19:12:03 +03:00
Petr Krutov
3e72f72d15 Merge branch 'feature/implement_resource_images' into '1.26'
Feature/implement resource images

See merge request rudecs/terraform-provider-decort!1
2022-03-22 11:44:51 +03:00
stSolo
bf179b9d12 Add some resources and data-resources, fix bugs 2022-03-18 20:49:16 +03:00
stSolo
9379289e58 Fix bugs, add grid, grid list, image, image list data 2022-03-10 20:19:56 +03:00
stSolo
edf7728cb5 Implement images resource 2022-03-05 12:31:51 +03:00
kjubybot
95cd7cb820 fixed pfw deletion 2022-02-07 12:19:21 +03:00
kjubybot
06c0578fa6 Merge branch 'rc-1.25' into 1.26 2022-02-07 12:14:31 +03:00
kjubybot
1bf17c23c8 updated id computation for pfw 2022-02-07 12:14:16 +03:00
kjubybot
668d57cd3b updated docs for pfw and kvmvm 2022-02-07 11:50:42 +03:00
kjubybot
fef6040cc6 k8s, k8s_wg resources 2022-02-03 15:20:12 +03:00
kjubybot
d0165918c3 Merge branch 'rc-1.25' into 1.26 2022-02-02 16:30:14 +03:00
kjubybot
dfeb9a9165 compute os_users parsing fix; driver field fix in compute datasource 2022-02-02 16:14:32 +03:00
kjubybot
e0dcd053c5 kubernetes resource (currently broken) 2022-02-02 15:58:20 +03:00
kjubybot
ab070b73cb docs and timeouts for pfw 2022-01-31 11:32:25 +03:00
kjubybot
80a4b70db8 added port forwarding resource 2022-01-27 17:51:44 +03:00
kjubybot
28db919ffa Fixed JSON parsing 2022-01-14 18:04:31 +03:00
104 changed files with 10548 additions and 295 deletions

37
.github/workflows/release.yml vendored Normal file
View File

@@ -0,0 +1,37 @@
name: Release to registry
on:
push:
tags:
- 'v*'
jobs:
release:
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v3
with:
fetch-depth: 0
- name: Fetch all tags
run: git fetch --force --tags
- name: Setup Go
uses: actions/setup-go@v2
with:
go-version: 1.17
- name: Import GPG key
id: import_gpg
uses: crazy-max/ghaction-import-gpg@v4
with:
gpg_private_key: ${{ secrets.GPG_PRIVATE_KEY }}
passphrase: ${{ secrets.PASSPHRASE }}
- name: Run GoReleaser
uses: goreleaser/goreleaser-action@v2
with:
args: release --rm-dist --release-notes CHANGELOG.md
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
GPG_FINGERPRINT: ${{ steps.import_gpg.outputs.fingerprint }}

2
.gitignore vendored
View File

@@ -1,2 +1,4 @@
decort/vendor/
examples/
url_scrapping/
terraform-provider-decort*

View File

@@ -1,14 +1,8 @@
# Visit https://goreleaser.com for documentation on how to customize this
# behavior.
before:
hooks:
# this is just an example and not a requirement for provider building/publishing
- go mod tidy
builds:
- env:
# goreleaser does not work with CGO, it could also complicate
# usage by users in CI/CD systems like Terraform Cloud where
# they are unable to install libraries.
- CGO_ENABLED=0
mod_timestamp: '{{ .CommitTimestamp }}'
flags:
@@ -37,11 +31,9 @@ checksum:
signs:
- artifacts: checksum
args:
# if you are using this in a GitHub action or some other automated pipeline, you
# need to pass the batch flag to indicate its not interactive.
- "--batch"
- "--local-user"
- "{{ .Env.GPG_FINGERPRINT }}" # set this environment variable for your signing key
- "{{ .Env.GPG_FINGERPRINT }}"
- "--output"
- "${signature}"
- "--detach-sign"
@@ -50,7 +42,5 @@ release:
extra_files:
- glob: 'terraform-registry-manifest.json'
name_template: '{{ .ProjectName }}_{{ .Version }}_manifest.json'
# If you want to manually examine the release before its live, uncomment this line:
# draft: true
changelog:
skip: true
skip: false

18
CHANGELOG.md Normal file
View File

@@ -0,0 +1,18 @@
### Bug fixes
- resgroup recreation if quotas unspecified
### New datasources
- vgpu
- pcidevice\_list
- pcidevice
- sep
- sep\_list
- sep\_disk\_list
- sep\_config
- sep\_pool
- sep\_consumption
### New resources
- pcidevice
- sep
- sep\_config

50
Jenkinsfile-sast Normal file
View File

@@ -0,0 +1,50 @@
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'
dependencyCheck additionalArguments: '-f JSON -f HTML -n --enableExperimental\
--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'
}
}
}
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
}
}
}
}

39
Makefile Normal file
View File

@@ -0,0 +1,39 @@
TEST?=$$(go list ./... | grep -v 'vendor')
HOSTNAME=digitalenergy.online
NAMESPACE=decort
NAME=terraform-provider-decort
#BINARY=terraform-provider-${NAME}
BINARY=${NAME}.exe
VERSION=0.2
#OS_ARCH=darwin_amd64
OS_ARCH=windows_amd64
default: install
build:
go build -o ${BINARY}
release:
GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64
GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386
GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64
GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm
GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386
GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64
GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm
GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386
GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64
GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64
GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386
GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64
install: build
mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH}
mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH}
test:
go test -i $(TEST) || exit 1
echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4
testacc:
TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m

149
README.md
View File

@@ -1,55 +1,120 @@
# terraform-provider-decort
Terraform provider for Digital Energy Cloud Orchestration Technology (DECORT) platform
Terraform provider для платформы Digital Energy Cloud Orchestration Technology (DECORT)
NOTE: provider rc-1.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)
Внимание: провайдер версии rc-1.25 разработан для DECORT API 3.7.x.
Для более старых версий можно использовать:
- DECORT API 3.6.x - версия провайдера rc-1.10
- DECORT API до 3.6.0 - terraform DECS provider (https://github.com/rudecs/terraform-provider-decs)
With this provider you can manage Compute instances, disks, virtual network segments and resource
groups in DECORT platform, as well as query the platform for information about existing resources.
This provider supports Import operations on pre-existing resources.
## Возможности провайдера
- Работа с Compute instances,
- Работа с disks,
- Работа с k8s,
- Работа с image,
- Работа с reource groups,
- Работа с VINS,
- Работа с pfw,
- Работа с accounts,
- Работа с snapshots,
- Работа с pcidevice,
- Работа с sep,
- Работа с vgpu.
See user guide at https://github.com/rudecs/terraform-provider-decort/wiki
Вики проекта: https://github.com/rudecs/terraform-provider-decort/wiki
For a quick start follow these steps (assuming that your build host is running Linux; this provider builds on Windows as well, however, some paths may differ from what is mentioned below).
## Начало
Старт возможен по двум путям:
1. Установка через собранные пакеты.
2. Ручная установка.
1. Obtain the latest GO compiler. As of beginning 2021 it is recommended to use v.1.16.3 but as new Terraform versions are released newer Go compiler may be required, so check official Terraform repository regularly for more information.
### Установка через собранные пакеты.
1. Скачайте и установите terraform по ссылке: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
2. Создайте файл `main.tf` и добавьте в него следующий блок.
```terraform
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
```
cd /tmp
wget https://golang.org/dl/go1.16.3.linux-amd64.tar.gz
tar xvf ./go1.16.3.linux-amd64.tar.gz
sudo mv go /usr/local
3. Выполните команду
```
terraform init
```
Провайдер автоматически будет установлен на ваш компьютер из terraform registry.
### Ручная установка
1. Скачайте и установите Go по ссылке: https://go.dev/dl/
2. Скачайте и установите terraform по ссылке: https://learn.hashicorp.com/tutorials/terraform/install-cli?in=terraform/aws-get-started
3. Склонируйте репозиторий с провайдером, выполнив команду:
```bash
git clone https://github.com/rudecs/terraform-provider-decort.git
```
4. Перейдите в скачанную папку с провайдером и выполните команду
```bash
go build -o terraform-provider-decort
```
Если вы знаете как устроен _makefile_, то можно изменить в файле `Makefile` параметры под вашу ОС и выполнить команду
```bash
make build
```
5. Полученный файл необходимо поместить:
Linux:
```bash
~/.terraform.d/plugins/${host_name}/${namespace}/${type}/${version}/${target}
```
Windows:
```powershell
%APPDATA%\terraform.d\plugins\${host_name}\${namespace}\${type}\${version}\${target}
```
ВНИМАНИЕ: для ОС Windows `%APP_DATA%` является каталогом, в котором будут помещены будущие файлы terraform.
Где:
- host_name - имя хоста, держателя провайдера, например, digitalenergy.online
- namespace - пространство имен хоста, например decort
- type - тип провайдера, может совпадать с пространством имен, например, decort
- version - версия провайдера, например 1.2
- target - версия ОС, например windows_amd64
6. После этого, создайте файл `main.tf`.
7. Добавьте в него следующий блок
```terraform
terraform {
required_providers {
decort = {
version = "1.2"
source = "digitalenergy.online/decort/decort"
}
}
}
```
В поле `version` указывается версия провайдера.
Обязательный параметр
Тип поля - строка
ВНИМАНИЕ: Версии в блоке и в репозитории, в который был помещен провайдер должны совпадать!
В поле `source` помещается путь до репозитория с версией вида:
```bash
${host_name}/${namespace}/${type}
```
ВНИМАНИЕ: все параметры должны совпадать с путем репозитория, в котором помещен провайдер.
8. В консоле выполнить команду
```bash
terraform init
```
2. Add the following environment variables' declarations to shell startup script:
```
export GOPATH=/opt/gopkg:~/
export GOROOT=/usr/local/go
export PATH=$PATH:$GOROOT/bin
```
9. Если все прошло хорошо - ошибок не будет.
3. Clone Terraform Plugin SDK framework repository to $GOPKG/src/github.com/hashicorp
```
mkdir -p $GOPKG/src/github.com/hashicorp
cd $GOPKG/src/github.com/hashicorp
git clone https://github.com/hashicorp/terraform-plugin-sdk.git
```
Более подробно о сборке провайдера можно найти по ссылке: https://learn.hashicorp.com/tutorials/terraform/provider-use?in=terraform/providers
4. Clone jwt-go package repository to $GOPKG/src/github.com/dgrijalva/jwt-go:
```
mkdir -p $GOPKG/src/github.com/dgrijalva
cd $GOPKG/src/github.com/dgrijalva
git clone https://github.com/dgrijalva/jwt-go.git
```
## Примеры работы
Примеры работы можно найти:
- На вики проекта: https://github.com/rudecs/terraform-provider-decort/wiki
- В папке `samples`
5. Clone Terraform DECORT provider repository to $GOPKG/src/github.com/terraform-provider-decort
```
cd $GOPKG/src/github.com
git clone https://github.com/rudecs/terraform-provider-decort.git
```
Схемы к terraform'у доступны:
- В папке `docs`
6. Build Terraform DECORT provider:
```
cd $GOPKG/src/github.com/terraform-provider-decort
go build -o terraform-provider-decort
```
Хорошей работы!

121
README_EN.md Normal file
View File

@@ -0,0 +1,121 @@
# 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.
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!

View File

@@ -16,24 +16,26 @@ limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"bytes"
"crypto/tls"
"errors"
"fmt"
"io/ioutil"
"net/http"
"net/url"
"strconv"
"strings"
"time"
// "time"
log "github.com/sirupsen/logrus"
@@ -42,42 +44,41 @@ import (
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
// "github.com/hashicorp/terraform-plugin-sdk/terraform"
)
// enumerated constants that define authentication modes
// enumerated constants that define authentication modes
const (
MODE_UNDEF = iota // this is the invalid mode - it should never be seen
MODE_LEGACY = iota
MODE_OAUTH2 = iota
MODE_JWT = iota
MODE_UNDEF = iota // this is the invalid mode - it should never be seen
MODE_LEGACY = iota
MODE_OAUTH2 = iota
MODE_JWT = iota
)
type ControllerCfg struct {
controller_url string // always required
auth_mode_code int // always required
auth_mode_txt string // always required, it is a text representation of auth mode
legacy_user string // required for legacy mode
legacy_password string // required for legacy mode
legacy_sid string // obtained from DECORT controller on successful login in legacy mode
jwt string // obtained from Outh2 provider on successful login in oauth2 mode, required in jwt mode
app_id string // required for oauth2 mode
app_secret string // required for oauth2 mode
oauth2_url string // always required
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
cc_client *http.Client // assigned when all initial checks successfully passed
controller_url string // always required
auth_mode_code int // always required
auth_mode_txt string // always required, it is a text representation of auth mode
legacy_user string // required for legacy mode
legacy_password string // required for legacy mode
legacy_sid string // obtained from DECORT controller on successful login in legacy mode
jwt string // obtained from Outh2 provider on successful login in oauth2 mode, required in jwt mode
app_id string // required for oauth2 mode
app_secret string // required for oauth2 mode
oauth2_url string // always required
decort_username string // assigned to either legacy_user (legacy mode) or Oauth2 user (oauth2 mode) upon successful verification
cc_client *http.Client // assigned when all initial checks successfully passed
}
func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
// This function first will check that all required provider parameters for the
// This function first will check that all required provider parameters for the
// selected authenticator mode are set correctly and initialize ControllerCfg structure
// based on the provided parameters.
//
// Next, it will check for validity of supplied credentials by initiating connection to the specified
// DECORT controller URL and, if succeeded, completes ControllerCfg structure with the rest of computed
// Next, it will check for validity of supplied credentials by initiating connection to the specified
// DECORT controller URL and, if succeeded, completes ControllerCfg structure with the rest of computed
// parameters (e.g. JWT, session ID and Oauth2 user name).
//
// The structure created by this function should be used with subsequent calls to decortAPICall() method,
// The structure created by this function should be used with subsequent calls to decortAPICall() method,
// which is a DECORT authentication mode aware wrapper around standard HTTP requests.
ret_config := &ControllerCfg{
@@ -90,7 +91,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
app_id: d.Get("app_id").(string),
app_secret: d.Get("app_secret").(string),
oauth2_url: d.Get("oauth2_url").(string),
decort_username: "",
decort_username: "",
}
var allow_unverified_ssl bool
@@ -137,10 +138,10 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
if allow_unverified_ssl {
log.Warn("ControllerConfigure: allow_unverified_ssl is set - will not check certificates!")
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true},}
transCfg := &http.Transport{TLSClientConfig: &tls.Config{InsecureSkipVerify: true}}
ret_config.cc_client = &http.Client{
Transport: transCfg,
Timeout: Timeout180s,
Timeout: Timeout180s,
}
} else {
ret_config.cc_client = &http.Client{
@@ -150,7 +151,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
switch ret_config.auth_mode_code {
case MODE_LEGACY:
ok, err := ret_config.validateLegacyUser()
ok, err := ret_config.validateLegacyUser()
if !ok {
return nil, err
}
@@ -162,13 +163,13 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
return nil, err
}
case MODE_OAUTH2:
// on success getOAuth2JWT will set config.jwt to the obtained JWT, so there is no
// on success getOAuth2JWT will set config.jwt to the obtained JWT, so there is no
// need to set it once again here
_, err := ret_config.getOAuth2JWT()
if err != nil {
return nil, err
}
// we are not verifying the JWT when parsing because actual verification is done on the
// we are not verifying the JWT when parsing because actual verification is done on the
// OVC controller side. Here we do parsing solely to extract Oauth2 user name (claim "user")
// and JWT issuer name (claim "iss")
parser := jwt.Parser{}
@@ -181,7 +182,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
tbuf.WriteString(claims["username"].(string))
tbuf.WriteString("@")
tbuf.WriteString(claims["iss"].(string))
ret_config.decort_username = tbuf.String()
ret_config.decort_username = tbuf.String()
} else {
return nil, fmt.Errorf("Failed to extract user and iss fields from JWT token in oauth2 mode.")
}
@@ -195,7 +196,7 @@ func ControllerConfigure(d *schema.ResourceData) (*ControllerCfg, error) {
return ret_config, nil
}
func (config *ControllerCfg) getDecortUsername() (string) {
func (config *ControllerCfg) getDecortUsername() string {
return config.decort_username
}
@@ -216,14 +217,14 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
params.Add("validity", "3600")
params_str := params.Encode()
req, err := http.NewRequest("POST", config.oauth2_url + "/v1/oauth/access_token", strings.NewReader(params_str))
req, err := http.NewRequest("POST", config.oauth2_url+"/v1/oauth/access_token", strings.NewReader(params_str))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
resp, err := config.cc_client.Do(req)
resp, err := config.cc_client.Do(req)
if err != nil {
return "", err
}
@@ -231,16 +232,16 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
// fmt.Println("response Status:", resp.Status)
// fmt.Println("response Headers:", resp.Header)
// fmt.Println("response Headers:", req.URL)
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
resp.StatusCode, req.URL, config.app_id, params_str)
return "", fmt.Errorf("getOauth2JWT: unexpected status code %d when obtaining JWT from %q for APP_ID %q, request Body %q",
resp.StatusCode, req.URL, config.app_id, params_str)
}
defer resp.Body.Close()
responseData, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", err
}
if err != nil {
return "", err
}
// validation successful - store JWT in the corresponding field of the ControllerCfg structure
config.jwt = strings.TrimSpace(string(responseData))
@@ -249,10 +250,10 @@ func (config *ControllerCfg) getOAuth2JWT() (string, error) {
func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
/*
Validate JWT against DECORT controller. JWT can be supplied as argument to this method. If empty string supplied as
argument, JWT will be taken from config attribute.
DECORT controller URL will always be taken from the config attribute assigned at instantiation.
Validation is accomplished by attempting API call that lists accounts for the invoking user.
Validate JWT against DECORT controller. JWT can be supplied as argument to this method. If empty string supplied as
argument, JWT will be taken from config attribute.
DECORT controller URL will always be taken from the config attribute assigned at instantiation.
Validation is accomplished by attempting API call that lists accounts for the invoking user.
*/
if jwt == "" {
if config.jwt == "" {
@@ -265,7 +266,7 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
return false, fmt.Errorf("validateJWT method called, but no OAuth2 URL provided.")
}
req, err := http.NewRequest("POST", config.controller_url + "/restmachine/cloudapi/accounts/list", nil)
req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/accounts/list", nil)
if err != nil {
return false, err
}
@@ -273,14 +274,14 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", jwt))
// req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
// req.Header.Set("Content-Length", strconv.Itoa(0))
resp, err := config.cc_client.Do(req)
resp, err := config.cc_client.Do(req)
if err != nil {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q.",
resp.StatusCode, req.URL)
return false, fmt.Errorf("validateJWT: unexpected status code %d when validating JWT against %q.",
resp.StatusCode, req.URL)
}
defer resp.Body.Close()
@@ -289,10 +290,10 @@ func (config *ControllerCfg) validateJWT(jwt string) (bool, error) {
func (config *ControllerCfg) validateLegacyUser() (bool, error) {
/*
Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls
to DECORT controller.
If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any
reason, the method will return false and error.
Validate legacy user by obtaining a session key, which will be used for authenticating subsequent API calls
to DECORT controller.
If successful, the session key is stored in config.legacy_sid and true is returned. If unsuccessful for any
reason, the method will return false and error.
*/
if config.auth_mode_code == MODE_UNDEF {
return false, fmt.Errorf("validateLegacyUser method called for undefined authorization mode.")
@@ -306,7 +307,7 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
params.Add("password", config.legacy_password)
params_str := params.Encode()
req, err := http.NewRequest("POST", config.controller_url + "/restmachine/cloudapi/users/authenticate", strings.NewReader(params_str))
req, err := http.NewRequest("POST", config.controller_url+"/restmachine/cloudapi/users/authenticate", strings.NewReader(params_str))
if err != nil {
return false, err
}
@@ -314,21 +315,21 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
resp, err := config.cc_client.Do(req)
resp, err := config.cc_client.Do(req)
if err != nil {
return false, err
}
if resp.StatusCode != http.StatusOK {
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q.",
resp.StatusCode, config.legacy_user, config.controller_url)
return false, fmt.Errorf("validateLegacyUser: unexpected status code %d when validating legacy user %q against %q.",
resp.StatusCode, config.legacy_user, config.controller_url)
}
defer resp.Body.Close()
responseData, err := ioutil.ReadAll(resp.Body)
if err != nil {
log.Fatal(err)
}
if err != nil {
log.Fatal(err)
}
// validation successful - keep session ID for future use
config.legacy_sid = string(responseData)
@@ -336,16 +337,16 @@ func (config *ControllerCfg) validateLegacyUser() (bool, error) {
}
func (config *ControllerCfg) decortAPICall(method string, api_name string, url_values *url.Values) (json_resp string, err error) {
// This is a convenience wrapper around standard HTTP request methods that is aware of the
// This is a convenience wrapper around standard HTTP request methods that is aware of the
// authorization mode for which the provider was initialized and compiles request accordingly.
if config.cc_client == nil {
// this should never happen if ClientConfig was properly called prior to decortAPICall
// this should never happen if ClientConfig was properly called prior to decortAPICall
return "", fmt.Errorf("decortAPICall method called with unconfigured DECORT cloud controller HTTP client.")
}
// Example: to create api_params, one would generally do the following:
//
//
// data := []byte(`{"machineId": "2638"}`)
// api_params := bytes.NewBuffer(data))
//
@@ -367,42 +368,43 @@ func (config *ControllerCfg) decortAPICall(method string, api_name string, url_v
}
params_str := url_values.Encode()
req, err := http.NewRequest(method, config.controller_url + api_name, strings.NewReader(params_str))
req, err := http.NewRequest(method, config.controller_url+api_name, strings.NewReader(params_str))
if err != nil {
return "", err
}
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("Content-Length", strconv.Itoa(len(params_str)))
req.Header.Set("Accept", "application/json")
if config.auth_mode_code == MODE_OAUTH2 || config.auth_mode_code == MODE_JWT {
req.Header.Set("Authorization", fmt.Sprintf("bearer %s", config.jwt))
}
resp, err := config.cc_client.Do(req)
if err != nil {
return "", err
}
defer resp.Body.Close()
if resp.StatusCode == http.StatusOK {
tmp_body, err := ioutil.ReadAll(resp.Body)
for i := 0; i < 5; i++ {
resp, err := config.cc_client.Do(req)
if err != nil {
return "", err
}
json_resp := Jo2JSON(string(tmp_body))
log.Debugf("decortAPICall: %s %s\n %s", method, api_name, json_resp)
return json_resp, nil
} else {
return "", fmt.Errorf("decortAPICall: unexpected status code %d when calling API %q with request Body %q",
resp.StatusCode, req.URL, params_str)
}
/*
if resp.StatusCode == StatusServiceUnavailable {
return nil, fmt.Errorf("decortAPICall method called for incompatible authorization mode %q.", config.auth_mode_txt)
}
*/
}
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 "", errors.New("number of retries exceeded")
}

View File

@@ -263,7 +263,7 @@ func flattenCompute(d *schema.ResourceData, compFacts string) error {
d.Set("rg_name", model.RgName)
d.Set("account_id", model.AccountID)
d.Set("account_name", model.AccountName)
d.Set("arch", model.Arch)
d.Set("driver", model.Driver)
d.Set("cpu", model.Cpu)
d.Set("ram", model.Ram)
// d.Set("boot_disk_size", model.BootDiskSize) - bootdiskSize key in API compute/get is always zero, so we set boot_disk_size in another way
@@ -367,7 +367,7 @@ func dataSourceCompute() *schema.Resource {
Description: "Name of the account this compute instance belongs to.",
},
"arch": {
"driver": {
Type: schema.TypeString,
Computed: true,
Description: "Hardware architecture of this compute instance.",

100
decort/data_source_grid.go Normal file
View File

@@ -0,0 +1,100 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenGrid(d *schema.ResourceData, grid *Grid) {
d.Set("name", grid.Name)
d.Set("flag", grid.Flag)
d.Set("gid", grid.Gid)
d.Set("guid", grid.Guid)
d.Set("location_code", grid.LocationCode)
d.Set("id", grid.Id)
return
}
func dataSourceGridRead(d *schema.ResourceData, m interface{}) error {
grid, err := utilityGridCheckPresence(d, m)
if err != nil {
return err
}
d.SetId(strconv.Itoa(grid.Id))
flattenGrid(d, grid)
return nil
}
func dataSourceGetGridSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"grid_id": {
Type: schema.TypeInt,
Required: true,
},
"flag": {
Type: schema.TypeString,
Computed: true,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"location_code": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
}
}
func dataSourceGrid() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceGridRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceGetGridSchemaMake(),
}
}

View File

@@ -0,0 +1,128 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenGridList(gl GridList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, item := range gl {
temp := map[string]interface{}{
"name": item.Name,
"flag": item.Flag,
"gid": item.Gid,
"guid": item.Guid,
"location_code": item.LocationCode,
"id": item.Id,
}
res = append(res, temp)
}
return res
}
func dataSourceGridListRead(d *schema.ResourceData, m interface{}) error {
gridList, err := utilityGridListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenGridList(gridList))
return nil
}
func dataSourceGridListSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"page": {
Type: schema.TypeInt,
Optional: true,
Description: "page number",
},
"size": {
Type: schema.TypeInt,
Optional: true,
Description: "page size",
},
"items": {
Type: schema.TypeList,
Computed: true,
Description: "grid list",
Elem: &schema.Resource{
Schema: dataSourceGridSchemaMake(),
},
},
}
return rets
}
func dataSourceGridSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"flag": {
Type: schema.TypeString,
Computed: true,
},
"gid": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"location_code": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
}
}
func dataSourceGridList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceGridListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceGridListSchemaMake(),
}
}

View File

@@ -1,6 +1,6 @@
/*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Sergey Shubin, <sergey.shubin@digitalenergy.online>, <svs1370@gmail.com>
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
@@ -25,57 +25,275 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
package decort
import (
"encoding/json"
"fmt"
"net/url"
log "github.com/sirupsen/logrus"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
)
func flattenImage(d *schema.ResourceData, image *Image) {
d.Set("name", image.Name)
d.Set("drivers", image.Drivers)
d.Set("url", image.Url)
d.Set("gid", image.Gid)
d.Set("image_id", image.ImageId)
d.Set("boot_type", image.Boottype)
d.Set("image_type", image.Imagetype)
d.Set("bootable", image.Bootable)
d.Set("sep_id", image.SepId)
d.Set("unc_path", image.UNCPath)
d.Set("link_to", image.LinkTo)
d.Set("status", image.Status)
d.Set("tech_status", image.TechStatus)
d.Set("version", image.Version)
d.Set("size", image.Size)
d.Set("enabled", image.Enabled)
d.Set("computeci_id", image.ComputeciId)
d.Set("pool_name", image.PoolName)
d.Set("username", image.Username)
d.Set("username_dl", image.UsernameDL)
d.Set("password", image.Password)
d.Set("password_dl", image.PasswordDL)
d.Set("account_id", image.AccountId)
d.Set("guid", image.Guid)
d.Set("milestones", image.Milestones)
d.Set("provider_name", image.ProviderName)
d.Set("purge_attempts", image.PurgeAttempts)
d.Set("reference_id", image.ReferenceId)
d.Set("res_id", image.ResId)
d.Set("res_name", image.ResName)
d.Set("rescuecd", image.Rescuecd)
d.Set("architecture", image.Architecture)
d.Set("hot_resize", image.Hotresize)
d.Set("history", flattenHistory(image.History))
d.Set("last_modified", image.LastModified)
d.Set("meta", flattenMeta(image.Meta))
d.Set("desc", image.Desc)
d.Set("shared_with", image.SharedWith)
return
}
func dataSourceImageRead(d *schema.ResourceData, m interface{}) error {
name := d.Get("name").(string)
// rg_id, rgid_set := d.GetOk("rg_id")
accId, accSet := d.GetOk("account_id")
controller := m.(*ControllerCfg)
url_values := &url.Values{}
if accSet {
url_values.Add("accountId", fmt.Sprintf("%d", accId.(int)))
}
body_string, err := controller.decortAPICall("POST", ImagesListAPI, url_values)
image, err := utilityImageCheckPresence(d, m)
if err != nil {
return err
}
d.SetId(strconv.Itoa(image.Guid))
flattenImage(d, image)
log.Debugf("dataSourceImageRead: ready to decode response body from %s", ImagesListAPI)
model := ImagesListResp{}
err = json.Unmarshal([]byte(body_string), &model)
if err != nil {
return err
return nil
}
func dataSourceImageSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Computed: true,
Description: "Name of the rescue disk",
},
"url": {
Type: schema.TypeString,
Computed: true,
Description: "URL where to download media from",
},
"gid": {
Type: schema.TypeInt,
Computed: true,
Description: "grid (platform) ID where this template should be create in",
},
"boot_type": {
Type: schema.TypeString,
Computed: true,
Description: "Boot type of image bios or uefi",
},
"image_type": {
Type: schema.TypeString,
Computed: true,
Description: "Image type linux, windows or other",
},
"shared_with": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"history": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"guid": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"timestamp": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"drivers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
},
"meta": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "meta",
},
"hot_resize": {
Type: schema.TypeBool,
Computed: true,
Description: "Does this machine supports hot resize",
},
"username": {
Type: schema.TypeString,
Computed: true,
Description: "Optional username for the image",
},
"password": {
Type: schema.TypeString,
Computed: true,
Description: "Optional password for the image",
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
Description: "AccountId to make the image exclusive",
},
"username_dl": {
Type: schema.TypeString,
Computed: true,
Description: "username for upload binary media",
},
"password_dl": {
Type: schema.TypeString,
Computed: true,
Description: "password for upload binary media",
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
Description: "storage endpoint provider ID",
},
"pool_name": {
Type: schema.TypeString,
Computed: true,
Description: "pool for image create",
},
"architecture": {
Type: schema.TypeString,
Computed: true,
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
},
"image_id": {
Type: schema.TypeInt,
Required: true,
Description: "image id",
},
"permanently": {
Type: schema.TypeBool,
Computed: true,
Description: "Whether to completely delete the image",
},
"bootable": {
Type: schema.TypeBool,
Computed: true,
Description: "Does this image boot OS",
},
"unc_path": {
Type: schema.TypeString,
Computed: true,
Description: "unc path",
},
"link_to": {
Type: schema.TypeInt,
Computed: true,
Description: "",
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: "status",
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
Description: "tech atatus",
},
"version": {
Type: schema.TypeString,
Computed: true,
Description: "version",
},
"size": {
Type: schema.TypeInt,
Computed: true,
Description: "image size",
},
"enabled": {
Type: schema.TypeBool,
Computed: true,
},
"computeci_id": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"provider_name": {
Type: schema.TypeString,
Computed: true,
},
"purge_attempts": {
Type: schema.TypeInt,
Computed: true,
},
"reference_id": {
Type: schema.TypeString,
Computed: true,
},
"res_id": {
Type: schema.TypeString,
Computed: true,
},
"res_name": {
Type: schema.TypeString,
Computed: true,
},
"rescuecd": {
Type: schema.TypeBool,
Computed: true,
},
"last_modified": {
Type: schema.TypeInt,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
}
// log.Printf("%#v", model)
log.Debugf("dataSourceImageRead: traversing decoded JSON of length %d", len(model))
for index, item := range model {
// need to match Image by name
if item.Name == name {
log.Debugf("dataSourceImageRead: index %d, matched name %s", index, item.Name)
d.SetId(fmt.Sprintf("%d", item.ID))
d.Set("account_id", item.AccountID)
d.Set("arch", item.Arch)
d.Set("sep_id", item.SepID)
d.Set("pool", item.Pool)
d.Set("status", item.Status)
d.Set("size", item.Size)
// d.Set("field_name", value)
return nil
}
}
return fmt.Errorf("Cannot find Image name %s", name)
}
func dataSourceImage() *schema.Resource {
@@ -89,57 +307,6 @@ func dataSourceImage() *schema.Resource {
Default: &Timeout60s,
},
Schema: map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of the image to locate. This parameter is case sensitive.",
},
"account_id": {
Type: schema.TypeInt,
Optional: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "Optional ID of the account to limit image search to.",
},
"arch": {
Type: schema.TypeString,
Computed: true,
Description: "Binary architecture of this image.",
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
Description: "Storage end-point provider serving this image.",
},
/*
"sep_type": {
Type: schema.TypeString,
Computed: true,
Description: "Type of the storage end-point provider serving this image.",
},
*/
"pool": {
Type: schema.TypeString,
Computed: true,
Description: "Pool where this image is located.",
},
"size": {
Type: schema.TypeInt,
Computed: true,
Description: "Size of the image in GB.",
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: "Current model status of this image.",
},
},
Schema: dataSourceImageSchemaMake(),
}
}

View File

@@ -0,0 +1,140 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenImageList(il ImageList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, item := range il {
temp := map[string]interface{}{
"name": item.Name,
"url": item.Url,
"gid": item.Gid,
"guid": item.Guid,
"drivers": item.Drivers,
"image_id": item.ImageId,
"boot_type": item.Boottype,
"bootable": item.Bootable,
"image_type": item.Imagetype,
"status": item.Status,
"tech_status": item.TechStatus,
"version": item.Version,
"username": item.Username,
"username_dl": item.UsernameDL,
"password": item.Password,
"password_dl": item.PasswordDL,
"purge_attempts": item.PurgeAttempts,
"architecture": item.Architecture,
"account_id": item.AccountId,
"computeci_id": item.ComputeciId,
"enabled": item.Enabled,
"reference_id": item.ReferenceId,
"res_id": item.ResId,
"res_name": item.ResName,
"rescuecd": item.Rescuecd,
"provider_name": item.ProviderName,
"milestones": item.Milestones,
"size": item.Size,
"sep_id": item.SepId,
"link_to": item.LinkTo,
"unc_path": item.UNCPath,
"pool_name": item.PoolName,
"hot_resize": item.Hotresize,
"history": flattenHistory(item.History),
"last_modified": item.LastModified,
"meta": flattenMeta(item.Meta),
"desc": item.Desc,
"shared_with": item.SharedWith,
}
res = append(res, temp)
}
return res
}
func dataSourceImageListRead(d *schema.ResourceData, m interface{}) error {
imageList, err := utilityImageListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenImageList(imageList))
return nil
}
func dataSourceImageListSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"sep_id": {
Type: schema.TypeInt,
Optional: true,
Description: "filter images by storage endpoint provider ID",
},
"shared_with": {
Type: schema.TypeInt,
Optional: true,
Description: "filter images by account ID availability",
},
"page": {
Type: schema.TypeInt,
Optional: true,
Description: "page number",
},
"size": {
Type: schema.TypeInt,
Optional: true,
Description: "page size",
},
"items": {
Type: schema.TypeList,
Computed: true,
Description: "image list",
Elem: &schema.Resource{
Schema: dataSourceImageSchemaMake(),
},
},
}
return rets
}
func dataSourceImageList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceImageListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceImageListSchemaMake(),
}
}

View File

@@ -0,0 +1,182 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func flattenImageListStacks(d *schema.ResourceData, stack ImageListStacks) []map[string]interface{} {
temp := make([]map[string]interface{}, 0)
for _, item := range stack {
t := map[string]interface{}{
"api_url": item.ApiURL,
"api_key": item.ApiKey,
"app_id": item.AppId,
"desc": item.Desc,
"drivers": item.Drivers,
"error": item.Error,
"guid": item.Guid,
"id": item.Id,
"images": item.Images,
"login": item.Login,
"name": item.Name,
"passwd": item.Passwd,
"reference_id": item.ReferenceId,
"status": item.Status,
"type": item.Type,
}
temp = append(temp, t)
}
return temp
}
func dataSourceImageListStacksRead(d *schema.ResourceData, m interface{}) error {
imageListStacks, err := utilityImageListStacksCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenImageListStacks(d, imageListStacks))
return nil
}
func dataSourceImageListStackSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"api_url": {
Type: schema.TypeString,
Computed: true,
},
"api_key": {
Type: schema.TypeString,
Computed: true,
},
"app_id": {
Type: schema.TypeString,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"drivers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"error": {
Type: schema.TypeInt,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"images": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"login": {
Type: schema.TypeString,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"passwd": {
Type: schema.TypeString,
Computed: true,
},
"reference_id": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
}
}
func dataSourceImageListStacksSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"image_id": {
Type: schema.TypeInt,
Required: true,
Description: "image id",
},
"page": {
Type: schema.TypeInt,
Optional: true,
Description: "page number",
},
"size": {
Type: schema.TypeInt,
Optional: true,
Description: "page size",
},
"items": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: dataSourceImageListStackSchemaMake(),
},
Description: "items of stacks list",
},
}
}
func dataSourceImageListStacks() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceImageListStacksRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceImageListStacksSchemaMake(),
}
}

View File

@@ -0,0 +1,128 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"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(),
}
}

View File

@@ -0,0 +1,152 @@
/*
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(),
}
}

145
decort/data_source_sep.go Normal file
View File

@@ -0,0 +1,145 @@
/*
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(),
}
}

View File

@@ -0,0 +1,77 @@
/*
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(),
}
}

View File

@@ -0,0 +1,195 @@
/*
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(),
}
}

View File

@@ -0,0 +1,82 @@
/*
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(),
}
}

View File

@@ -0,0 +1,180 @@
/*
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(),
}
}

View File

@@ -0,0 +1,80 @@
/*
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(),
}
}

View File

@@ -0,0 +1,120 @@
/*
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 flattenSnapshotList(gl SnapshotList) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, item := range gl {
temp := map[string]interface{}{
"label": item.Label,
"guid": item.Guid,
"disks": item.Disks,
"timestamp": item.Timestamp,
}
res = append(res, temp)
}
return res
}
func dataSourceSnapshotListRead(d *schema.ResourceData, m interface{}) error {
snapshotList, err := utilitySnapshotListCheckPresence(d, m)
if err != nil {
return err
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenSnapshotList(snapshotList))
return nil
}
func dataSourceSnapshotListSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"compute_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "ID of the compute instance to create snapshot for.",
},
"items": {
Type: schema.TypeList,
Computed: true,
Description: "snapshot list",
Elem: &schema.Resource{
Schema: dataSourceSnapshotSchemaMake(),
},
},
}
return rets
}
func dataSourceSnapshotSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"label": {
Type: schema.TypeString,
Computed: true,
Description: "text label for snapshot. Must be unique among this compute snapshots.",
},
"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 dataSourceSnapshotList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceSnapshotListRead,
Timeouts: &schema.ResourceTimeout{
Read: &Timeout30s,
Default: &Timeout60s,
},
Schema: dataSourceSnapshotListSchemaMake(),
}
}

111
decort/data_source_vgpu.go Normal file
View File

@@ -0,0 +1,111 @@
/*
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 (
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func dataSourceVGPURead(d *schema.ResourceData, m interface{}) error {
vgpu, err := utilityVGPUCheckPresence(d, m)
if vgpu == nil {
d.SetId("")
return err
}
d.SetId(strconv.Itoa(vgpu.ID))
d.Set("vgpu_id", vgpu.ID)
d.Set("account_id", vgpu.AccountID)
d.Set("mode", vgpu.Mode)
d.Set("pgpu", vgpu.PgpuID)
d.Set("profile_id", vgpu.ProfileID)
d.Set("ram", vgpu.RAM)
d.Set("status", vgpu.Status)
d.Set("type", vgpu.Type)
d.Set("vm_id", vgpu.VmID)
return nil
}
func dataSourceVGPUSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"vgpu_id": {
Type: schema.TypeInt,
Required: true,
},
"account_id": {
Type: schema.TypeInt,
Computed: true,
},
"mode": {
Type: schema.TypeString,
Computed: true,
},
"pgpu": {
Type: schema.TypeInt,
Computed: true,
},
"profile_id": {
Type: schema.TypeInt,
Computed: true,
},
"ram": {
Type: schema.TypeInt,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
"vm_id": {
Type: schema.TypeInt,
Computed: true,
},
}
}
func dataSourceVGPU() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Read: dataSourceVGPURead,
Schema: dataSourceVGPUSchemaMake(),
}
}

View File

@@ -25,6 +25,9 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
package decort
import (
"encoding/json"
"fmt"
"strconv"
"time"
)
@@ -33,6 +36,7 @@ import (
var Timeout30s = time.Second * 30
var Timeout60s = time.Second * 60
var Timeout180s = time.Second * 180
var Timeout20m = time.Minute * 20
//
// structures related to /cloudapi/rg/list API
@@ -356,6 +360,7 @@ type ComputeGetResp struct {
Cpu int `json:"cpus"`
Desc string `json:"desc"`
Disks []DiskRecord `json:"disks"`
Driver string `json:"driver"`
GridID int `json:"gid"`
ID uint `json:"id"`
ImageID int `json:"imageId"`
@@ -572,6 +577,115 @@ const VinsExtNetDisconnectAPI = "/restmachine/cloudapi/vins/extNetDisconnect"
const VinsDeleteAPI = "/restmachine/cloudapi/vins/delete"
//
// K8s structures
//
//K8sNodeRecord represents a worker/master group
type K8sNodeRecord struct {
ID int `json:"id"`
Name string `json:"name"`
Disk int `json:"disk"`
Cpu int `json:"cpu"`
Num int `json:"num"`
Ram int `json:"ram"`
DetailedInfo []struct {
ID int `json:"id"`
Name string `json:"name"`
} `json:"detailedInfo"`
}
//K8sRecord represents k8s instance
type K8sRecord struct {
AccountID int `json:"accountId"`
AccountName string `json:"accountName"`
CI int `json:"ciId"`
ID int `json:"id"`
Groups struct {
Masters K8sNodeRecord `json:"masters"`
Workers []K8sNodeRecord `json:"workers"`
} `json:"k8sGroups"`
LbID int `json:"lbId"`
Name string `json:"name"`
RgID int `json:"rgId"`
RgName string `json:"rgName"`
}
//LbRecord represents load balancer instance
type LbRecord struct {
ID int `json:"id"`
Name string `json:"name"`
RgID int `json:"rgId"`
VinsID int `json:"vinsId"`
ExtNetID int `json:"extnetId"`
PrimaryNode struct {
BackendIP string `json:"backendIp"`
ComputeID int `json:"computeId"`
FrontendIP string `json:"frontendIp"`
NetworkID int `json:"networkId"`
} `json:"primaryNode"`
}
const K8sCreateAPI = "/restmachine/cloudapi/k8s/create"
const K8sGetAPI = "/restmachine/cloudapi/k8s/get"
const K8sUpdateAPI = "/restmachine/cloudapi/k8s/update"
const K8sDeleteAPI = "/restmachine/cloudapi/k8s/delete"
const K8sWgCreateAPI = "/restmachine/cloudapi/k8s/workersGroupAdd"
const K8sWgDeleteAPI = "/restmachine/cloudapi/k8s/workersGroupDelete"
const K8sWorkerAddAPI = "/restmachine/cloudapi/k8s/workerAdd"
const K8sWorkerDeleteAPI = "/restmachine/cloudapi/k8s/deleteWorkerFromGroup"
const K8sGetConfigAPI = "/restmachine/cloudapi/k8s/getConfig"
const LbGetAPI = "/restmachine/cloudapi/lb/get"
//Blasphemous workaround for parsing Result value
type TaskResult int
func (r *TaskResult) UnmarshalJSON(b []byte) error {
if b[0] == '"' {
b := b[1 : len(b)-1]
if len(b) == 0 {
*r = 0
return nil
}
n, err := strconv.Atoi(string(b))
if err != nil {
return err
}
*r = TaskResult(n)
} else if b[0] == '[' {
res := []interface{}{}
if err := json.Unmarshal(b, &res); err != nil {
return err
}
if n, ok := res[0].(float64); ok {
*r = TaskResult(n)
} else {
return fmt.Errorf("could not unmarshal %v into int", res[0])
}
}
return nil
}
//AsyncTask represents a long task completion status
type AsyncTask struct {
AuditID string `json:"auditId"`
Completed bool `json:"completed"`
Error string `json:"error"`
Log []string `json:"log"`
Result TaskResult `json:"result"`
Stage string `json:"stage"`
Status string `json:"status"`
UpdateTime uint64 `json:"updateTime"`
UpdatedTime uint64 `json:"updatedTime"`
}
const AsyncTaskGetAPI = "/restmachine/cloudapi/tasks/get"
//
// Grid ID structures
//
@@ -594,3 +708,250 @@ type SshKeyConfig struct {
SshKey string
UserShell string
}
////////////////////
// IMAGE API //
////////////////////
const imageCreateAPI = "/restmachine/cloudbroker/image/createImage"
const imageSyncCreateAPI = "/restmachine/cloudbroker/image/syncCreateImage"
const imageCreateVirtualAPI = "/restmachine/cloudbroker/image/createVirtual"
const imageCreateCDROMAPI = "/restmachine/cloudbroker/image/createCDROMImage"
const imageListStacksApi = "/restmachine/cloudbroker/image/listStacks"
const imageGetAPI = "/restmachine/cloudbroker/image/get"
const imageListGetAPI = "/restmachine/cloudbroker/image/list"
const imageEditAPI = "/restmachine/cloudbroker/image/edit"
const imageDeleteAPI = "/restmachine/cloudbroker/image/delete"
const imageDeleteCDROMAPI = "/restmachine/cloudbroker/image/deleteCDROMImage"
const imageEnableAPI = "/restmachine/cloudbroker/image/enable"
const imageDisableAPI = "/restmachine/cloudbroker/image/disable"
const imageEditNameAPI = "/restmachine/cloudbroker/image/rename"
const imageLinkAPI = "/restmachine/cloudbroker/image/link"
const imageShareAPI = "/restmachine/cloudbroker/image/share"
const imageComputeciSetAPI = "/restmachine/cloudbroker/image/computeciSet"
const imageComputeciUnsetAPI = "/restmachine/cloudbroker/image/computeciUnset"
const imageUpdateNodesAPI = "/restmachine/cloudbroker/image/updateNodes"
const imageDeleteImagesAPI = "/restmachine/cloudbroker/image/deleteImages"
type History struct {
Guid string `json:"guid"`
Id int `json:"id"`
Timestamp int64 `json:"timestamp"`
}
type Image struct {
ImageId int `json:"id"`
Name string `json:"name"`
Url string `json:"url"`
Gid int `json:"gid"`
Guid int `json:"guid"`
Boottype string `json:"bootType"`
Imagetype string `json:"type"`
Drivers []string `json:"drivers"`
Hotresize bool `json:"hotResize"`
Bootable bool `json:"bootable"`
Username string `json:"username"`
Password string `json:"password"`
AccountId int `json:"accountId"`
UsernameDL string `json:"usernameDL"`
PasswordDL string `json:"passwordDL"`
SepId int `json:"sepId"`
PoolName string `json:"pool"`
Architecture string `json:"architecture"`
UNCPath string `json:"UNCPath"`
LinkTo int `json:"linkTo"`
Status string `json:"status"`
TechStatus string `json:"techStatus"`
Size int `json:"size"`
Version string `json:"version"`
Enabled bool `json:"enabled"`
ComputeciId int `json:"computeciId"`
Milestones int `json:"milestones"`
ProviderName string `json:"provider_name"`
PurgeAttempts int `json:"purgeAttempts"`
ReferenceId string `json:"referenceId"`
ResId string `json:"resId"`
ResName string `json:"resName"`
Rescuecd bool `json:"rescuecd"`
Meta []interface{} `json:"_meta"`
History []History `json:"history"`
LastModified int64 `json:"lastModified"`
Desc string `json:"desc"`
SharedWith []int `json:"sharedWith"`
}
type ImageList []Image
type ImageStack struct {
ApiURL string `json:"apiUrl"`
ApiKey string `json:"apikey"`
AppId string `json:"appId"`
Desc string `json:"desc"`
Drivers []string `json:"drivers"`
Error int `json:"error"`
Guid int `json:"guid"`
Id int `json:"id"`
Images []int `json:"images"`
Login string `json:"login"`
Name string `json:"name"`
Passwd string `json:"passwd"`
ReferenceId string `json:"referenceId"`
Status string `json:"status"`
Type string `json:"type"`
}
type ImageListStacks []ImageStack
/////////////////
// GRID API //
/////////////////
const GridListGetAPI = "/restmachine/cloudbroker/grid/list"
const GridGetAPI = "/restmachine/cloudbroker/grid/get"
type Grid struct {
Flag string `json:"flag"`
Gid int `json:"gid"`
Guid int `json:"guid"`
Id int `json:"id"`
LocationCode string `json:"locationCode"`
Name string `json:"name"`
}
type GridList []Grid
/////////////////////
/// SNAPSHOT API ///
/////////////////////
const snapshotCreateAPI = "/restmachine/cloudapi/compute/snapshotCreate"
const snapshotDeleteAPI = "/restmachine/cloudapi/compute/snapshotDelete"
const snapshotRollbackAPI = "/restmachine/cloudapi/compute/snapshotRollback"
const snapshotListAPI = "/restmachine/cloudapi/compute/snapshotList"
type Snapshot struct {
Disks []int `json:"disks"`
Guid string `json:"guid"`
Label string `json:"label"`
Timestamp uint64 `json:"timestamp"`
}
type SnapshotList []Snapshot
////////////////
/// VGPU API ///
////////////////
const vgpuListAPI = "/restmachine/cloudbroker/vgpu/list"
type VGPU struct {
AccountID int `json:"accountId"`
ID int `json:"id"`
Mode string `json:"mode"`
PgpuID int `json:"pgpuid"`
ProfileID int `json:"profileId"`
RAM int `json:"ram"`
Status string `json:"status"`
Type string `json:"type"`
VmID int `json:"vmid"`
}
/////////////////////////////
// PCIDEVICE //
/////////////////////////////
const pcideviceListAPI = "/restmachine/cloudbroker/pcidevice/list"
const pcideviceDisableAPI = "/restmachine/cloudbroker/pcidevice/disable"
const pcideviceEnableAPI = "/restmachine/cloudbroker/pcidevice/enable"
const pcideviceCreateAPI = "/restmachine/cloudbroker/pcidevice/create"
const pcideviceDeleteAPI = "/restmachine/cloudbroker/pcidevice/delete"
type Pcidevice struct {
CKey string `json:"_ckey"`
Meta []interface{} `json:"_meta"`
Computeid int `json:"computeId"`
Description string `json:"description"`
Guid int `json:"guid"`
HwPath string `json:"hwPath"`
ID int `json:"id"`
Name string `json:"name"`
RgID int `json:"rgId"`
StackID int `json:"stackId"`
Status string `json:"status"`
SystemName string `json:"systemName"`
}
type PcideviceList []Pcidevice
///////////////////
///// SEP API /////
///////////////////
const sepAddConsumerNodesAPI = "/restmachine/cloudbroker/sep/addConsumerNodes"
const sepDelConsumerNodesAPI = "/restmachine/cloudbroker/sep/delConsumerNodes"
const sepAddProviderNodesAPI = "/restmachine/cloudbroker/sep/addProviderNodes"
const sepConfigFieldEditAPI = "/restmachine/cloudbroker/sep/configFieldEdit"
const sepConfigInsertAPI = "/restmachine/cloudbroker/sep/configInsert"
const sepConfigValidateAPI = "/restmachine/cloudbroker/sep/configValidate"
const sepConsumptionAPI = "/restmachine/cloudbroker/sep/consumption"
const sepDecommissionAPI = "/restmachine/cloudbroker/sep/decommission"
const sepEnableAPI = "/restmachine/cloudbroker/sep/enable"
const sepDisableAPI = "/restmachine/cloudbroker/sep/disable"
const sepDiskListAPI = "/restmachine/cloudbroker/sep/diskList"
const sepGetAPI = "/restmachine/cloudbroker/sep/get"
const sepGetConfigAPI = "/restmachine/cloudbroker/sep/getConfig"
const sepGetPoolAPI = "/restmachine/cloudbroker/sep/getPool"
const sepCreateAPI = "/restmachine/cloudbroker/sep/create"
const sepDeleteAPI = "/restmachine/cloudbroker/sep/delete"
const sepListAPI = "/restmachine/cloudbroker/sep/list"
const sepUpdateCapacityLimitAPI = "/restmachine/cloudbroker/sep/updateCapacityLimit"
///Sep Models
type SepConsumptionInd struct {
DiskCount int `json:"disk_count"`
DiskUsage int `json:"disk_usage"`
SnapshotCount int `json:"snapshot_count"`
SnapshotUsage int `json:"snapshot_usage"`
Usage int `json:"usage"`
UsageLimit int `json:"usage_limit"`
}
type SepConsumptionTotal struct {
CapacityLimit int `json:"capacity_limit"`
SepConsumptionInd
}
type SepConsumption struct {
Total SepConsumptionTotal `json:"total"`
Type string `json:"type"`
ByPool map[string]SepConsumptionInd `json:"byPool"`
}
type SepDiskList []int
type Sep struct {
Ckey string `json:"_ckey"`
Meta []interface{} `json:"_meta"`
ConsumedBy []int `json:"consumedBy"`
Desc string `json:"desc"`
Gid int `json:"gid"`
Guid int `json:"guid"`
Id int `json:"id"`
Milestones int `json:"milestones"`
Name string `json:"name"`
ObjStatus string `json:"objStatus"`
ProvidedBy []int `json:"providedBy"`
TechStatus string `json:"techStatus"`
Type string `json:"type"`
Config SepConfig `json:"config"`
}
type SepConfig map[string]interface{}
type SepList []Sep
type SepPool map[string]interface{}

View File

@@ -0,0 +1,98 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import "github.com/hashicorp/terraform-plugin-sdk/helper/schema"
func nodeMasterDefault() K8sNodeRecord {
return K8sNodeRecord{
Num: 1,
Cpu: 2,
Ram: 2048,
Disk: 0,
}
}
func nodeWorkerDefault() K8sNodeRecord {
return K8sNodeRecord{
Num: 1,
Cpu: 1,
Ram: 1024,
Disk: 0,
}
}
func parseNode(nodeList []interface{}) K8sNodeRecord {
node := nodeList[0].(map[string]interface{})
return K8sNodeRecord{
Num: node["num"].(int),
Cpu: node["cpu"].(int),
Ram: node["ram"].(int),
Disk: node["disk"].(int),
}
}
func nodeToResource(node K8sNodeRecord) []interface{} {
mp := make(map[string]interface{})
mp["num"] = node.Num
mp["cpu"] = node.Cpu
mp["ram"] = node.Ram
mp["disk"] = node.Disk
return []interface{}{mp}
}
func nodeK8sSubresourceSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"num": {
Type: schema.TypeInt,
Required: true,
Description: "Number of nodes to create.",
},
"cpu": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "Node CPU count.",
},
"ram": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "Node RAM in MB.",
},
"disk": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "Node boot disk size in GB.",
},
}
}

View File

@@ -27,9 +27,9 @@ import (
func parseOsUsers(logins []OsUserRecord) []interface{} {
var result = make([]interface{}, len(logins))
elem := make(map[string]interface{})
for index, value := range logins {
elem := make(map[string]interface{})
elem["guid"] = value.Guid
elem["login"] = value.Login
elem["password"] = value.Password

View File

@@ -99,20 +99,44 @@ func Provider() *schema.Provider {
},
ResourcesMap: map[string]*schema.Resource{
"decort_resgroup": resourceResgroup(),
"decort_kvmvm": resourceCompute(),
"decort_disk": resourceDisk(),
"decort_vins": resourceVins(),
// "decort_pfw": resourcePfw(),
"decort_resgroup": resourceResgroup(),
"decort_kvmvm": resourceCompute(),
"decort_disk": resourceDisk(),
"decort_vins": resourceVins(),
"decort_pfw": resourcePfw(),
"decort_k8s": resourceK8s(),
"decort_k8s_wg": resourceK8sWg(),
"decort_image": resourceImage(),
"decort_virtual_image": resourceVirtualImage(),
"decort_cdrom_image": resourceCDROMImage(),
"decort_delete_images": resourceDeleteImages(),
"decort_snapshot": resourceSnapshot(),
"decort_pcidevice": resourcePcidevice(),
"decort_sep": resourceSep(),
"decort_sep_config": resourceSepConfig(),
},
DataSourcesMap: map[string]*schema.Resource{
"decort_account": dataSourceAccount(),
"decort_resgroup": dataSourceResgroup(),
"decort_kvmvm": dataSourceCompute(),
"decort_image": dataSourceImage(),
"decort_disk": dataSourceDisk(),
"decort_vins": dataSourceVins(),
"decort_account": dataSourceAccount(),
"decort_resgroup": dataSourceResgroup(),
"decort_kvmvm": dataSourceCompute(),
"decort_image": dataSourceImage(),
"decort_disk": dataSourceDisk(),
"decort_vins": dataSourceVins(),
"decort_grid": dataSourceGrid(),
"decort_grid_list": dataSourceGridList(),
"decort_image_list": dataSourceImageList(),
"decort_image_list_stacks": dataSourceImageListStacks(),
"decort_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_pfw": dataSourcePfw(),
},

View File

@@ -0,0 +1,449 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
log "github.com/sirupsen/logrus"
)
func resourceCDROMImageCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceCDROMImageCreate: called for image %s", d.Get("name").(string))
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("name", d.Get("name").(string))
urlValues.Add("url", d.Get("url").(string))
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
tstr := d.Get("drivers").([]interface{})
temp := ""
l := len(tstr)
for i, str := range tstr {
s := "\"" + str.(string) + "\""
if i != (l - 1) {
s += ","
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("drivers", temp)
if username, ok := d.GetOk("username"); ok {
urlValues.Add("username", username.(string))
}
if password, ok := d.GetOk("password"); ok {
urlValues.Add("password", password.(string))
}
if accountId, ok := d.GetOk("account_id"); ok {
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
}
if usernameDL, ok := d.GetOk("username_dl"); ok {
urlValues.Add("usernameDL", usernameDL.(string))
}
if passwordDL, ok := d.GetOk("password_dl"); ok {
urlValues.Add("passwordDL", passwordDL.(string))
}
if sepId, ok := d.GetOk("sep_id"); ok {
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
}
if poolName, ok := d.GetOk("pool_name"); ok {
urlValues.Add("pool_name", poolName.(string))
}
if architecture, ok := d.GetOk("architecture"); ok {
urlValues.Add("architecture", architecture.(string))
}
imageId, err := controller.decortAPICall("POST", imageCreateCDROMAPI, urlValues)
if err != nil {
return err
}
d.SetId(imageId)
d.Set("image_id", imageId)
image, err := utilityImageCheckPresence(d, m)
if err != nil {
return err
}
d.SetId(strconv.Itoa(image.ImageId))
d.Set("bootable", image.Bootable)
//d.Set("image_id", image.ImageId)
err = resourceImageRead(d, m)
if err != nil {
return err
}
return nil
}
func resourceCDROMImageDelete(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceCDROMImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
image, err := utilityImageCheckPresence(d, m)
if image == nil {
if err != nil {
return err
}
return nil
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
if permanently, ok := d.GetOk("permanently"); ok {
urlValues.Add("permanently", strconv.FormatBool(permanently.(bool)))
}
_, err = controller.decortAPICall("POST", imageDeleteCDROMAPI, urlValues)
if err != nil {
return err
}
d.SetId("")
return nil
}
func resourceCDROMImageSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of the rescue disk",
},
"url": {
Type: schema.TypeString,
Required: true,
Description: "URL where to download ISO from",
},
"gid": {
Type: schema.TypeInt,
Required: true,
Description: "grid (platform) ID where this template should be create in",
},
"boot_type": {
Type: schema.TypeString,
Computed: true,
Description: "Boot type of image bios or uefi",
},
"image_type": {
Type: schema.TypeString,
Computed: true,
Description: "Image type linux, windows or other",
},
"drivers": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
},
"meta": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "meta",
},
"hot_resize": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Does this machine supports hot resize",
},
"username": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Optional username for the image",
},
"password": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Optional password for the image",
},
"account_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "AccountId to make the image exclusive",
},
"username_dl": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "username for upload binary media",
},
"password_dl": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "password for upload binary media",
},
"sep_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "storage endpoint provider ID",
},
"pool_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "pool for image create",
},
"architecture": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
},
"image_id": {
Type: schema.TypeInt,
Computed: true,
Description: "image id",
},
"permanently": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Whether to completely delete the image",
},
"bootable": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Does this image boot OS",
},
"unc_path": {
Type: schema.TypeString,
Computed: true,
Description: "unc path",
},
"link_to": {
Type: schema.TypeInt,
Computed: true,
Description: "",
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: "status",
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
Description: "tech atatus",
},
"version": {
Type: schema.TypeString,
Computed: true,
Description: "version",
},
"size": {
Type: schema.TypeInt,
Computed: true,
Description: "image size",
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"computeci_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"provider_name": {
Type: schema.TypeString,
Computed: true,
},
"purge_attempts": {
Type: schema.TypeInt,
Computed: true,
},
"reference_id": {
Type: schema.TypeString,
Computed: true,
},
"res_id": {
Type: schema.TypeString,
Computed: true,
},
"res_name": {
Type: schema.TypeString,
Computed: true,
},
"rescuecd": {
Type: schema.TypeBool,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"shared_with": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"enabled_stacks": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"history": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"guid": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"timestamp": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
}
}
func resourceCDROMImage() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourceCDROMImageCreate,
Read: resourceImageRead,
Update: resourceImageEdit,
Delete: resourceCDROMImageDelete,
Exists: resourceImageExists,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout60s,
Read: &Timeout30s,
Update: &Timeout60s,
Delete: &Timeout60s,
Default: &Timeout60s,
},
CustomizeDiff: customdiff.All(
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
if old.(bool) != new.(bool) {
return true
}
return false
}, resourceImageChangeEnabled),
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
if old.(string) != new.(string) && old.(string) != "" {
return true
}
return false
}, resourceImageEditName),
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
o := old.([]interface{})
n := new.([]interface{})
if len(o) != len(n) {
return true
} else if len(o) == 0 {
return false
}
count := 0
for i, v := range n {
if v.(int) == o[i].(int) {
count++
}
}
if count == 0 {
return true
}
return false
}, resourceImageShare),
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
if old.(int) != new.(int) {
return true
}
return false
}, resourceImageChangeComputeci),
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
o := old.([]interface{})
n := new.([]interface{})
if len(o) != len(n) {
return true
} else if len(o) == 0 {
return false
}
count := 0
for i, v := range n {
if v.(string) == o[i].(string) {
count++
}
}
if count == 0 {
return true
}
return false
}, resourceImageUpdateNodes),
),
Schema: resourceCDROMImageSchemaMake(),
}
}

View File

@@ -0,0 +1,131 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"net/url"
"strconv"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
log "github.com/sirupsen/logrus"
)
func resourceCreateListImages(d *schema.ResourceData, m interface{}) error {
id := uuid.New()
d.SetId(id.String())
return nil
}
func resourceDeleteListImages(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceDeleteListImages: start deleting...")
c := m.(*ControllerCfg)
urlValues := &url.Values{}
imageIds := d.Get("image_ids").([]interface{})
temp := ""
l := len(imageIds)
for i, imageId := range imageIds {
s := strconv.Itoa(imageId.(int))
if i != (l - 1) {
s += ",\n"
} else {
s += "\n"
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("reason", d.Get("reason").(string))
urlValues.Add("permanently", strconv.FormatBool(d.Get("permanently").(bool)))
urlValues.Add("imageIds", temp)
_, err := c.decortAPICall("POST", imageDeleteImagesAPI, urlValues)
if err != nil {
return err
}
d.SetId("")
return nil
}
func resourceReadListImages(d *schema.ResourceData, m interface{}) error {
return nil
}
func resourceDeleteImagesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"image_ids": {
Type: schema.TypeList,
Required: true,
ForceNew: true,
MinItems: 1,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
Description: "images ids for deleting",
},
"reason": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "reason for deleting the images",
},
"permanently": {
Type: schema.TypeBool,
Optional: true,
ForceNew: true,
Default: false,
Description: "whether to completely delete the images",
},
}
}
func resourceDeleteImages() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourceCreateListImages,
Read: resourceReadListImages,
Delete: resourceDeleteListImages,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout60s,
Read: &Timeout30s,
Update: &Timeout60s,
Delete: &Timeout60s,
Default: &Timeout60s,
},
Schema: resourceDeleteImagesSchemaMake(),
}
}

738
decort/resource_image.go Normal file
View File

@@ -0,0 +1,738 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"errors"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
log "github.com/sirupsen/logrus"
)
func resourceImageCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string))
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("name", d.Get("name").(string))
urlValues.Add("url", d.Get("url").(string))
urlValues.Add("gid", strconv.Itoa(d.Get("gid").(int)))
urlValues.Add("boottype", d.Get("boot_type").(string))
urlValues.Add("imagetype", d.Get("image_type").(string))
tstr := d.Get("drivers").([]interface{})
temp := ""
l := len(tstr)
for i, str := range tstr {
s := "\"" + str.(string) + "\""
if i != (l - 1) {
s += ","
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("drivers", temp)
if hotresize, ok := d.GetOk("hot_resize"); ok {
urlValues.Add("hotresize", strconv.FormatBool(hotresize.(bool)))
}
if username, ok := d.GetOk("username"); ok {
urlValues.Add("username", username.(string))
}
if password, ok := d.GetOk("password"); ok {
urlValues.Add("password", password.(string))
}
if accountId, ok := d.GetOk("account_id"); ok {
urlValues.Add("accountId", strconv.Itoa(accountId.(int)))
}
if usernameDL, ok := d.GetOk("username_dl"); ok {
urlValues.Add("usernameDL", usernameDL.(string))
}
if passwordDL, ok := d.GetOk("password_dl"); ok {
urlValues.Add("passwordDL", passwordDL.(string))
}
if sepId, ok := d.GetOk("sep_id"); ok {
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
}
if poolName, ok := d.GetOk("pool_name"); ok {
urlValues.Add("poolName", poolName.(string))
}
if architecture, ok := d.GetOk("architecture"); ok {
urlValues.Add("architecture", architecture.(string))
}
api := ""
isSync := d.Get("sync").(bool)
if !isSync {
api = imageCreateAPI
} else {
api = imageSyncCreateAPI
}
imageId, err := controller.decortAPICall("POST", api, urlValues)
if err != nil {
return err
}
d.SetId(imageId)
d.Set("image_id", imageId)
image, err := utilityImageCheckPresence(d, m)
if err != nil {
return err
}
d.SetId(strconv.Itoa(image.ImageId))
d.Set("bootable", image.Bootable)
//d.Set("image_id", image.ImageId)
err = resourceImageRead(d, m)
if err != nil {
return err
}
return nil
}
func resourceImageRead(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceImageRead: called for %s id: %s", d.Get("name").(string), d.Id())
image, err := utilityImageCheckPresence(d, m)
if image == nil {
d.SetId("")
return err
}
d.Set("name", image.Name)
d.Set("drivers", image.Drivers)
d.Set("url", image.Url)
d.Set("gid", image.Gid)
d.Set("image_id", image.ImageId)
d.Set("boot_type", image.Boottype)
d.Set("image_type", image.Imagetype)
d.Set("bootable", image.Bootable)
d.Set("sep_id", image.SepId)
d.Set("unc_path", image.UNCPath)
d.Set("link_to", image.LinkTo)
d.Set("status", image.Status)
d.Set("tech_status", image.TechStatus)
d.Set("version", image.Version)
d.Set("size", image.Size)
d.Set("enabled", image.Enabled)
d.Set("computeci_id", image.ComputeciId)
d.Set("pool_name", image.PoolName)
d.Set("username", image.Username)
d.Set("username_dl", image.UsernameDL)
d.Set("password", image.Password)
d.Set("password_dl", image.PasswordDL)
d.Set("account_id", image.AccountId)
d.Set("guid", image.Guid)
d.Set("milestones", image.Milestones)
d.Set("provider_name", image.ProviderName)
d.Set("purge_attempts", image.PurgeAttempts)
d.Set("reference_id", image.ReferenceId)
d.Set("res_id", image.ResId)
d.Set("res_name", image.ResName)
d.Set("rescuecd", image.Rescuecd)
d.Set("architecture", image.Architecture)
d.Set("meta", flattenMeta(image.Meta))
d.Set("hot_resize", image.Hotresize)
d.Set("history", flattenHistory(image.History))
d.Set("last_modified", image.LastModified)
d.Set("desc", image.Desc)
d.Set("shared_with", image.SharedWith)
return nil
}
func resourceImageDelete(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceImageDelete: called for %s, id: %s", d.Get("name").(string), d.Id())
image, err := utilityImageCheckPresence(d, m)
if image == nil {
if err != nil {
return err
}
return nil
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
if reason, ok := d.GetOk("reason"); ok {
urlValues.Add("reason", reason.(string))
} else {
urlValues.Add("reason", "")
}
if permanently, ok := d.GetOk("permanently"); ok {
urlValues.Add("permanently", strconv.FormatBool(permanently.(bool)))
}
_, err = controller.decortAPICall("POST", imageDeleteAPI, urlValues)
if err != nil {
return err
}
d.SetId("")
return nil
}
func resourceImageExists(d *schema.ResourceData, m interface{}) (bool, error) {
log.Debugf("resourceImageExists: called for %s, id: %s", d.Get("name").(string), d.Id())
image, err := utilityImageCheckPresence(d, m)
if image == nil {
if err != nil {
return false, err
}
return false, nil
}
return true, nil
}
func resourceImageEditName(d *schema.ResourceDiff, m interface{}) error {
log.Debugf("resourceImageEditName: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
urlValues.Add("name", d.Get("name").(string))
_, err := c.decortAPICall("POST", imageEditNameAPI, urlValues)
if err != nil {
return err
}
return nil
}
func resourceImageEdit(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
urlValues.Add("name", d.Get("name").(string))
urlValues.Add("username", d.Get("username").(string))
urlValues.Add("password", d.Get("password").(string))
urlValues.Add("accountId", strconv.Itoa(d.Get("account_id").(int)))
urlValues.Add("bootable", strconv.FormatBool(d.Get("bootable").(bool)))
urlValues.Add("hotresize", strconv.FormatBool(d.Get("hot_resize").(bool)))
//_, err := c.decortAPICall("POST", imageEditAPI, urlValues)
_, err := c.decortAPICall("POST", imageEditAPI, urlValues)
if err != nil {
err = resourceImageRead(d, m)
if err != nil {
return err
}
return nil
}
err = resourceImageRead(d, m)
if err != nil {
return err
}
return nil
}
func resourceImageChangeEnabled(d *schema.ResourceDiff, m interface{}) error {
var api string
c := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
if d.Get("enabled").(bool) {
api = imageEnableAPI
} else {
api = imageDisableAPI
}
resp, err := c.decortAPICall("POST", api, urlValues)
if err != nil {
return err
}
res, err := strconv.ParseBool(resp)
if err != nil {
return err
}
if !res {
return errors.New("Cannot enable/disable")
}
return nil
}
func resourceImageLink(d *schema.ResourceDiff, m interface{}) error {
log.Debugf("resourceVirtualImageLink: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
urlValues.Add("targetId", strconv.Itoa(d.Get("link_to").(int)))
_, err := c.decortAPICall("POST", imageLinkAPI, urlValues)
if err != nil {
return err
}
return nil
}
func resourceImageShare(d *schema.ResourceDiff, m interface{}) error {
log.Debugf("resourceImageShare: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
accIds := d.Get("shared_with").([]interface{})
temp := ""
l := len(accIds)
for i, accId := range accIds {
s := strconv.Itoa(accId.(int))
if i != (l - 1) {
s += ",\n"
} else {
s += "\n"
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("accounts", temp)
_, err := c.decortAPICall("POST", imageShareAPI, urlValues)
if err != nil {
return err
}
return nil
}
func resourceImageChangeComputeci(d *schema.ResourceDiff, m interface{}) error {
c := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
computeci := d.Get("computeci_id").(int)
api := ""
if computeci == 0 {
api = imageComputeciUnsetAPI
} else {
urlValues.Add("computeciId", strconv.Itoa(computeci))
api = imageComputeciSetAPI
}
_, err := c.decortAPICall("POST", api, urlValues)
if err != nil {
return err
}
return nil
}
func resourceImageUpdateNodes(d *schema.ResourceDiff, m interface{}) error {
log.Debugf("resourceImageUpdateNodes: called for %s, id: %s", d.Get("name").(string), d.Id())
c := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
enabledStacks := d.Get("enabled_stacks").([]interface{})
temp := ""
l := len(enabledStacks)
for i, stackId := range enabledStacks {
s := stackId.(string)
if i != (l - 1) {
s += ","
}
temp = temp + s
}
temp = "[" + temp + "]"
urlValues.Add("enabledStacks", temp)
_, err := c.decortAPICall("POST", imageUpdateNodesAPI, urlValues)
if err != nil {
return err
}
return nil
}
func resourceImageSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of the rescue disk",
},
"url": {
Type: schema.TypeString,
Required: true,
Description: "URL where to download media from",
},
"gid": {
Type: schema.TypeInt,
Required: true,
Description: "grid (platform) ID where this template should be create in",
},
"boot_type": {
Type: schema.TypeString,
Required: true,
Description: "Boot type of image bios or uefi",
},
"image_type": {
Type: schema.TypeString,
Required: true,
Description: "Image type linux, windows or other",
},
"drivers": {
Type: schema.TypeList,
Required: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
},
"meta": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "meta",
},
"hot_resize": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Does this machine supports hot resize",
},
"username": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Optional username for the image",
},
"password": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Optional password for the image",
},
"account_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "AccountId to make the image exclusive",
},
"username_dl": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "username for upload binary media",
},
"password_dl": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "password for upload binary media",
},
"sep_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "storage endpoint provider ID",
},
"pool_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "pool for image create",
},
"architecture": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
},
"image_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "image id",
},
"permanently": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Whether to completely delete the image",
},
"bootable": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Does this image boot OS",
},
"unc_path": {
Type: schema.TypeString,
Computed: true,
Description: "unc path",
},
"link_to": {
Type: schema.TypeInt,
Computed: true,
Description: "",
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: "status",
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
Description: "tech atatus",
},
"version": {
Type: schema.TypeString,
Computed: true,
Description: "version",
},
"size": {
Type: schema.TypeInt,
Computed: true,
Description: "image size",
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"computeci_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"provider_name": {
Type: schema.TypeString,
Computed: true,
},
"purge_attempts": {
Type: schema.TypeInt,
Computed: true,
},
"reference_id": {
Type: schema.TypeString,
Computed: true,
},
"res_id": {
Type: schema.TypeString,
Computed: true,
},
"res_name": {
Type: schema.TypeString,
Computed: true,
},
"rescuecd": {
Type: schema.TypeBool,
Computed: true,
},
"reason": {
Type: schema.TypeString,
Optional: true,
},
"last_modified": {
Type: schema.TypeInt,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"shared_with": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"sync": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Create image from a media identified by URL (in synchronous mode)",
},
"enabled_stacks": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"history": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"guid": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"timestamp": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
}
}
func resourceImage() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourceImageCreate,
Read: resourceImageRead,
Update: resourceImageEdit,
Delete: resourceImageDelete,
Exists: resourceImageExists,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout60s,
Read: &Timeout30s,
Update: &Timeout60s,
Delete: &Timeout60s,
Default: &Timeout60s,
},
CustomizeDiff: customdiff.All(
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
if old.(bool) != new.(bool) {
return true
}
return false
}, resourceImageChangeEnabled),
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
if old.(string) != new.(string) && old.(string) != "" {
return true
}
return false
}, resourceImageEditName),
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
o := old.([]interface{})
n := new.([]interface{})
if len(o) != len(n) {
return true
} else if len(o) == 0 {
return false
}
count := 0
for i, v := range n {
if v.(int) == o[i].(int) {
count++
}
}
if count == 0 {
return true
}
return false
}, resourceImageShare),
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
if old.(int) != new.(int) {
return true
}
return false
}, resourceImageChangeComputeci),
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
o := old.([]interface{})
n := new.([]interface{})
if len(o) != len(n) {
return true
} else if len(o) == 0 {
return false
}
count := 0
for i, v := range n {
if v.(string) == o[i].(string) {
count++
}
}
if count == 0 {
return true
}
return false
}, resourceImageUpdateNodes),
),
Schema: resourceImageSchemaMake(),
}
}
func flattenMeta(m []interface{}) []string {
output := []string{}
for _, item := range m {
switch d := item.(type) {
case string:
output = append(output, d)
case int:
output = append(output, strconv.Itoa(d))
case int64:
output = append(output, strconv.FormatInt(d, 10))
case float64:
output = append(output, strconv.FormatInt(int64(d), 10))
default:
output = append(output, "")
}
}
return output
}
func flattenHistory(history []History) []map[string]interface{} {
temp := make([]map[string]interface{}, 0)
for _, item := range history {
t := map[string]interface{}{
"id": item.Id,
"guid": item.Guid,
"timestamp": item.Timestamp,
}
temp = append(temp, t)
}
return temp
}

395
decort/resource_k8s.go Normal file
View File

@@ -0,0 +1,395 @@
/*
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))
_, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues)
if err != nil {
return err
}
} else {
for i := wg.Num - 1; i >= newWorkers.Num; i-- {
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
_, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues)
if err != nil {
return err
}
}
}
}
return nil
}
func resourceK8sDelete(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceK8sDelete: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
k8s, err := utilityK8sCheckPresence(d, m)
if k8s == nil {
if err != nil {
return err
}
return nil
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("k8sId", d.Id())
urlValues.Add("permanently", "true")
_, err = controller.decortAPICall("POST", K8sDeleteAPI, urlValues)
if err != nil {
return err
}
return nil
}
func resourceK8sExists(d *schema.ResourceData, m interface{}) (bool, error) {
log.Debugf("resourceK8sExists: called with id %s, rg %d", d.Id(), d.Get("rg_id").(int))
k8s, err := utilityK8sCheckPresence(d, m)
if k8s == nil {
return false, err
}
return true, nil
}
func resourceK8sSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "Name of the cluster.",
},
"rg_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "Resource group ID that this instance belongs to.",
},
"k8sci_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "ID of the k8s catalog item to base this instance on.",
},
"wg_name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Name for first worker group created with cluster.",
},
"masters": {
Type: schema.TypeList,
Optional: true,
ForceNew: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: nodeK8sSubresourceSchemaMake(),
},
Description: "Master node(s) configuration.",
},
"workers": {
Type: schema.TypeList,
Optional: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: nodeK8sSubresourceSchemaMake(),
},
Description: "Worker node(s) configuration.",
},
//"with_lb": {
//Type: schema.TypeBool,
//Optional: true,
//ForceNew: true,
//Default: true,
//Description: "Create k8s with load balancer if true.",
//},
"extnet_id": {
Type: schema.TypeInt,
Optional: true,
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(),
}
}

250
decort/resource_k8s_wg.go Normal file
View File

@@ -0,0 +1,250 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
log "github.com/sirupsen/logrus"
)
func resourceK8sWgCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceK8sWgCreate: called with k8s id %d", d.Get("k8s_id").(int))
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
urlValues.Add("name", d.Get("name").(string))
urlValues.Add("workerNum", strconv.Itoa(d.Get("num").(int)))
urlValues.Add("workerCpu", strconv.Itoa(d.Get("cpu").(int)))
urlValues.Add("workerRam", strconv.Itoa(d.Get("ram").(int)))
urlValues.Add("workerDisk", strconv.Itoa(d.Get("disk").(int)))
resp, err := controller.decortAPICall("POST", K8sWgCreateAPI, urlValues)
if err != nil {
return err
}
d.SetId(resp)
// This code is the supposed flow, but at the time of writing it's not yet implemented by the platfom
//urlValues = &url.Values{}
//urlValues.Add("auditId", strings.Trim(resp, `"`))
//for {
//resp, err := controller.decortAPICall("POST", AsyncTaskGetAPI, urlValues)
//if err != nil {
//return err
//}
//task := AsyncTask{}
//if err := json.Unmarshal([]byte(resp), &task); err != nil {
//return err
//}
//log.Debugf("resourceK8sCreate: workers group creating - %s", task.Stage)
//if task.Completed {
//if task.Error != "" {
//return fmt.Errorf("cannot create workers group: %v", task.Error)
//}
//d.SetId(strconv.Itoa(int(task.Result)))
//break
//}
//time.Sleep(time.Second * 5)
//}
return nil
}
func resourceK8sWgRead(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceK8sWgRead: called with k8s id %d", d.Get("k8s_id").(int))
wg, err := utilityK8sWgCheckPresence(d, m)
if wg == nil {
d.SetId("")
return err
}
d.Set("name", wg.Name)
d.Set("num", wg.Num)
d.Set("cpu", wg.Cpu)
d.Set("ram", wg.Ram)
d.Set("disk", wg.Disk)
return nil
}
func resourceK8sWgUpdate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceK8sWgUpdate: called with k8s id %d", d.Get("k8s_id").(int))
controller := m.(*ControllerCfg)
wg, err := utilityK8sWgCheckPresence(d, m)
if err != nil {
return nil
}
urlValues := &url.Values{}
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
urlValues.Add("workersGroupId", d.Id())
newNum := d.Get("num").(int)
if newNum > wg.Num {
urlValues.Add("num", strconv.Itoa(newNum-wg.Num))
_, err := controller.decortAPICall("POST", K8sWorkerAddAPI, urlValues)
if err != nil {
return err
}
} else {
for i := wg.Num - 1; i >= newNum; i-- {
urlValues.Set("workerId", strconv.Itoa(wg.DetailedInfo[i].ID))
_, err := controller.decortAPICall("POST", K8sWorkerDeleteAPI, urlValues)
if err != nil {
return err
}
}
}
return nil
}
func resourceK8sWgDelete(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceK8sWgDelete: called with k8s id %d", d.Get("k8s_id").(int))
wg, err := utilityK8sWgCheckPresence(d, m)
if wg == nil {
if err != nil {
return err
}
return nil
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
urlValues.Add("workersGroupId", strconv.Itoa(wg.ID))
_, err = controller.decortAPICall("POST", K8sWgDeleteAPI, urlValues)
if err != nil {
return err
}
return nil
}
func resourceK8sWgExists(d *schema.ResourceData, m interface{}) (bool, error) {
log.Debugf("resourceK8sWgExists: called with k8s id %d", d.Get("k8s_id").(int))
wg, err := utilityK8sWgCheckPresence(d, m)
if wg == nil {
if err != nil {
return false, err
}
return false, nil
}
return true, nil
}
func resourceK8sWgSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"k8s_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "ID of k8s instance.",
},
"name": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
Description: "Name of the worker group.",
},
"num": {
Type: schema.TypeInt,
Optional: true,
Default: 1,
Description: "Number of worker nodes to create.",
},
"cpu": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Default: 1,
Description: "Worker node CPU count.",
},
"ram": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Default: 1024,
Description: "Worker node RAM in MB.",
},
"disk": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
Default: 0,
Description: "Worker node boot disk size. If unspecified or 0, size is defined by OS image size.",
},
}
}
func resourceK8sWg() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourceK8sWgCreate,
Read: resourceK8sWgRead,
Update: resourceK8sWgUpdate,
Delete: resourceK8sWgDelete,
Exists: resourceK8sWgExists,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout20m,
Read: &Timeout30s,
Update: &Timeout20m,
Delete: &Timeout60s,
Default: &Timeout60s,
},
Schema: resourceK8sWgSchemaMake(),
}
}

View File

@@ -0,0 +1,263 @@
/*
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(),
}
}

200
decort/resource_pfw.go Normal file
View File

@@ -0,0 +1,200 @@
/*
Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"fmt"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
"github.com/hashicorp/terraform-plugin-sdk/helper/validation"
log "github.com/sirupsen/logrus"
)
func resourcePfwCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourcePfwCreate: called for compute %d", d.Get("compute_id").(int))
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
urlValues.Add("publicPortStart", strconv.Itoa(d.Get("public_port_start").(int)))
urlValues.Add("localBasePort", strconv.Itoa(d.Get("local_base_port").(int)))
urlValues.Add("proto", d.Get("proto").(string))
if portEnd, ok := d.GetOk("public_port_end"); ok {
urlValues.Add("publicPortEnd", strconv.Itoa(portEnd.(int)))
}
pfwId, err := controller.decortAPICall("POST", ComputePfwAddAPI, urlValues)
if err != nil {
return err
}
d.SetId(fmt.Sprintf("%d-%s", d.Get("compute_id").(int), pfwId))
pfw, err := utilityPfwCheckPresence(d, m)
if err != nil {
return err
}
d.Set("local_ip", pfw.LocalIP)
if _, ok := d.GetOk("public_port_end"); !ok {
d.Set("public_port_end", pfw.PublicPortEnd)
}
return nil
}
func resourcePfwRead(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourcePfwRead: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
pfw, err := utilityPfwCheckPresence(d, m)
if pfw == nil {
d.SetId("")
return err
}
d.Set("compute_id", pfw.ComputeID)
d.Set("public_port_start", pfw.PublicPortStart)
d.Set("public_port_end", pfw.PublicPortEnd)
d.Set("local_ip", pfw.LocalIP)
d.Set("local_base_port", pfw.LocalPort)
d.Set("proto", pfw.Protocol)
return nil
}
func resourcePfwDelete(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourcePfwDelete: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
pfw, err := utilityPfwCheckPresence(d, m)
if pfw == nil {
if err != nil {
return err
}
return nil
}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
urlValues.Add("ruleId", strconv.Itoa(pfw.ID))
_, err = controller.decortAPICall("POST", ComputePfwDelAPI, urlValues)
if err != nil {
return err
}
return nil
}
func resourcePfwExists(d *schema.ResourceData, m interface{}) (bool, error) {
log.Debugf("resourcePfwExists: called for compute %d, rule %s", d.Get("compute_id").(int), d.Id())
pfw, err := utilityPfwCheckPresence(d, m)
if pfw == nil {
if err != nil {
return false, err
}
return false, nil
}
return true, nil
}
func resourcePfwSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"compute_id": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
Description: "ID of compute instance.",
},
"public_port_start": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 65535),
Description: "External start port number for the rule.",
},
"public_port_end": {
Type: schema.TypeInt,
Optional: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 65535),
Description: "End port number (inclusive) for the ranged rule.",
},
"local_ip": {
Type: schema.TypeString,
Computed: true,
Description: "IP address of compute instance.",
},
"local_base_port": {
Type: schema.TypeInt,
Required: true,
ForceNew: true,
ValidateFunc: validation.IntBetween(1, 65535),
Description: "Internal base port number.",
},
"proto": {
Type: schema.TypeString,
Required: true,
ForceNew: true,
ValidateFunc: validation.StringInSlice([]string{"tcp", "udp"}, false),
Description: "Network protocol, either 'tcp' or 'udp'.",
},
}
}
func resourcePfw() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourcePfwCreate,
Read: resourcePfwRead,
Delete: resourcePfwDelete,
Exists: resourcePfwExists,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout60s,
Read: &Timeout30s,
Update: &Timeout60s,
Delete: &Timeout60s,
Default: &Timeout60s,
},
Schema: resourcePfwSchemaMake(),
}
}

View File

@@ -24,6 +24,7 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p
package decort
import (
"encoding/json"
"fmt"
"net/url"
@@ -122,6 +123,19 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
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)
@@ -130,7 +144,7 @@ func resourceResgroupCreate(d *schema.ResourceData, m interface{}) error {
func resourceResgroupRead(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceResgroupRead: called for RG name %s, account ID %s",
d.Get("name").(string), d.Get("account_id").(int))
rg_facts, err := utilityResgroupCheckPresence(d, m)
if rg_facts == "" {
// if empty string is returned from utilityResgroupCheckPresence then there is no
@@ -165,9 +179,8 @@ func resourceResgroupUpdate(d *schema.ResourceData, m interface{}) error {
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)
do_general_update := false // will be true if general RG update is necessary (API rg/update)
controller := m.(*ControllerCfg)
url_values := &url.Values{}
@@ -314,18 +327,18 @@ func resourceResgroup() *schema.Resource {
},
"account_id": {
Type: schema.TypeInt,
Required: true,
Type: schema.TypeInt,
Required: true,
ValidateFunc: validation.IntAtLeast(1),
Description: "Unique ID of the account, which this resource group belongs to.",
Description: "Unique ID of the account, which this resource group belongs to.",
},
"def_net_type": {
Type: schema.TypeString,
Optional: true,
Default: "PRIVATE",
Type: schema.TypeString,
Optional: true,
Default: "PRIVATE",
ValidateFunc: validation.StringInSlice([]string{"PRIVATE", "PUBLIC", "NONE"}, false),
Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.",
Description: "Type of the network, which this resource group will use as default for its computes - PRIVATE or PUBLIC or NONE.",
},
"def_net_id": {
@@ -354,7 +367,7 @@ func resourceResgroup() *schema.Resource {
},
/* commented out, as in this version of provider we use default Grid ID
"grid_id": {
"grid_id": {
Type: schema.TypeInt,
Optional: true,
Default: 0, // if 0 is passed, default Grid ID will be used
@@ -367,6 +380,7 @@ func resourceResgroup() *schema.Resource {
"quota": {
Type: schema.TypeList,
Optional: true,
Computed: true,
MaxItems: 1,
Elem: &schema.Resource{
Schema: quotaRgSubresourceSchemaMake(),
@@ -387,30 +401,30 @@ func resourceResgroup() *schema.Resource {
},
/*
"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,
"status": {
Type: schema.TypeString,
Computed: true,
Description: "Current status of this resource group.",
},
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,
"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.",
},
Description: "List of computes deployed in this resource group.",
},
*/
},
}

560
decort/resource_sep.go Normal file
View File

@@ -0,0 +1,560 @@
/*
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{}
err := resourceSepRead(d, m)
if 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")
d1 := t1.([]interface{})
d2 := t2.([]interface{})
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
consumedIds := make([]interface{}, 0)
temp := ""
api := ""
if 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 {
if old.(bool) != new.(bool) {
return true
}
return false
}, 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++
}
}
if count == 0 {
return true
}
return false
}, 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++
}
}
if count == 0 {
return true
}
return false
}, resourceSepUpdateProviders),
),
}
}

View File

@@ -0,0 +1,197 @@
/*
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")
}
resourceSepConfigRead(d, m)
return nil
}
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(),
}
}

203
decort/resource_snapshot.go Normal file
View File

@@ -0,0 +1,203 @@
/*
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 == false {
return true
}
return false
}, resourceSnapshotRollback),
),
Schema: resourceSnapshotSchemaMake(),
}
}

View File

@@ -0,0 +1,402 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/customdiff"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
log "github.com/sirupsen/logrus"
)
func resourceVirtualImageCreate(d *schema.ResourceData, m interface{}) error {
log.Debugf("resourceImageCreate: called for image %s", d.Get("name").(string))
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("name", d.Get("name").(string))
urlValues.Add("targetId", strconv.Itoa(d.Get("target_id").(int)))
imageId, err := controller.decortAPICall("POST", imageCreateVirtualAPI, urlValues)
if err != nil {
return err
}
d.SetId(imageId)
d.Set("image_id", imageId)
image, err := utilityImageCheckPresence(d, m)
if err != nil {
return err
}
d.SetId(strconv.Itoa(image.ImageId))
d.Set("bootable", image.Bootable)
//d.Set("image_id", image.ImageId)
err = resourceImageRead(d, m)
if err != nil {
return err
}
return nil
}
func resourceVirtualImageSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"name": {
Type: schema.TypeString,
Required: true,
Description: "name of the virtual image to create",
},
"target_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of real image to link this virtual image to upon creation",
},
"history": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"guid": {
Type: schema.TypeString,
Computed: true,
},
"id": {
Type: schema.TypeInt,
Computed: true,
},
"timestamp": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"url": {
Type: schema.TypeString,
Computed: true,
Description: "URL where to download media from",
},
"gid": {
Type: schema.TypeInt,
Computed: true,
Description: "grid (platform) ID where this template should be create in",
},
"boot_type": {
Type: schema.TypeString,
Computed: true,
Description: "Boot type of image bios or uefi",
},
"image_type": {
Type: schema.TypeString,
Computed: true,
Description: "Image type linux, windows or other",
},
"drivers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]",
},
"meta": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
Description: "meta",
},
"hot_resize": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Does this machine supports hot resize",
},
"username": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Optional username for the image",
},
"password": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "Optional password for the image",
},
"account_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "AccountId to make the image exclusive",
},
"username_dl": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "username for upload binary media",
},
"password_dl": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "password for upload binary media",
},
"sep_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "storage endpoint provider ID",
},
"pool_name": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "pool for image create",
},
"architecture": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "binary architecture of this image, one of X86_64 of PPC64_LE",
},
"image_id": {
Type: schema.TypeInt,
Computed: true,
Description: "image id",
},
"permanently": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Whether to completely delete the image",
},
"bootable": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
Description: "Does this image boot OS",
},
"unc_path": {
Type: schema.TypeString,
Computed: true,
Description: "unc path",
},
"link_to": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "",
},
"status": {
Type: schema.TypeString,
Computed: true,
Description: "status",
},
"tech_status": {
Type: schema.TypeString,
Computed: true,
Description: "tech atatus",
},
"version": {
Type: schema.TypeString,
Computed: true,
Description: "version",
},
"size": {
Type: schema.TypeInt,
Computed: true,
Description: "image size",
},
"enabled": {
Type: schema.TypeBool,
Optional: true,
Computed: true,
},
"computeci_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
},
"guid": {
Type: schema.TypeInt,
Computed: true,
},
"milestones": {
Type: schema.TypeInt,
Computed: true,
},
"provider_name": {
Type: schema.TypeString,
Computed: true,
},
"purge_attempts": {
Type: schema.TypeInt,
Computed: true,
},
"reference_id": {
Type: schema.TypeString,
Computed: true,
},
"res_id": {
Type: schema.TypeString,
Computed: true,
},
"res_name": {
Type: schema.TypeString,
Computed: true,
},
"rescuecd": {
Type: schema.TypeBool,
Computed: true,
},
"reason": {
Type: schema.TypeString,
Optional: true,
},
"last_modified": {
Type: schema.TypeInt,
Computed: true,
},
"desc": {
Type: schema.TypeString,
Computed: true,
},
"enabled_stacks": {
Type: schema.TypeList,
Optional: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"shared_with": {
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
}
}
func resourceVirtualImage() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
Create: resourceVirtualImageCreate,
Read: resourceImageRead,
Update: resourceImageEdit,
Delete: resourceImageDelete,
Exists: resourceImageExists,
Importer: &schema.ResourceImporter{
State: schema.ImportStatePassthrough,
},
Timeouts: &schema.ResourceTimeout{
Create: &Timeout60s,
Read: &Timeout30s,
Update: &Timeout60s,
Delete: &Timeout60s,
Default: &Timeout60s,
},
CustomizeDiff: customdiff.All(
customdiff.IfValueChange("enabled", func(old, new, meta interface{}) bool {
if old.(bool) != new.(bool) {
return true
}
return false
}, resourceImageChangeEnabled),
customdiff.IfValueChange("link_to", func(old, new, meta interface{}) bool {
if old.(int) != new.(int) {
return true
}
return false
}, resourceImageLink),
customdiff.IfValueChange("name", func(old, new, meta interface{}) bool {
if old.(string) != new.(string) && old.(string) != "" {
return true
}
return false
}, resourceImageEditName),
customdiff.IfValueChange("shared_with", func(old, new, meta interface{}) bool {
o := old.([]interface{})
n := new.([]interface{})
if len(o) != len(n) {
return true
} else if len(o) == 0 {
return false
}
count := 0
for i, v := range n {
if v.(int) == o[i].(int) {
count++
}
}
if count == 0 {
return true
}
return false
}, resourceImageShare),
customdiff.IfValueChange("computeci_id", func(old, new, meta interface{}) bool {
if old.(int) != new.(int) {
return true
}
return false
}, resourceImageChangeComputeci),
customdiff.IfValueChange("enabled_stacks", func(old, new, meta interface{}) bool {
o := old.([]interface{})
n := new.([]interface{})
if len(o) != len(n) {
return true
} else if len(o) == 0 {
return false
}
count := 0
for i, v := range n {
if v.(string) == o[i].(string) {
count++
}
}
if count == 0 {
return true
}
return false
}, resourceImageUpdateNodes),
),
Schema: resourceVirtualImageSchemaMake(),
}
}

62
decort/utility_grid.go Normal file
View File

@@ -0,0 +1,62 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"errors"
"fmt"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityGridCheckPresence(d *schema.ResourceData, m interface{}) (*Grid, error) {
grid := &Grid{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if gridId, ok := d.GetOk("grid_id"); ok {
urlValues.Add("gridId", strconv.Itoa(gridId.(int)))
} else {
return nil, errors.New(fmt.Sprintf("grid_id is required"))
}
log.Debugf("utilityGridCheckPresence: load grid")
gridRaw, err := controller.decortAPICall("POST", GridGetAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(gridRaw), grid)
if err != nil {
return nil, err
}
return grid, nil
}

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityGridListCheckPresence(d *schema.ResourceData, m interface{}) (GridList, error) {
gridList := GridList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if page, ok := d.GetOk("page"); ok {
urlValues.Add("page", strconv.Itoa(page.(int)))
}
if size, ok := d.GetOk("size"); ok {
urlValues.Add("size", strconv.Itoa(size.(int)))
}
log.Debugf("utilityGridListCheckPresence: load grid list")
gridListRaw, err := controller.decortAPICall("POST", GridListGetAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(gridListRaw), &gridList)
if err != nil {
return nil, err
}
return gridList, nil
}

62
decort/utility_image.go Normal file
View File

@@ -0,0 +1,62 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"errors"
"fmt"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityImageCheckPresence(d *schema.ResourceData, m interface{}) (*Image, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if (strconv.Itoa(d.Get("image_id").(int))) != "0" {
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
} else {
urlValues.Add("imageId", d.Id())
}
resp, err := controller.decortAPICall("POST", imageGetAPI, urlValues)
if err != nil {
return nil, err
}
if resp == "" {
return nil, nil
}
image := &Image{}
if err := json.Unmarshal([]byte(resp), image); err != nil {
return nil, errors.New(fmt.Sprint("Can not unmarshall data to image: ", resp, " ", image))
}
return image, nil
}

View File

@@ -0,0 +1,68 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityImageListCheckPresence(d *schema.ResourceData, m interface{}) (ImageList, error) {
imageList := ImageList{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
if sepId, ok := d.GetOk("sep_id"); ok {
urlValues.Add("sepId", strconv.Itoa(sepId.(int)))
}
if sharedWith, ok := d.GetOk("shared_with"); ok {
urlValues.Add("sharedWith", strconv.Itoa(sharedWith.(int)))
}
if page, ok := d.GetOk("page"); ok {
urlValues.Add("page", strconv.Itoa(page.(int)))
}
if size, ok := d.GetOk("size"); ok {
urlValues.Add("size", strconv.Itoa(size.(int)))
}
log.Debugf("utilityImageListCheckPresence: load image list")
imageListRaw, err := controller.decortAPICall("POST", imageListGetAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(imageListRaw), &imageList)
if err != nil {
return nil, err
}
return imageList, nil
}

View File

@@ -0,0 +1,56 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityImageListStacksCheckPresence(d *schema.ResourceData, m interface{}) (ImageListStacks, error) {
imageListStacks := ImageListStacks{}
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int)))
log.Debugf("utilityImageListStacksCheckPresence: load image list")
imageListRaw, err := controller.decortAPICall("POST", imageListStacksApi, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(imageListRaw), &imageListStacks)
if err != nil {
return nil, err
}
return imageListStacks, nil
}

54
decort/utility_k8s.go Normal file
View File

@@ -0,0 +1,54 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityK8sCheckPresence(d *schema.ResourceData, m interface{}) (*K8sRecord, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("k8sId", d.Id())
resp, err := controller.decortAPICall("POST", K8sGetAPI, urlValues)
if err != nil {
return nil, err
}
if resp == "" {
return nil, nil
}
var k8s K8sRecord
if err := json.Unmarshal([]byte(resp), &k8s); err != nil {
return nil, err
}
return &k8s, nil
}

66
decort/utility_k8s_wg.go Normal file
View File

@@ -0,0 +1,66 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityK8sWgCheckPresence(d *schema.ResourceData, m interface{}) (*K8sNodeRecord, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("k8sId", strconv.Itoa(d.Get("k8s_id").(int)))
resp, err := controller.decortAPICall("POST", K8sGetAPI, urlValues)
if err != nil {
return nil, err
}
if resp == "" {
return nil, nil
}
var k8s K8sRecord
if err := json.Unmarshal([]byte(resp), &k8s); err != nil {
return nil, err
}
id, err := strconv.Atoi(d.Id())
if err != nil {
return nil, err
}
for _, wg := range k8s.Groups.Workers {
if wg.ID == id {
return &wg, nil
}
}
return nil, nil
}

View File

@@ -0,0 +1,63 @@
/*
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
}
pcidevice := &Pcidevice{}
flag := false
for _, pd := range pcideviceList {
if pd.ID == pcideviceId {
pcidevice = &pd
flag = true
break
}
}
if !flag {
return nil, nil
}
return pcidevice, nil
}

View File

@@ -0,0 +1,50 @@
/*
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(d *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
}

68
decort/utility_pfw.go Normal file
View File

@@ -0,0 +1,68 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Petr Krutov, <petr.krutov@digitalenergy.online>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
"strings"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilityPfwCheckPresence(d *schema.ResourceData, m interface{}) (*PfwRecord, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
resp, err := controller.decortAPICall("POST", ComputePfwListAPI, urlValues)
if err != nil {
return nil, err
}
if resp == "" {
return nil, nil
}
idS := strings.Split(d.Id(), "-")[1]
id, err := strconv.Atoi(idS)
if err != nil {
return nil, err
}
var pfws []PfwRecord
if err := json.Unmarshal([]byte(resp), &pfws); err != nil {
return nil, err
}
for _, pfw := range pfws {
if pfw.ID == id {
return &pfw, nil
}
}
return nil, nil
}

61
decort/utility_sep.go Normal file
View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func 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
}

View File

@@ -0,0 +1,57 @@
/*
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
}

View File

@@ -0,0 +1,54 @@
/*
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
}

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilitySepDiskListCheckPresence(d *schema.ResourceData, m interface{}) ([]int, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
sepDiskList := SepDiskList{}
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
if poolName, ok := d.GetOk("pool_name"); ok {
urlValues.Add("pool_name", poolName.(string))
}
log.Debugf("utilitySepDiskListCheckPresence: load sep")
sepDiskListRaw, err := controller.decortAPICall("POST", sepDiskListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(sepDiskListRaw), &sepDiskList)
if err != nil {
return nil, err
}
return sepDiskList, nil
}

View File

@@ -0,0 +1,61 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Author: Stanislav Solovev, <spsolovev@digitalenergy.online>, <svs1370@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration
Technology platfom.
Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates.
*/
package decort
import (
"encoding/json"
"net/url"
"strconv"
log "github.com/sirupsen/logrus"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilitySepListCheckPresence(d *schema.ResourceData, m interface{}) (SepList, error) {
sepList := SepList{}
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("utilitySepListCheckPresence: load image list")
sepListRaw, err := controller.decortAPICall("POST", sepListAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(sepListRaw), &sepList)
if err != nil {
return nil, err
}
return sepList, nil
}

View File

@@ -0,0 +1,58 @@
/*
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 utilitySepPoolCheckPresence(d *schema.ResourceData, m interface{}) (SepPool, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
sepPool := SepPool{}
urlValues.Add("sep_id", strconv.Itoa(d.Get("sep_id").(int)))
urlValues.Add("pool_name", d.Get("pool_name").(string))
log.Debugf("utilitySepDesPoolCheckPresence: load sep")
sepPoolRaw, err := controller.decortAPICall("POST", sepGetPoolAPI, urlValues)
if err != nil {
return nil, err
}
err = json.Unmarshal([]byte(sepPoolRaw), &sepPool)
if err != nil {
return nil, err
}
return sepPool, nil
}

View File

@@ -0,0 +1,55 @@
/*
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"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilitySnapshotCheckPresence(d *schema.ResourceData, m interface{}) (*Snapshot, error) {
snapShotList, err := utilitySnapshotListCheckPresence(d, m)
if err != nil {
return nil, err
}
findId := ""
if (d.Get("guid").(string)) != "" {
findId = d.Get("guid").(string)
} else {
findId = d.Id()
}
for _, s := range snapShotList {
if s.Guid == findId {
return &s, nil
}
}
return nil, errors.New("snapshot not found")
}

View File

@@ -0,0 +1,56 @@
/*
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"
"net/url"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
)
func utilitySnapshotListCheckPresence(d *schema.ResourceData, m interface{}) (SnapshotList, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("computeId", strconv.Itoa(d.Get("compute_id").(int)))
resp, err := controller.decortAPICall("POST", snapshotListAPI, urlValues)
if err != nil {
return nil, err
}
if resp == "" {
return nil, nil
}
snapshotList := SnapshotList{}
if err := json.Unmarshal([]byte(resp), &snapshotList); err != nil {
//return nil, errors.New(fmt.Sprint("Can not unmarshall data to snapshotList: ", resp, " ", snapshotList))
return nil, err
}
return snapshotList, nil
}

74
decort/utility_vgpu.go Normal file
View File

@@ -0,0 +1,74 @@
/*
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 utilityVGPUCheckPresence(d *schema.ResourceData, m interface{}) (*VGPU, error) {
controller := m.(*ControllerCfg)
urlValues := &url.Values{}
urlValues.Add("size", "50")
var vgpuId int
var err error
if vId, ok := d.GetOk("vgpu_id"); ok {
vgpuId = vId.(int)
} else {
vgpuId, err = strconv.Atoi(d.Id())
if err != nil {
return nil, err
}
}
for page := 1; ; page++ {
urlValues.Set("page", strconv.Itoa(page))
resp, err := controller.decortAPICall("POST", vgpuListAPI, urlValues)
if err != nil {
return nil, err
}
if resp == "[]" {
return nil, nil
}
var vgpus []VGPU
if err := json.Unmarshal([]byte(resp), &vgpus); err != nil {
return nil, err
}
for _, vgpu := range vgpus {
if vgpu.ID == vgpuId {
return &vgpu, nil
}
}
}
}

43
docs/data-sources/grid.md Normal file
View File

@@ -0,0 +1,43 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_grid Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_grid (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **grid_id** (Number)
### Optional
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **flag** (String)
- **gid** (Number)
- **guid** (Number)
- **id** (Number) The ID of this resource.
- **location_code** (String)
- **name** (String)
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)

View File

@@ -0,0 +1,50 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_grid_list Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_grid_list (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Optional
- **id** (String) The ID of this resource.
- **page** (Number) page number
- **size** (Number) page size
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **items** (List of Object) grid list (see [below for nested schema](#nestedatt--items))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)
<a id="nestedatt--items"></a>
### Nested Schema for `items`
Read-Only:
- **flag** (String)
- **gid** (Number)
- **guid** (Number)
- **id** (Number)
- **location_code** (String)
- **name** (String)

View File

@@ -17,21 +17,53 @@ description: |-
### Required
- **name** (String) Name of the image to locate. This parameter is case sensitive.
- **image_id** (Number) image id
### Optional
- **account_id** (Number) Optional ID of the account to limit image search to.
- **id** (String) The ID of this resource.
- **shared_with** (List of Number)
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **arch** (String) Binary architecture of this image.
- **pool** (String) Pool where this image is located.
- **sep_id** (Number) Storage end-point provider serving this image.
- **size** (Number) Size of the image in GB.
- **status** (String) Current model status of this image.
- **account_id** (Number) AccountId to make the image exclusive
- **architecture** (String) binary architecture of this image, one of X86_64 of PPC64_LE
- **boot_type** (String) Boot type of image bios or uefi
- **bootable** (Boolean) Does this image boot OS
- **computeci_id** (Number)
- **desc** (String)
- **drivers** (List of String) List of types of compute suitable for image. Example: [ "KVM_X86" ]
- **enabled** (Boolean)
- **gid** (Number) grid (platform) ID where this template should be create in
- **guid** (Number)
- **history** (List of Object) (see [below for nested schema](#nestedatt--history))
- **hot_resize** (Boolean) Does this machine supports hot resize
- **image_type** (String) Image type linux, windows or other
- **last_modified** (Number)
- **link_to** (Number)
- **meta** (List of String) meta
- **milestones** (Number)
- **name** (String) Name of the rescue disk
- **password** (String) Optional password for the image
- **password_dl** (String) password for upload binary media
- **permanently** (Boolean) Whether to completely delete the image
- **pool_name** (String) pool for image create
- **provider_name** (String)
- **purge_attempts** (Number)
- **reference_id** (String)
- **res_id** (String)
- **res_name** (String)
- **rescuecd** (Boolean)
- **sep_id** (Number) storage endpoint provider ID
- **size** (Number) image size
- **status** (String) status
- **tech_status** (String) tech atatus
- **unc_path** (String) unc path
- **url** (String) URL where to download media from
- **username** (String) Optional username for the image
- **username_dl** (String) username for upload binary media
- **version** (String) version
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
@@ -42,3 +74,13 @@ Optional:
- **read** (String)
<a id="nestedatt--history"></a>
### Nested Schema for `history`
Read-Only:
- **guid** (String)
- **id** (Number)
- **timestamp** (Number)

View File

@@ -0,0 +1,94 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_image_list Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_image_list (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Optional
- **id** (String) The ID of this resource.
- **page** (Number) page number
- **sep_id** (Number) filter images by storage endpoint provider ID
- **shared_with** (Number) filter images by account ID availability
- **size** (Number) page size
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **items** (List of Object) image list (see [below for nested schema](#nestedatt--items))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)
<a id="nestedatt--items"></a>
### Nested Schema for `items`
Read-Only:
- **account_id** (Number)
- **architecture** (String)
- **boot_type** (String)
- **bootable** (Boolean)
- **computeci_id** (Number)
- **desc** (String)
- **drivers** (List of String)
- **enabled** (Boolean)
- **gid** (Number)
- **guid** (Number)
- **history** (List of Object) (see [below for nested schema](#nestedobjatt--items--history))
- **hot_resize** (Boolean)
- **image_id** (Number)
- **image_type** (String)
- **last_modified** (Number)
- **link_to** (Number)
- **meta** (List of String)
- **milestones** (Number)
- **name** (String)
- **password** (String)
- **password_dl** (String)
- **permanently** (Boolean)
- **pool_name** (String)
- **provider_name** (String)
- **purge_attempts** (Number)
- **reference_id** (String)
- **res_id** (String)
- **res_name** (String)
- **rescuecd** (Boolean)
- **sep_id** (Number)
- **shared_with** (List of Number)
- **size** (Number)
- **status** (String)
- **tech_status** (String)
- **unc_path** (String)
- **url** (String)
- **username** (String)
- **username_dl** (String)
- **version** (String)
<a id="nestedobjatt--items--history"></a>
### Nested Schema for `items.history`
Read-Only:
- **guid** (String)
- **id** (Number)
- **timestamp** (Number)

View File

@@ -0,0 +1,63 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_image_list_stacks Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_image_list_stacks (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **image_id** (Number) image id
### Optional
- **id** (String) The ID of this resource.
- **page** (Number) page number
- **size** (Number) page size
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **items** (List of Object) items of stacks list (see [below for nested schema](#nestedatt--items))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)
<a id="nestedatt--items"></a>
### Nested Schema for `items`
Read-Only:
- **api_key** (String)
- **api_url** (String)
- **app_id** (String)
- **desc** (String)
- **drivers** (List of String)
- **error** (Number)
- **guid** (Number)
- **id** (Number)
- **images** (List of Number)
- **login** (String)
- **name** (String)
- **passwd** (String)
- **reference_id** (String)
- **status** (String)
- **type** (String)

View File

@@ -29,12 +29,12 @@ description: |-
- **account_id** (Number) ID of the account this compute instance belongs to.
- **account_name** (String) Name of the account this compute instance belongs to.
- **arch** (String) Hardware architecture of this compute instance.
- **boot_disk_id** (Number) This compute instance boot disk ID.
- **boot_disk_size** (Number) This compute instance boot disk size in GB.
- **cloud_init** (String) Placeholder for cloud_init parameters.
- **cpu** (Number) Number of CPUs allocated for this compute instance.
- **description** (String) User-defined text description of this compute instance.
- **driver** (String) Hardware architecture of this compute instance.
- **extra_disks** (Set of Number) IDs of the extra disk(s) attached to this compute.
- **image_id** (Number) ID of the OS image this compute instance is based on.
- **image_name** (String) Name of the OS image this compute instance is based on.

View File

@@ -0,0 +1,50 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_snapshot_list Data Source - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_snapshot_list (Data Source)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **compute_id** (Number) ID of the compute instance to create snapshot for.
### Optional
- **id** (String) The ID of this resource.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **items** (List of Object) snapshot list (see [below for nested schema](#nestedatt--items))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **default** (String)
- **read** (String)
<a id="nestedatt--items"></a>
### Nested Schema for `items`
Read-Only:
- **disks** (List of Number)
- **guid** (String)
- **label** (String)
- **timestamp** (Number)

View File

@@ -0,0 +1,89 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_cdrom_image Resource - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_cdrom_image (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **drivers** (List of String) List of types of compute suitable for image. Example: [ "KVM_X86" ]
- **gid** (Number) grid (platform) ID where this template should be create in
- **name** (String) Name of the rescue disk
- **url** (String) URL where to download ISO from
### Optional
- **account_id** (Number) AccountId to make the image exclusive
- **architecture** (String) binary architecture of this image, one of X86_64 of PPC64_LE
- **bootable** (Boolean) Does this image boot OS
- **computeci_id** (Number)
- **enabled** (Boolean)
- **enabled_stacks** (List of String)
- **hot_resize** (Boolean) Does this machine supports hot resize
- **id** (String) The ID of this resource.
- **password** (String) Optional password for the image
- **password_dl** (String) password for upload binary media
- **permanently** (Boolean) Whether to completely delete the image
- **pool_name** (String) pool for image create
- **sep_id** (Number) storage endpoint provider ID
- **shared_with** (List of Number)
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
- **username** (String) Optional username for the image
- **username_dl** (String) username for upload binary media
### Read-Only
- **boot_type** (String) Boot type of image bios or uefi
- **desc** (String)
- **guid** (Number)
- **history** (List of Object) (see [below for nested schema](#nestedatt--history))
- **image_id** (Number) image id
- **image_type** (String) Image type linux, windows or other
- **link_to** (Number)
- **meta** (List of String) meta
- **milestones** (Number)
- **provider_name** (String)
- **purge_attempts** (Number)
- **reference_id** (String)
- **res_id** (String)
- **res_name** (String)
- **rescuecd** (Boolean)
- **size** (Number) image size
- **status** (String) status
- **tech_status** (String) tech atatus
- **unc_path** (String) unc path
- **version** (String) version
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **create** (String)
- **default** (String)
- **delete** (String)
- **read** (String)
- **update** (String)
<a id="nestedatt--history"></a>
### Nested Schema for `history`
Read-Only:
- **guid** (String)
- **id** (Number)
- **timestamp** (Number)

View File

@@ -0,0 +1,40 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_delete_images Resource - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_delete_images (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **image_ids** (List of Number) images ids for deleting
- **reason** (String) reason for deleting the images
### Optional
- **id** (String) The ID of this resource.
- **permanently** (Boolean) whether to completely delete the images
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **create** (String)
- **default** (String)
- **delete** (String)
- **read** (String)
- **update** (String)

92
docs/resources/image.md Normal file
View File

@@ -0,0 +1,92 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_image Resource - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_image (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **boot_type** (String) Boot type of image bios or uefi
- **drivers** (List of String) List of types of compute suitable for image. Example: [ "KVM_X86" ]
- **gid** (Number) grid (platform) ID where this template should be create in
- **image_type** (String) Image type linux, windows or other
- **name** (String) Name of the rescue disk
- **url** (String) URL where to download media from
### Optional
- **account_id** (Number) AccountId to make the image exclusive
- **architecture** (String) binary architecture of this image, one of X86_64 of PPC64_LE
- **bootable** (Boolean) Does this image boot OS
- **computeci_id** (Number)
- **enabled** (Boolean)
- **enabled_stacks** (List of String)
- **hot_resize** (Boolean) Does this machine supports hot resize
- **id** (String) The ID of this resource.
- **image_id** (Number) image id
- **password** (String) Optional password for the image
- **password_dl** (String) password for upload binary media
- **permanently** (Boolean) Whether to completely delete the image
- **pool_name** (String) pool for image create
- **reason** (String)
- **sep_id** (Number) storage endpoint provider ID
- **shared_with** (List of Number)
- **sync** (Boolean) Create image from a media identified by URL (in synchronous mode)
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
- **username** (String) Optional username for the image
- **username_dl** (String) username for upload binary media
### Read-Only
- **desc** (String)
- **guid** (Number)
- **history** (List of Object) (see [below for nested schema](#nestedatt--history))
- **last_modified** (Number)
- **link_to** (Number)
- **meta** (List of String) meta
- **milestones** (Number)
- **provider_name** (String)
- **purge_attempts** (Number)
- **reference_id** (String)
- **res_id** (String)
- **res_name** (String)
- **rescuecd** (Boolean)
- **size** (Number) image size
- **status** (String) status
- **tech_status** (String) tech atatus
- **unc_path** (String) unc path
- **version** (String) version
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **create** (String)
- **default** (String)
- **delete** (String)
- **read** (String)
- **update** (String)
<a id="nestedatt--history"></a>
### Nested Schema for `history`
Read-Only:
- **guid** (String)
- **id** (Number)
- **timestamp** (Number)

View File

@@ -0,0 +1,72 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_k8s Resource - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_k8s (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **k8sci_id** (Number) ID of the k8s catalog item to base this instance on.
- **name** (String) Name of the cluster.
- **rg_id** (Number) Resource group ID that this instance belongs to.
- **wg_name** (String) Name for first worker group created with cluster.
### Optional
- **extnet_id** (Number) ID of the external network to connect workers to. If omitted network will be chosen by the platfom.
- **id** (String) The ID of this resource.
- **masters** (Block List, Max: 1) Master node(s) configuration. (see [below for nested schema](#nestedblock--masters))
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
- **workers** (Block List, Max: 1) Worker node(s) configuration. (see [below for nested schema](#nestedblock--workers))
### Read-Only
- **default_wg_id** (Number) ID of default workers group for this instace.
- **kubeconfig** (String) Kubeconfig for cluster access.
- **lb_ip** (String) IP address of default load balancer.
<a id="nestedblock--masters"></a>
### Nested Schema for `masters`
Required:
- **cpu** (Number) Node CPU count.
- **disk** (Number) Node boot disk size in GB.
- **num** (Number) Number of nodes to create.
- **ram** (Number) Node RAM in MB.
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **create** (String)
- **default** (String)
- **delete** (String)
- **read** (String)
- **update** (String)
<a id="nestedblock--workers"></a>
### Nested Schema for `workers`
Required:
- **cpu** (Number) Node CPU count.
- **disk** (Number) Node boot disk size in GB.
- **num** (Number) Number of nodes to create.
- **ram** (Number) Node RAM in MB.

View File

@@ -0,0 +1,43 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_k8s_wg Resource - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_k8s_wg (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **k8s_id** (Number) ID of k8s instance.
- **name** (String) Name of the worker group.
### Optional
- **cpu** (Number) Worker node CPU count.
- **disk** (Number) Worker node boot disk size. If unspecified or 0, size is defined by OS image size.
- **id** (String) The ID of this resource.
- **num** (Number) Number of worker nodes to create.
- **ram** (Number) Worker node RAM in MB.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **create** (String)
- **default** (String)
- **delete** (String)
- **read** (String)
- **update** (String)

46
docs/resources/pfw.md Normal file
View File

@@ -0,0 +1,46 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_pfw Resource - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_pfw (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **compute_id** (Number) ID of compute instance.
- **local_base_port** (Number) Internal base port number.
- **proto** (String) Network protocol, either 'tcp' or 'udp'.
- **public_port_start** (Number) External start port number for the rule.
### Optional
- **id** (String) The ID of this resource.
- **public_port_end** (Number) End port number (inclusive) for the ranged rule.
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **local_ip** (String) IP address of compute instance.
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **create** (String)
- **default** (String)
- **delete** (String)
- **read** (String)
- **update** (String)

View File

@@ -0,0 +1,46 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_snapshot Resource - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_snapshot (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **compute_id** (Number) ID of the compute instance to create snapshot for.
- **label** (String) text label for snapshot. Must be unique among this compute snapshots.
### Optional
- **id** (String) The ID of this resource.
- **rollback** (Boolean) is rollback the snapshot
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
### Read-Only
- **disks** (List of Number)
- **guid** (String) guid of the snapshot
- **timestamp** (Number) timestamp
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **create** (String)
- **default** (String)
- **delete** (String)
- **read** (String)
- **update** (String)

View File

@@ -0,0 +1,92 @@
---
# generated by https://github.com/hashicorp/terraform-plugin-docs
page_title: "decort_virtual_image Resource - terraform-provider-decort"
subcategory: ""
description: |-
---
# decort_virtual_image (Resource)
<!-- schema generated by tfplugindocs -->
## Schema
### Required
- **name** (String) name of the virtual image to create
- **target_id** (Number) ID of real image to link this virtual image to upon creation
### Optional
- **account_id** (Number) AccountId to make the image exclusive
- **architecture** (String) binary architecture of this image, one of X86_64 of PPC64_LE
- **bootable** (Boolean) Does this image boot OS
- **computeci_id** (Number)
- **enabled** (Boolean)
- **enabled_stacks** (List of String)
- **hot_resize** (Boolean) Does this machine supports hot resize
- **id** (String) The ID of this resource.
- **link_to** (Number)
- **password** (String) Optional password for the image
- **password_dl** (String) password for upload binary media
- **permanently** (Boolean) Whether to completely delete the image
- **pool_name** (String) pool for image create
- **reason** (String)
- **sep_id** (Number) storage endpoint provider ID
- **shared_with** (List of Number)
- **timeouts** (Block, Optional) (see [below for nested schema](#nestedblock--timeouts))
- **username** (String) Optional username for the image
- **username_dl** (String) username for upload binary media
### Read-Only
- **boot_type** (String) Boot type of image bios or uefi
- **desc** (String)
- **drivers** (List of String) List of types of compute suitable for image. Example: [ "KVM_X86" ]
- **gid** (Number) grid (platform) ID where this template should be create in
- **guid** (Number)
- **history** (List of Object) (see [below for nested schema](#nestedatt--history))
- **image_id** (Number) image id
- **image_type** (String) Image type linux, windows or other
- **last_modified** (Number)
- **meta** (List of String) meta
- **milestones** (Number)
- **provider_name** (String)
- **purge_attempts** (Number)
- **reference_id** (String)
- **res_id** (String)
- **res_name** (String)
- **rescuecd** (Boolean)
- **size** (Number) image size
- **status** (String) status
- **tech_status** (String) tech atatus
- **unc_path** (String) unc path
- **url** (String) URL where to download media from
- **version** (String) version
<a id="nestedblock--timeouts"></a>
### Nested Schema for `timeouts`
Optional:
- **create** (String)
- **default** (String)
- **delete** (String)
- **read** (String)
- **update** (String)
<a id="nestedatt--history"></a>
### Nested Schema for `history`
Read-Only:
- **guid** (String)
- **id** (Number)
- **timestamp** (Number)

1
go.mod
View File

@@ -4,6 +4,7 @@ go 1.15
require (
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/google/uuid v1.3.0
github.com/hashicorp/terraform-plugin-docs v0.5.1
github.com/hashicorp/terraform-plugin-sdk v1.16.0
github.com/sirupsen/logrus v1.7.0

3
go.sum
View File

@@ -169,8 +169,9 @@ github.com/google/pprof v0.0.0-20200430221834-fc25d7d30c6d/go.mod h1:ZgVRPoUq/hf
github.com/google/pprof v0.0.0-20200708004538-1a94d8640e99/go.mod h1:ZgVRPoUq/hfqzAqh7sHMqb3I9Rq5C59dIz2SbBwJ4eM=
github.com/google/renameio v0.1.0/go.mod h1:KWCgfxg9yswjAJkECMjeO8J8rahYeXnNhOm40UhjYkI=
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y=
github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I=
github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg=
github.com/googleapis/gax-go/v2 v2.0.5 h1:sjZBwGj9Jlw33ImPtvFviGYvseOtDM7hkSKB7+Tv3SM=
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=

43
samples/README.md Normal file
View File

@@ -0,0 +1,43 @@
# Примеры применения ресурсов terraform-provider-decort
Каждый файл снабжен комментариями, которые кратко описывают возможности и параметры ресурса.
Для успешной работы необходим установленный terraform.
## Ресурсы в примерах
- data:
- grid
- grid_list
- image
- image_list
- image_list_stacks
- snapshot_list
- pcidevice_list
- pcidevice
- sep
- sep_list
- sep_disk_list
- sep_config
- sep_pool
- sep_consumption
- vgpu
- resources:
- image
- virtual_image
- cdrom_image
- delete_images
- k8s
- k8s_wg
- snapshot
- pcidevice
- sep
- sep_config
## Как пользоваться примерами
1. Установить terraform
2. Установить terraform-provider-decort с помощью команды `terraform init` (выполняется автоматически), либо вручную.
3. Заменить параметр *controller_url* на ваш.
4. Заменить параметр *oauth2* на ваш.
5. Добавить ключи
*DECORT_APP_SECRET* и *DECORT_APP_ID*
в качестве переменных окружения, либо
можно добавить `app_id` и `app_secret`
в блок `provider`,что небезопасно, т.к. данные
могут быть похищены при передачи файла.

38
samples/data_grid/main.tf Normal file
View File

@@ -0,0 +1,38 @@
/*
Пример использования
Получение data source grid по id
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_grid" "image" {
#id grid для получения информации
#обязательный параметр
#тип - число
grid_id = 1
}
output "test" {
value = data.decort_grid.image
}

View File

@@ -0,0 +1,45 @@
/*
Пример использования
Получение списка grid
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_grid_list" "gl" {
#номер страницы для отображения
#опциональный параметр, тип - число
#если не задан - выводятся все доступные данные
#page = 2
#размер страницы
#опциональный параметр, тип - число
#если не задан - выводятся все доступные данные
#size = 3
}
output "test" {
value = data.decort_grid_list.gl
}

View File

@@ -0,0 +1,38 @@
/*
Пример использования
Получение образа по id
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_image" "image" {
#id образа
#обязательный параметр
#тип - число
image_id = 5912
}
output "test" {
value = data.decort_image.image
}

View File

@@ -0,0 +1,58 @@
/*
Пример использования
Получение списка образов
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_image_list" "il" {
#номер страницы для отображения
#опциональный параметр
#тип - число
#если не задан - выводятся все доступные данные
#page = 2
#размер страницы
#опциональный параметр
#тип - число
#если не задан - выводятся все доступные данные
#size = 3
#фильтрация образов по id хранилища
#опциональный параметр
#тип - число
#если не задан - выволятся все доступные элементы
#sep_id = 123
#фильтрация образов по id доступных аккаунтов
#опциональный параметр
#тип - число
#если не задан - выволятся все доступные элементы
#shared_with = 123
}
output "test" {
value = data.decort_image_list.il
}

View File

@@ -0,0 +1,49 @@
/*
Пример использования
Получение списка stack по id образа
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_image_list_stacks" "im" {
#id образа
#обязательный параметр
#тип - число
image_id = 6040
#номер страницы для отображения информации
#опциональный параметр
#тип - число
#если не задан - отображается вся доступная информация
#page = 2
#количество отображаемых объектов на странице
#опциональный параметр
#тип - число
#если не задан - отображается вся доступная информация
#size = 3
}
output "test" {
value = data.decort_image_list_stacks.im
}

View File

@@ -0,0 +1,39 @@
/*
Пример использования
Получение информации об устройстве
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_pcidevice" "pd" {
#id устройства
#обязательный параметр
#тип - число
device_id = 85
}
output "test" {
value = data.decort_pcidevice.pd
}

View File

@@ -0,0 +1,34 @@
/*
Пример использования
Получение информации обо всех доступных устройствах
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_pcidevice_list" "pdl" {}
output "test" {
value = data.decort_pcidevice_list.pdl.items
}

42
samples/data_sep/main.tf Normal file
View File

@@ -0,0 +1,42 @@
/*
Пример использования
Получение данных sep
*/
#Расскомментируйте код ниже,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_sep" "sd" {
#id sep
#обязательный параметр
#тип - число
sep_id = 1111
}
output "test" {
value = data.decort_sep.sd
}
output "config" {
value = jsondecode(data.decort_sep.sd.config)
}

View File

@@ -0,0 +1,41 @@
/*
Пример использования
Получение данных конфигурации sep
*/
#Расскомментируйте код ниже,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_sep_config" "sc" {
#id sep
#обязательный параметр
#тип - число
sep_id = 1111
}
output "test" {
value = data.decort_sep_config.sc
}
output "config" {
value = jsondecode(data.decort_config.sc.config)
}

View File

@@ -0,0 +1,37 @@
/*
Пример использования
Получение общих данных об использовании sep
*/
#Расскомментируйте код ниже,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_sep_consumption" "scons" {
#id sep
#обязательный параметр
#тип - число
sep_id = 1111
}
output "test" {
value = data.decort_sep_consumption.scons
}

View File

@@ -0,0 +1,42 @@
/*
Пример использования
Получение данных об используемых sep дисках
*/
#Расскомментируйте код ниже,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_sep_disk_list" "sdl" {
#id sep
#обязательный параметр
#тип - число
sep_id = 1111
#sep pool name
#необязательный параметр
#тип - строка
#pool_name = "sep_pool"
}
output "test" {
value = data.decort_sep_disk_list.sdl
}

View File

@@ -0,0 +1,40 @@
/*
Пример использования
Получение списка sep
*/
#Расскомментируйте код ниже,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_sep_list" "sl" {
#страница
#необязательный параметр
#тип - число
#page = 3
#размер страницы
#необязательный параметр
#тип - число
#size = 2
}
output "test" {
value = data.decort_sep_list.sl
}

View File

@@ -0,0 +1,46 @@
/*
Пример использования
Получение данных sep pool
*/
#Расскомментируйте код ниже,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_sep_pool" "sp" {
#id sep
#обязательный параметр
#тип - число
sep_id = 1111
#sep pool name
#обязательный параметр
#тип - строка
pool_name = "sep_pool"
}
output "test" {
value = data.decort_sep_pool.sp
}
output "pool" {
value = jsondecode(data.decort_sep_pool.sp.pool)
}

View File

@@ -0,0 +1,40 @@
/*
Пример использования
Получение списка snapshot
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://mr4.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_snapshot_list" "sl" {
#обязательный параметр
#id вычислительной мощности
#тип - число
compute_id = 24074
}
output "test" {
value = data.decort_snapshot_list.sl
}

38
samples/data_vgpu/main.tf Normal file
View File

@@ -0,0 +1,38 @@
/*
Пример использования
Получение данных vgpu
*/
#Расскомментируйте код ниже,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
data "decort_vgpu" "vgpu" {
#id vgpu
#обязательный параметр
#тип - число
vgpu_id = 1111
}
output "test" {
value = data.decort_vgpu.vgpu
}

View File

@@ -0,0 +1,63 @@
/*
Пример использования
Ресурса delete images
Ресурс является служебным
Его можно использоваться для быстрого удаления нескольких образов
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
resource "decort_delete_images" "my_images" {
#массив, содержащий набор id образов для удаления
#обязательный параметр
#тип - массив чисел
image_ids = [6125]
#параметр удаления
#опциональный тип
#по-умолчанию - false
#тип - булев тип
permanently = true
#причина удаления
#обязательный параметр
#тип - строка
reason = "test delete"
}
output "test" {
value = decort_delete_images.my_images
}
/*
Применение:
1. terraform plan
2. terraform apply
3. terraform destroy
Примечание:
Данный ресурс не поддерживает обновления параметров, поэтому, для переиспользования
необходимо удалить старое состояние и повторить шаги выше.
*/

View File

@@ -0,0 +1,145 @@
/*
Пример использования
Ресурса image
Ресурс позволяет:
1. Создавать образ
2. Редактировать образ
3. Удалять образ
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
resource "decort_image" "my_image" {
#имя образа
#обязательный параметр
#тип - строка
#при изменении - изменяет название созданного образа
name = "test_image_rename"
#адрес образа
#обязательный параметр
#тип - строка
url = "https://colba.decs.online/index.php/s/G3H7AREngzeKGw2/download"
#grid id образа
#обязательный параметр
#тип - число
gid = 212
#тип загрузки образа
#обязательный параметр
#тип - строка
#возможные варианты: "bios" или "uefi"
boot_type = "bios"
#тип образа
#обязательный параметр
#тип - строка
#возможные варианты - "linux", "windows"
image_type = "linux"
#драйвера
#обязательный параметр
#тип - массив строк
#возможные варианты - ["KVM_X86", "SVA_KVM_X86"], ["KVM_X86"], ["SVA_KVM_X86"]
drivers = ["KVM_X86", "SVA_KVM_X86"]
#id аккаунта владельца образа
#опциональный параметр
#может быть использован как при создании,
#так и при редактировании образа
#тип данных - число
#account_id = 57252
#имя пользователя и пароль
#опциаональные параметры,
#могут быть использованы как при создании образа,
#так и при его редактировании
#тип - строка
#username = "Valera"
#password = "123"
#имя пользователя и пароль для загрузки бинарных данных
#опциаональные параметры,
#могут быть использованы как при создании образа,
#так и при его редактировании
#тип - строка
#username_dl = "Valera1"
#password_dl = "1231"
#id storage endpoint
#опциональный параметр, используется при создании
#тип - число
#sep_id = 1206
#пул для создания образа
#опциональный тип, используется при создании образа
#тип - строка
#pool_name = "vmstor"
#архитектура системы образа
#опциаональный параметр, используется при создании
#тип - строка
#доступные значения: "X86_64"
#architecture = "X86_64"
#доступность образа
#опциональный параметр, используется на уже созданном ресурсе
#тип - булево значение
#enabled = true
#настройка доступа образа аккаунтам
#опциональный параметр, используется на уже созданном ресурсе
#тип - массив чисел
#пустой маасив - удаление всех доступов, если они были
#shared_with = [28096, 57121]
#установка computeci
#опциональный параметр, используется на уже созданном ресурсе
#тип - число
#чтобы сбросить, необходимо передать 0
#computeci_id = 1
#доступные стаки
#опциональный параметр, используется на уже созданном ресурсе
#тип - массив строк
#для удаления всех доступных стаков, необходимо передать пустой массив
#enabled_stacks = ["9"]
#мгновенное удаление
#опциональный параметр, можно использовать перед удалением
#тип - булев тип
#permanently = true
#причина удаления
#опциональный параметр, можно использовать перед удалением
#тип - строка
#reason = "test"
}
output "test" {
value = decort_image.my_image
}

View File

@@ -0,0 +1,127 @@
/*
Пример использования
Ресурса cdrom image
Ресурс позволяет:
1. Создавать образ
2. Редактировать образ
3. Удалять образ
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
resource "decort_cdrom_image" "my_image" {
#имя образа
#обязательный параметр
#тип - строка
#при изменении - изменяет название созданного образа
name = "test_image_rename"
#адрес образа
#обязательный параметр
#тип - строка
url = "https://colba.decs.online/index.php/s/G3H7AREngzeKGw2/download"
#grid id образа
#обязательный параметр
#тип - число
gid = 212
#драйвера
#обязательный параметр
#тип - массив строк
#возможные варианты - ["KVM_X86", "SVA_KVM_X86"], ["KVM_X86"], ["SVA_KVM_X86"]
drivers = ["KVM_X86", "SVA_KVM_X86"]
#id аккаунта владельца образа
#опциональный параметр
#может быть использован как при создании,
#так и при редактировании образа
#тип данных - число
account_id = 57252
#имя пользователя и пароль
#опциаональные параметры,
#могут быть использованы как при создании образа,
#так и при его редактировании
#тип - строка
username = "Valera"
password = "123"
#имя пользователя и пароль для загрузки бинарных данных
#опциаональные параметры,
#могут быть использованы как при создании образа,
#так и при его редактировании
#тип - строка
#username_dl = "Valera1"
#password_dl = "1231"
#id storage endpoint
#опциональный параметр, используется при создании
#тип - число
#sep_id = 1206
#пул для создания образа
#опциональный тип, используется при создании образа
#тип - строка
#pool_name = "vmstor"
#архитектура системы образа
#опциаональный параметр, используется при создании
#тип - строка
#доступные значения: "X86_64"
architecture = "X86_64"
#доступность образа
#опциональный параметр, используется на уже созданном ресурсе
#тип - булево значение
#enabled = true
#настройка доступа образа аккаунтам
#опциональный параметр, используется на уже созданном ресурсе
#тип - массив чисел
#пустой маасив - удаление всех доступов, если они были
#shared_with = [28096, 57121]
#установка computeci
#опциональный параметр, используется на уже созданном ресурсе
#тип - число
#чтобы сбросить, необходимо передать 0
#computeci_id = 1
#доступные стаки
#опциональный параметр, используется на уже созданном ресурсе
#тип - массив строк
#для удаления всех доступных стаков, необходимо передать пустой массив
#enabled_stacks = ["9"]
#мгновенное удаление
#опциональный параметр, можно использовать перед удалением
#тип - булев тип
#permanently = true
}
output "test" {
value = decort_cdrom_image.my_image
}

View File

@@ -0,0 +1,122 @@
/*
Пример использования
Ресурсов k8s cluster
Ресурсы позволяет:
1. Создавать
2. Редактировать
3. Удалять
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
source = "terraform.local/local/decort"
version = "1.0.0"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
oauth2_url = "https://sso.digitalenergy.online"
controller_url = "https://mr4.digitalenergy.online"
app_id = ""
app_secret = ""
}
resource "decort_k8s" "cluster" {
#имя кластера
#обязательный параметр
#при изменении - обновдяет имя кластера
#тип - строка
name = "tftest"
#id resource group
#обязательный параметр
#тип - число
rg_id = 776
#id catalogue item
#обязательный параметр
#тип - число
k8sci_id = 9
#имя для первой worker group, созданной в кластере
#обязательный параметр
#тип - строка
wg_name = "workers"
#настройка мастер node или nodes
#опциональный параметр
#максимальное кол-во элементов - 1
#тип - список нод
masters {
#кол-во node
#обязательный параметр
#тип - число
num = 1
#кол-во cpu
#обязательный параметр
#тип - число
cpu = 2
#кол-во RAM в Мбайтах
#обязательный параметр
#тип - число
ram = 2048
#размер диска в Гбайтах
#обязательный параметр
#тип - число
disk = 10
}
#настройка worker node или nodes
#опциональный параметр
#максимальное кол-во элементов - 1
#тип - список нод
workers {
#кол-во node
#обязательный параметр
#тип - число
num = 1
#кол-во cpu
#обязательный параметр
#тип - число
cpu = 2
#кол-во RAM в Мбайтах
#обязательный параметр
#тип - число
ram = 2048
#размер диска в Гбайтах
#обязательный параметр
#тип - число
disk = 10
}
}
output "test_cluster" {
value = decort_k8s.cluster
}
/*
output "kubeconfig"{
value = decort_k8s.cluster.kubeconfig
}
*/

View File

@@ -0,0 +1,76 @@
/*
Пример использования
Ресурсов worker group
Ресурсы позволяет:
1. Создавать
2. Редактировать
3. Удалять
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
source = "terraform.local/local/decort"
version = "1.0.0"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
oauth2_url = "https://sso.digitalenergy.online"
controller_url = "https://mr4.digitalenergy.online"
app_id = ""
app_secret = ""
}
resource "decort_k8s_wg" "wg" {
#id экземпляра k8s
#обязательный параметр
#тип - число
k8s_id = 1234 //это значение должно быть и результат вызова decort_k8s.cluster.id
#имя worker group
#обязательный параметр
#тип - строка
name = "workers-2"
#количество worker node для создания
#опциональный параметр
#тип - число
#по - умолчанию - 1
num = 2
#количество cpu для 1 worker node
#опциональный параметр
#тип - число
#по - умолчанию - 1
cpu = 1
#количество RAM для одной worker node в Мбайтах
#опциональный параметр
#тип - число
#по-умолчанию - 1024
ram = 1024
#размер загрузочного диска для worker node, в Гбайтах
#опциональный параметр
#тип - число
#по - умолчанию - 0
#если установлен параметр 0, то размер диска будет равен размеру образа
disk = 10
}
output "test_wg" {
value = decort_k8s_wg.wg
}

View File

@@ -0,0 +1,85 @@
/*
Пример использования
Ресурса pdidevice
Ресурс позволяет:
1. Создавать устройство
2. Редактировать устройство
3. Удалять устройство
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
resource "decort_pcidevice" "pd" {
#имя устройства
#обязательный параметр
#тип - строка
name = "test_device"
#путь до устройства
#обязательный параметр
#тип - строка
hw_path = "0000:01:00.0"
#описание устройства
#обязательный параметр
#тип - строка
description = "test desc"
#id ресурсной группы устройства
#обязательный параметр
#тип - число
rg_id = 1111
#id стака устройства
#обязательный параметр
#тип - число
stack_id = 11
#доступность устройства
#опциональный параметр
#может использоваться на созданном ресурсе
#тип - булево значение
#enable = false
#принудительное удаление устройства
#опциональный параметр
#используется при удалении ресурса
#тип - булево значение
#force = true
#id устройства
#опциональный параметр
#позволяет "восстановить" состояние ресурса терраформа на локальной машине
#тип - число
#device_id = 86
}
output "test" {
value = decort_pcidevice.pd
}

View File

@@ -0,0 +1,124 @@
/*
Пример использования
Ресурса sep
Ресурс позволяет:
1. Создавать sep.
2. Редактировать sep.
3. Удалять sep.
4. Конфигурировать sep.
*/
#Расскомментируйте код ниже,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "1.1"
source = "digitalenergy.online/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://ds1.digitalenergy.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso.digitalenergy.online"
allow_unverified_ssl = true
}
resource "decort_sep" "s" {
#grid id
#обязательный параметр
#тип - число
gid = 212
#sep name
#обязательный параметр
#тип - строка
name = "test sep"
#тип sep
#обязательный параметр
#тип - строка
#возможные значения - des, dorado, tatlin, hitachi
type = "des"
#описание sep
#необязательный параметр, используется при создании ресурса
#тип - строка
desc = "rrrrr"
#конфигурация sep
#необязательный параметр, мб применен при создании или редактировании sep
#представляет собой json-строку
#тип - строка
#config = file("./config.json")
#изменение поля в конфигурации
#необязательный параметр, мб применен на уже созданном sep
#тип - объект
#внимание, во избежание конфликтов не использовать с полем config
/*
field_edit {
#имя поля
#обязательный параметр
#тип - строка
field_name = "edgeuser_password"
#значение поля
#обязательный параметр
#тип - json строка
field_value = "mosk"
#тип значения
#обязательный параметр
#тип - строка, возможные значения: list,dict,int,bool,str
field_type = "str"
}
*/
#доступность sep
#необязательный параметр, мб применен на уже созданном ресурсе
#тип - булево значение
#enable = false
#использование нодами
#необязательный параметр, используется при редактировании ресурса
#тип - массив чисел
#consumed_by = []
#обновление лимита объема
#необязательный параметр, применяется на уж созданнном ресурсе
#тип - булев тип
#upd_capacity_limit = true
#id provided nodes
#необязательный параметр, применяется на уже созданном ресурсе
#тип - массив чисел
#provided_by = [16, 14, 15]
#отключение nodes
#необязательный параметр, применяется на уже созданном ресурсе
#тип - булев тип
#используется в связке с clear_physically
#decommission = true
#физическое очищение nodes
#необязательный параметр, используется при удалении ресурса
#тип - булев тип
#clear_physically = false
}
output "test" {
value = decort_sep.s
}
output "config" {
value = jsondecode(decort_sep.s.config)
}

Some files were not shown because too many files have changed in this diff Show More