gos_tech_4.4.3
Nikita Sorokin 1 year ago
parent 739289fbb8
commit 83ca627cea

@ -1,5 +1,11 @@
## Version 4.3.8
## Version 4.4.0
## Bugfix
- Fixed bugs with restore and newCreate after destroy
### Bugfix
- Fixed bug with restore and new create resources at plan and refresh
## Feature
- Add in cloudapi in stack data_source_stack_list and data_source_stack
- Add in cloudapi in vins data_source_route, data_source_route_list, resource_static_route
- Cloudapi/lb/resource_lb extnet_id and vins_id can be equal to 0, but not together. If the value is 0, the api assigns it itself. Add Highly Available schema for LB deploy (parameter ha_mode). Cloudapi/lb/data_source_lb add parametr backend_haip, frontend_haip, part_k8s, data_source_lb_list, data_source_lb_list_deleted add parametr backend_haip, frontend_haip
- Cloudapi/bservice/resource_bservice_group added the ability to create a resource with the following sep_id, sep_pool and cloud_init
- Cloudapi/k8s/resource_k8s and resource_k8s_cp added the ability to create a resource with config (parameters cluster_config, kubelet_config, kube_proxy_config, join_config, cloud_init, init_config). Added the ability to create a resource with Highly Available schema for LB deploy (parameter ha_mode). Added the ability to create a resource with additional_sans. Added the ability to create a resource in extnet_only mode

@ -7,7 +7,7 @@ ZIPDIR = ./zip
BINARY=${NAME}
WORKPATH= ./examples/terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAMESPACE}/${VERSION}/${OS_ARCH}
MAINPATH = ./cmd/decort/
VERSION=4.3.8
VERSION=4.4.0
OS_ARCH=$(shell go env GOHOSTOS)_$(shell go env GOHOSTARCH)
FILES = ${BINARY}_${VERSION}_darwin_amd64\

@ -6,6 +6,7 @@ Terraform provider для платформы Digital Energy Cloud Orchestration
| Версия DECORT API | Версия провайдера Terraform |
| ------ | ------ |
| 3.8.8 | 4.4.x |
| 3.8.7 | 4.3.x |
| 3.8.6 | 4.0.x, 4.1.x, 4.2.x |
| 3.8.5 | 3.4.x |
@ -29,6 +30,8 @@ Terraform provider для платформы Digital Energy Cloud Orchestration
- Работа с disks,
- Работа с k8s,
- Работа с image,
- Работа с flipgroups,
- Работа с stacks,
- Работа с reource groups,
- Работа с VINS,
- Работа с pfw,

@ -8,8 +8,8 @@ require (
github.com/hashicorp/terraform-plugin-docs v0.13.0
github.com/hashicorp/terraform-plugin-sdk/v2 v2.24.1
github.com/sirupsen/logrus v1.9.0
golang.org/x/net v0.12.0
repository.basistech.ru/BASIS/decort-golang-sdk v1.5.10
golang.org/x/net v0.15.0
repository.basistech.ru/BASIS/decort-golang-sdk v1.6.0
)
require (
@ -24,7 +24,7 @@ require (
github.com/gabriel-vasile/mimetype v1.4.2 // indirect
github.com/go-playground/locales v0.14.1 // indirect
github.com/go-playground/universal-translator v0.18.1 // indirect
github.com/go-playground/validator/v10 v10.14.1 // indirect
github.com/go-playground/validator/v10 v10.15.4 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/google/go-cmp v0.5.9 // indirect
github.com/google/go-querystring v1.1.0 // indirect
@ -67,9 +67,9 @@ require (
github.com/vmihailenco/msgpack/v4 v4.3.12 // indirect
github.com/vmihailenco/tagparser v0.1.2 // indirect
github.com/zclconf/go-cty v1.12.1 // indirect
golang.org/x/crypto v0.11.0 // indirect
golang.org/x/sys v0.10.0 // indirect
golang.org/x/text v0.11.0 // indirect
golang.org/x/crypto v0.13.0 // indirect
golang.org/x/sys v0.12.0 // indirect
golang.org/x/text v0.13.0 // indirect
google.golang.org/appengine v1.6.7 // indirect
google.golang.org/genproto v0.0.0-20221207170731-23e4bf6bdc37 // indirect
google.golang.org/grpc v1.51.0 // indirect

@ -55,8 +55,8 @@ github.com/go-playground/locales v0.14.1 h1:EWaQ/wswjilfKLTECiXz7Rh+3BjFhfDFKv/o
github.com/go-playground/locales v0.14.1/go.mod h1:hxrqLVvrK65+Rwrd5Fc6F2O76J/NuW9t0sjnWqG1slY=
github.com/go-playground/universal-translator v0.18.1 h1:Bcnm0ZwsGyWbCzImXv+pAJnYK9S473LQFuzCbDbfSFY=
github.com/go-playground/universal-translator v0.18.1/go.mod h1:xekY+UJKNuX9WP91TpwSH2VMlDf28Uj24BCp08ZFTUY=
github.com/go-playground/validator/v10 v10.14.1 h1:9c50NUPC30zyuKprjL3vNZ0m5oG+jU0zvx4AqHGnv4k=
github.com/go-playground/validator/v10 v10.14.1/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-playground/validator/v10 v10.15.4 h1:zMXza4EpOdooxPel5xDqXEdXG5r+WggpvnAKMsalBjs=
github.com/go-playground/validator/v10 v10.15.4/go.mod h1:9iXMNT7sEkjXb0I+enO7QXmzG6QCsPWY4zveKFVRSyU=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
github.com/golang-jwt/jwt/v4 v4.4.3 h1:Hxl6lhQFj4AnOX6MLrsCb/+7tCj7DxP7VA+2rDIq5AU=
github.com/golang-jwt/jwt/v4 v4.4.3/go.mod h1:m21LjoU+eqJr34lmDMbreY2eSTRJ1cv77w39/MY0Ch0=
@ -249,8 +249,8 @@ golang.org/x/crypto v0.0.0-20210421170649-83a5a9bb288b/go.mod h1:T9bdIzuCu7OtxOm
golang.org/x/crypto v0.0.0-20210616213533-5ff15b29337e/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.3.0/go.mod h1:hebNnKkNXi2UzZN1eVRvBB7co0a+JxK6XbPiWVs/3J4=
golang.org/x/crypto v0.11.0 h1:6Ewdq3tDic1mg5xRO4milcWCfMVQhI4NkqWWvqejpuA=
golang.org/x/crypto v0.11.0/go.mod h1:xgJhtzW8F9jGdVFWZESrid1U1bjeNy4zgy5cRr/CIio=
golang.org/x/crypto v0.13.0 h1:mvySKfSWJ+UKUii46M40LOvyWfN0s2U+46/jDd0e6Ck=
golang.org/x/crypto v0.13.0/go.mod h1:y6Z2r+Rw4iayiXXAIxJIDAJ1zMW4yaTpebo8fPOliYc=
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -265,8 +265,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210326060303-6b1517762897/go.mod h1:uSPa2vr4CLtc/ILN5odXGNXS6mhrKVzTaCXzk9m6W3k=
golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
golang.org/x/net v0.2.0/go.mod h1:KqCZLdyyvdV855qA2rE3GC2aiw5xGR5TEjj8smXukLY=
golang.org/x/net v0.12.0 h1:cfawfvKITfUsFCeJIHJrbSxpeu/E81khclypR0GVT50=
golang.org/x/net v0.12.0/go.mod h1:zEVYFnQC7m/vmpQFELhcD1EWkZlX69l4oqgmer6hfKA=
golang.org/x/net v0.15.0 h1:ugBLEUaxABaB5AJqW9enI0ACdci2RUd4eP51NTBvuJ8=
golang.org/x/net v0.15.0/go.mod h1:idbUs1IY1+zTqbi8yxTbhexhEEk5ur9LInksu6HrEpk=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -293,8 +293,8 @@ golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.2.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.12.0 h1:CM0HF96J0hcLAwsHPJZjfdNzs0gftsLfgKt57wWHJ0o=
golang.org/x/sys v0.12.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
golang.org/x/term v0.2.0/go.mod h1:TVmDHMZPmdnySmBfhjOoOdhjzdE1h4u1VwSiw2l1Nuc=
@ -304,8 +304,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
golang.org/x/text v0.4.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
golang.org/x/text v0.11.0 h1:LAntKIrcmeSKERyiOh0XMV39LXS8IE9UL2yP7+f5ij4=
golang.org/x/text v0.11.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
@ -339,5 +339,5 @@ gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C
gopkg.in/yaml.v3 v3.0.0/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
repository.basistech.ru/BASIS/decort-golang-sdk v1.5.10 h1:LnnOxO8QxSaIfetrzivmRf7qBZJkiakHD0FJLYYAvv8=
repository.basistech.ru/BASIS/decort-golang-sdk v1.5.10/go.mod h1:szsTGa73O75ckCWVGJPvTtRbhA/ubuYrYhMkPjvHlmE=
repository.basistech.ru/BASIS/decort-golang-sdk v1.6.0 h1:vH+11kM7P8SKJBIMKi3ry04cBjj+hfdVlo1gN91SElY=
repository.basistech.ru/BASIS/decort-golang-sdk v1.6.0/go.mod h1:szsTGa73O75ckCWVGJPvTtRbhA/ubuYrYhMkPjvHlmE=

@ -34,6 +34,7 @@ import (
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/locations"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/rg"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/snapshot"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/stack"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudapi/vins"
cb_account "repository.basistech.ru/BASIS/terraform-provider-decort/internal/service/cloudbroker/account"
@ -74,6 +75,8 @@ func newDataSourcesMap() map[string]*schema.Resource {
"decort_vins_list_deleted": vins.DataSourceVinsListDeleted(),
"decort_vins_ext_net_list": vins.DataSourceVinsExtNetList(),
"decort_vins_nat_rule_list": vins.DataSourceVinsNatRuleList(),
"decort_vins_static_route_list": vins.DataSourceStaticRouteList(),
"decort_vins_static_route": vins.DataSourceStaticRoute(),
"decort_snapshot_list": snapshot.DataSourceSnapshotList(),
"decort_disk": disks.DataSourceDisk(),
"decort_disk_list": disks.DataSourceDiskList(),
@ -124,6 +127,8 @@ func newDataSourcesMap() map[string]*schema.Resource {
"decort_lb_list_deleted": lb.DataSourceLBListDeleted(),
"decort_flipgroup": flipgroup.DataSourceFlipgroup(),
"decort_flipgroup_list": flipgroup.DataSourceFlipGroupList(),
"decort_stack": stack.DataSourceStack(),
"decort_stack_list": stack.DataSourceStackList(),
"decort_cb_account": cb_account.DataSourceAccount(),
"decort_cb_account_list": cb_account.DataSourceAccountList(),

@ -72,6 +72,7 @@ func newResourcesMap() map[string]*schema.Resource {
"decort_lb_frontend": lb.ResourceLBFrontend(),
"decort_lb_frontend_bind": lb.ResourceLBFrontendBind(),
"decort_flipgroup": flipgroup.ResourceFlipgroup(),
"decort_vins_static_route": vins.ResourceStaticRoute(),
"decort_cb_account": cb_account.ResourceAccount(),
"decort_cb_extnet": cb_extnet.ResourceExtnetCB(),

@ -30,6 +30,7 @@ func flattenResourceBasicServiceGroup(d *schema.ResourceData, bsg *bservice.Reco
d.Set("rg_name", bsg.RGName)
d.Set("role", bsg.Role)
d.Set("sep_id", bsg.SEPID)
d.Set("sep_pool", bsg.PoolName)
d.Set("seq_no", bsg.SeqNo)
d.Set("status", bsg.Status)
d.Set("tech_status", bsg.TechStatus)

@ -77,6 +77,23 @@ func resourceBasicServiceCreate(ctx context.Context, d *schema.ResourceData, m i
d.SetId(strconv.FormatUint(serviceId, 10))
d.Set("service_id", serviceId)
service, err := utilityBasicServiceCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
if d.Get("enable").(bool) && (service.Status == status.Disabled || service.Status == status.Created) {
log.Debugf("trying to enable bservice %v", serviceId)
_, err := c.CloudAPI().BService().Enable(ctx, bservice.EnableRequest{
ServiceID: serviceId,
})
if err != nil {
return diag.FromErr(err)
}
}
return resourceBasicServiceRead(ctx, d, m)
}

@ -68,6 +68,20 @@ func resourceBasicServiceGroupCreate(ctx context.Context, d *schema.ResourceData
req.TimeoutStart = uint64(timeoutStart.(int))
}
///4.4.0
if sepId, ok := d.GetOk("sep_id"); ok {
req.SEPID = uint64(sepId.(int))
}
if sepPool, ok := d.GetOk("sep_pool"); ok {
req.SEPPool = sepPool.(string)
}
if cloudInit, ok := d.GetOk("cloud_init"); ok {
req.UserData = cloudInit.(string)
}
///
if vinses, ok := d.GetOk("vinses"); ok {
res := []uint64{}
for _, vins := range vinses.([]interface{}) {
@ -362,6 +376,25 @@ func resourceBasicServiceGroupSchemaMake() map[string]*schema.Schema {
Required: true,
Description: "compute driver like a KVM_X86, KVM_PPC, etc.",
},
///4.4.0
"sep_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "storage endpoint provider ID",
},
"sep_pool": {
Type: schema.TypeString,
Optional: true,
Computed: true,
Description: "pool to use if sepId is set, can be also empty if needed to be chosen by system",
},
"cloud_init": {
Type: schema.TypeString,
Optional: true,
Description: "Optional cloud_init parameters. Applied when creating new compute instance only, ignored in all other cases.",
},
///
"role": {
Type: schema.TypeString,
Optional: true,
@ -524,10 +557,6 @@ func resourceBasicServiceGroupSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString,
Computed: true,
},
"sep_id": {
Type: schema.TypeInt,
Computed: true,
},
"seq_no": {
Type: schema.TypeInt,
Computed: true,

@ -80,10 +80,6 @@ func computesSchemaMake() map[string]*schema.Schema {
}
}
func workerComputesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{}
}
func dataSourceK8sComputesSchemaMake() map[string]*schema.Schema {
return map[string]*schema.Schema{
"k8s_id": {

@ -222,15 +222,15 @@ func flattenK8sGroup(k8SGroupList k8s.ListK8SGroups, workers []compute.RecordCom
return res
}
func flattenK8sGroups(k8sGroups k8s.RecordK8SGroups, masters []compute.RecordCompute, workers []compute.RecordCompute) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
temp := map[string]interface{}{
"masters": flattenMasterGroup(k8sGroups.Masters, masters),
"workers": flattenK8sGroup(k8sGroups.Workers, workers),
}
res = append(res, temp)
return res
}
// func flattenK8sGroups(k8sGroups k8s.RecordK8SGroups, masters []compute.RecordCompute, workers []compute.RecordCompute) []map[string]interface{} {
// res := make([]map[string]interface{}, 0)
// temp := map[string]interface{}{
// "masters": flattenMasterGroup(k8sGroups.Masters, masters),
// "workers": flattenK8sGroup(k8sGroups.Workers, workers),
// }
// res = append(res, temp)
// return res
// }
func flattenK8sData(d *schema.ResourceData, cluster k8s.RecordK8S, masters []compute.RecordCompute, workers []compute.RecordCompute) {
d.Set("acl", flattenAcl(cluster.ACL))

@ -145,6 +145,54 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
createReq.WithLB = d.Get("with_lb").(bool)
///4.4.0
createReq.HighlyAvailable = d.Get("ha_mode").(bool)
if additionalSans, ok := d.GetOk("additional_sans"); ok {
addSans := additionalSans.([]interface{})
resSans := make([]string, 0)
for _, san := range addSans {
resSans = append(resSans, san.(string))
}
createReq.AdditionalSANs = resSans
}
if clusterConfig, ok := d.GetOk("cluster_config"); ok {
createReq.ClusterConfiguration = clusterConfig.(string)
}
if kubeletConfig, ok := d.GetOk("kubelet_config"); ok {
createReq.KubeletConfiguration = kubeletConfig.(string)
}
if kubeProxyConfig, ok := d.GetOk("kube_proxy_config"); ok {
createReq.KubeProxyConfiguration = kubeProxyConfig.(string)
}
if joinConfig, ok := d.GetOk("join_config"); ok {
createReq.JoinConfiguration = joinConfig.(string)
}
if cloudInit, ok := d.GetOk("cloud_init"); ok {
createReq.UserData = cloudInit.(string)
}
if initConfig, ok := d.GetOk("init_config"); ok {
createReq.InitConfiguration = initConfig.(string)
}
if lbSysctlParams, ok := d.GetOk("lb_sysctl_params"); ok {
createReq.LbSysctlParams = lbSysctlParams.(string)
}
if oidcCertificate, ok := d.GetOk("oidc_cert"); ok {
createReq.OidcCertificate = oidcCertificate.(string)
}
///
createReq.ExtNetOnly = d.Get("extnet_only").(bool)
if extNet, ok := d.GetOk("extnet_id"); ok {
createReq.ExtNetID = uint64(extNet.(int))
} else {
@ -181,7 +229,7 @@ func resourceK8sCreate(ctx context.Context, d *schema.ResourceData, m interface{
break
}
time.Sleep(time.Second * 10)
time.Sleep(time.Second * 20)
}
return resourceK8sRead(ctx, d, m)
@ -563,6 +611,12 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
Default: true,
Description: "Create k8s with load balancer if true.",
},
"extnet_only": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Use only selected ExtNet for infrastructure connections",
},
"extnet_id": {
Type: schema.TypeInt,
Optional: true,
@ -570,6 +624,63 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
ForceNew: true,
Description: "ID of the external network to connect workers to. If omitted network will be chosen by the platfom.",
},
///4.4.0
"cloud_init": {
Type: schema.TypeString,
Optional: true,
Description: "Meta data for working group computes, format YAML 'user_data': 1111",
},
"join_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting.",
},
"kube_proxy_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.",
},
"kubelet_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting.",
},
"cluster_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting.",
},
"init_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.",
},
"additional_sans": {
Type: schema.TypeList,
Optional: true,
Description: "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"ha_mode": {
Type: schema.TypeBool,
Optional: true,
Description: "Use Highly Available schema for LB deploy",
},
"lb_sysctl_params": {
Type: schema.TypeString,
Optional: true,
Description: "Custom sysctl values for Load Balancer instance. Applied on boot.",
},
"oidc_cert": {
Type: schema.TypeString,
Optional: true,
Description: "insert ssl certificate in x509 pem format",
},
////
"desc": {
Type: schema.TypeString,
Optional: true,
@ -662,6 +773,7 @@ func resourceK8sSchemaMake() map[string]*schema.Schema {
},
"vins_id": {
Type: schema.TypeInt,
Optional: true,
Computed: true,
Description: "ID of default vins for this instace.",
},

@ -129,6 +129,56 @@ func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interfac
createReq.WithLB = d.Get("with_lb").(bool)
///4.4.0
createReq.HighlyAvailable = d.Get("ha_mode").(bool)
if additionalSans, ok := d.GetOk("additional_sans"); ok {
addSans := additionalSans.([]interface{})
resSans := make([]string, 0)
for _, san := range addSans {
resSans = append(resSans, san.(string))
}
createReq.AdditionalSANs = resSans
}
if clusterConfig, ok := d.GetOk("cluster_config"); ok {
createReq.ClusterConfiguration = clusterConfig.(string)
}
if kubeletConfig, ok := d.GetOk("kubelet_config"); ok {
createReq.KubeletConfiguration = kubeletConfig.(string)
}
if kubeProxyConfig, ok := d.GetOk("kube_proxy_config"); ok {
createReq.KubeProxyConfiguration = kubeProxyConfig.(string)
}
if joinConfig, ok := d.GetOk("join_config"); ok {
createReq.JoinConfiguration = joinConfig.(string)
}
if cloudInit, ok := d.GetOk("cloud_init"); ok {
createReq.UserData = cloudInit.(string)
}
if initConfig, ok := d.GetOk("init_config"); ok {
createReq.InitConfiguration = initConfig.(string)
}
if lbSysctlParams, ok := d.GetOk("lb_sysctl_params"); ok {
createReq.LbSysctlParams = lbSysctlParams.(string)
}
if oidcCertificate, ok := d.GetOk("oidc_cert"); ok {
createReq.OidcCertificate = oidcCertificate.(string)
log.Debug(createReq.OidcCertificate)
}
///
createReq.ExtNetOnly = d.Get("extnet_only").(bool)
if extNet, ok := d.GetOk("extnet_id"); ok {
createReq.ExtNetID = uint64(extNet.(int))
} else {
@ -165,7 +215,7 @@ func resourceK8sCPCreate(ctx context.Context, d *schema.ResourceData, m interfac
break
}
time.Sleep(time.Second * 10)
time.Sleep(time.Second * 20)
}
cluster, err := utilityK8sCheckPresence(ctx, d, m)
@ -292,7 +342,7 @@ func resourceK8sCPRead(ctx context.Context, d *schema.ResourceData, m interface{
if _, ok := d.GetOk("k8s_id"); !ok {
for _, worker := range cluster.K8SGroups.Workers {
err := fmt.Errorf("Found worker-group with ID %d. Make sure to import it to decort_k8s_wg resource if you wish to manage it", worker.ID)
err := fmt.Errorf("found worker-group with ID %d. Make sure to import it to decort_k8s_wg resource if you wish to manage it", worker.ID)
warnings.Add(err)
}
}
@ -569,6 +619,67 @@ func resourceK8sCPSchemaMake() map[string]*schema.Schema {
Default: true,
Description: "Create k8s with load balancer if true.",
},
"extnet_only": {
Type: schema.TypeBool,
Optional: true,
Default: false,
Description: "Use only selected ExtNet for infrastructure connections",
},
///4.4.0
"cloud_init": {
Type: schema.TypeString,
Optional: true,
Description: "Meta data for working group computes, format YAML 'user_data': 1111",
},
"join_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings for joining a node to a cluster. It includes parameters such as the cluster's control plane endpoint, token, and certificate key. insert a valid JSON string with all levels of nesting.",
},
"kube_proxy_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings of the Kube-proxy, which is responsible for network proxying and load balancing within the cluster. It includes parameters such as proxy mode, cluster IP ranges, and other Kube-proxy specific configurations. insert a valid JSON string with all levels of nesting.",
},
"kubelet_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to configure the behavior and settings of the Kubelet, which is the primary node agent that runs on each node in the cluster. It includes parameters such as node IP address, resource allocation, pod eviction policies, and other Kubelet-specific configurations. insert a valid JSON string with all levels of nesting.",
},
"cluster_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to define global settings and configurations for the entire cluster. It includes parameters such as cluster name, DNS settings, authentication methods, and other cluster-wide configurations. insert a valid JSON string with all levels of nesting.",
},
"init_config": {
Type: schema.TypeString,
Optional: true,
Description: "is used to define settings and actions that should be performed before any other component in the cluster starts. It allows you to configure things like node registration, network setup, and other initialization tasks. insert a valid JSON string with all levels of nesting.",
},
"additional_sans": {
Type: schema.TypeList,
Optional: true,
Description: "Optional extra Subject Alternative Names (SANs) to use for the API Server serving certificate. Can be both IP addresses and DNS names",
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"ha_mode": {
Type: schema.TypeBool,
Optional: true,
Description: "Use Highly Available schema for LB deploy",
},
"lb_sysctl_params": {
Type: schema.TypeString,
Optional: true,
Description: "Custom sysctl values for Load Balancer instance. Applied on boot.",
},
"oidc_cert": {
Type: schema.TypeString,
Optional: true,
Description: "insert ssl certificate in x509 pem format",
},
////
"extnet_id": {
Type: schema.TypeInt,
Optional: true,

@ -110,7 +110,7 @@ func resourceK8sWgRead(ctx context.Context, d *schema.ResourceData, m interface{
return diag.FromErr(err)
}
workersComputeList := make([]compute.RecordCompute, 0, 0)
workersComputeList := make([]compute.RecordCompute, 0)
for _, info := range wg.DetailedInfo {
compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID)
if err != nil {

@ -70,7 +70,7 @@ func utilityDataK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData,
return nil, nil, fmt.Errorf("WG with id %v in k8s cluster %v not found", wgId, k8sId)
}
workersComputeList := make([]compute.RecordCompute, 0, 0)
workersComputeList := make([]compute.RecordCompute, 0)
for _, info := range curWg.DetailedInfo {
compute, err := utilityComputeCheckPresence(ctx, d, m, info.ID)
if err != nil {
@ -121,7 +121,7 @@ func utilityK8sWgCheckPresence(ctx context.Context, d *schema.ResourceData, m in
}
}
return nil, fmt.Errorf("Not found wg with id: %v in k8s cluster: %v", wgId, cluster.ID)
return nil, fmt.Errorf("not found wg with id: %v in k8s cluster: %v", wgId, cluster.ID)
}
func utilityK8sWgListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (k8s.ListK8SGroups, error) {

@ -91,6 +91,7 @@ func flattenResourceLBBackend(d *schema.ResourceData, b *lb.ItemBackend, lbId in
func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("ha_mode", lb.HAMode)
d.Set("backend_haip", lb.BackendHAIP)
d.Set("backends", flattenLBBackends(lb.Backends))
d.Set("created_by", lb.CreatedBy)
d.Set("created_time", lb.CreatedTime)
@ -99,6 +100,7 @@ func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("desc", lb.Description)
d.Set("dp_api_user", lb.DPAPIUser)
d.Set("extnet_id", lb.ExtNetID)
d.Set("frontend_haip", lb.FrontendHAIP)
d.Set("frontends", flattenFrontends(lb.Frontends))
d.Set("gid", lb.GID)
d.Set("guid", lb.GUID)
@ -106,6 +108,7 @@ func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("image_id", lb.ImageID)
d.Set("milestones", lb.Milestones)
d.Set("name", lb.Name)
d.Set("part_k8s", lb.PartK8s)
d.Set("primary_node", flattenNode(lb.PrimaryNode))
d.Set("rg_id", lb.RGID)
d.Set("rg_name", lb.RGName)
@ -120,6 +123,7 @@ func flattenResourceLB(d *schema.ResourceData, lb *lb.RecordLB) {
func flattenLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("ha_mode", lb.HAMode)
d.Set("backend_haip", lb.BackendHAIP)
d.Set("backends", flattenLBBackends(lb.Backends))
d.Set("created_by", lb.CreatedBy)
d.Set("created_time", lb.CreatedTime)
@ -128,12 +132,14 @@ func flattenLB(d *schema.ResourceData, lb *lb.RecordLB) {
d.Set("desc", lb.Description)
d.Set("dp_api_user", lb.DPAPIUser)
d.Set("extnet_id", lb.ExtNetID)
d.Set("frontend_haip", lb.FrontendHAIP)
d.Set("frontends", flattenFrontends(lb.Frontends))
d.Set("gid", lb.GID)
d.Set("guid", lb.GUID)
d.Set("image_id", lb.ImageID)
d.Set("milestones", lb.Milestones)
d.Set("name", lb.Name)
d.Set("part_k8s", lb.PartK8s)
d.Set("primary_node", flattenNode(lb.PrimaryNode))
d.Set("rg_id", lb.RGID)
d.Set("rg_name", lb.RGName)
@ -246,6 +252,7 @@ func flattenLBList(lbl *lb.ListLB) []map[string]interface{} {
for _, lb := range lbl.Data {
temp := map[string]interface{}{
"ha_mode": lb.HAMode,
"backend_haip": lb.BackendHAIP,
"backends": flattenLBBackends(lb.Backends),
"created_by": lb.CreatedBy,
"created_time": lb.CreatedTime,
@ -255,6 +262,7 @@ func flattenLBList(lbl *lb.ListLB) []map[string]interface{} {
"dp_api_user": lb.DPAPIUser,
"dp_api_password": lb.DPAPIPassword,
"extnet_id": lb.ExtNetID,
"frontend_haip": lb.FrontendHAIP,
"frontends": flattenFrontends(lb.Frontends),
"gid": lb.GID,
"guid": lb.GUID,

@ -181,5 +181,6 @@ func dsLBItemSchemaMake() map[string]*schema.Schema {
Type: schema.TypeString,
Computed: true,
}
delete(sch, "part_k8s")
return sch
}

@ -47,12 +47,12 @@ func lbResourceSchemaMake() map[string]*schema.Schema {
sch["extnet_id"] = &schema.Schema{
Type: schema.TypeInt,
Required: true,
Optional: true,
}
sch["vins_id"] = &schema.Schema{
Type: schema.TypeInt,
Required: true,
Optional: true,
}
sch["start"] = &schema.Schema{
Type: schema.TypeBool,
@ -83,7 +83,18 @@ func lbResourceSchemaMake() map[string]*schema.Schema {
Type: schema.TypeBool,
Optional: true,
}
///4.4.0
sch["ha_mode"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,
}
sch["lb_sysctl_params"] = &schema.Schema{
Type: schema.TypeString,
Optional: true,
}
///
sch["permanently"] = &schema.Schema{
Type: schema.TypeBool,
Optional: true,

@ -40,6 +40,10 @@ func createLBSchema() map[string]*schema.Schema {
Type: schema.TypeBool,
Computed: true,
},
"backend_haip": {
Type: schema.TypeString,
Computed: true,
},
"backends": {
Type: schema.TypeList,
Computed: true,
@ -204,6 +208,10 @@ func createLBSchema() map[string]*schema.Schema {
Type: schema.TypeInt,
Computed: true,
},
"frontend_haip": {
Type: schema.TypeString,
Computed: true,
},
"frontends": {
Type: schema.TypeList,
Computed: true,
@ -272,6 +280,10 @@ func createLBSchema() map[string]*schema.Schema {
Type: schema.TypeString,
Computed: true,
},
"part_k8s": {
Type: schema.TypeBool,
Computed: true,
},
"primary_node": {
Type: schema.TypeList,
Computed: true,

@ -43,6 +43,11 @@ func existExtNetID(ctx context.Context, d *schema.ResourceData, m interface{}) (
c := m.(*controller.ControllerCfg)
extNetID := uint64(d.Get("extnet_id").(int))
// this code is needed in order to be able to pass 0
if extNetID == 0 {
return true, nil
}
req := extnet.ListRequest{}
extNetList, err := c.CloudAPI().ExtNet().List(ctx, req)
@ -57,6 +62,11 @@ func existViNSID(ctx context.Context, d *schema.ResourceData, m interface{}) (bo
c := m.(*controller.ControllerCfg)
vinsID := uint64(d.Get("vins_id").(int))
// this code is needed in order to be able to pass 0
if vinsID == 0 {
return true, nil
}
req := vins.ListRequest{}
vinsList, err := c.CloudAPI().VINS().List(ctx, req)

@ -88,15 +88,19 @@ func resourceLBCreate(ctx context.Context, d *schema.ResourceData, m interface{}
req.Description = desc.(string)
}
if haMode, ok := d.GetOk("ha_mode"); ok {
req.HighlyAvailable = haMode.(bool)
}
lbId, err := c.CloudAPI().LB().Create(ctx, req)
if err != nil {
return diag.FromErr(err)
}
lbIdParsed, _ := strconv.ParseInt(lbId, 10, 64)
lbIdParsed := strconv.Itoa(int(lbId))
d.SetId(lbId)
d.Set("lb_id", lbIdParsed)
d.SetId(lbIdParsed)
d.Set("lb_id", lbId)
_, err = utilityLBCheckPresence(ctx, d, m)
if err != nil {
@ -288,13 +292,26 @@ func resourceLBUpdate(ctx context.Context, d *schema.ResourceData, m interface{}
}
if hasChanged {
lbRec, err = utilityLBCheckPresence(ctx, d, m)
_, err = utilityLBCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
}
if d.HasChange("ha_mode") {
hamode := d.Get("ha_mode").(bool)
if hamode {
req:= lb.HighlyAvailableRequest {
LBID: uint64(d.Get("lb_id").(int)),
}
_, err := c.CloudAPI().LB().HighlyAvailable(ctx, req)
if err != nil {
return diag.FromErr(err)
}
}
}
if d.HasChange("enable") {
enable := d.Get("enable").(bool)
req := lb.DisableEnableRequest{

@ -0,0 +1,110 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package stack
import (
"context"
"strconv"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func dataSourceStackSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"stack_id": {
Type: schema.TypeInt,
Required: true,
},
"cpu_allocation_ratio": {
Type: schema.TypeInt,
Computed: true,
},
"descr": {
Type: schema.TypeString,
Computed: true,
},
"drivers": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeString,
},
},
"mem_allocation_ratio": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
}
return res
}
func dataSourceStackRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
stack, err := utilityStackCheckPresence(ctx, d, m)
if err != nil {
d.SetId("") // ensure ID is empty in this case
return diag.FromErr(err)
}
d.SetId(strconv.Itoa(d.Get("stack_id").(int)))
flattenStack(d, *stack)
return nil
}
func DataSourceStack() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceStackRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceStackSchemaMake(),
}
}

@ -0,0 +1,136 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package stack
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
)
func dataSourceStackListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
stackList, err := utilityStackListCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenStackList(stackList))
d.Set("entry_count", stackList.EntryCount)
return nil
}
func dataSourceStackListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"by_id": {
Type: schema.TypeInt,
Optional: true,
Description: "Find by ID",
},
"name": {
Type: schema.TypeString,
Optional: true,
Description: "Find by name",
},
"type": {
Type: schema.TypeString,
Optional: true,
Description: "Find by type",
},
"status": {
Type: schema.TypeString,
Optional: true,
Description: "Find by status",
},
"page": {
Type: schema.TypeInt,
Optional: true,
Description: "Page number",
},
"size": {
Type: schema.TypeInt,
Optional: true,
Description: "Page size",
},
"items": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"stack_id": {
Type: schema.TypeInt,
Computed: true,
},
"name": {
Type: schema.TypeString,
Computed: true,
},
"status": {
Type: schema.TypeString,
Computed: true,
},
"type": {
Type: schema.TypeString,
Computed: true,
},
},
},
},
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
}
return res
}
func DataSourceStackList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceStackListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceStackListSchemaMake(),
}
}

@ -0,0 +1,69 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package stack
import (
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack"
)
func flattenStackList(stackl *stack.ListStacks) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, stack := range stackl.Data {
temp := map[string]interface{}{
"stack_id": stack.ID,
"name": stack.Name,
"status": stack.Status,
"type": stack.Type,
}
res = append(res, temp)
}
return res
}
func flattenStack(d *schema.ResourceData, details stack.InfoStack) error {
log.Debugf("flattenStack: decoded Stack name %q / ID %d",
details.Name, details.ID)
d.Set("stack_id", details.ID)
d.Set("cpu_allocation_ratio", details.CPUAllocationRatio)
d.Set("name", details.Name)
d.Set("descr", details.Descr)
d.Set("mem_allocation_ratio", details.MemAllocationRatio)
d.Set("status", details.Status)
d.Set("type", details.Type)
d.Set("drivers", details.Drivers)
return nil
}

@ -0,0 +1,62 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package stack
import (
"context"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func utilityStackCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stack.InfoStack, error) {
c := m.(*controller.ControllerCfg)
req := stack.GetRequest{}
if d.Id() != "" {
stackId, _ := strconv.ParseUint(d.Id(), 10, 64)
req.StackId = stackId
} else {
req.StackId = uint64(d.Get("stack_id").(int))
}
stackData, err := c.CloudAPI().Stack().Get(ctx, req)
if err != nil {
return nil, err
}
return stackData, nil
}

@ -0,0 +1,77 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package stack
import (
"context"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/stack"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func utilityStackListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*stack.ListStacks, error) {
c := m.(*controller.ControllerCfg)
req := stack.ListRequest{}
if byId, ok := d.GetOk("by_id"); ok {
req.ByID = uint64(byId.(int))
}
if name, ok := d.GetOk("name"); ok {
req.Name = name.(string)
}
if status, ok := d.GetOk("status"); ok {
req.Status = status.(string)
}
if stackType, ok := d.GetOk("type"); ok {
req.Type = stackType.(string)
}
if size, ok := d.GetOk("size"); ok {
req.Size = uint64(size.(int))
}
if page, ok := d.GetOk("page"); ok {
req.Page = uint64(page.(int))
}
log.Debugf("utilityStackListCheckPresence: load stack list")
stackList, err := c.CloudAPI().Stack().List(ctx, req)
if err != nil {
return nil, err
}
return stackList, nil
}

@ -0,0 +1,107 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"strconv"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
)
func dataSourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
staticRoute, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(staticRoute.ID, 10))
flattenStaticRouteData(d, staticRoute)
return nil
}
func dataSourceStaticRouteSchemaMake() map[string]*schema.Schema {
rets := map[string]*schema.Schema{
"vins_id": {
Type: schema.TypeInt,
Required: true,
Description: "Unique ID of the ViNS",
},
"route_id": {
Type: schema.TypeInt,
Required: true,
Description: "Unique ID of the static route",
},
"compute_ids": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"destination": {
Type: schema.TypeString,
Computed: true,
},
"gateway": {
Type: schema.TypeString,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"netmask": {
Type: schema.TypeString,
Computed: true,
},
}
return rets
}
func DataSourceStaticRoute() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceStaticRouteRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceStaticRouteSchemaMake(),
}
}

@ -0,0 +1,121 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"github.com/google/uuid"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
)
func dataSourceStaticRouteListRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
staticRouteList, err := utilityStaticRouteListCheckPresence(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
id := uuid.New()
d.SetId(id.String())
d.Set("items", flattenStaticRouteList(staticRouteList))
d.Set("entry_count", staticRouteList.EntryCount)
return nil
}
func dataSourceStaticRouteListSchemaMake() map[string]*schema.Schema {
res := map[string]*schema.Schema{
"vins_id": {
Type: schema.TypeInt,
Required: true,
Description: "ID of VINS",
},
"items": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Resource{
Schema: map[string]*schema.Schema{
"compute_ids": {
Type: schema.TypeList,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
},
"destination": {
Type: schema.TypeString,
Computed: true,
},
"gateway": {
Type: schema.TypeString,
Computed: true,
},
"guid": {
Type: schema.TypeString,
Computed: true,
},
"netmask": {
Type: schema.TypeString,
Computed: true,
},
"route_id": {
Type: schema.TypeInt,
Computed: true,
},
},
},
},
"entry_count": {
Type: schema.TypeInt,
Computed: true,
},
}
return res
}
func DataSourceStaticRouteList() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
ReadContext: dataSourceStaticRouteListRead,
Timeouts: &schema.ResourceTimeout{
Read: &constants.Timeout30s,
Default: &constants.Timeout60s,
},
Schema: dataSourceStaticRouteListSchemaMake(),
}
}

@ -506,6 +506,34 @@ func flattenVinsList(vl *vins.ListVINS) []map[string]interface{} {
return res
}
// /4.4.0
func flattenStaticRouteList(sr *vins.ListStaticRoutes) []map[string]interface{} {
res := make([]map[string]interface{}, 0)
for _, staticRoute := range sr.Data {
temp := map[string]interface{}{
"route_id": staticRoute.ID,
"destination": staticRoute.Destination,
"gateway": staticRoute.Gateway,
"guid": staticRoute.GUID,
"netmask": staticRoute.Netmask,
"compute_ids": staticRoute.ComputeIds,
}
res = append(res, temp)
}
return res
}
func flattenStaticRouteData(d *schema.ResourceData, route *vins.ItemRoutes) {
d.Set("destination", route.Destination)
d.Set("gateway", route.Gateway)
d.Set("guid", route.GUID)
d.Set("netmask", route.Netmask)
d.Set("compute_ids", route.ComputeIds)
}
///
func flattenVinsNatRuleList(natRules *vins.ListNATRules) []map[string]interface{} {
res := make([]map[string]interface{}, 0, len(natRules.Data))
for _, natRule := range natRules.Data {

@ -8,6 +8,7 @@ import (
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/extnet"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/locations"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/rg"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
)
@ -68,3 +69,16 @@ func existGID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool,
return len(locationList.FilterByGID(gid).Data) != 0, nil
}
func existVinsID(ctx context.Context, d *schema.ResourceData, m interface{}) (bool, error) {
c := m.(*controller.ControllerCfg)
vinsID := uint64(d.Get("vins_id").(int))
req := vins.ListRequest{}
vinsList, err := c.CloudAPI().VINS().List(ctx, req)
if err != nil {
return false, err
}
return len(vinsList.FilterByID(vinsID).Data) != 0, nil
}

@ -0,0 +1,270 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"strconv"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/constants"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/dc"
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
log "github.com/sirupsen/logrus"
)
func resourceStaticRouteCreate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*controller.ControllerCfg)
if _, ok := d.GetOk("vins_id"); ok {
haveVinsID, err := existVinsID(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
if !haveVinsID {
return diag.Errorf("resourceStaticRouteCreate: can't create Static Route because Vins ID %d is not allowed or does not exist", d.Get("vins_id").(int))
}
}
req := vins.StaticRouteAddRequest{
VINSID: uint64(d.Get("vins_id").(int)),
Destination: d.Get("destination").(string),
Netmask: d.Get("netmask").(string),
Gateway: d.Get("gateway").(string),
}
if computesIDS, ok := d.GetOk("compute_ids"); ok {
ids := computesIDS.([]interface{})
res := make([]uint64, 10)
for _, id := range ids {
computeId := uint64(id.(int))
res = append(res, computeId)
}
req.ComputeIds = res
}
_, err := c.CloudAPI().VINS().StaticRouteAdd(ctx, req)
if err != nil {
return diag.FromErr(err)
}
staticRouteData, err := getStaticRouteData(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
d.SetId(strconv.FormatUint(staticRouteData.ID, 10))
log.Debugf("TRY TO SET STATE ID %v", staticRouteData.ID)
return resourceStaticRouteRead(ctx, d, m)
}
func resourceStaticRouteRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
warnings := dc.Warnings{}
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
flattenStaticRouteData(d, staticRouteData)
return warnings.Get()
}
func resourceStaticRouteUpdate(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*controller.ControllerCfg)
warnings := dc.Warnings{}
if _, ok := d.GetOk("vins_id"); ok {
haveVinsID, err := existVinsID(ctx, d, m)
if err != nil {
return diag.FromErr(err)
}
if !haveVinsID {
return diag.Errorf("resourceVinsUpdate: can't update Static Route because VinsID %d is not allowed or does not exist", d.Get("vins_id").(int))
}
}
staticRouteData, err := utilityDataStaticRouteCheckPresence(ctx, d, m)
if err != nil {
d.SetId("")
return diag.FromErr(err)
}
if d.HasChange("compute_ids") {
deletedIds := make([]uint64, 0)
addedIds := make([]uint64, 0)
oldComputeIds, newComputeIds := d.GetChange("compute_ids")
oldComputeIdsSlice := oldComputeIds.([]interface{})
newComputeIdsSlice := newComputeIds.([]interface{})
for _, el := range oldComputeIdsSlice {
if !isContainsIds(newComputeIdsSlice, el) {
convertedEl := uint64(el.(int))
deletedIds = append(deletedIds, convertedEl)
}
}
for _, el := range newComputeIdsSlice {
if !isContainsIds(oldComputeIdsSlice, el) {
convertedEl := uint64(el.(int))
addedIds = append(addedIds, convertedEl)
}
}
if len(deletedIds) > 0 {
req := vins.StaticRouteAccessRevokeRequest{
VINSID: uint64(d.Get("vins_id").(int)),
RouteId: staticRouteData.ID,
ComputeIds: deletedIds,
}
_, err := c.CloudAPI().VINS().StaticRouteAccessRevoke(ctx, req)
if err != nil {
warnings.Add(err)
}
}
if len(addedIds) > 0 {
req := vins.StaticRouteAccessGrantRequest{
VINSID: uint64(d.Get("vins_id").(int)),
RouteId: staticRouteData.ID,
ComputeIds: addedIds,
}
_, err := c.CloudAPI().VINS().StaticRouteAccessGrant(ctx, req)
if err != nil {
warnings.Add(err)
}
}
}
defer resourceVinsRead(ctx, d, m)
return warnings.Get()
}
func resourceStaticRouteDelete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*controller.ControllerCfg)
vinsId := uint64(d.Get("vins_id").(int))
routeId, _ := strconv.ParseUint(d.Id(), 10, 64)
req := vins.StaticRouteDelRequest{
VINSID: vinsId,
RouteId: routeId,
}
_, err := c.CloudAPI().VINS().StaticRouteDel(ctx, req)
if err != nil {
return diag.FromErr(err)
}
d.SetId("")
return nil
}
func resourceStaticRouteSchemaMake() map[string]*schema.Schema {
rets := dataSourceStaticRouteSchemaMake()
rets["route_id"] = &schema.Schema{
Type: schema.TypeInt,
Computed: true,
Optional: true,
}
rets["compute_ids"] = &schema.Schema{
Type: schema.TypeList,
Optional: true,
Computed: true,
Elem: &schema.Schema{
Type: schema.TypeInt,
},
}
rets["destination"] = &schema.Schema{
Type: schema.TypeString,
Required: true,
}
rets["gateway"] = &schema.Schema{
Type: schema.TypeString,
Required: true,
}
rets["netmask"] = &schema.Schema{
Type: schema.TypeString,
Required: true,
}
return rets
}
func isContainsIds(els []interface{}, el interface{}) bool {
convEl := el.(int)
for _, elOld := range els {
if convEl == elOld.(int) {
return true
}
}
return false
}
func ResourceStaticRoute() *schema.Resource {
return &schema.Resource{
SchemaVersion: 1,
CreateContext: resourceStaticRouteCreate,
ReadContext: resourceStaticRouteRead,
UpdateContext: resourceStaticRouteUpdate,
DeleteContext: resourceStaticRouteDelete,
Importer: &schema.ResourceImporter{
StateContext: schema.ImportStatePassthroughContext,
},
Timeouts: &schema.ResourceTimeout{
Create: &constants.Timeout20m,
Read: &constants.Timeout600s,
Update: &constants.Timeout20m,
Delete: &constants.Timeout600s,
Default: &constants.Timeout600s,
},
Schema: resourceStaticRouteSchemaMake(),
}
}

@ -223,7 +223,7 @@ func resourceVinsCreate(ctx context.Context, d *schema.ResourceData, m interface
}
func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics {
c := m.(*controller.ControllerCfg)
// c := m.(*controller.ControllerCfg)
warnings := dc.Warnings{}
vinsData, err := utilityDataVinsCheckPresence(ctx, d, m)
@ -232,7 +232,7 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}
return diag.FromErr(err)
}
isEnabled := d.Get("enable").(bool)
// isEnabled := d.Get("enable").(bool)
hasChangeState := false
@ -257,30 +257,30 @@ func resourceVinsRead(ctx context.Context, d *schema.ResourceData, m interface{}
return diag.Errorf("ViNS are in status: %s, please, contact support for more information", vinsData.Status)
case status.Created:
case status.Enabled:
if !isEnabled {
hasChangeState = true
req := vins.DisableEnableRequest{
VINSID: vinsData.ID,
}
// if !isEnabled {
// hasChangeState = true
// req := vins.DisableEnableRequest{
// VINSID: vinsData.ID,
// }
_, err := c.CloudAPI().VINS().Disable(ctx, req)
if err != nil {
warnings.Add(err)
}
}
// _, err := c.CloudAPI().VINS().Disable(ctx, req)
// if err != nil {
// warnings.Add(err)
// }
// }
case status.Enabling:
case status.Disabled:
if isEnabled {
hasChangeState = true
req := vins.DisableEnableRequest{
VINSID: vinsData.ID,
}
// if isEnabled {
// hasChangeState = true
// req := vins.DisableEnableRequest{
// VINSID: vinsData.ID,
// }
_, err := c.CloudAPI().VINS().Enable(ctx, req)
if err != nil {
warnings.Add(err)
}
}
// _, err := c.CloudAPI().VINS().Enable(ctx, req)
// if err != nil {
// warnings.Add(err)
// }
// }
case status.Disabling:
case status.Deleting:
return diag.Errorf("ViNS are in progress with status: %s", vinsData.Status)

@ -0,0 +1,96 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package vins
import (
"context"
"fmt"
"strconv"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func utilityDataStaticRouteCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ItemRoutes, error) {
c := m.(*controller.ControllerCfg)
req := vins.StaticRouteListRequest{}
req.VINSID = uint64(d.Get("vins_id").(int))
log.Debugf("utilityStaticRouteCheckPresence, vins_id: %v", req.VINSID)
staticRouteList, err := c.CloudAPI().VINS().StaticRouteList(ctx, req)
if err != nil {
return nil, err
}
routeId, _ := strconv.ParseUint(d.Id(), 10, 64)
log.Debugf("utilityStaticRouteCheckPresence: ROUTE ID %v", routeId)
staticRoute := &vins.ItemRoutes{}
for _, route := range staticRouteList.Data {
if routeId == route.ID {
staticRoute = &route
return staticRoute, nil
}
}
return nil, fmt.Errorf("static route not found")
}
func getStaticRouteData(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ItemRoutes, error) {
c := m.(*controller.ControllerCfg)
req := vins.StaticRouteListRequest{}
req.VINSID = uint64(d.Get("vins_id").(int))
staticRouteList, err := c.CloudAPI().VINS().StaticRouteList(ctx, req)
if err != nil {
return nil, err
}
destination := d.Get("destination").(string)
gateway := d.Get("gateway").(string)
staticRoute := &vins.ItemRoutes{}
for _, route := range staticRouteList.Data {
if destination == route.Destination && gateway == route.Gateway {
staticRoute = &route
return staticRoute, nil
}
}
return nil, fmt.Errorf("static route not found")
}

@ -0,0 +1,58 @@
/*
Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved.
Authors:
Petr Krutov, <petr.krutov@digitalenergy.online>
Stanislav Solovev, <spsolovev@digitalenergy.online>
Kasim Baybikov, <kmbaybikov@basistech.ru>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
/*
Terraform DECORT provider - manage resources provided by DECORT (Digital Energy Cloud
Orchestration Technology) with Terraform by Hashicorp.
Source code: https://repository.basistech.ru/BASIS/terraform-provider-decort
Please see README.md to learn where to place source code so that it
builds seamlessly.
Documentation: https://repository.basistech.ru/BASIS/terraform-provider-decort/wiki
*/
package vins
import (
"context"
log "github.com/sirupsen/logrus"
"repository.basistech.ru/BASIS/decort-golang-sdk/pkg/cloudapi/vins"
"repository.basistech.ru/BASIS/terraform-provider-decort/internal/controller"
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
)
func utilityStaticRouteListCheckPresence(ctx context.Context, d *schema.ResourceData, m interface{}) (*vins.ListStaticRoutes, error) {
c := m.(*controller.ControllerCfg)
req := vins.StaticRouteListRequest{}
req.VINSID = uint64(d.Get("vins_id").(int))
log.Debugf("utilityStaticRouteListCheckPresence")
staticRouteList, err := c.CloudAPI().VINS().StaticRouteList(ctx, req)
if err != nil {
return nil, err
}
return staticRouteList, nil
}

@ -0,0 +1,37 @@
/*
Получение stack по его id
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "4.4.0"
source = "basis/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://alpha.dev.decs.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso-alpha.dev.decs.online"
allow_unverified_ssl = true
}
data "decort_stack" "stack" {
#обязательный параметр
#тип - число
#идентификатор стека
stack_id = 2
}
output "test" {
value = data.decort_stack.stack
}

@ -0,0 +1,64 @@
/*
Получение списка stack
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "4.4.0"
source = "basis/decort/decort"
}
}
}
*/
provider "decort" {
authenticator = "oauth2"
#controller_url = <DECORT_CONTROLLER_URL>
controller_url = "https://alpha.dev.decs.online"
#oauth2_url = <DECORT_SSO_URL>
oauth2_url = "https://sso-alpha.dev.decs.online"
allow_unverified_ssl = true
}
data "decort_stack_list" "stack_list" {
#необязательный параметр
#тип - число
#фильтрация списка для получения информации о конкретном stack по его id
#by_id =
#необязательный параметр
#тип - строка
#фильтрация списка для получения информации о конкретном stack по его имени
#name = "alpha-cpu-04"
#необязательный параметр
#тип - строка
#фильтрация списка для получения информации о конкретном stack по его типу
#type = "KVM"
#необязательный параметр
#тип - строка
#фильтрация списка для получения информации о конкретном stack по его статусу
#status = "ENABLED"
#номер страницы для отображения
#опциональный параметр
#тип - число
#если не задан - выводятся все доступные данные
#page = 2
#размер страницы
#опциональный параметр
#тип - число
#если не задан - выводятся все доступные данные
#size = 3
}
output "test" {
value = data.decort_stack_list.stack_list
}

@ -0,0 +1,50 @@
/*
Пример использования
Ресурса vins static routes
Ресурс позволяет:
1. Создавать static routes
2. Удалять static routes
3. Получать информацию о всех static routes в данном Vins
4. Предоставлять доступ виртуальным машинам к static routes
5. Удалять доступ виртуальным машинам к static routes
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "<VERSION>"
source = "basis/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_vins_static_route" "route" {
#обязательный параметр
#id vins в котором добавлены routes
#тип - число
vins_id = 1111
#обязательный параметр
#id route
#тип - число
route_id = 1
}
output "route" {
value = decort_vins_static_route.route
}

@ -0,0 +1,45 @@
/*
Пример использования
Ресурса vins static routes
Ресурс позволяет:
1. Создавать static routes
2. Удалять static routes
3. Получать информацию о всех static routes в данном Vins
4. Предоставлять доступ виртуальным машинам к static routes
5. Удалять доступ виртуальным машинам к static routes
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "<VERSION>"
source = "basis/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_vins_static_route_list" "list" {
#обязательный параметр
#id vins в котором добавлены routes
#тип - число
vins_id = 1111
}
output "list" {
value = decort_vins_static_route_list.list
}

@ -77,32 +77,47 @@ resource "decort_bservice_group" "bsg" {
#драйвер
#обязательный параметр
#тип - число
#тип - строка
driver = "kvm_x86"
#id Storage endpoint provider
#необязательный параметр
#тип - число
sep_id = 3
#Наименование SEPPool используется если установлен sepId, также может быть пустым
#необязательный параметр
#тип - строка
sep_pool = "name"
#тег группы
#необязательный параметр
#тип - строка
#используется при создании и редактировании ресурса
role = "tf_test_changed"
#id сетей extnet
#обязательный параметр
#необязательный параметр
#тип - массив чисел
#должен быть использован vins или extnets
extnets = [1111]
extnets = [1111, 2222]
#id сетей vinses
#обязательный параметр
#необязательный параметр
#тип - массив чисел
#должен быть использован vins или extnets
#vinses = [1111, 2222]
vinses = [1111, 2222]
#время таймуата перед стартом
#необязательный параметр
#тип - число
#используется при создании ресурса
#timeout_start = 0
timeout_start = 0
#тег группы
#Перечень аргументов для cloud-init создаваемым группам узлов Worker
#необязательный параметр
#тип - строка
#используется при создании и редактировании ресурса
# role = "tf_test_changed"
#тип - файл
cloud_init = file("initconfig.tftpl")
#id групп родителей
#необязательный параметр
@ -113,13 +128,14 @@ resource "decort_bservice_group" "bsg" {
#принудительное обновление параметров выч. мощностей (ram,disk,cpu) и имени группы
#необязательный параметр
#тип - булев тип
#используется при редактировании
#используется при редактировании ресурса
#по-умолчанию - false
#force_update = true
#старт/стоп вычислительных мощностей
#необязательный параметр
#тип - булев тип
#используется при редактировании
#используется при редактировании ресурса
#по-умолчанию - false
#start = false
@ -141,6 +157,7 @@ resource "decort_bservice_group" "bsg" {
#тип - строка
#используется в связке с comp_count при редактировании группы
#возможные варианты - RELATIVE и ABSOLUTE
#по-умолчанию - "RELATIVE"
#mode = "RELATIVE"
}

@ -14,10 +14,11 @@ 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"
controller_url = "https://mr4.digitalenergy.online"
app_id = ""
app_secret = ""
allow_unverified_ssl = true
}
resource "decort_k8s" "cluster" {
@ -49,7 +50,6 @@ resource "decort_k8s" "cluster" {
# список labels для дефолтной worker группы
# опциональный параметр
# В скором времени параметры labels, annotations, taints будут полностью перенесены в блок workers
# тип - массив строк
labels = ["key1=val1", "key2=val2"]
@ -80,29 +80,32 @@ resource "decort_k8s" "cluster" {
#тип - число
cpu = 2
#кол-во RAM в Мбайтах
#обязательный параметр
#тип - число
ram = 2048
#размер диска в Гбайтах
#обязательный параметр
#тип - число
disk = 10
}
#идентификатор SEP для создания загрузочных дисков для master узлов
#опциональный параметр
#тип - число
sep_id = 3
#наименование MasterSEPPool используется если установлен master sepId, также может быть пустым
#опциональный параметр
#тип - строка
sep_pool = "data_01"
}
#настройка worker группы
#опциональный параметр
#Первая указанная воркер-группа должна соответствовать изначально созданной вместе с кластером.
# labels, annotations, taints для дефолтной worker группы указываются в корне ресурса при создании кластера.
workers {
#наименование worker группы
#обязательный параметр
#тип - строка
name = "workers_wg"
#кол-во node
#обязательный параметр
#тип - число
@ -187,6 +190,89 @@ resource "decort_k8s" "cluster" {
#тип - массив строк
taints = ["key1=value1:NoSchedule", "key2=value2:NoExecute"]
}
# id extnet
#опциональный параметр
#тип - число
extnet_id = 0
# id vins
# опциональный параметр
# тип - число
vins_id = 1234
# создать Kubernetes cluster с masters nodes с подключенным LB
# опциональный параметр
# тип - булев тип
with_lb = true
# пользовательские значения sysctl для LB
# опциональный параметр
# тип - строка
lb_sysctl_params = "some"
# позволяет создать схему отказоустройчивой LB
# опциональный параметр
# тип - булев тип
ha_mode = true
# дополнительные SAN (Subject Alternative Names) для использования в процессе автоматического выписывания сертификата Кластера Kubernetes;
# возможность взаимодействовать с кластером по FQDN
# параметр получает список строк IP-адреса и/или DNS (по формату RFC 1123 c поддержкой wildcard)
# опциональный параметр
# тип - массив строк
additional_sans = ["192.168.201.0","192.168.201.1"]
# используется для определения настроек и действий, которые должны быть выполнены перед запуском любого другого компонента в кластере
# это позволяет вам настраивать такие вещи, как регистрация node, настройка network и другие задачи инициализации
# опциональный параметр
# тип - строка
init_config = "{JSON string}"
# используется для определения глобальных настроек и конфигураций для всего кластера
# он включает в себя такие параметры, как имя кластера, настройки DNS, методы аутентификации и другие конфигурации в масштабах кластера
# опциональный параметр
# тип - строка
cluster_config = "{JSON string}"
# используется для настройки поведения и параметров Kubelet, который является агентом primary node, запускаемым на каждом node кластера
# он включает в себя такие параметры, как IP-адрес node, распределение ресурсов, политики удаления модулей и другие конфигурации, специфичные для Kubelet
# опциональный параметр
# тип - строка
kubelet_config = "{JSON string}"
# используется для настройки поведения и параметров присоединения node к кластеру
# он включает в себя такие параметры, как режим прокси-сервера, диапазоны IP-адресов кластера и другие конфигурации, специфичные для Kube-proxy
# опциональный параметр
# тип - строка
kube_proxy_config = "{JSON string}"
# используется для настройки поведения и параметров присоединения node к кластеру
# он включает в себя такие параметры, как cluster's control plane endpoint, токен и ключ сертификата
# опциональный параметр
# тип - строка
join_config = "{JSON string}"
# описание кластера
# опциональный параметр
# тип - строка
desc = "description"
# перечень аргументов для cloud-init создаваемым группам узлов Worker
# необязательный параметр
# тип - файл
cloud_init = file("initconfig.tftpl")
# при создании кластре использовать подключение только к сети ExtNet
# опциональный параметр
# тип - булев тип
extnet_only = true
# добавить ssl-сертификат в формате x509 pem
# необязательный параметр
# тип - файл
oidc_cert = file("ca.crt")
}
output "test_cluster" {

@ -41,13 +41,15 @@ resource "decort_lb" "lb" {
#тип - строка
name = "tf-test-lb"
#id внешней сети и id виртуальной сети не могут быть одновременно = 0
#id внешней сети
#обязательный параметр
#опциональный параметр
#тип - число
extnet_id = 6
#id виртуальной сети
#обязательный параметр
#опциональный параметр
#тип - число
vins_id = 758
@ -59,6 +61,11 @@ resource "decort_lb" "lb" {
#то для успешного старта, он должен быть доступен (enable = true)
start = true
# позволяет создать схему отказоустройчивой LB
# опциональный параметр
# тип - булев тип
ha_mode = true
#описание
#опциональный параметр
#тип - строка

@ -0,0 +1,74 @@
/*
Пример использования
Ресурса vins static routes
Ресурс позволяет:
1. Создавать static routes
2. Удалять static routes
3. Получать информацию о всех static routes в данном Vins
4. Предоставлять доступ виртуальным машинам к static routes
5. Удалять доступ виртуальным машинам к static routes
*/
#Расскомментируйте этот код,
#и внесите необходимые правки в версию и путь,
#чтобы работать с установленным вручную (не через hashicorp provider registry) провайдером
/*
terraform {
required_providers {
decort = {
version = "<VERSION>"
source = "basis/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
}
resource "decort_vins_static_route" "sr" {
#id Vins
#обязательный параметр
#тип - число
vins_id = 1111
# destination network
# обязательный параметр
#тип - строка
destination = "192.168.201.0"
# destination network mask
#обязательный параметр
#тип - строка
netmask = "255.255.255.255"
# IP-адрес из пула свободных IP-адресов ViNS ID
#обязательный параметр
#тип - строка
gateway = "192.168.201.40"
# список виртуальных машин, которым будет предоставлен доступ к роуту
#опциональный параметр
#тип - массив чисел
compute_ids = [111,222]
}
output "sr" {
value = decort_vins_static_route.sr
}
data "decort_vins_static_routes_list" "list" {
vins_id = 1111
}
output "list" {
value = decort_vins_static_routes_list.list
}

@ -27,18 +27,19 @@ arch=$(basename $filename | cut -d '_' -f 4)
plugins_dir=~/.terraform.d/plugins/
provider_path=basis/decort/decort/$version/$os\_$arch/
print_success () {
echo "DECORT provider version $version has been successfully installed"
echo "\n"
echo "Copy this provider configuration to main.tf file"
echo "terraform {"
echo " required_providers {"
echo " decort = {"
echo " version = \"$version\""
echo " source = \"basis/decort/decort\""
echo " }"
echo " }"
echo "}"
print_info () {
cat <<EOF
Copy this provider configuration to main.tf file
terraform {
required_providers {
decort = {
version = "$version"
source = "basis/decort/decort"
}
}
}
EOF
}
install () {
@ -47,15 +48,17 @@ install () {
echo "Provider directory already exists, checking for decort provider executable.."
if [[ ! "$(ls -A $plugins_dir$provider_path)" ]]; then
cp bin/terraform-provider-decort_$version\_$os\_$arch $plugins_dir$provider_path/terraform-provider-decort
print_success
print_info
else
echo "DECORT provider version $version is already installed. Exiting.."
print_info
fi
else
echo "Creating provider directory.."
mkdir -p $plugins_dir/$provider_path
cp bin/terraform-provider-decort_$version\_$os\_$arch $plugins_dir$provider_path/terraform-provider-decort
print_success
echo "DECORT provider version $version has been successfully installed"
print_info
fi
}

Loading…
Cancel
Save