| /* |
| Copyright (c) 2017 VMware, Inc. All Rights Reserved. |
| |
| 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. |
| */ |
| |
| package pbm |
| |
| import ( |
| "fmt" |
| "strconv" |
| "strings" |
| |
| "github.com/vmware/govmomi/pbm/types" |
| ) |
| |
| // A struct to capture pbm create spec details. |
| type CapabilityProfileCreateSpec struct { |
| Name string |
| Description string |
| Category string |
| CapabilityList []Capability |
| } |
| |
| // A struct to capture pbm capability instance details. |
| type Capability struct { |
| ID string |
| Namespace string |
| PropertyList []Property |
| } |
| |
| // A struct to capture pbm property instance details. |
| type Property struct { |
| ID string |
| Operator string |
| Value string |
| DataType string |
| } |
| |
| func CreateCapabilityProfileSpec(pbmCreateSpec CapabilityProfileCreateSpec) (*types.PbmCapabilityProfileCreateSpec, error) { |
| capabilities, err := createCapabilityInstances(pbmCreateSpec.CapabilityList) |
| if err != nil { |
| return nil, err |
| } |
| |
| pbmCapabilityProfileSpec := types.PbmCapabilityProfileCreateSpec{ |
| Name: pbmCreateSpec.Name, |
| Description: pbmCreateSpec.Description, |
| Category: pbmCreateSpec.Category, |
| ResourceType: types.PbmProfileResourceType{ |
| ResourceType: string(types.PbmProfileResourceTypeEnumSTORAGE), |
| }, |
| Constraints: &types.PbmCapabilitySubProfileConstraints{ |
| SubProfiles: []types.PbmCapabilitySubProfile{ |
| types.PbmCapabilitySubProfile{ |
| Capability: capabilities, |
| }, |
| }, |
| }, |
| } |
| return &pbmCapabilityProfileSpec, nil |
| } |
| |
| func createCapabilityInstances(rules []Capability) ([]types.PbmCapabilityInstance, error) { |
| var capabilityInstances []types.PbmCapabilityInstance |
| for _, capabilityRule := range rules { |
| capability := types.PbmCapabilityInstance{ |
| Id: types.PbmCapabilityMetadataUniqueId{ |
| Namespace: capabilityRule.Namespace, |
| Id: capabilityRule.ID, |
| }, |
| } |
| |
| var propertyInstances []types.PbmCapabilityPropertyInstance |
| for _, propertyRule := range capabilityRule.PropertyList { |
| property := types.PbmCapabilityPropertyInstance{ |
| Id: propertyRule.ID, |
| } |
| if propertyRule.Operator != "" { |
| property.Operator = propertyRule.Operator |
| } |
| var err error |
| switch strings.ToLower(propertyRule.DataType) { |
| case "int": |
| // Go int32 is marshalled to xsi:int whereas Go int is marshalled to xsi:long when sending down the wire. |
| var val int32 |
| val, err = verifyPropertyValueIsInt(propertyRule.Value, propertyRule.DataType) |
| property.Value = val |
| case "bool": |
| var val bool |
| val, err = verifyPropertyValueIsBoolean(propertyRule.Value, propertyRule.DataType) |
| property.Value = val |
| case "string": |
| property.Value = propertyRule.Value |
| case "set": |
| set := types.PbmCapabilityDiscreteSet{} |
| for _, val := range strings.Split(propertyRule.Value, ",") { |
| set.Values = append(set.Values, val) |
| } |
| property.Value = set |
| default: |
| return nil, fmt.Errorf("invalid value: %q with datatype: %q", propertyRule.Value, propertyRule.Value) |
| } |
| if err != nil { |
| return nil, fmt.Errorf("invalid value: %q with datatype: %q", propertyRule.Value, propertyRule.Value) |
| } |
| propertyInstances = append(propertyInstances, property) |
| } |
| constraintInstances := []types.PbmCapabilityConstraintInstance{ |
| types.PbmCapabilityConstraintInstance{ |
| PropertyInstance: propertyInstances, |
| }, |
| } |
| capability.Constraint = constraintInstances |
| capabilityInstances = append(capabilityInstances, capability) |
| } |
| return capabilityInstances, nil |
| } |
| |
| // Verify if the capability value is of type integer. |
| func verifyPropertyValueIsInt(propertyValue string, dataType string) (int32, error) { |
| val, err := strconv.ParseInt(propertyValue, 10, 32) |
| if err != nil { |
| return -1, err |
| } |
| return int32(val), nil |
| } |
| |
| // Verify if the capability value is of type integer. |
| func verifyPropertyValueIsBoolean(propertyValue string, dataType string) (bool, error) { |
| val, err := strconv.ParseBool(propertyValue) |
| if err != nil { |
| return false, err |
| } |
| return val, nil |
| } |