Skip to content
This repository has been archived by the owner on Nov 20, 2020. It is now read-only.

Commit

Permalink
Merged with Master
Browse files Browse the repository at this point in the history
Signed-off-by: Viraj Indasrao <[email protected]>
  • Loading branch information
khachanem committed Jun 27, 2018
2 parents 99b75c6 + 6b45828 commit b1d0298
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 52 deletions.
13 changes: 13 additions & 0 deletions vrealize/actions.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ type ActionTemplate struct {
Type string `json:"type"`
}

// byLength yype to sort component name list by it's name length
type byLength []string

//GetActionTemplate - set call for read template/blueprint
func (c *APIClient) GetActionTemplate(resourceViewsTemplate *ResourceView, actionURLString string) (*ActionTemplate, *ResourceView, error) {
//Fetch an action URL from given template
Expand Down Expand Up @@ -84,3 +87,13 @@ func (c *APIClient) GetDestroyActionTemplate(resourceData *ResourceView) (*Actio
//Set get action URL function call
return c.GetActionTemplate(resourceData, actionURL)
}

func (s byLength) Less(i, j int) bool {
return len(s[i]) < len(s[j])
}
func (s byLength) Len() int {
return len(s)
}
func (s byLength) Swap(i, j int) {
s[i], s[j] = s[j], s[i]
}
107 changes: 55 additions & 52 deletions vrealize/resource.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"strconv"
"strings"
"time"
"sort"
)

//ResourceActionTemplate - is used to store information
Expand Down Expand Up @@ -260,78 +261,49 @@ func createResource(d *schema.ResourceData, meta interface{}) error {
templateCatalogItem.BusinessGroupID = d.Get("businessgroup_id").(string)
}

//Get all resource keys from blueprint in array
var keyList []string
// Get all resource keys from blueprint in array
var componentNameList []string
for field := range templateCatalogItem.Data {
if reflect.ValueOf(templateCatalogItem.Data[field]).Kind() == reflect.Map {
keyList = append(keyList, field)
componentNameList = append(componentNameList, field)
}
}
log.Printf("createResource->key_list %v\n", keyList)
log.Printf("createResource->key_list %v\n", componentNameList)

//Arrange keys in descending order of text length
for field1 := range keyList {
for field2 := range keyList {
if len(keyList[field1]) > len(keyList[field2]) {
temp := keyList[field1]
keyList[field1], keyList[field2] = keyList[field2], temp
}
}
}

//array to keep track of resource values that have been used
var usedConfigKeys []string
var replaced bool
// Arrange keys in descending order of text length
// Sorting component name list is required because in the following condition
// 1. CentOS_6.3
// 2. CentOS_6.3.1
// So the case was updated happened for 2nd component instead of 1st.
// Hence, to make sure all is going fine, this block of code is added.
sort.Sort(byLength(componentNameList))

//Update template field values with user configuration
resourceConfiguration, _ := d.Get("resource_configuration").(map[string]interface{})
for configKey, configValue := range resourceConfiguration {
if len(configValue.(string)) == 0 {
break
}
for dataKey, dataValue := range keyList {
for _, componentName := range componentNameList {
//compare resource list (resource_name) with user configuration fields (resource_name+field_name)
if strings.HasPrefix(configKey, dataValue) {
if strings.HasPrefix(configKey, componentName) {
//If user_configuration contains resource_list element
// then split user configuration key into resource_name and field_name
propertyName := strings.TrimPrefix(configKey, dataValue+".")
propertyName := strings.TrimPrefix(configKey, componentName+".")
if len(propertyName) == 0 {
return fmt.Errorf("resource_configuration key is not in correct format. Expected %s to start with %s", configKey, keyList[dataKey]+".")
return fmt.Errorf("resource_configuration key is not in correct format. Expected %s to start with %s", configKey, componentName+".")
}
//Function call which changes the template field values with user values
templateCatalogItem.Data[dataValue], replaced = changeTemplateValue(
templateCatalogItem.Data[dataValue].(map[string]interface{}),
// Function call which changes the template field values with user values
templateCatalogItem.Data[componentName] = addOrUpdateConfigTemplateMap(
templateCatalogItem.Data[componentName].(map[string]interface{}),
propertyName,
configValue)
if replaced {
usedConfigKeys = append(usedConfigKeys, configKey)

}
break
}
}

}

//Add remaining keys to template vs updating values
// first clean out used values
for usedKey := range usedConfigKeys {
delete(resourceConfiguration, usedConfigKeys[usedKey])
}
log.Println("Entering Add Loop")
for configKey2, configValue2 := range resourceConfiguration {
for dataKey, dataValue := range keyList {
log.Printf("Add Loop: configKey2=[%s] keyList[%d] =[%v]", configKey2, dataKey, dataValue)
if strings.HasPrefix(configKey2, dataValue) {
splitArray := strings.Split(configKey2, dataValue+".")
log.Printf("Add Loop Contains %+v", splitArray[1])
resourceItem := templateCatalogItem.Data[dataValue].(map[string]interface{})
resourceItem = addTemplateValue(
resourceItem["data"].(map[string]interface{}),
splitArray[1],
configValue2)
}
}
}
//update template with deployment level config
// limit to description and reasons as other things could get us into trouble
deploymentConfiguration, _ := d.Get("deployment_configuration").(map[string]interface{})
Expand Down Expand Up @@ -369,9 +341,10 @@ func createResource(d *schema.ResourceData, meta interface{}) error {
d.Set("request_status", "SUBMITTED")

waitTimeout := d.Get("wait_timeout").(int) * 60
sleepFor := 30
for i := 0; i < waitTimeout/sleepFor; i++ {
time.Sleep(time.Duration(sleepFor)*time.Second)

for i := 0; i < waitTimeout/30; i++ {
time.Sleep(3e+10)
readResource(d, meta)

if d.Get("request_status") == "SUCCESSFUL" {
Expand Down Expand Up @@ -399,6 +372,18 @@ func createResource(d *schema.ResourceData, meta interface{}) error {
return nil
}

func addOrUpdateConfigTemplateMap(templateInterface map[string]interface{}, field string, value interface{}) (map[string]interface{}) {
var replaced bool
templateInterface, replaced = changeTemplateValue(templateInterface, field, value)

if !replaced {
templateInterface = addTemplateValue(templateInterface["data"].(map[string]interface{}), field, value)
}
return templateInterface
}

//Function use - to update centOS 6.3 machine present in state file
//Terraform call - terraform refresh
func readActionLink(resourceSpecificLinks []interface{}, reconfigGetLinkTitleRel string) string {
var actionLink string
for _, linkData := range resourceSpecificLinks {
Expand Down Expand Up @@ -845,8 +830,26 @@ func deleteResource(d *schema.ResourceData, meta interface{}) error {
if errDestroyMachine != nil {
return fmt.Errorf("Destory Machine machine operation failed: %v", errDestroyMachine)
}
//If resource got deleted then unset the resource ID from state file
d.SetId("")

waitTimeout := d.Get("wait_timeout").(int) * 60
sleepFor := 30
for i := 0; i < waitTimeout/sleepFor; i++ {
time.Sleep(time.Duration(sleepFor)*time.Second)

deploymentStateData, err := vRAClient.GetDeploymentState(catalogItemRequestID)
if err != nil {
return fmt.Errorf("Resource view failed to load: %v", err)
}
if len(deploymentStateData.Content) == 0 {
//If resource got deleted then unset the resource ID from state file
d.SetId("")
break
}
}
if d.Id() != "" {
d.SetId("")
return fmt.Errorf("resource still being deleted after %v minutes", d.Get("wait_timeout"))
}
return nil
}

Expand Down

0 comments on commit b1d0298

Please sign in to comment.