github.com/verrazzano/verrazzano@v1.7.0/platform-operator/internal/vzconfig/args.go (about) 1 // Copyright (c) 2022, 2023, Oracle and/or its affiliates. 2 // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl. 3 4 package vzconfig 5 6 import ( 7 "fmt" 8 vzapi "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1alpha1" 9 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/v1beta1" 10 "github.com/verrazzano/verrazzano/platform-operator/apis/verrazzano/validators" 11 "github.com/verrazzano/verrazzano/platform-operator/controllers/verrazzano/component/common/override" 12 corev1 "k8s.io/api/core/v1" 13 "k8s.io/apimachinery/pkg/runtime" 14 "net" 15 "reflect" 16 "sigs.k8s.io/controller-runtime/pkg/client" 17 ) 18 19 var GetControllerRuntimeClient = validators.GetClient 20 21 const invalidDataType = "value of externalIP is of type \"%v\", is invalid data type, expected properly formatted IP" 22 23 // CheckExternalIPsArgs method goes through the key-value pair to detect the presence of the 24 // specific key for the corresponding component that holds the external IP address 25 // It also checks whether IP addresses are valid and provided in a List format 26 func CheckExternalIPsArgs(installArgs []vzapi.InstallArgs, overrides []vzapi.Overrides, argsKeyName, jsonPath, compName, namespace string) error { 27 var keyPresent bool 28 var v1beta1Overrides = vzapi.ConvertValueOverridesToV1Beta1(overrides) 29 overrideYAMLs, err := getOverrideYAMLs(v1beta1Overrides, namespace) 30 if err != nil { 31 return err 32 } 33 34 for _, o := range overrideYAMLs { 35 value, err := override.ExtractValueFromOverrideString(o, jsonPath) 36 if err != nil { 37 return err 38 } 39 if value == nil { 40 continue 41 } 42 v, err := castValuesToString(value) 43 if err != nil { 44 return err 45 } 46 if v != nil { 47 keyPresent = true 48 if err := validateExternalIP(v, jsonPath, compName); err != nil { 49 return err 50 } 51 } 52 } 53 if keyPresent { 54 return nil 55 } 56 57 for _, installArg := range installArgs { 58 if installArg.Name == argsKeyName { 59 keyPresent = true 60 if err := validateExternalIP(installArg.ValueList, installArg.Name, compName); err != nil { 61 return err 62 } 63 } 64 } 65 if !keyPresent { 66 return fmt.Errorf("Key \"%v\" not found for component \"%v\" for type NodePort", argsKeyName, compName) 67 } 68 return nil 69 } 70 71 // CheckExternalIPsOverridesArgs method goes through the key-value pair to detect the presence of the 72 // specific key for the corresponding component that holds the external IP address 73 // It also checks whether IP addresses are valid and provided in a List format 74 func CheckExternalIPsOverridesArgs(overrides []v1beta1.Overrides, jsonPath, compName string, namespace string) error { 75 overrideYAMLs, err := getOverrideYAMLs(overrides, namespace) 76 if err != nil { 77 return err 78 } 79 for _, o := range overrideYAMLs { 80 value, err := override.ExtractValueFromOverrideString(o, jsonPath) 81 if err != nil { 82 return err 83 } 84 if value == nil { 85 continue 86 } 87 v, err := castValuesToString(value) 88 if err != nil { 89 return err 90 } 91 if v != nil { 92 if err := validateExternalIP(v, jsonPath, compName); err != nil { 93 return err 94 } 95 } 96 } 97 return nil 98 } 99 100 // CheckExternalIPsOverridesArgsWithPaths method goes through the key-value pair to detect the presence of the 101 // specific keys for the corresponding component that holds the Service type and external IP address 102 // It checks whether the service is of a specific type. 103 // It also checks whether IP addresses are valid and provided in a List format 104 func CheckExternalIPsOverridesArgsWithPaths(overrides []v1beta1.Overrides, jsonBasePath, serviceTypePath, serviceTypeValue, externalIPPath, compName, namespace string) error { 105 overrideYAMLs, err := getOverrideYAMLs(overrides, namespace) 106 if err != nil { 107 return err 108 } 109 110 for _, o := range overrideYAMLs { 111 value, err := override.ExtractValueFromOverrideString(o, jsonBasePath) 112 if err != nil { 113 return err 114 } 115 116 if value != nil { 117 valueMap := value.(map[string]interface{}) 118 extractedIP := valueMap[externalIPPath] 119 if extractedIP == nil { 120 continue 121 } 122 extractedType := valueMap[serviceTypePath] 123 externalIPPathFull := jsonBasePath + "." + externalIPPath 124 extractedIPsArray, err := castValuesToString(extractedIP) 125 if err != nil { 126 return err 127 } 128 if extractedType != nil && extractedType == serviceTypeValue { 129 err := validateExternalIP(extractedIPsArray, externalIPPathFull, compName) 130 if err != nil { 131 return err 132 } 133 } 134 } 135 } 136 return nil 137 } 138 139 func validateExternalIP(addresses []string, key, compName string) error { 140 if len(addresses) < 1 { 141 return fmt.Errorf("At least one %s external IPs need to be set as an array for the key \"%v\"", compName, key) 142 } 143 for _, address := range addresses { 144 if net.ParseIP(address) == nil { 145 return fmt.Errorf("Controller external service key \"%v\" with IP \"%v\" is of invalid format for %s. Must be a proper IP address format", key, address, compName) 146 } 147 } 148 return nil 149 } 150 151 func castValuesToString(value interface{}) ([]string, error) { 152 var values []string 153 switch val := value.(type) { 154 case string: 155 values = append(values, value.(string)) 156 case []interface{}: 157 valueArray := value.([]interface{}) 158 for _, v := range valueArray { 159 if v != nil && reflect.TypeOf(v).String() == "string" { 160 values = append(values, v.(string)) 161 } else { 162 return nil, fmt.Errorf(invalidDataType, reflect.TypeOf(v)) 163 } 164 } 165 default: 166 return nil, fmt.Errorf(invalidDataType, val) 167 } 168 169 return values, nil 170 } 171 172 func getOverrideYAMLs(overrides []v1beta1.Overrides, namespace string) ([]string, error) { 173 client, err := getRunTimeClient() 174 if err != nil { 175 return nil, err 176 } 177 overrideYAMLs, err := override.GetInstallOverridesYAMLUsingClient(client, overrides, namespace) 178 if err != nil { 179 return nil, err 180 } 181 return overrideYAMLs, err 182 } 183 184 func getRunTimeClient() (client.Client, error) { 185 scheme := runtime.NewScheme() 186 _ = corev1.AddToScheme(scheme) 187 client, err := GetControllerRuntimeClient(scheme) 188 if err != nil { 189 return nil, err 190 } 191 return client, err 192 }