github.com/kyma-project/kyma-environment-broker@v0.0.1/internal/provisioner/graphqlizer.go (about) 1 package provisioner 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "reflect" 7 "text/template" 8 9 "github.com/sirupsen/logrus" 10 11 "fmt" 12 13 "strconv" 14 15 "github.com/Masterminds/sprig" 16 "github.com/kyma-project/control-plane/components/provisioner/pkg/gqlschema" 17 ) 18 19 // Graphqlizer is responsible for converting Go objects to input arguments in graphql format 20 type Graphqlizer struct{} 21 22 func (g *Graphqlizer) ProvisionRuntimeInputToGraphQL(in gqlschema.ProvisionRuntimeInput) (string, error) { 23 return g.genericToGraphQL(in, `{ 24 {{- if .RuntimeInput }} 25 runtimeInput: {{ RuntimeInputToGraphQL .RuntimeInput }}, 26 {{- end }} 27 {{- if .ClusterConfig }} 28 clusterConfig: {{ ClusterConfigToGraphQL .ClusterConfig }}, 29 {{- end }} 30 {{- if .KymaConfig }} 31 kymaConfig: {{ KymaConfigToGraphQL .KymaConfig }}, 32 {{- end }} 33 }`) 34 } 35 36 func (g *Graphqlizer) RuntimeInputToGraphQL(in gqlschema.RuntimeInput) (string, error) { 37 return g.genericToGraphQL(in, `{ 38 name: "{{.Name}}", 39 {{- if .Description }} 40 description: "{{.Description}}", 41 {{- end }} 42 {{- if .Labels }} 43 labels: {{ LabelsToGQL .Labels}}, 44 {{- end }} 45 }`) 46 } 47 48 func (g *Graphqlizer) LabelsToGQL(in gqlschema.Labels) (string, error) { 49 return g.marshal(in), nil 50 } 51 52 func (g *Graphqlizer) ClusterConfigToGraphQL(in gqlschema.ClusterConfigInput) (string, error) { 53 return g.genericToGraphQL(in, `{ 54 {{- if .GardenerConfig }} 55 gardenerConfig: {{ GardenerConfigInputToGraphQL .GardenerConfig }}, 56 {{- end }} 57 {{- if .Administrators }} 58 administrators: {{.Administrators | marshal }}, 59 {{- end }} 60 }`) 61 } 62 63 func (g *Graphqlizer) GardenerConfigInputToGraphQL(in gqlschema.GardenerConfigInput) (string, error) { 64 return g.genericToGraphQL(in, `{ 65 {{- if .Name }} 66 name: "{{.Name}}", 67 {{- end }} 68 kubernetesVersion: "{{.KubernetesVersion}}", 69 {{- if .VolumeSizeGb }} 70 volumeSizeGB: {{.VolumeSizeGb }}, 71 {{- end }} 72 machineType: "{{.MachineType}}", 73 {{- if .MachineImage }} 74 machineImage: "{{.MachineImage}}", 75 {{- end}} 76 {{- if .MachineImageVersion }} 77 machineImageVersion: "{{.MachineImageVersion}}", 78 {{- end }} 79 region: "{{.Region}}", 80 provider: "{{ .Provider }}", 81 {{- if .Purpose }} 82 purpose: "{{ .Purpose }}", 83 {{- end }} 84 {{- if .LicenceType }} 85 licenceType: "{{ .LicenceType }}", 86 {{- end }} 87 {{- if .DiskType }} 88 diskType: "{{.DiskType}}", 89 {{- end }} 90 targetSecret: "{{ .TargetSecret }}", 91 workerCidr: "{{ .WorkerCidr }}", 92 {{- if .PodsCidr }} 93 podsCidr: "{{ .PodsCidr }}", 94 {{- end }} 95 {{- if .ServicesCidr }} 96 servicesCidr: "{{ .ServicesCidr }}" 97 {{- end }} 98 autoScalerMin: {{ .AutoScalerMin }}, 99 autoScalerMax: {{ .AutoScalerMax }}, 100 maxSurge: {{ .MaxSurge }}, 101 maxUnavailable: {{ .MaxUnavailable }}, 102 {{- if .ExposureClassName }} 103 exposureClassName: "{{ .ExposureClassName }}", 104 {{- end }} 105 {{- if .EnableKubernetesVersionAutoUpdate }} 106 enableKubernetesVersionAutoUpdate: {{ .EnableKubernetesVersionAutoUpdate }}, 107 {{- end }} 108 {{- if .EnableMachineImageVersionAutoUpdate }} 109 enableMachineImageVersionAutoUpdate: {{ .EnableMachineImageVersionAutoUpdate }}, 110 {{- end }} 111 {{- if .ProviderSpecificConfig }} 112 providerSpecificConfig: { 113 {{- if .ProviderSpecificConfig.AzureConfig }} 114 azureConfig: {{ AzureProviderConfigInputToGraphQL .ProviderSpecificConfig.AzureConfig }}, 115 {{- end}} 116 {{- if .ProviderSpecificConfig.GcpConfig }} 117 gcpConfig: {{ GCPProviderConfigInputToGraphQL .ProviderSpecificConfig.GcpConfig }}, 118 {{- end}} 119 {{- if .ProviderSpecificConfig.AwsConfig }} 120 awsConfig: {{ AWSProviderConfigInputToGraphQL .ProviderSpecificConfig.AwsConfig }}, 121 {{- end}} 122 {{- if .ProviderSpecificConfig.OpenStackConfig }} 123 openStackConfig: {{ OpenStackProviderConfigInputToGraphQL .ProviderSpecificConfig.OpenStackConfig }}, 124 {{- end}} 125 } 126 {{- end}} 127 {{- if .OidcConfig }} 128 oidcConfig: { 129 clientID: "{{ .OidcConfig.ClientID }}", 130 issuerURL: "{{ .OidcConfig.IssuerURL }}", 131 groupsClaim: "{{ .OidcConfig.GroupsClaim }}", 132 signingAlgs: {{ .OidcConfig.SigningAlgs | marshal }}, 133 usernameClaim: "{{ .OidcConfig.UsernameClaim }}", 134 usernamePrefix: "{{ .OidcConfig.UsernamePrefix }}", 135 } 136 {{- end }} 137 {{- if .DNSConfig }} 138 dnsConfig: {{ DNSConfigInputToGraphQL .DNSConfig }} 139 {{- end }} 140 {{- if .ControlPlaneFailureTolerance }} 141 controlPlaneFailureTolerance: "{{ .ControlPlaneFailureTolerance }}", 142 {{- end }} 143 {{- if .EuAccess }} 144 euAccess: {{ .EuAccess }}, 145 {{- end }} 146 {{- if .ShootNetworkingFilterDisabled }} 147 shootNetworkingFilterDisabled: {{ .ShootNetworkingFilterDisabled }}, 148 {{- end }} 149 }`) 150 } 151 152 func (g *Graphqlizer) DNSConfigInputToGraphQL(in gqlschema.DNSConfigInput) (string, error) { 153 return g.genericToGraphQL(in, `{ 154 domain: "{{ .Domain }}", 155 {{- with .Providers }} 156 providers: [ 157 {{- range . }} 158 { 159 domainsInclude: {{ .DomainsInclude | marshal }}, 160 primary: {{ .Primary }}, 161 secretName: "{{ .SecretName }}", 162 type: "{{ .Type }}", 163 } 164 {{- end }} 165 ] 166 {{- end }} 167 }`) 168 } 169 170 func (g *Graphqlizer) AzureProviderConfigInputToGraphQL(in gqlschema.AzureProviderConfigInput) (string, error) { 171 return g.genericToGraphQL(in, `{ 172 {{- if .EnableNatGateway}} 173 enableNatGateway: {{.EnableNatGateway}}, 174 {{- end }} 175 vnetCidr: "{{.VnetCidr}}", 176 {{- if .Zones }} 177 zones: {{.Zones | marshal }}, 178 {{- end }} 179 {{- with .AzureZones }} 180 azureZones: [ 181 {{- range . }} 182 { 183 name: {{ .Name }}, 184 cidr: "{{ .Cidr }}", 185 } 186 {{- end }} 187 ] 188 {{- end }} 189 }`) 190 } 191 192 func (g *Graphqlizer) GCPProviderConfigInputToGraphQL(in gqlschema.GCPProviderConfigInput) (string, error) { 193 return fmt.Sprintf(`{ zones: %s }`, g.marshal(in.Zones)), nil 194 } 195 196 func (g *Graphqlizer) AWSProviderConfigInputToGraphQL(in gqlschema.AWSProviderConfigInput) (string, error) { 197 return g.genericToGraphQL(in, `{ 198 vpcCidr: "{{.VpcCidr}}", 199 {{- with .AwsZones }} 200 awsZones: [ 201 {{- range . }} 202 { 203 name: "{{ .Name }}", 204 workerCidr: "{{ .WorkerCidr }}", 205 publicCidr: "{{ .PublicCidr }}", 206 internalCidr: "{{ .InternalCidr }}", 207 } 208 {{- end }} 209 ] 210 {{- end }} 211 }`) 212 } 213 214 func (g *Graphqlizer) OpenStackProviderConfigInputToGraphQL(in gqlschema.OpenStackProviderConfigInput) (string, error) { 215 return fmt.Sprintf(`{ 216 zones: %s, 217 floatingPoolName: "%s", 218 cloudProfileName: "%s", 219 loadBalancerProvider: "%s" 220 }`, g.marshal(in.Zones), in.FloatingPoolName, in.CloudProfileName, in.LoadBalancerProvider), nil 221 } 222 223 func (g *Graphqlizer) KymaConfigToGraphQL(in gqlschema.KymaConfigInput) (string, error) { 224 return g.genericToGraphQL(in, `{ 225 version: "{{ .Version }}", 226 {{- if .Profile }} 227 profile: {{ .Profile }}, 228 {{- end }} 229 {{- if .ConflictStrategy }} 230 conflictStrategy: {{ .ConflictStrategy }}, 231 {{- end }} 232 {{- with .Components }} 233 components: [ 234 {{- range . }} 235 { 236 component: "{{ .Component }}", 237 namespace: "{{ .Namespace }}", 238 {{- if .SourceURL }} 239 sourceURL: "{{ .SourceURL }}", 240 {{- end }} 241 {{- if .ConflictStrategy }} 242 conflictStrategy: {{ .ConflictStrategy }}, 243 {{- end }} 244 {{- with .Configuration }} 245 configuration: [ 246 {{- range . }} 247 { 248 key: "{{ .Key }}", 249 value: {{ .Value | strQuote }}, 250 {{- if .Secret }} 251 secret: true, 252 {{- end }} 253 } 254 {{- end }} 255 ] 256 {{- end }} 257 } 258 {{- end }} 259 ] 260 {{- end }} 261 {{- with .Configuration }} 262 configuration: [ 263 {{- range . }} 264 { 265 key: "{{ .Key }}", 266 value: {{ .Value | strQuote }}, 267 {{- if .Secret }} 268 secret: true, 269 {{- end }} 270 } 271 {{- end }} 272 ] 273 {{- end }} 274 }`) 275 } 276 277 func (g *Graphqlizer) GardenerUpgradeInputToGraphQL(in gqlschema.GardenerUpgradeInput) (string, error) { 278 return g.genericToGraphQL(in, `{ 279 {{- if .KubernetesVersion }} 280 kubernetesVersion: "{{.KubernetesVersion}}", 281 {{- end }} 282 {{- if .MachineType }} 283 machineType: "{{ .MachineType }}", 284 {{- end}} 285 {{- if .MachineImage }} 286 machineImage: "{{.MachineImage}}", 287 {{- end}} 288 {{- if .MachineImageVersion }} 289 machineImageVersion: "{{.MachineImageVersion}}", 290 {{- end }} 291 {{- if .AutoScalerMin }} 292 autoScalerMin: {{ .AutoScalerMin }}, 293 {{- end }} 294 {{- if .AutoScalerMax }} 295 autoScalerMax: {{ .AutoScalerMax }}, 296 {{- end }} 297 {{- if .MaxSurge }} 298 maxSurge: {{ .MaxSurge }}, 299 {{- end }} 300 {{- if .MaxUnavailable }} 301 maxUnavailable: {{ .MaxUnavailable }}, 302 {{- end }} 303 {{- if .ExposureClassName }} 304 exposureClassName: "{{ .ExposureClassName }}", 305 {{- end }} 306 {{- if .EnableKubernetesVersionAutoUpdate }} 307 enableKubernetesVersionAutoUpdate: {{ .EnableKubernetesVersionAutoUpdate }}, 308 {{- end }} 309 {{- if .EnableMachineImageVersionAutoUpdate }} 310 enableMachineImageVersionAutoUpdate: {{ .EnableMachineImageVersionAutoUpdate }}, 311 {{- end }} 312 {{- if .OidcConfig }} 313 oidcConfig: { 314 clientID: "{{ .OidcConfig.ClientID }}", 315 issuerURL: "{{ .OidcConfig.IssuerURL }}", 316 groupsClaim: "{{ .OidcConfig.GroupsClaim }}", 317 signingAlgs: {{ .OidcConfig.SigningAlgs | marshal }}, 318 usernameClaim: "{{ .OidcConfig.UsernameClaim }}", 319 usernamePrefix: "{{ .OidcConfig.UsernamePrefix }}", 320 }, 321 {{- end }} 322 {{- if .ShootNetworkingFilterDisabled }} 323 shootNetworkingFilterDisabled: {{ .ShootNetworkingFilterDisabled }}, 324 {{- end }} 325 }`) 326 } 327 328 func (g *Graphqlizer) marshal(obj interface{}) string { 329 var out string 330 331 val := reflect.ValueOf(obj) 332 333 switch val.Kind() { 334 case reflect.Map: 335 s, err := g.genericToGraphQL(obj, `{ {{- range $k, $v := . }}{{ $k }}:{{ marshal $v }},{{ end -}} }`) 336 if err != nil { 337 logrus.Warnf("failed to marshal labels: %s", err.Error()) 338 return "" 339 } 340 out = s 341 case reflect.Slice, reflect.Array: 342 s, err := g.genericToGraphQL(obj, `[{{ range $i, $e := . }}{{ if $i }},{{ end }}{{ marshal $e }}{{ end }}]`) 343 if err != nil { 344 logrus.Warnf("failed to marshal labels: %s", err.Error()) 345 return "" 346 } 347 out = s 348 default: 349 marshalled, err := json.Marshal(obj) 350 if err != nil { 351 logrus.Warnf("failed to marshal labels: %s", err.Error()) 352 return "" 353 } 354 out = string(marshalled) 355 } 356 357 return out 358 } 359 360 func (g *Graphqlizer) UpgradeRuntimeInputToGraphQL(in gqlschema.UpgradeRuntimeInput) (string, error) { 361 return g.genericToGraphQL(in, `{ 362 kymaConfig: {{ KymaConfigToGraphQL .KymaConfig }} 363 }`) 364 } 365 366 func (g Graphqlizer) UpgradeShootInputToGraphQL(in gqlschema.UpgradeShootInput) (string, error) { 367 return g.genericToGraphQL(in, `{ 368 gardenerConfig: {{ GardenerUpgradeInputToGraphQL .GardenerConfig }}, 369 {{- if .Administrators }} 370 administrators: {{.Administrators | marshal }}, 371 {{- end }} 372 }`) 373 } 374 375 func (g *Graphqlizer) genericToGraphQL(obj interface{}, tmpl string) (string, error) { 376 fm := sprig.TxtFuncMap() 377 fm["marshal"] = g.marshal 378 fm["RuntimeInputToGraphQL"] = g.RuntimeInputToGraphQL 379 fm["ClusterConfigToGraphQL"] = g.ClusterConfigToGraphQL 380 fm["KymaConfigToGraphQL"] = g.KymaConfigToGraphQL 381 fm["GardenerConfigInputToGraphQL"] = g.GardenerConfigInputToGraphQL 382 fm["GardenerUpgradeInputToGraphQL"] = g.GardenerUpgradeInputToGraphQL 383 fm["AzureProviderConfigInputToGraphQL"] = g.AzureProviderConfigInputToGraphQL 384 fm["GCPProviderConfigInputToGraphQL"] = g.GCPProviderConfigInputToGraphQL 385 fm["AWSProviderConfigInputToGraphQL"] = g.AWSProviderConfigInputToGraphQL 386 fm["OpenStackProviderConfigInputToGraphQL"] = g.OpenStackProviderConfigInputToGraphQL 387 fm["DNSConfigInputToGraphQL"] = g.DNSConfigInputToGraphQL 388 fm["LabelsToGQL"] = g.LabelsToGQL 389 fm["strQuote"] = strconv.Quote 390 391 t, err := template.New("tmpl").Funcs(fm).Parse(tmpl) 392 if err != nil { 393 return "", fmt.Errorf("while parsing template: %w", err) 394 } 395 396 var b bytes.Buffer 397 398 if err := t.Execute(&b, obj); err != nil { 399 return "", fmt.Errorf("while executing template: %w", err) 400 } 401 return b.String(), nil 402 }