github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/dto.go (about) 1 package internal 2 3 import ( 4 "fmt" 5 "net/url" 6 "reflect" 7 "strings" 8 9 "github.com/kyma-project/kyma-environment-broker/internal/ptr" 10 ) 11 12 const ( 13 LicenceTypeLite = "TestDevelopmentAndDemo" 14 oidcValidSigningAlgs = "RS256,RS384,RS512,ES256,ES384,ES512,PS256,PS384,PS512" 15 ) 16 17 type OIDCConfigDTO struct { 18 ClientID string `json:"clientID" yaml:"clientID"` 19 GroupsClaim string `json:"groupsClaim" yaml:"groupsClaim"` 20 IssuerURL string `json:"issuerURL" yaml:"issuerURL"` 21 SigningAlgs []string `json:"signingAlgs" yaml:"signingAlgs"` 22 UsernameClaim string `json:"usernameClaim" yaml:"usernameClaim"` 23 UsernamePrefix string `json:"usernamePrefix" yaml:"usernamePrefix"` 24 } 25 26 func (o *OIDCConfigDTO) IsProvided() bool { 27 if o == nil { 28 return false 29 } 30 if o.ClientID == "" && o.IssuerURL == "" && o.GroupsClaim == "" && o.UsernamePrefix == "" && o.UsernameClaim == "" && len(o.SigningAlgs) == 0 { 31 return false 32 } 33 return true 34 } 35 36 func (o *OIDCConfigDTO) Validate() error { 37 errs := make([]string, 0) 38 if len(o.ClientID) == 0 { 39 errs = append(errs, "clientID must not be empty") 40 } 41 if len(o.IssuerURL) == 0 { 42 errs = append(errs, "issuerURL must not be empty") 43 } else { 44 issuer, err := url.Parse(o.IssuerURL) 45 if err != nil || (issuer != nil && len(issuer.Host) == 0) { 46 errs = append(errs, "issuerURL must be a valid URL") 47 } 48 if issuer != nil && issuer.Scheme != "https" { 49 errs = append(errs, "issuerURL must have https scheme") 50 } 51 } 52 if len(o.SigningAlgs) != 0 { 53 validSigningAlgs := o.validSigningAlgsSet() 54 for _, providedAlg := range o.SigningAlgs { 55 if !validSigningAlgs[providedAlg] { 56 errs = append(errs, "signingAlgs must contain valid signing algorithm(s)") 57 break 58 } 59 } 60 } 61 62 if len(errs) > 0 { 63 err := fmt.Errorf(strings.Join(errs, ", ")) 64 return err 65 } 66 return nil 67 } 68 69 func (o *OIDCConfigDTO) validSigningAlgsSet() map[string]bool { 70 algs := strings.Split(oidcValidSigningAlgs, ",") 71 signingAlgsSet := make(map[string]bool, len(algs)) 72 73 for _, v := range algs { 74 signingAlgsSet[v] = true 75 } 76 77 return signingAlgsSet 78 } 79 80 type ProvisioningParameters struct { 81 PlanID string `json:"plan_id"` 82 ServiceID string `json:"service_id"` 83 ErsContext ERSContext `json:"ers_context"` 84 Parameters ProvisioningParametersDTO `json:"parameters"` 85 86 // PlatformRegion defines the Platform region send in the request path, terminology: 87 // - `Platform` is a place where KEB is registered and which later sends request to KEB. 88 // - `Region` value is use e.g. for billing integration such as EDP. 89 PlatformRegion string `json:"platform_region"` 90 91 PlatformProvider CloudProvider `json:"platform_provider"` 92 } 93 94 func (p ProvisioningParameters) IsEqual(input ProvisioningParameters) bool { 95 if p.PlanID != input.PlanID { 96 return false 97 } 98 if p.ServiceID != input.ServiceID { 99 return false 100 } 101 if p.PlatformRegion != input.PlatformRegion { 102 return false 103 } 104 105 if !reflect.DeepEqual(p.ErsContext, input.ErsContext) { 106 return false 107 } 108 109 p.Parameters.TargetSecret = nil 110 p.Parameters.LicenceType = nil 111 input.Parameters.LicenceType = nil 112 113 if !reflect.DeepEqual(p.Parameters, input.Parameters) { 114 return false 115 } 116 117 return true 118 } 119 120 type CloudProvider string 121 122 const ( 123 Azure CloudProvider = "Azure" 124 AWS CloudProvider = "AWS" 125 GCP CloudProvider = "GCP" 126 UnknownProvider CloudProvider = "unknown" 127 Openstack CloudProvider = "OpenStack" 128 ) 129 130 type AutoScalerParameters struct { 131 AutoScalerMin *int `json:"autoScalerMin,omitempty"` 132 AutoScalerMax *int `json:"autoScalerMax,omitempty"` 133 MaxSurge *int `json:"maxSurge,omitempty"` 134 MaxUnavailable *int `json:"maxUnavailable,omitempty"` 135 } 136 137 // FIXME: this is a makeshift check until the provisioner is capable of returning error messages 138 // https://github.com/kyma-project/control-plane/issues/946 139 func (p AutoScalerParameters) Validate(planMin, planMax int) error { 140 min, max := planMin, planMax 141 if p.AutoScalerMin != nil { 142 min = *p.AutoScalerMin 143 } 144 if p.AutoScalerMax != nil { 145 max = *p.AutoScalerMax 146 } 147 if min > max { 148 userMin := fmt.Sprintf("%v", p.AutoScalerMin) 149 if p.AutoScalerMin != nil { 150 userMin = fmt.Sprintf("%v", *p.AutoScalerMin) 151 } 152 userMax := fmt.Sprintf("%v", p.AutoScalerMax) 153 if p.AutoScalerMax != nil { 154 userMax = fmt.Sprintf("%v", *p.AutoScalerMax) 155 } 156 return fmt.Errorf("AutoScalerMax %v should be larger than AutoScalerMin %v. User provided values min:%v, max:%v; plan defaults min:%v, max:%v", max, min, userMin, userMax, planMin, planMax) 157 } 158 return nil 159 } 160 161 type NetworkingDTO struct { 162 NodesCidr string `json:"nodes,omitempty"` 163 PodsCidr *string `json:"pods,omitempty"` 164 ServicesCidr *string `json:"services,omitempty"` 165 } 166 167 type ProvisioningParametersDTO struct { 168 AutoScalerParameters `json:",inline"` 169 170 Name string `json:"name"` 171 TargetSecret *string `json:"targetSecret,omitempty"` 172 VolumeSizeGb *int `json:"volumeSizeGb,omitempty"` 173 MachineType *string `json:"machineType,omitempty"` 174 Region *string `json:"region,omitempty"` 175 Purpose *string `json:"purpose,omitempty"` 176 // LicenceType - based on this parameter, some options can be enabled/disabled when preparing the input 177 // for the provisioner e.g. use default overrides for SKR instead overrides from resource 178 // with "provisioning-runtime-override" label when LicenceType is "TestDevelopmentAndDemo" 179 LicenceType *string `json:"licence_type,omitempty"` 180 Zones []string `json:"zones,omitempty"` 181 OptionalComponentsToInstall []string `json:"components,omitempty"` 182 KymaVersion string `json:"kymaVersion,omitempty"` 183 OverridesVersion string `json:"overridesVersion,omitempty"` 184 RuntimeAdministrators []string `json:"administrators,omitempty"` 185 // Provider - used in Trial plan to determine which cloud provider to use during provisioning 186 Provider *CloudProvider `json:"provider,omitempty"` 187 188 Kubeconfig string `json:"kubeconfig,omitempty"` 189 ShootName string `json:"shootName,omitempty"` 190 ShootDomain string `json:"shootDomain,omitempty"` 191 192 OIDC *OIDCConfigDTO `json:"oidc,omitempty"` 193 Networking *NetworkingDTO `json:"networking,omitempty""` 194 Modules *ModulesDTO `json:"modules,omitempty"` 195 } 196 197 type UpdatingParametersDTO struct { 198 AutoScalerParameters `json:",inline"` 199 200 OIDC *OIDCConfigDTO `json:"oidc,omitempty"` 201 RuntimeAdministrators []string `json:"administrators,omitempty"` 202 MachineType *string `json:"machineType,omitempty"` 203 204 // Expired - means that the trial SKR is marked as expired 205 Expired bool `json:"expired"` 206 } 207 208 func (u UpdatingParametersDTO) UpdateAutoScaler(p *ProvisioningParametersDTO) bool { 209 updated := false 210 if u.AutoScalerMin != nil { 211 updated = true 212 p.AutoScalerMin = u.AutoScalerMin 213 } 214 if u.AutoScalerMax != nil { 215 updated = true 216 p.AutoScalerMax = u.AutoScalerMax 217 } 218 if u.MaxSurge != nil { 219 updated = true 220 p.MaxSurge = u.MaxSurge 221 } 222 if u.MaxUnavailable != nil { 223 updated = true 224 p.MaxUnavailable = u.MaxUnavailable 225 } 226 return updated 227 } 228 229 type ERSContext struct { 230 TenantID string `json:"tenant_id,omitempty"` 231 SubAccountID string `json:"subaccount_id"` 232 GlobalAccountID string `json:"globalaccount_id"` 233 SMOperatorCredentials *ServiceManagerOperatorCredentials `json:"sm_operator_credentials,omitempty"` 234 Active *bool `json:"active,omitempty"` 235 UserID string `json:"user_id"` 236 CommercialModel *string `json:"commercial_model,omitempty"` 237 LicenseType *string `json:"license_type,omitempty"` 238 Origin *string `json:"origin,omitempty"` 239 Platform *string `json:"platform,omitempty"` 240 Region *string `json:"region,omitempty"` 241 } 242 243 func InheritMissingERSContext(currentOperation, previousOperation ERSContext) ERSContext { 244 if currentOperation.SMOperatorCredentials == nil { 245 currentOperation.SMOperatorCredentials = previousOperation.SMOperatorCredentials 246 } 247 if currentOperation.CommercialModel == nil { 248 currentOperation.CommercialModel = previousOperation.CommercialModel 249 } 250 if currentOperation.LicenseType == nil { 251 currentOperation.LicenseType = previousOperation.LicenseType 252 } 253 if currentOperation.Origin == nil { 254 currentOperation.Origin = previousOperation.Origin 255 } 256 if currentOperation.Platform == nil { 257 currentOperation.Platform = previousOperation.Platform 258 } 259 if currentOperation.Region == nil { 260 currentOperation.Region = previousOperation.Region 261 } 262 return currentOperation 263 } 264 265 func UpdateInstanceERSContext(instance, operation ERSContext) ERSContext { 266 if operation.SMOperatorCredentials != nil { 267 instance.SMOperatorCredentials = operation.SMOperatorCredentials 268 } 269 if operation.CommercialModel != nil { 270 instance.CommercialModel = operation.CommercialModel 271 } 272 if operation.LicenseType != nil { 273 instance.LicenseType = operation.LicenseType 274 } 275 if operation.Origin != nil { 276 instance.Origin = operation.Origin 277 } 278 if operation.Platform != nil { 279 instance.Platform = operation.Platform 280 } 281 if operation.Region != nil { 282 instance.Region = operation.Region 283 } 284 return instance 285 } 286 287 func (e ERSContext) DisableEnterprisePolicyFilter() *bool { 288 // the provisioner and gardener API expects the feature to be enabled by disablement flag 289 // it feels counterintuitive but there is currently no plan in changing it, therefore 290 // following code is written the way it's written 291 disable := false 292 if e.LicenseType == nil { 293 return &disable 294 } 295 switch *e.LicenseType { 296 case "CUSTOMER", "PARTNER", "TRIAL": 297 disable = true 298 return &disable 299 } 300 return &disable 301 } 302 303 func (e ERSContext) ERSUpdate() bool { 304 if e.SMOperatorCredentials != nil { 305 return true 306 } 307 if e.CommercialModel != nil { 308 return true 309 } 310 if e.LicenseType != nil { 311 return true 312 } 313 if e.Origin != nil { 314 return true 315 } 316 if e.Platform != nil { 317 return true 318 } 319 if e.Region != nil { 320 return true 321 } 322 return false 323 } 324 325 type ServiceManagerEntryDTO struct { 326 Credentials ServiceManagerCredentials `json:"credentials"` 327 URL string `json:"url"` 328 } 329 330 type ServiceManagerCredentials struct { 331 BasicAuth ServiceManagerBasicAuth `json:"basic"` 332 } 333 334 type ServiceManagerBasicAuth struct { 335 Username string `json:"username"` 336 Password string `json:"password"` 337 } 338 339 type ServiceManagerOperatorCredentials struct { 340 ClientID string `json:"clientid"` 341 ClientSecret string `json:"clientsecret"` 342 ServiceManagerURL string `json:"sm_url"` 343 URL string `json:"url"` 344 XSAppName string `json:"xsappname"` 345 } 346 347 type Channel *string 348 349 var ( 350 Fast Channel = ptr.String("fast") 351 Regular Channel = ptr.String("regular") 352 ) 353 354 type CustomResourcePolicy *string 355 356 var ( 357 Ignore CustomResourcePolicy = ptr.String("Ignore") 358 CreateAndDelete CustomResourcePolicy = ptr.String("CreateAndDelete") 359 ) 360 361 type ModulesDTO struct { 362 Default *bool `json:"default,omitempty" yaml:"default,omitempty"` 363 List []*ModuleDTO `json:"list,omitempty" yaml:"list,omitempty"` 364 } 365 366 type ModuleDTO struct { 367 Name string `json:"name,omitempty" yaml:"name,omitempty"` 368 Channel Channel `json:"channel,omitempty" yaml:"channel,omitempty"` 369 CustomResourcePolicy CustomResourcePolicy `json:"customResourcePolicy,omitempty" yaml:"customResourcePolicy,omitempty"` 370 }