github.com/vmware/govmomi@v0.37.2/pbm/pbm_util.go (about)

     1  /*
     2  Copyright (c) 2017 VMware, Inc. All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package pbm
    18  
    19  import (
    20  	"fmt"
    21  	"strconv"
    22  	"strings"
    23  
    24  	"github.com/vmware/govmomi/pbm/types"
    25  )
    26  
    27  // A struct to capture pbm create spec details.
    28  type CapabilityProfileCreateSpec struct {
    29  	Name           string
    30  	SubProfileName string
    31  	Description    string
    32  	Category       string
    33  	CapabilityList []Capability
    34  }
    35  
    36  // A struct to capture pbm capability instance details.
    37  type Capability struct {
    38  	ID           string
    39  	Namespace    string
    40  	PropertyList []Property
    41  }
    42  
    43  // A struct to capture pbm property instance details.
    44  type Property struct {
    45  	ID       string
    46  	Operator string
    47  	Value    string
    48  	DataType string
    49  }
    50  
    51  func CreateCapabilityProfileSpec(pbmCreateSpec CapabilityProfileCreateSpec) (*types.PbmCapabilityProfileCreateSpec, error) {
    52  	capabilities, err := createCapabilityInstances(pbmCreateSpec.CapabilityList)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	pbmCapabilityProfileSpec := types.PbmCapabilityProfileCreateSpec{
    58  		Name:        pbmCreateSpec.Name,
    59  		Description: pbmCreateSpec.Description,
    60  		Category:    pbmCreateSpec.Category,
    61  		ResourceType: types.PbmProfileResourceType{
    62  			ResourceType: string(types.PbmProfileResourceTypeEnumSTORAGE),
    63  		},
    64  		Constraints: &types.PbmCapabilitySubProfileConstraints{
    65  			SubProfiles: []types.PbmCapabilitySubProfile{
    66  				types.PbmCapabilitySubProfile{
    67  					Capability: capabilities,
    68  					Name:       pbmCreateSpec.SubProfileName,
    69  				},
    70  			},
    71  		},
    72  	}
    73  	return &pbmCapabilityProfileSpec, nil
    74  }
    75  
    76  func createCapabilityInstances(rules []Capability) ([]types.PbmCapabilityInstance, error) {
    77  	var capabilityInstances []types.PbmCapabilityInstance
    78  	for _, capabilityRule := range rules {
    79  		capability := types.PbmCapabilityInstance{
    80  			Id: types.PbmCapabilityMetadataUniqueId{
    81  				Namespace: capabilityRule.Namespace,
    82  				Id:        capabilityRule.ID,
    83  			},
    84  		}
    85  
    86  		var propertyInstances []types.PbmCapabilityPropertyInstance
    87  		for _, propertyRule := range capabilityRule.PropertyList {
    88  			property := types.PbmCapabilityPropertyInstance{
    89  				Id: propertyRule.ID,
    90  			}
    91  			if propertyRule.Operator != "" {
    92  				property.Operator = propertyRule.Operator
    93  			}
    94  			var err error
    95  			switch strings.ToLower(propertyRule.DataType) {
    96  			case "int":
    97  				// Go int32 is marshalled to xsi:int whereas Go int is marshalled to xsi:long when sending down the wire.
    98  				var val int32
    99  				val, err = verifyPropertyValueIsInt(propertyRule.Value, propertyRule.DataType)
   100  				property.Value = val
   101  			case "bool":
   102  				var val bool
   103  				val, err = verifyPropertyValueIsBoolean(propertyRule.Value, propertyRule.DataType)
   104  				property.Value = val
   105  			case "string":
   106  				property.Value = propertyRule.Value
   107  			case "set":
   108  				set := types.PbmCapabilityDiscreteSet{}
   109  				for _, val := range strings.Split(propertyRule.Value, ",") {
   110  					set.Values = append(set.Values, val)
   111  				}
   112  				property.Value = set
   113  			default:
   114  				return nil, fmt.Errorf("invalid value: %q with datatype: %q", propertyRule.Value, propertyRule.Value)
   115  			}
   116  			if err != nil {
   117  				return nil, fmt.Errorf("invalid value: %q with datatype: %q", propertyRule.Value, propertyRule.Value)
   118  			}
   119  			propertyInstances = append(propertyInstances, property)
   120  		}
   121  		constraintInstances := []types.PbmCapabilityConstraintInstance{
   122  			types.PbmCapabilityConstraintInstance{
   123  				PropertyInstance: propertyInstances,
   124  			},
   125  		}
   126  		capability.Constraint = constraintInstances
   127  		capabilityInstances = append(capabilityInstances, capability)
   128  	}
   129  	return capabilityInstances, nil
   130  }
   131  
   132  // Verify if the capability value is of type integer.
   133  func verifyPropertyValueIsInt(propertyValue string, dataType string) (int32, error) {
   134  	val, err := strconv.ParseInt(propertyValue, 10, 32)
   135  	if err != nil {
   136  		return -1, err
   137  	}
   138  	return int32(val), nil
   139  }
   140  
   141  // Verify if the capability value is of type integer.
   142  func verifyPropertyValueIsBoolean(propertyValue string, dataType string) (bool, error) {
   143  	val, err := strconv.ParseBool(propertyValue)
   144  	if err != nil {
   145  		return false, err
   146  	}
   147  	return val, nil
   148  }