providers/gcp/gcp_compute_code_generator/main.go (207 lines of code) (raw):

// Copyright 2018 The Terraformer Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package main import ( "bytes" "encoding/json" "go/format" "log" "os" "strings" "text/template" ) const pathForGenerateFiles = "/providers/gcp/" const serviceTemplate = ` // Copyright 2018 The Terraformer Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package gcp import ( "context" "log" {{ if .byZone }}"strings"{{end}} "github.com/GoogleCloudPlatform/terraformer/terraformutils" "google.golang.org/api/compute/v1" ) var {{.resource}}AllowEmptyValues = []string{"{{join .allowEmptyValues "\",\"" }}"} var {{.resource}}AdditionalFields = map[string]interface{}{ {{ range $key,$value := .additionalFields}} "{{$key}}": "{{$value}}",{{end}} } type {{.titleResourceName}}Generator struct { GCPService } // Run on {{.resource}}List and create for each TerraformResource func (g {{.titleResourceName}}Generator) createResources(ctx context.Context, {{.resource}}List *compute.{{.titleResourceName}}ListCall{{ if .byZone }}, zone string{{end}}) []terraformutils.Resource { resources := []terraformutils.Resource{} if err := {{.resource}}List.Pages(ctx, func(page *compute.{{.responseName}}) error { for _, obj := range page.Items { resources = append(resources, terraformutils.NewResource( {{ if .idWithZone }}zone+"/"+obj.Name,{{else}}obj.Name,{{end}} {{ if .idWithZone }}zone+"/"+obj.Name,{{else}}obj.Name,{{end}} "{{.terraformName}}", g.ProviderName, map[string]string{ "name": obj.Name, "project": g.GetArgs()["project"].(string), {{ if .needRegion}}"region": g.GetArgs()["region"].(compute.Region).Name,{{end}} {{ if .byZone }}"zone": zone,{{end}} {{ range $key, $value := .additionalFieldsForRefresh}} "{{$key}}": "{{$value}}",{{end}} }, {{.resource}}AllowEmptyValues, {{.resource}}AdditionalFields, )) } return nil }); err != nil { log.Println(err) } return resources } // Generate TerraformResources from GCP API, // from each {{.resource}} create 1 TerraformResource // Need {{.resource}} name as ID for terraform resource func (g *{{.titleResourceName}}Generator) InitResources() error { ctx := context.Background() computeService, err := compute.NewService(ctx) if err != nil { return err } {{ if .byZone }} for _, zoneLink := range g.GetArgs()["region"].(compute.Region).Zones { t := strings.Split(zoneLink, "/") zone := t[len(t)-1] {{.resource}}List := computeService.{{.titleResourceName}}.List(g.GetArgs()["project"].(string), zone) g.Resources = append(g.Resources, g.createResources(ctx, {{.resource}}List, zone)...) } {{else}} {{.resource}}List := computeService.{{.titleResourceName}}.List({{.parameterOrder}}) g.Resources = g.createResources(ctx, {{.resource}}List) {{end}} return nil } ` const computeTemplate = ` // Copyright 2018 The Terraformer Authors. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. // AUTO-GENERATED CODE. DO NOT EDIT. package gcp import ( "github.com/GoogleCloudPlatform/terraformer/terraformutils" ) // Map of supported GCP compute service with code generate var ComputeServices = map[string]terraformutils.ServiceGenerator{ {{ range $key, $value := .services }} "{{$key}}": &GCPFacade{service: &{{title $key}}Generator{}},{{ end }} } ` func main() { computeAPIData, err := os.ReadFile(os.Getenv("GOPATH") + "/src/google.golang.org/api/compute/v1/compute-api.json") // TODO delete this hack if err != nil { log.Fatal(err) } computeAPI := map[string]interface{}{} err = json.Unmarshal(computeAPIData, &computeAPI) if err != nil { log.Fatal(err) } funcMap := template.FuncMap{ "title": strings.Title, "toLower": strings.ToLower, "join": strings.Join, } for resource, v := range computeAPI["resources"].(map[string]interface{}) { if _, exist := terraformResources[resource]; !exist { continue } if value, exist := v.(map[string]interface{})["methods"].(map[string]interface{})["list"]; exist { parameters := []string{} for _, param := range value.(map[string]interface{})["parameterOrder"].([]interface{}) { switch param.(string) { case "region": parameters = append(parameters, `g.GetArgs()["region"].(compute.Region).Name`) case "project": parameters = append(parameters, `g.GetArgs()["project"].(string)`) case "zone": parameters = append(parameters, `g.GetArgs()["zone"].(string)`) } } parameterOrder := strings.Join(parameters, ", ") var tpl bytes.Buffer t := template.Must(template.New("resource.go").Funcs(funcMap).Parse(serviceTemplate)) err := t.Execute(&tpl, map[string]interface{}{ "titleResourceName": strings.Title(resource), "resource": resource, "responseName": value.(map[string]interface{})["response"].(map[string]interface{})["$ref"].(string), "terraformName": terraformResources[resource].getTerraformName(), "additionalFields": terraformResources[resource].getAdditionalFields(), "additionalFieldsForRefresh": terraformResources[resource].getAdditionalFieldsForRefresh(), "allowEmptyValues": terraformResources[resource].getAllowEmptyValues(), "needRegion": terraformResources[resource].ifNeedRegion(), "resourcePackageName": resource, "parameterOrder": parameterOrder, "byZone": terraformResources[resource].ifNeedZone(strings.Contains(parameterOrder, "zone")), "idWithZone": terraformResources[resource].ifIDWithZone(strings.Contains(parameterOrder, "zone")), }) if err != nil { log.Print(resource, err) continue } rootPath, _ := os.Getwd() currentPath := rootPath + pathForGenerateFiles err = os.MkdirAll(currentPath, os.ModePerm) if err != nil { log.Print(resource, err) continue } err = os.WriteFile(currentPath+"/"+resource+"_gen.go", codeFormat(tpl.Bytes()), os.ModePerm) if err != nil { log.Print(resource, err) continue } } else { log.Println(resource) } } var tpl bytes.Buffer t := template.Must(template.New("compute.go").Funcs(funcMap).Parse(computeTemplate)) err = t.Execute(&tpl, map[string]interface{}{ "services": terraformResources, }) if err != nil { log.Print(err) } rootPath, _ := os.Getwd() err = os.WriteFile(rootPath+pathForGenerateFiles+"compute.go", codeFormat(tpl.Bytes()), os.ModePerm) if err != nil { log.Println(err) } } func codeFormat(src []byte) []byte { code, err := format.Source(src) if err != nil { log.Println(err) } return code }