diff --git a/CHANGELOG.md b/CHANGELOG.md index 45254d0..ecd78ab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 diff --git a/Makefile b/Makefile index 158684c..573a8c7 100644 --- a/Makefile +++ b/Makefile @@ -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\ diff --git a/README.md b/README.md index fcc9cde..04a44fe 100644 --- a/README.md +++ b/README.md @@ -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, diff --git a/go.mod b/go.mod index 994d6a3..ed85817 100644 --- a/go.mod +++ b/go.mod @@ -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 diff --git a/go.sum b/go.sum index c0d9edd..ad45bdf 100644 --- a/go.sum +++ b/go.sum @@ -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= diff --git a/internal/provider/data_sources_map.go b/internal/provider/data_sources_map.go index bb63ddd..d84fab4 100644 --- a/internal/provider/data_sources_map.go +++ b/internal/provider/data_sources_map.go @@ -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(), diff --git a/internal/provider/resource_map.go b/internal/provider/resource_map.go index 0042e38..c7b5067 100644 --- a/internal/provider/resource_map.go +++ b/internal/provider/resource_map.go @@ -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(), diff --git a/internal/service/cloudapi/bservice/flattens.go b/internal/service/cloudapi/bservice/flattens.go index bfa496f..9042059 100644 --- a/internal/service/cloudapi/bservice/flattens.go +++ b/internal/service/cloudapi/bservice/flattens.go @@ -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) diff --git a/internal/service/cloudapi/bservice/resource_bservice.go b/internal/service/cloudapi/bservice/resource_bservice.go index bc0889c..ca4095c 100644 --- a/internal/service/cloudapi/bservice/resource_bservice.go +++ b/internal/service/cloudapi/bservice/resource_bservice.go @@ -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) } diff --git a/internal/service/cloudapi/bservice/resource_bservice_group.go b/internal/service/cloudapi/bservice/resource_bservice_group.go index db53f15..75647a6 100644 --- a/internal/service/cloudapi/bservice/resource_bservice_group.go +++ b/internal/service/cloudapi/bservice/resource_bservice_group.go @@ -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, diff --git a/internal/service/cloudapi/k8s/data_source_k8s_computes.go b/internal/service/cloudapi/k8s/data_source_k8s_computes.go index 6474e0b..5151d43 100644 --- a/internal/service/cloudapi/k8s/data_source_k8s_computes.go +++ b/internal/service/cloudapi/k8s/data_source_k8s_computes.go @@ -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": { diff --git a/internal/service/cloudapi/k8s/flattens.go b/internal/service/cloudapi/k8s/flattens.go index 03387f3..1be70d4 100644 --- a/internal/service/cloudapi/k8s/flattens.go +++ b/internal/service/cloudapi/k8s/flattens.go @@ -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)) diff --git a/internal/service/cloudapi/k8s/resource_k8s.go b/internal/service/cloudapi/k8s/resource_k8s.go index 8445a91..dac7178 100644 --- a/internal/service/cloudapi/k8s/resource_k8s.go +++ b/internal/service/cloudapi/k8s/resource_k8s.go @@ -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.", }, diff --git a/internal/service/cloudapi/k8s/resource_k8s_cp.go b/internal/service/cloudapi/k8s/resource_k8s_cp.go index 8444b65..0eee12c 100644 --- a/internal/service/cloudapi/k8s/resource_k8s_cp.go +++ b/internal/service/cloudapi/k8s/resource_k8s_cp.go @@ -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) @@ -229,7 +279,7 @@ func resourceK8sCPRead(ctx context.Context, d *schema.ResourceData, m interface{ case status.Destroyed: d.SetId("") return diag.Errorf("The resource cannot be updated because it has been destroyed") - // return resourceK8sCreate(ctx, d, m) + // return resourceK8sCreate(ctx, d, m) case status.Enabling: case status.Enabled: case status.Disabling: @@ -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, diff --git a/internal/service/cloudapi/k8s/resource_k8s_wg.go b/internal/service/cloudapi/k8s/resource_k8s_wg.go index 76825ac..c6020c9 100644 --- a/internal/service/cloudapi/k8s/resource_k8s_wg.go +++ b/internal/service/cloudapi/k8s/resource_k8s_wg.go @@ -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 { diff --git a/internal/service/cloudapi/k8s/utility_k8s_wg.go b/internal/service/cloudapi/k8s/utility_k8s_wg.go index b5226f2..072fdeb 100644 --- a/internal/service/cloudapi/k8s/utility_k8s_wg.go +++ b/internal/service/cloudapi/k8s/utility_k8s_wg.go @@ -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) { diff --git a/internal/service/cloudapi/lb/flattens.go b/internal/service/cloudapi/lb/flattens.go index c23265f..9ce3cb9 100644 --- a/internal/service/cloudapi/lb/flattens.go +++ b/internal/service/cloudapi/lb/flattens.go @@ -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, diff --git a/internal/service/cloudapi/lb/lb_data_subresource.go b/internal/service/cloudapi/lb/lb_data_subresource.go index e279992..1e7b667 100644 --- a/internal/service/cloudapi/lb/lb_data_subresource.go +++ b/internal/service/cloudapi/lb/lb_data_subresource.go @@ -181,5 +181,6 @@ func dsLBItemSchemaMake() map[string]*schema.Schema { Type: schema.TypeString, Computed: true, } + delete(sch, "part_k8s") return sch } diff --git a/internal/service/cloudapi/lb/lb_resource_subresource.go b/internal/service/cloudapi/lb/lb_resource_subresource.go index 6679466..66d68f7 100644 --- a/internal/service/cloudapi/lb/lb_resource_subresource.go +++ b/internal/service/cloudapi/lb/lb_resource_subresource.go @@ -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, diff --git a/internal/service/cloudapi/lb/lb_schema.go b/internal/service/cloudapi/lb/lb_schema.go index fac4c7d..0d91c25 100644 --- a/internal/service/cloudapi/lb/lb_schema.go +++ b/internal/service/cloudapi/lb/lb_schema.go @@ -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, diff --git a/internal/service/cloudapi/lb/resource_check_input_values.go b/internal/service/cloudapi/lb/resource_check_input_values.go index 6c48dc1..ff71172 100644 --- a/internal/service/cloudapi/lb/resource_check_input_values.go +++ b/internal/service/cloudapi/lb/resource_check_input_values.go @@ -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) diff --git a/internal/service/cloudapi/lb/resource_lb.go b/internal/service/cloudapi/lb/resource_lb.go index 36ee3c5..7732e6d 100644 --- a/internal/service/cloudapi/lb/resource_lb.go +++ b/internal/service/cloudapi/lb/resource_lb.go @@ -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{ diff --git a/internal/service/cloudapi/stack/data_source_stack.go b/internal/service/cloudapi/stack/data_source_stack.go new file mode 100644 index 0000000..48a9e04 --- /dev/null +++ b/internal/service/cloudapi/stack/data_source_stack.go @@ -0,0 +1,110 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/stack/data_source_stack_list.go b/internal/service/cloudapi/stack/data_source_stack_list.go new file mode 100644 index 0000000..b949cce --- /dev/null +++ b/internal/service/cloudapi/stack/data_source_stack_list.go @@ -0,0 +1,136 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/stack/flattens.go b/internal/service/cloudapi/stack/flattens.go new file mode 100644 index 0000000..d6c0805 --- /dev/null +++ b/internal/service/cloudapi/stack/flattens.go @@ -0,0 +1,69 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/service/cloudapi/stack/utility_stack.go b/internal/service/cloudapi/stack/utility_stack.go new file mode 100644 index 0000000..b034972 --- /dev/null +++ b/internal/service/cloudapi/stack/utility_stack.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/service/cloudapi/stack/utility_stack_list.go b/internal/service/cloudapi/stack/utility_stack_list.go new file mode 100644 index 0000000..c8ea467 --- /dev/null +++ b/internal/service/cloudapi/stack/utility_stack_list.go @@ -0,0 +1,77 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/internal/service/cloudapi/vins/data_source_static_route.go b/internal/service/cloudapi/vins/data_source_static_route.go new file mode 100644 index 0000000..3946f03 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_static_route.go @@ -0,0 +1,107 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/vins/data_source_static_route_list.go b/internal/service/cloudapi/vins/data_source_static_route_list.go new file mode 100644 index 0000000..38a0697 --- /dev/null +++ b/internal/service/cloudapi/vins/data_source_static_route_list.go @@ -0,0 +1,121 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/vins/flattens.go b/internal/service/cloudapi/vins/flattens.go index b6afe6b..8765d18 100644 --- a/internal/service/cloudapi/vins/flattens.go +++ b/internal/service/cloudapi/vins/flattens.go @@ -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 { diff --git a/internal/service/cloudapi/vins/resource_check_input_values.go b/internal/service/cloudapi/vins/resource_check_input_values.go index 682be89..9fd11f4 100644 --- a/internal/service/cloudapi/vins/resource_check_input_values.go +++ b/internal/service/cloudapi/vins/resource_check_input_values.go @@ -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 +} diff --git a/internal/service/cloudapi/vins/resource_static_route.go b/internal/service/cloudapi/vins/resource_static_route.go new file mode 100644 index 0000000..fafb1a9 --- /dev/null +++ b/internal/service/cloudapi/vins/resource_static_route.go @@ -0,0 +1,270 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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(), + } +} diff --git a/internal/service/cloudapi/vins/resource_vins.go b/internal/service/cloudapi/vins/resource_vins.go index 1f9e425..7cb195a 100644 --- a/internal/service/cloudapi/vins/resource_vins.go +++ b/internal/service/cloudapi/vins/resource_vins.go @@ -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, - } - - _, err := c.CloudAPI().VINS().Disable(ctx, req) - if err != nil { - warnings.Add(err) - } - } + // if !isEnabled { + // hasChangeState = true + // req := vins.DisableEnableRequest{ + // VINSID: vinsData.ID, + // } + + // _, 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, - } - - _, err := c.CloudAPI().VINS().Enable(ctx, req) - if err != nil { - warnings.Add(err) - } - } + // if isEnabled { + // hasChangeState = true + // req := vins.DisableEnableRequest{ + // VINSID: vinsData.ID, + // } + + // _, 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) diff --git a/internal/service/cloudapi/vins/utility_static_route.go b/internal/service/cloudapi/vins/utility_static_route.go new file mode 100644 index 0000000..82ea6a8 --- /dev/null +++ b/internal/service/cloudapi/vins/utility_static_route.go @@ -0,0 +1,96 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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") +} diff --git a/internal/service/cloudapi/vins/utility_static_route_list.go b/internal/service/cloudapi/vins/utility_static_route_list.go new file mode 100644 index 0000000..005013a --- /dev/null +++ b/internal/service/cloudapi/vins/utility_static_route_list.go @@ -0,0 +1,58 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Authors: +Petr Krutov, +Stanislav Solovev, +Kasim Baybikov, + +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 +} diff --git a/samples/cloudapi/data_stack/main.tf b/samples/cloudapi/data_stack/main.tf new file mode 100644 index 0000000..0e83532 --- /dev/null +++ b/samples/cloudapi/data_stack/main.tf @@ -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 = + controller_url = "https://alpha.dev.decs.online" + #oauth2_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 +} + diff --git a/samples/cloudapi/data_stack_list/main.tf b/samples/cloudapi/data_stack_list/main.tf new file mode 100644 index 0000000..2b18b66 --- /dev/null +++ b/samples/cloudapi/data_stack_list/main.tf @@ -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 = + controller_url = "https://alpha.dev.decs.online" + #oauth2_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 +} + diff --git a/samples/cloudapi/data_vins_static_route/main.tf b/samples/cloudapi/data_vins_static_route/main.tf new file mode 100644 index 0000000..c83b144 --- /dev/null +++ b/samples/cloudapi/data_vins_static_route/main.tf @@ -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 = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/data_vins_static_route_list/main.tf b/samples/cloudapi/data_vins_static_route_list/main.tf new file mode 100644 index 0000000..36279b1 --- /dev/null +++ b/samples/cloudapi/data_vins_static_route_list/main.tf @@ -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 = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_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 +} diff --git a/samples/cloudapi/resource_bservice_group/main.tf b/samples/cloudapi/resource_bservice_group/main.tf index db2b7c1..5d0c8d8 100644 --- a/samples/cloudapi/resource_bservice_group/main.tf +++ b/samples/cloudapi/resource_bservice_group/main.tf @@ -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" } diff --git a/samples/cloudapi/resource_k8s/main.tf b/samples/cloudapi/resource_k8s/main.tf index b17348e..a441b9b 100644 --- a/samples/cloudapi/resource_k8s/main.tf +++ b/samples/cloudapi/resource_k8s/main.tf @@ -13,11 +13,12 @@ terraform { */ provider "decort" { - authenticator = "oauth2" - oauth2_url = "https://sso.digitalenergy.online" - controller_url = "https://mr4.digitalenergy.online" - app_id = "" - app_secret = "" + authenticator = "oauth2" + #controller_url = + controller_url = "https://ds1.digitalenergy.online" + #oauth2_url = + oauth2_url = "https://sso.digitalenergy.online" + 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" { diff --git a/samples/cloudapi/resource_lb/main.tf b/samples/cloudapi/resource_lb/main.tf index 6454c58..2a9f924 100644 --- a/samples/cloudapi/resource_lb/main.tf +++ b/samples/cloudapi/resource_lb/main.tf @@ -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 + #описание #опциональный параметр #тип - строка diff --git a/samples/cloudapi/resource_vins_static_route/main.tf b/samples/cloudapi/resource_vins_static_route/main.tf new file mode 100644 index 0000000..05ac508 --- /dev/null +++ b/samples/cloudapi/resource_vins_static_route/main.tf @@ -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 = "" + source = "basis/decort/decort" + } + } +} +*/ + +provider "decort" { + authenticator = "oauth2" + #controller_url = + controller_url = "https://mr4.digitalenergy.online" + #oauth2_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 +} diff --git a/scripts/install.sh b/scripts/install.sh index a800f19..457bbbb 100755 --- a/scripts/install.sh +++ b/scripts/install.sh @@ -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 <