Skip to content

Commit

Permalink
Add common validator for struct input type, and apply it.
Browse files Browse the repository at this point in the history
  • Loading branch information
powerkimhub committed Nov 8, 2021
1 parent a80114e commit 67d9ce5
Show file tree
Hide file tree
Showing 3 changed files with 232 additions and 8 deletions.
96 changes: 96 additions & 0 deletions api-runtime/common-runtime/CCMCommon.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,16 @@ func CreateImage(connectionName string, rsType string, reqInfo cres.ImageReqInfo
return nil, err
}

emptyPermissionList := []string{
"resources.IID:SystemId",
}

err = ValidateStruct(reqInfo, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}

cldConn, err := ccm.GetCloudConnection(connectionName)
if err != nil {
cblog.Error(err)
Expand Down Expand Up @@ -614,6 +624,15 @@ func RegisterVPC(connectionName string, userIID cres.IID) (*cres.VPCInfo, error)
return nil, err
}

emptyPermissionList := []string{
}

err = ValidateStruct(userIID, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}

rsType := rsVPC

cldConn, err := ccm.GetCloudConnection(connectionName)
Expand Down Expand Up @@ -840,6 +859,19 @@ func CreateVPC(connectionName string, rsType string, reqInfo cres.VPCReqInfo) (*
return nil, err
}

emptyPermissionList := []string{
"resources.IID:SystemId",
"resources.VPCReqInfo:IPv4_CIDR", // because can be unused in some VPC
"resources.KeyValue:Key", // because unusing key-value list
"resources.KeyValue:Value", // because unusing key-value list
}

err = ValidateStruct(reqInfo, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}

cldConn, err := ccm.GetCloudConnection(connectionName)
if err != nil {
cblog.Error(err)
Expand Down Expand Up @@ -1321,6 +1353,15 @@ func RegisterSecurity(connectionName string, vpcUserID string, userIID cres.IID)
return nil, err
}

emptyPermissionList := []string{
}

err = ValidateStruct(userIID, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}

rsType := rsSG

cldConn, err := ccm.GetCloudConnection(connectionName)
Expand Down Expand Up @@ -1428,6 +1469,19 @@ func CreateSecurity(connectionName string, rsType string, reqInfo cres.SecurityR
return nil, err
}

/*
emptyPermissionList := []string{
"resources.IID:SystemId",
"resources.SecurityReqInfo:Direction", // because can be unused in some CSP
"resources.SecurityRuleInfo:CIDR", // because can be set without soruce CIDR
}
err = ValidateStruct(reqInfo, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}
*/
//+++++++++++++++++++++++++++++++++++++++++++
// set VPC's SystemId
vpcIIDInfo, err := iidRWLock.GetIID(iidm.IIDSGROUP, connectionName, rsVPC, reqInfo.VpcIID)
Expand Down Expand Up @@ -1748,6 +1802,15 @@ func RegisterKey(connectionName string, userIID cres.IID) (*cres.KeyPairInfo, er
return nil, err
}

emptyPermissionList := []string{
}

err = ValidateStruct(userIID, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}

rsType := rsKey

cldConn, err := ccm.GetCloudConnection(connectionName)
Expand Down Expand Up @@ -1821,6 +1884,16 @@ func CreateKey(connectionName string, rsType string, reqInfo cres.KeyPairReqInfo
return nil, err
}

emptyPermissionList := []string{
"resources.IID:SystemId",
}

err = ValidateStruct(reqInfo, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}

cldConn, err := ccm.GetCloudConnection(connectionName)
if err != nil {
cblog.Error(err)
Expand Down Expand Up @@ -2104,6 +2177,15 @@ func RegisterVM(connectionName string, userIID cres.IID) (*cres.VMInfo, error) {
return nil, err
}

emptyPermissionList := []string{
}

err = ValidateStruct(userIID, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}

rsType := rsVM

cldConn, err := ccm.GetCloudConnection(connectionName)
Expand Down Expand Up @@ -2191,6 +2273,20 @@ func StartVM(connectionName string, rsType string, reqInfo cres.VMReqInfo) (*cre
return nil, err
}

emptyPermissionList := []string{
"resources.IID:SystemId",
"resources.VMReqInfo:RootDiskType", // because can be set without disk type
"resources.VMReqInfo:RootDiskSize", // because can be set without disk type
"resources.VMReqInfo:VMUserId", // because can be set without disk type
"resources.VMReqInfo:VMUserPasswd", // because can be set without disk type
}

err = ValidateStruct(reqInfo, emptyPermissionList)
if err != nil {
cblog.Error(err)
return nil, err
}

cldConn, err := ccm.GetCloudConnection(connectionName)
if err != nil {
cblog.Error(err)
Expand Down
114 changes: 114 additions & 0 deletions api-runtime/common-runtime/test/validate_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
// Mock Driver Test of CB-Spider.
// The CB-Spider is a sub-Framework of the Cloud-Barista Multi-Cloud Project.
// The CB-Spider Mission is to connect all the clouds with a single interface.
//
// * Cloud-Barista: https://github.com/cloud-barista
//
// by CB-Spider Team, 2021.10.

package validatetest

import (
valid "github.com/cloud-barista/cb-spider/api-runtime/common-runtime"

"testing"
"fmt"
)

func TestEmpty(t *testing.T) {

inputValue := ""

inputValue, err := valid.EmptyCheckAndTrim("inputValue", inputValue)
if err != nil {
fmt.Println(err.Error())
}
fmt.Printf("Trimed input value: %v.\n", inputValue)
}

func TestEmptyCheckAndTrim(t *testing.T) {

inputValue := "inputValue "

inputValue, err := valid.EmptyCheckAndTrim("inputValue", inputValue)
if err != nil {
fmt.Println(err.Error())
}
fmt.Printf("Trimed input value: %v.\n", inputValue)
}

func TestValidate(t *testing.T) {
type InnerTestStruct struct {
Depth2_a string
Depth2_b string
}

type TestStruct struct {
Depth1_a string
Depth1_b string
Depth1_s *InnerTestStruct
}


var ts = TestStruct{
"name01",
"name02",
&InnerTestStruct{"name03", "name04"},
}

err := valid.ValidateStruct(ts, nil)
err = valid.ValidateStruct(&ts, nil)
if err != nil {
fmt.Println(err.Error())
}
}

func TestValidateNilByFail(t *testing.T) {
type InnerTestStruct struct {
Depth2_a string
Depth2_b string
}

type TestStruct struct {
Depth1_a string
Depth1_b string
Depth1_s *InnerTestStruct
}


var ts = TestStruct{
Depth1_a: "name01",
Depth1_s: &InnerTestStruct{"name03", ""},
}

err := valid.ValidateStruct(ts, nil)
if err != nil {
fmt.Println(err.Error())
}
}

func TestValidateNilByPass(t *testing.T) {
type InnerTestStruct struct {
Depth2_a string
Depth2_b string
}

type TestStruct struct {
Depth1_a string
Depth1_b string
Depth1_s *InnerTestStruct
}


var ts = TestStruct{
Depth1_a: "name01",
Depth1_s: &InnerTestStruct{"name03", ""},
}

err := valid.ValidateStruct(ts, []string{"validatetest.TestStruct:Depth1_b", "validatetest.InnerTestStruct:Depth2_b"})
if err != nil {
fmt.Println(err.Error())
}
}


30 changes: 22 additions & 8 deletions api-runtime/common-runtime/validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,31 @@ func EmptyCheckAndTrim(inputName string, inputValue string) (string, error) {
return strings.TrimSpace(inputValue), nil
}

func ValidateStruct(is interface{}, nilPermissionList []string) error {
func ValidateStruct(is interface{}, emptyPermissionList []string) error {
var retErr error

inValue := reflect.ValueOf(is)
if inValue.Kind() == reflect.Ptr {
inValue = inValue.Elem() // When Input is ptr of Struct, Get the element.
if inValue.Kind() == reflect.Slice { // When ptr of Array, ex) SecurityRules *[]SecurityRuleInfo
for j := 0; j < inValue.Len(); j++ {
err := ValidateStruct(inValue.Index(j).Interface(), emptyPermissionList)
if retErr != nil {
retErr = fmt.Errorf("%v\n%v", retErr, err)
}else {
retErr = err
}
}

}
}

var retErr error

for i := 0; i < inValue.NumField(); i++ {
fv := inValue.Field(i)
switch fv.Kind() {
case reflect.Struct, reflect.Ptr:
err := ValidateStruct(fv.Interface(), nilPermissionList)
err := ValidateStruct(fv.Interface(), emptyPermissionList)
if err != nil {
if retErr != nil {
retErr = fmt.Errorf("%v\n%v", retErr, err)
Expand All @@ -45,7 +58,7 @@ func ValidateStruct(is interface{}, nilPermissionList []string) error {
}
case reflect.Slice:
for j := 0; j < fv.Len(); j++ {
err := ValidateStruct(fv.Index(j).Interface(), nilPermissionList)
err := ValidateStruct(fv.Index(j).Interface(), emptyPermissionList)
if retErr != nil {
retErr = fmt.Errorf("%v\n%v", retErr, err)
}else {
Expand All @@ -58,7 +71,7 @@ func ValidateStruct(is interface{}, nilPermissionList []string) error {
//fmt.Println("-----------: " + argNameType)
argNameType := fmt.Sprintf("%v:%v", inValue.Type(), inValue.Type().Field(i).Name)
if inValue.Field(i).Interface() == "" {
err := checkNilPermission(argNameType, nilPermissionList)
err := checkNilPermission(argNameType, emptyPermissionList)
if err != nil {
if retErr != nil {
retErr = fmt.Errorf("%v\n%v", retErr, err)
Expand All @@ -69,16 +82,17 @@ func ValidateStruct(is interface{}, nilPermissionList []string) error {
}

default:
fmt.Println("=========== other type: ", inValue.Field(i).Kind())
cblog.Info("=========== Currently, Unhandling Type: ", inValue.Field(i).Kind())
//fmt.Println("=========== other type: ", inValue.Field(i).Kind())
}
}
return retErr
}

// Check the arguments that can be used as empty.
func checkNilPermission(argTypeName string, nilPermissionList []string) error {
func checkNilPermission(argTypeName string, emptyPermissionList []string) error {

for _, permittedArgTypeName := range(nilPermissionList) {
for _, permittedArgTypeName := range(emptyPermissionList) {
if permittedArgTypeName == argTypeName {
return nil
}
Expand Down

0 comments on commit 67d9ce5

Please sign in to comment.