blob: 4cc8085f3446884c427283177dabfc1b62e728d1 [file] [log] [blame]
/*
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
}