diff --git a/sdk/schema.go b/sdk/schema.go index f8f7716a..23039937 100644 --- a/sdk/schema.go +++ b/sdk/schema.go @@ -55,38 +55,7 @@ type DeploymentResource struct { RequestID string `json:"requestId,omitempty"` ResourceID string `json:"resourceId,omitempty"` ResourceType string `json:"resourceType,omitempty"` - ResourcesData DeploymentResourceData `json:"data,omitempty"` -} - -// DeploymentResourceData - view of the resources/machines in a deployment -type DeploymentResourceData struct { - Memory int `json:"MachineMemory,omitempty"` - CPU int `json:"MachineCPU,omitempty"` - IPAddress string `json:"ip_address,omitempty"` - Storage int `json:"MachineStorage,omitempty"` - MachineInterfaceType string `json:"MachineInterfaceType,omitempty"` - MachineName string `json:"MachineName,omitempty"` - MachineGuestOperatingSystem string `json:"MachineGuestOperatingSystem,omitempty"` - MachineDestructionDate string `json:"MachineDestructionDate,omitempty"` - MachineGroupName string `json:"MachineGroupName,omitempty"` - MachineBlueprintName string `json:"MachineBlueprintName,omitempty"` - MachineReservationName string `json:"MachineReservationName,omitempty"` - MachineType string `json:"MachineType,omitempty"` - MachineID string `json:"machineId,omitempty"` - MachineExpirationDate string `json:"MachineExpirationDate,omitempty"` - Component string `json:"Component,omitempty"` - Expire bool `json:"Expire,omitempty"` - Reconfigure bool `json:"Reconfigure,omitempty"` - Reset bool `json:"Reset,omitempty"` - Reboot bool `json:"Reboot,omitempty"` - PowerOff bool `json:"PowerOff,omitempty"` - Destroy bool `json:"Destroy,omitempty"` - Shutdown bool `json:"Shutdown,omitempty"` - Suspend bool `json:"Suspend,omitempty"` - Reprovision bool `json:"Reprovision,omitempty"` - ChangeLease bool `json:"ChangeLease,omitempty"` - ChangeOwner bool `json:"ChangeOwner,omitempty"` - CreateSnapshot bool `json:"CreateSnapshot,omitempty"` + ResourcesData map[string]interface{} `json:"data,omitempty"` } // ResourceActions - Retrieves the resources that were provisioned as a result of a given request. diff --git a/utils/utilities.go b/utils/utilities.go index d9235abc..b14a4e3e 100644 --- a/utils/utilities.go +++ b/utils/utilities.go @@ -3,6 +3,7 @@ package utils import ( "bytes" "encoding/json" + "fmt" "reflect" "strconv" "strings" @@ -116,3 +117,46 @@ func AddValueToRequestTemplate(templateInterface map[string]interface{}, field s //Return updated map interface type return templateInterface } + +// Flatten takes a generic map of maps and flattens the properties via a dot seperator. +func Flatten(m map[string]interface{}) map[string]interface{} { + o := make(map[string]interface{}) + for k, v := range m { + switch child := v.(type) { + case map[string]interface{}: + nm := Flatten(child) + for nk, nv := range nm { + o[k+"."+nk] = nv + } + default: + o[k] = v + } + } + return o +} + +// FlattenJSON takes a generic map of maps (representing nested json data) and flattens the properties via a do seperator. +func FlattenJSON(jsonMap map[string]interface{}, key string) map[string]interface{} { + viewData := make(map[string]interface{}) + + value := jsonMap[key] + if value == nil { + value = "" + } + + if reflect.TypeOf(value).String() == "[]interface {}" { + for _, data := range value.([]interface{}) { + if reflect.TypeOf(data).String() == "map[string]interface {}" { + res := Flatten(data.(map[string]interface{})) + for nestedKey := range res { + viewData[fmt.Sprintf("%s.%s", key, nestedKey)] = fmt.Sprintf("%v", res[nestedKey]) + } + } else { + viewData[key] = fmt.Sprintf("%v", data) + } + } + } else { + viewData[key] = fmt.Sprintf("%v", value) + } + return viewData +} diff --git a/utils/utilities_test.go b/utils/utilities_test.go new file mode 100644 index 00000000..47786379 --- /dev/null +++ b/utils/utilities_test.go @@ -0,0 +1,45 @@ +package utils + +import ( + "testing" +) + +func TestFlatten(t *testing.T) { + inside := make(map[string]interface{}) + inside["outside"] = "valid" + outside := make(map[string]interface{}) + outside["test"] = inside + actual := Flatten(outside) + + expected := make(map[string]interface{}) + expected["test.outside"] = "valid" + + for k := range actual { + if actual[k] != expected[k] { + t.Fatalf("Expected %s, got %s at key %s", expected, actual, k) + } + } +} + +func TestFlattenComplex(t *testing.T) { + deep := make(map[string]interface{}) + deep["outside"] = "valid" + + inside := make(map[string]interface{}) + inside["outside"] = "valid" + inside["deep"] = deep + + outside := make(map[string]interface{}) + outside["test"] = inside + actual := Flatten(outside) + + expected := make(map[string]interface{}) + expected["test.outside"] = "valid" + expected["test.deep.outside"] = "valid" + + for k := range actual { + if actual[k] != expected[k] { + t.Fatalf("Expected %s, got %s at key %s", expected, actual, k) + } + } +} diff --git a/vra7/resource_vra7_deployment.go b/vra7/resource_vra7_deployment.go index 23cc54e4..3b0a6029 100644 --- a/vra7/resource_vra7_deployment.go +++ b/vra7/resource_vra7_deployment.go @@ -105,6 +105,15 @@ func resourceVra7Deployment() *schema.Resource { Computed: true, Elem: schema.TypeString, }, + "resource_views_data": { + Type: schema.TypeList, + Elem: &schema.Schema{ + Type: schema.TypeMap, + Elem: schema.TypeString, + }, + Description: "The response data located along side the resource view API calls", + Computed: true, + }, }, } } @@ -347,27 +356,19 @@ func resourceVra7DeploymentRead(d *schema.ResourceData, meta interface{}) error } resourceDataMap := make(map[string]map[string]interface{}) + var resourceViewsData []map[string]interface{} for _, resource := range requestResourceView.Content { - if resource.ResourceType == sdk.InfrastructureVirtual { - resourceData := resource.ResourcesData - log.Info("The resource data map of the resource %v is: \n%v", resourceData.Component, resource.ResourcesData) - dataVals := make(map[string]interface{}) - resourceDataMap[resourceData.Component] = dataVals - dataVals[sdk.MachineCPU] = resourceData.CPU - dataVals[sdk.MachineStorage] = resourceData.Storage - dataVals[sdk.IPAddress] = resourceData.IPAddress - dataVals[sdk.MachineMemory] = resourceData.Memory - dataVals[sdk.MachineName] = resourceData.MachineName - dataVals[sdk.MachineGuestOs] = resourceData.MachineGuestOperatingSystem - dataVals[sdk.MachineBpName] = resourceData.MachineBlueprintName - dataVals[sdk.MachineType] = resourceData.MachineType - dataVals[sdk.MachineReservationName] = resourceData.MachineReservationName - dataVals[sdk.MachineInterfaceType] = resourceData.MachineInterfaceType - dataVals[sdk.MachineID] = resourceData.MachineID - dataVals[sdk.MachineGroupName] = resourceData.MachineGroupName - dataVals[sdk.MachineDestructionDate] = resourceData.MachineDestructionDate + viewData := make(map[string]interface{}) + for key := range resource.ResourcesData { + viewData[key] = utils.FlattenJSON(resource.ResourcesData, key) } + resourceViewsData = append(resourceViewsData, utils.Flatten(viewData)) + } + setDataError := d.Set("resource_views_data", resourceViewsData) + if setDataError != nil { + return fmt.Errorf(setDataError.Error()) } + resourceConfiguration, _ := d.Get("resource_configuration").(map[string]interface{}) resourceConfiguration, changed := utils.UpdateResourceConfigurationMap(resourceConfiguration, resourceDataMap) @@ -378,6 +379,7 @@ func resourceVra7DeploymentRead(d *schema.ResourceData, meta interface{}) error return fmt.Errorf(setError.Error()) } } + return nil }