diff --git a/.gitignore b/.gitignore index 2e7cefe..b293db0 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ decort/vendor/ +examples/ terraform-provider-decort* diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..7dfe1d4 --- /dev/null +++ b/Makefile @@ -0,0 +1,39 @@ +TEST?=$$(go list ./... | grep -v 'vendor') +HOSTNAME=digitalenergy.online +NAMESPACE=decort +NAME=terraform-provider-decort +#BINARY=terraform-provider-${NAME} +BINARY=${NAME}.exe +VERSION=0.2 +#OS_ARCH=darwin_amd64 +OS_ARCH=windows_amd64 + +default: install + +build: + go build -o ${BINARY} + +release: + GOOS=darwin GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_darwin_amd64 + GOOS=freebsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_freebsd_386 + GOOS=freebsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_freebsd_amd64 + GOOS=freebsd GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_freebsd_arm + GOOS=linux GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_linux_386 + GOOS=linux GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_linux_amd64 + GOOS=linux GOARCH=arm go build -o ./bin/${BINARY}_${VERSION}_linux_arm + GOOS=openbsd GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_openbsd_386 + GOOS=openbsd GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_openbsd_amd64 + GOOS=solaris GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_solaris_amd64 + GOOS=windows GOARCH=386 go build -o ./bin/${BINARY}_${VERSION}_windows_386 + GOOS=windows GOARCH=amd64 go build -o ./bin/${BINARY}_${VERSION}_windows_amd64 + +install: build + mkdir -p ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH} + mv ${BINARY} ~/.terraform.d/plugins/${HOSTNAME}/${NAMESPACE}/${NAME}/${VERSION}/${OS_ARCH} + +test: + go test -i $(TEST) || exit 1 + echo $(TEST) | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 + +testacc: + TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m \ No newline at end of file diff --git a/decort/data_source_grid.go b/decort/data_source_grid.go new file mode 100644 index 0000000..ef33329 --- /dev/null +++ b/decort/data_source_grid.go @@ -0,0 +1,98 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func flattenGrid(d *schema.ResourceData, grid *Grid) { + d.Set("name", grid.Name) + d.Set("flag", grid.Flag) + d.Set("gid", grid.Gid) + d.Set("guid", grid.Guid) + d.Set("location_code", grid.LocationCode) + d.Set("id", grid.Id) + return +} + +func dataSourceGridRead(d *schema.ResourceData, m interface{}) error { + grid, err := utilityGridCheckPresence(d, m) + if err != nil { + return err + } + d.SetId("1234") + flattenGrid(d, grid) + + return nil +} + +func dataSourceGetGridSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "grid_id": { + Type: schema.TypeInt, + Required: true, + }, + "flag": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "location_code": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func dataSourceGrid() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Read: dataSourceGridRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &Timeout30s, + Default: &Timeout60s, + }, + + Schema: dataSourceGetGridSchemaMake(), + } +} diff --git a/decort/data_source_grid_list.go b/decort/data_source_grid_list.go new file mode 100644 index 0000000..04e0e96 --- /dev/null +++ b/decort/data_source_grid_list.go @@ -0,0 +1,124 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func flattenGridList(gl GridList) []map[string]interface{} { + res := make([]map[string]interface{}, len(gl), len(gl)) + for _, item := range gl { + temp := map[string]interface{}{} + temp["name"] = item.Name + temp["flag"] = item.Flag + temp["gid"] = item.Gid + temp["guid"] = item.Guid + temp["location_code"] = item.LocationCode + temp["id"] = item.Id + res = append(res, temp) + } + return res +} + +func dataSourceGridListRead(d *schema.ResourceData, m interface{}) error { + gridList, err := utilityGridListCheckPresence(d, m) + if err != nil { + return err + } + d.SetId("1234") + d.Set("items", flattenGridList(gridList)) + + return nil +} + +func dataSourceGridListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "grid list", + Elem: &schema.Resource{ + Schema: dataSourceGridSchemaMake(), + }, + }, + } + + return rets +} + +func dataSourceGridSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "flag": { + Type: schema.TypeString, + Computed: true, + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + }, + "guid": { + Type: schema.TypeInt, + Computed: true, + }, + "id": { + Type: schema.TypeInt, + Computed: true, + }, + "location_code": { + Type: schema.TypeString, + Computed: true, + }, + "name": { + Type: schema.TypeString, + Computed: true, + }, + } +} + +func dataSourceGridList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Read: dataSourceGridListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &Timeout30s, + Default: &Timeout60s, + }, + + Schema: dataSourceGridListSchemaMake(), + } +} diff --git a/decort/data_source_image.go b/decort/data_source_image.go index c0b6369..82c73bc 100644 --- a/decort/data_source_image.go +++ b/decort/data_source_image.go @@ -1,6 +1,6 @@ /* -Copyright (c) 2019-2021 Digital Energy Cloud Solutions LLC. All Rights Reserved. -Author: Sergey Shubin, , +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. @@ -25,57 +25,151 @@ Visit https://github.com/rudecs/terraform-provider-decort for full source code p package decort import ( - "encoding/json" - "fmt" - "net/url" - - log "github.com/sirupsen/logrus" - "github.com/hashicorp/terraform-plugin-sdk/helper/schema" - "github.com/hashicorp/terraform-plugin-sdk/helper/validation" ) -func dataSourceImageRead(d *schema.ResourceData, m interface{}) error { - name := d.Get("name").(string) - // rg_id, rgid_set := d.GetOk("rg_id") - accId, accSet := d.GetOk("account_id") +func flattenImage(d *schema.ResourceData, image *Image) { + d.Set("name", image.Name) + d.Set("url", image.Url) + d.Set("gid", image.Gid) + d.Set("image_id", image.ImageId) + d.Set("boot_type", image.Boottype) + d.Set("image_type", image.Imagetype) + d.Set("sep_id", image.SepId) + return +} - controller := m.(*ControllerCfg) - url_values := &url.Values{} - if accSet { - url_values.Add("accountId", fmt.Sprintf("%d", accId.(int))) - } - body_string, err := controller.decortAPICall("POST", ImagesListAPI, url_values) +func dataSourceImageRead(d *schema.ResourceData, m interface{}) error { + image, err := utilityImageCheckPresence(d, m) if err != nil { return err } + d.SetId("1234") + flattenImage(d, image) - log.Debugf("dataSourceImageRead: ready to decode response body from %s", ImagesListAPI) - model := ImagesListResp{} - err = json.Unmarshal([]byte(body_string), &model) - if err != nil { - return err - } + return nil +} - // log.Printf("%#v", model) - log.Debugf("dataSourceImageRead: traversing decoded JSON of length %d", len(model)) - for index, item := range model { - // need to match Image by name - if item.Name == name { - log.Debugf("dataSourceImageRead: index %d, matched name %s", index, item.Name) - d.SetId(fmt.Sprintf("%d", item.ID)) - d.Set("account_id", item.AccountID) - d.Set("arch", item.Arch) - d.Set("sep_id", item.SepID) - d.Set("pool", item.Pool) - d.Set("status", item.Status) - d.Set("size", item.Size) - // d.Set("field_name", value) - return nil - } +func dataSourceImageSchemaMake() map[string]*schema.Schema { + return map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Computed: true, + Description: "Name of the rescue disk", + }, + "url": { + Type: schema.TypeString, + Computed: true, + Description: "URL where to download media from", + }, + "gid": { + Type: schema.TypeInt, + Computed: true, + Description: "grid (platform) ID where this template should be create in", + }, + "boot_type": { + Type: schema.TypeString, + Computed: true, + Description: "Boot type of image bios or uefi", + }, + "image_type": { + Type: schema.TypeString, + Computed: true, + Description: "Image type linux, windows or other", + }, + "drivers": { + Type: schema.TypeList, + Computed: true, + Elem: &schema.Schema{ + Type: schema.TypeString, + }, + Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", + }, + "hot_resize": { + Type: schema.TypeBool, + Computed: true, + Description: "Does this machine supports hot resize", + }, + "username": { + Type: schema.TypeString, + Computed: true, + Description: "Optional username for the image", + }, + "password": { + Type: schema.TypeString, + Computed: true, + Description: "Optional password for the image", + }, + "account_id": { + Type: schema.TypeInt, + Computed: true, + Description: "AccountId to make the image exclusive", + }, + "username_dl": { + Type: schema.TypeString, + Computed: true, + Description: "username for upload binary media", + }, + "password_dl": { + Type: schema.TypeString, + Computed: true, + Description: "password for upload binary media", + }, + "sep_id": { + Type: schema.TypeInt, + Computed: true, + Description: "storage endpoint provider ID", + }, + "pool_name": { + Type: schema.TypeString, + Computed: true, + Description: "pool for image create", + }, + "architecture": { + Type: schema.TypeString, + Computed: true, + Description: "binary architecture of this image, one of X86_64 of PPC64_LE", + }, + "image_id": { + Type: schema.TypeInt, + Required: true, + Description: "image id", + }, + "permanently": { + Type: schema.TypeBool, + Computed: true, + Description: "Whether to completely delete the image", + }, + "bootable": { + Type: schema.TypeBool, + Computed: true, + Description: "Does this image boot OS", + }, + "virtual": { + Type: schema.TypeMap, + Computed: true, + Description: "Create virtual image", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + "name": { + Type: schema.TypeString, + Required: true, + Description: "name of the virtual image to create", + }, + "v_image_id": { + Type: schema.TypeInt, + Computed: true, + Description: "", + }, + }, + }, + }, + "link_to": { + Type: schema.TypeInt, + Computed: true, + Description: "", + }, } - - return fmt.Errorf("Cannot find Image name %s", name) } func dataSourceImage() *schema.Resource { @@ -89,57 +183,6 @@ func dataSourceImage() *schema.Resource { Default: &Timeout60s, }, - Schema: map[string]*schema.Schema{ - "name": { - Type: schema.TypeString, - Required: true, - Description: "Name of the image to locate. This parameter is case sensitive.", - }, - - "account_id": { - Type: schema.TypeInt, - Optional: true, - ValidateFunc: validation.IntAtLeast(1), - Description: "Optional ID of the account to limit image search to.", - }, - - "arch": { - Type: schema.TypeString, - Computed: true, - Description: "Binary architecture of this image.", - }, - - "sep_id": { - Type: schema.TypeInt, - Computed: true, - Description: "Storage end-point provider serving this image.", - }, - - /* - "sep_type": { - Type: schema.TypeString, - Computed: true, - Description: "Type of the storage end-point provider serving this image.", - }, - */ - - "pool": { - Type: schema.TypeString, - Computed: true, - Description: "Pool where this image is located.", - }, - - "size": { - Type: schema.TypeInt, - Computed: true, - Description: "Size of the image in GB.", - }, - - "status": { - Type: schema.TypeString, - Computed: true, - Description: "Current model status of this image.", - }, - }, + Schema: dataSourceImageSchemaMake(), } } diff --git a/decort/data_source_image_list.go b/decort/data_source_image_list.go new file mode 100644 index 0000000..0d611ec --- /dev/null +++ b/decort/data_source_image_list.go @@ -0,0 +1,106 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func flattenImageList(il ImageList) []map[string]interface{} { + res := make([]map[string]interface{}, len(il), len(il)) + for _, item := range il { + temp := map[string]interface{}{} + temp["name"] = item.Name + temp["url"] = item.Url + temp["gid"] = item.Gid + temp["drivers"] = item.Drivers + temp["image_id"] = item.ImageId + temp["boot_type"] = item.Boottype + temp["image_type"] = item.Imagetype + res = append(res, temp) + } + return res +} + +func dataSourceImageListRead(d *schema.ResourceData, m interface{}) error { + imageList, err := utilityImageListCheckPresence(d, m) + if err != nil { + return err + } + d.SetId("1234") + d.Set("items", flattenImageList(imageList)) + + return nil +} + +func dataSourceImageListSchemaMake() map[string]*schema.Schema { + rets := map[string]*schema.Schema{ + "sep_id": { + Type: schema.TypeInt, + Optional: true, + Description: "filter images by storage endpoint provider ID", + }, + "shared_with": { + Type: schema.TypeInt, + Optional: true, + Description: "filter images by account ID availability", + }, + "page": { + Type: schema.TypeInt, + Optional: true, + Description: "page number", + }, + "size": { + Type: schema.TypeInt, + Optional: true, + Description: "page size", + }, + "items": { + Type: schema.TypeList, + Computed: true, + Description: "image list", + Elem: &schema.Resource{ + Schema: resourceImageSchemaMake(), + }, + }, + } + + return rets +} + +func dataSourceImageList() *schema.Resource { + return &schema.Resource{ + SchemaVersion: 1, + + Read: dataSourceImageListRead, + + Timeouts: &schema.ResourceTimeout{ + Read: &Timeout30s, + Default: &Timeout60s, + }, + + Schema: dataSourceImageListSchemaMake(), + } +} diff --git a/decort/models_api.go b/decort/models_api.go index b2e8a62..a7af6ca 100644 --- a/decort/models_api.go +++ b/decort/models_api.go @@ -668,24 +668,27 @@ type SshKeyConfig struct { UserShell string } -// +///////////////// // images api -// -const imageCreateAPI = "/restmachine/cloudapi/image/create" -const imageGetAPI = "/restmachine/cloudapi/image/get" -const imageDeleteAPI = "/restmachine/cloudapi/image/delete" +//////////////////// +const imageCreateAPI = "/restmachine/cloudbroker/image/createImage" +const imageGetAPI = "/restmachine/cloudbroker/image/get" +const imageListGetAPI = "/restmachine/cloudbroker/image/list" +const imageEditAPI = "/restmachine/cloudbroker/image/edit" +const imageDeleteAPI = "/restmachine/cloudbroker/image/delete" const imageEditNameAPI = "/restmachine/cloudapi/image/rename" const imageLinkAPI = "/restmachine/cloudapi/image/link" type Image struct { - ImageId int `json:"imageId"` + ImageId int `json:"id"` Name string `json:"name"` Url string `json:"url"` Gid int `json:"gid"` - Boottype string `json:"boottype"` + Boottype string `json:"bootType"` Imagetype string `json:"imagetype"` Drivers []string `json:"drivers"` Hotresize bool `json:"hotresize"` + Bootable bool `json:"bootable"` Username string `json:"username"` Password string `json:"password"` AccountId int `json:"accountId"` @@ -695,3 +698,22 @@ type Image struct { PoolName string `json:"poolName"` Architecture string `json:"architecture"` } + +type ImageList []Image + +///////////// +////GRID +//////////////// +const GridListGetAPI = "/restmachine/cloudbroker/grid/list" +const GridGetAPI = "/restmachine/cloudbroker/grid/get" + +type Grid struct { + Flag string `json:"flag"` + Gid int `json:"gid"` + Guid int `json:"guid"` + Id int `json:"id"` + LocationCode string `json:"locationCode"` + Name string `json:"name"` +} + +type GridList []Grid diff --git a/decort/provider.go b/decort/provider.go index d85c12a..d5cf0e2 100644 --- a/decort/provider.go +++ b/decort/provider.go @@ -110,12 +110,15 @@ func Provider() *schema.Provider { }, DataSourcesMap: map[string]*schema.Resource{ - "decort_account": dataSourceAccount(), - "decort_resgroup": dataSourceResgroup(), - "decort_kvmvm": dataSourceCompute(), - "decort_image": dataSourceImage(), - "decort_disk": dataSourceDisk(), - "decort_vins": dataSourceVins(), + "decort_account": dataSourceAccount(), + "decort_resgroup": dataSourceResgroup(), + "decort_kvmvm": dataSourceCompute(), + "decort_image": dataSourceImage(), + "decort_disk": dataSourceDisk(), + "decort_vins": dataSourceVins(), + "decort_grid": dataSourceGrid(), + "decort_grid_list": dataSourceGridList(), + "decort_image_list": dataSourceImageList(), // "decort_pfw": dataSourcePfw(), }, diff --git a/decort/resource_image.go b/decort/resource_image.go index ea85a85..21f6877 100644 --- a/decort/resource_image.go +++ b/decort/resource_image.go @@ -27,9 +27,7 @@ package decort import ( "net/url" "strconv" - "strings" - "github.com/hashicorp/terraform-plugin-sdk/helper/customdiff" "github.com/hashicorp/terraform-plugin-sdk/helper/schema" "github.com/hashicorp/terraform-plugin-sdk/helper/validation" log "github.com/sirupsen/logrus" @@ -46,9 +44,14 @@ func resourceImageCreate(d *schema.ResourceData, m interface{}) error { urlValues.Add("boottype", d.Get("boot_type").(string)) urlValues.Add("imagetype", d.Get("image_type").(string)) - tstr := strings.Join(d.Get("drivers").([]string), ",") - tstr = "[" + tstr + "]" - urlValues.Add("drivers", tstr) + tstr := d.Get("drivers").([]interface{}) + temp := "" + for _, str := range tstr { + s := "\"" + str.(string) + "\"" + temp = temp + s + } + temp = "[" + temp + "]" + urlValues.Add("drivers", temp) if hotresize, ok := d.GetOk("hot_resize"); ok { urlValues.Add("hotresize", strconv.FormatBool(hotresize.(bool))) @@ -65,10 +68,10 @@ func resourceImageCreate(d *schema.ResourceData, m interface{}) error { if accountId, ok := d.GetOk("account_id"); ok { urlValues.Add("accountId", strconv.Itoa(accountId.(int))) } - if usernameDL, ok := d.GetOk("username_DL"); ok { + if usernameDL, ok := d.GetOk("username_dl"); ok { urlValues.Add("usernameDL", usernameDL.(string)) } - if passwordDL, ok := d.GetOk("password_DL"); ok { + if passwordDL, ok := d.GetOk("password_dl"); ok { urlValues.Add("passwordDL", passwordDL.(string)) } if sepId, ok := d.GetOk("sep_id"); ok { @@ -95,7 +98,8 @@ func resourceImageCreate(d *schema.ResourceData, m interface{}) error { } d.SetId(strconv.Itoa(image.ImageId)) - d.Set("image_id", image.ImageId) + d.Set("bootable", image.Bootable) + //d.Set("image_id", image.ImageId) return nil } @@ -120,11 +124,12 @@ func resourceImageRead(d *schema.ResourceData, m interface{}) error { d.Set("username", image.Username) d.Set("password", image.Password) d.Set("account_id", image.AccountId) - d.Set("username_DL", image.UsernameDL) - d.Set("password_DL", image.PasswordDL) + d.Set("username_dl", image.UsernameDL) + d.Set("password_dl", image.PasswordDL) d.Set("sep_id", image.SepId) d.Set("pool_name", image.PoolName) d.Set("architecture", image.Architecture) + d.Set("bootable", image.Bootable) return nil } @@ -143,6 +148,7 @@ func resourceImageDelete(d *schema.ResourceData, m interface{}) error { controller := m.(*ControllerCfg) urlValues := &url.Values{} urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + urlValues.Add("reason", "") if permanently, ok := d.GetOk("permanently"); ok { urlValues.Add("permanently", strconv.FormatBool(permanently.(bool))) } @@ -198,6 +204,34 @@ func resourceImageLink(d *schema.ResourceDiff, m interface{}) error { return nil } +func resourceImageEdit(d *schema.ResourceData, m interface{}) error { + log.Debugf("resourceImageEdit: called for %s, id: %s", d.Get("name").(string), d.Id()) + c := m.(*ControllerCfg) + urlValues := &url.Values{} + urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + urlValues.Add("name", d.Get("name").(string)) + if username, ok := d.GetOk("username"); ok { + urlValues.Add("username", username.(string)) + } + if password, ok := d.GetOk("password"); ok { + urlValues.Add("password", password.(string)) + } + if accountId, ok := d.GetOk("account_id"); ok { + urlValues.Add("accountId", strconv.Itoa(accountId.(int))) + } + if bootable, ok := d.GetOk("bootable"); ok { + urlValues.Add("bootable", strconv.FormatBool(bootable.(bool))) + } + if hotresize, ok := d.GetOk("hot_resize"); ok { + urlValues.Add("hotresize", strconv.FormatBool(hotresize.(bool))) + } + _, err := c.decortAPICall("POST", imageEditAPI, urlValues) + if err != nil { + return err + } + return nil +} + func resourceImageSchemaMake() map[string]*schema.Schema { return map[string]*schema.Schema{ "name": { @@ -235,12 +269,9 @@ func resourceImageSchemaMake() map[string]*schema.Schema { "drivers": { Type: schema.TypeList, Required: true, - ForceNew: true, MinItems: 1, Elem: &schema.Schema{ - Type: schema.TypeString, - Required: true, - ForceNew: true, + Type: schema.TypeString, }, Description: "List of types of compute suitable for image. Example: [ \"KVM_X86\" ]", }, @@ -264,12 +295,12 @@ func resourceImageSchemaMake() map[string]*schema.Schema { Optional: true, Description: "AccountId to make the image exclusive", }, - "username_DL": { + "username_dl": { Type: schema.TypeString, Optional: true, Description: "username for upload binary media", }, - "password_DL": { + "password_dl": { Type: schema.TypeString, Optional: true, Description: "password for upload binary media", @@ -300,6 +331,11 @@ func resourceImageSchemaMake() map[string]*schema.Schema { Optional: true, Description: "Whether to completely delete the image", }, + "bootable": { + Type: schema.TypeBool, + Optional: true, + Description: "Does this image boot OS", + }, "virtual": { Type: schema.TypeMap, Optional: true, @@ -319,24 +355,10 @@ func resourceImageSchemaMake() map[string]*schema.Schema { }, }, }, - "link": { - Type: schema.TypeMap, + "link_to": { + Type: schema.TypeInt, Optional: true, - Description: "Link virtual image to another image in the platform", - Elem: &schema.Resource{ - Schema: map[string]*schema.Schema{ - "image_id": { - Type: schema.TypeInt, - Required: true, - Description: "ID of the virtual image", - }, - "target_id": { - Type: schema.TypeInt, - Required: true, - Description: "ID of real image to link this virtual image to", - }, - }, - }, + Description: "", }, } } @@ -347,6 +369,7 @@ func resourceImage() *schema.Resource { Create: resourceImageCreate, Read: resourceImageRead, + Update: resourceImageEdit, Delete: resourceImageDelete, Exists: resourceImageExists, @@ -361,7 +384,7 @@ func resourceImage() *schema.Resource { Delete: &Timeout60s, Default: &Timeout60s, }, - CustomizeDiff: customdiff.All( + /*CustomizeDiff: customdiff.All( customdiff.IfValueChange("name", func(old, new, meta interface{}) bool { return !(old.(string) == new.(string)) }, resourceImageEditName), @@ -373,7 +396,7 @@ func resourceImage() *schema.Resource { } return false }, resourceImageLink), - ), + ),*/ Schema: resourceImageSchemaMake(), } diff --git a/decort/utility_grid.go b/decort/utility_grid.go new file mode 100644 index 0000000..2131cde --- /dev/null +++ b/decort/utility_grid.go @@ -0,0 +1,62 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "encoding/json" + "errors" + "fmt" + "net/url" + "strconv" + + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func utilityGridCheckPresence(d *schema.ResourceData, m interface{}) (*Grid, error) { + grid := &Grid{} + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + + if gridId, ok := d.GetOk("grid_id"); ok { + urlValues.Add("gridId", strconv.Itoa(gridId.(int))) + } else { + return nil, errors.New(fmt.Sprintf("grid_id is required")) + } + + log.Debugf("utilityGridCheckPresence: load grid") + gridRaw, err := controller.decortAPICall("POST", GridGetAPI, urlValues) + if err != nil { + return nil, err + } + + err = json.Unmarshal([]byte(gridRaw), grid) + if err != nil { + return nil, err + } + + return grid, nil +} diff --git a/decort/utility_grid_list.go b/decort/utility_grid_list.go new file mode 100644 index 0000000..202f6ad --- /dev/null +++ b/decort/utility_grid_list.go @@ -0,0 +1,61 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "encoding/json" + "net/url" + "strconv" + + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func utilityGridListCheckPresence(d *schema.ResourceData, m interface{}) (GridList, error) { + gridList := GridList{} + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + + if page, ok := d.GetOk("page"); ok { + urlValues.Add("page", strconv.Itoa(page.(int))) + } + if size, ok := d.GetOk("size"); ok { + urlValues.Add("size", strconv.Itoa(size.(int))) + } + + log.Debugf("utilityGridListCheckPresence: load grid list") + gridListRaw, err := controller.decortAPICall("POST", GridListGetAPI, urlValues) + if err != nil { + return nil, err + } + + err = json.Unmarshal([]byte(gridListRaw), &gridList) + if err != nil { + return nil, err + } + + return gridList, nil +} diff --git a/decort/utility_image.go b/decort/utility_image.go index 60090d3..e23afd3 100644 --- a/decort/utility_image.go +++ b/decort/utility_image.go @@ -26,6 +26,8 @@ package decort import ( "encoding/json" + "errors" + "fmt" "net/url" "strconv" @@ -36,7 +38,12 @@ func utilityImageCheckPresence(d *schema.ResourceData, m interface{}) (*Image, e controller := m.(*ControllerCfg) urlValues := &url.Values{} - urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + if (strconv.Itoa(d.Get("image_id").(int))) != "0" { + urlValues.Add("imageId", strconv.Itoa(d.Get("image_id").(int))) + } else { + urlValues.Add("imageId", d.Id()) + } + resp, err := controller.decortAPICall("POST", imageGetAPI, urlValues) if err != nil { return nil, err @@ -46,9 +53,9 @@ func utilityImageCheckPresence(d *schema.ResourceData, m interface{}) (*Image, e return nil, nil } - var image *Image + image := &Image{} if err := json.Unmarshal([]byte(resp), image); err != nil { - return nil, err + return nil, errors.New(fmt.Sprintf(resp, " ", image)) } return image, nil diff --git a/decort/utility_image_list.go b/decort/utility_image_list.go new file mode 100644 index 0000000..13bcc49 --- /dev/null +++ b/decort/utility_image_list.go @@ -0,0 +1,68 @@ +/* +Copyright (c) 2019-2022 Digital Energy Cloud Solutions LLC. All Rights Reserved. +Author: Stanislav Solovev, , + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +This file is part of Terraform (by Hashicorp) provider for Digital Energy Cloud Orchestration +Technology platfom. + +Visit https://github.com/rudecs/terraform-provider-decort for full source code package and updates. +*/ + +package decort + +import ( + "encoding/json" + "net/url" + "strconv" + + log "github.com/sirupsen/logrus" + + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +func utilityImageListCheckPresence(d *schema.ResourceData, m interface{}) (ImageList, error) { + imageList := ImageList{} + controller := m.(*ControllerCfg) + urlValues := &url.Values{} + + if sepId, ok := d.GetOk("sep_id"); ok { + urlValues.Add("sepId", strconv.Itoa(sepId.(int))) + } + if sharedWith, ok := d.GetOk("shared_with"); ok { + urlValues.Add("sharedWith", strconv.Itoa(sharedWith.(int))) + } + + if page, ok := d.GetOk("page"); ok { + urlValues.Add("page", strconv.Itoa(page.(int))) + } + if size, ok := d.GetOk("size"); ok { + urlValues.Add("size", strconv.Itoa(size.(int))) + } + + log.Debugf("utilityGridListCheckPresence: load image list") + imageListRaw, err := controller.decortAPICall("POST", imageListGetAPI, urlValues) + if err != nil { + return nil, err + } + + err = json.Unmarshal([]byte(imageListRaw), &imageList) + if err != nil { + return nil, err + } + + return imageList, nil +}