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  }