| // Copyright Istio 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. |
| |
| // Tool to generate pilot/pkg/config/kube/crdclient/types.gen.go |
| // Example run command: |
| // REPO_ROOT=`pwd` go generate ./pilot/pkg/config/kube/crdclient/... |
| package main |
| |
| import ( |
| "bytes" |
| "flag" |
| "fmt" |
| "go/format" |
| "log" |
| "os" |
| "path" |
| "text/template" |
| ) |
| |
| import ( |
| "github.com/apache/dubbo-go-pixiu/pkg/config/schema/collection" |
| "github.com/apache/dubbo-go-pixiu/pkg/config/schema/collections" |
| "github.com/apache/dubbo-go-pixiu/pkg/test/env" |
| ) |
| |
| // ConfigData is data struct to feed to types.go template. |
| type ConfigData struct { |
| Namespaced bool |
| VariableName string |
| APIImport string |
| ClientImport string |
| ClientGroupPath string |
| ClientTypePath string |
| Kind string |
| StatusAPIImport string |
| StatusKind string |
| |
| // Support gateway-api, which require a custom client and the Spec suffix |
| Client string |
| TypeSuffix string |
| |
| Readonly bool |
| NoSpec bool |
| } |
| |
| var ( |
| GatewayAPITypes = collections.PilotGatewayAPI.Remove(collections.Pilot.All()...) |
| NonIstioTypes = collections.All.Remove(collections.Pilot.All()...) |
| ) |
| |
| // MakeConfigData prepare data for code generation for the given schema. |
| func MakeConfigData(schema collection.Schema) ConfigData { |
| out := ConfigData{ |
| Namespaced: !schema.Resource().IsClusterScoped(), |
| VariableName: schema.VariableName(), |
| APIImport: apiImport[schema.Resource().ProtoPackage()], |
| ClientImport: clientGoImport[schema.Resource().ProtoPackage()], |
| ClientGroupPath: clientGoAccessPath[schema.Resource().ProtoPackage()], |
| ClientTypePath: clientGoTypePath[schema.Resource().Plural()], |
| Kind: schema.Resource().Kind(), |
| Client: "ic", |
| StatusAPIImport: apiImport[schema.Resource().StatusPackage()], |
| StatusKind: schema.Resource().StatusKind(), |
| } |
| if _, f := GatewayAPITypes.Find(schema.Name().String()); f { |
| out.Client = "sc" |
| out.TypeSuffix = "Spec" |
| } else if _, f := NonIstioTypes.Find(schema.Name().String()); f { |
| out.TypeSuffix = "Spec" |
| out.Readonly = true |
| } |
| if _, f := noSpec[schema.Resource().Plural()]; f { |
| out.NoSpec = true |
| } |
| log.Printf("Generating Istio type %s for %s/%s CRD\n", out.VariableName, out.APIImport, out.Kind) |
| return out |
| } |
| |
| var ( |
| // Mapping from istio/api path import to api import path |
| apiImport = map[string]string{ |
| "istio.io/api/networking/v1alpha3": "networkingv1alpha3", |
| "istio.io/api/networking/v1beta1": "networkingv1beta1", |
| "istio.io/api/security/v1beta1": "securityv1beta1", |
| "istio.io/api/telemetry/v1alpha1": "telemetryv1alpha1", |
| "sigs.k8s.io/gateway-api/apis/v1alpha2": "gatewayv1alpha2", |
| "istio.io/api/meta/v1alpha1": "metav1alpha1", |
| "istio.io/api/extensions/v1alpha1": "extensionsv1alpha1", |
| "k8s.io/api/admissionregistration/v1": "admissionregistrationv1", |
| "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1": "apiextensionsv1", |
| "k8s.io/api/apps/v1": "appsv1", |
| "k8s.io/api/core/v1": "corev1", |
| "k8s.io/api/extensions/v1beta1": "extensionsv1beta1", |
| } |
| // Mapping from istio/api path import to client go import path |
| clientGoImport = map[string]string{ |
| "istio.io/api/networking/v1alpha3": "clientnetworkingv1alpha3", |
| "istio.io/api/networking/v1beta1": "clientnetworkingv1beta1", |
| "istio.io/api/security/v1beta1": "clientsecurityv1beta1", |
| "istio.io/api/telemetry/v1alpha1": "clienttelemetryv1alpha1", |
| "sigs.k8s.io/gateway-api/apis/v1alpha2": "gatewayv1alpha2", |
| "istio.io/api/extensions/v1alpha1": "clientextensionsv1alpha1", |
| "k8s.io/api/admissionregistration/v1": "admissionregistrationv1", |
| "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1": "apiextensionsv1", |
| "k8s.io/api/apps/v1": "appsv1", |
| "k8s.io/api/core/v1": "corev1", |
| "k8s.io/api/extensions/v1beta1": "extensionsv1beta1", |
| } |
| // Translates an api import path to the top level path in client-go |
| clientGoAccessPath = map[string]string{ |
| "istio.io/api/networking/v1alpha3": "NetworkingV1alpha3", |
| "istio.io/api/networking/v1beta1": "NetworkingV1beta1", |
| "istio.io/api/security/v1beta1": "SecurityV1beta1", |
| "istio.io/api/telemetry/v1alpha1": "TelemetryV1alpha1", |
| "sigs.k8s.io/gateway-api/apis/v1alpha2": "GatewayV1alpha2", |
| "istio.io/api/extensions/v1alpha1": "ExtensionsV1alpha1", |
| "k8s.io/api/admissionregistration/v1": "admissionregistrationv1", |
| "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1": "apiextensionsv1", |
| "k8s.io/api/apps/v1": "appsv1", |
| "k8s.io/api/core/v1": "corev1", |
| "k8s.io/api/extensions/v1beta1": "extensionsv1beta1", |
| } |
| // Translates a plural type name to the type path in client-go |
| // TODO: can we automatically derive this? I don't think we can, its internal to the kubegen |
| clientGoTypePath = map[string]string{ |
| "destinationrules": "DestinationRules", |
| "envoyfilters": "EnvoyFilters", |
| "gateways": "Gateways", |
| "serviceentries": "ServiceEntries", |
| "sidecars": "Sidecars", |
| "proxyconfigs": "ProxyConfigs", |
| "virtualservices": "VirtualServices", |
| "workloadentries": "WorkloadEntries", |
| "workloadgroups": "WorkloadGroups", |
| "authorizationpolicies": "AuthorizationPolicies", |
| "peerauthentications": "PeerAuthentications", |
| "requestauthentications": "RequestAuthentications", |
| "gatewayclasses": "GatewayClasses", |
| "httproutes": "HTTPRoutes", |
| "tcproutes": "TCPRoutes", |
| "tlsroutes": "TLSRoutes", |
| "referencepolicies": "ReferencePolicies", |
| "telemetries": "Telemetries", |
| "wasmplugins": "WasmPlugins", |
| "mutatingwebhookconfigurations": "MutatingWebhookConfigurations", |
| "customresourcedefinitions": "CustomResourceDefinitions", |
| "deployments": "Deployments", |
| "configmaps": "ConfigMaps", |
| "pods": "Pods", |
| "services": "Services", |
| "namespaces": "Namespaces", |
| "endpoints": "Endpoints", |
| "nodes": "Nodes", |
| "secrets": "Secrets", |
| "ingresses": "Ingresses", |
| "servicemetadatas": "ServiceMetadatas", |
| "servicenamemappings": "ServiceNameMappings", |
| } |
| |
| noSpec = map[string]struct{}{ |
| "secrets": {}, |
| "endpoints": {}, |
| "configmaps": {}, |
| "mutatingwebhookconfigurations": {}, |
| } |
| ) |
| |
| func main() { |
| templateFile := flag.String("template", path.Join(env.IstioSrc, "pilot/pkg/config/kube/crdclient/gen/types.go.tmpl"), "Template file") |
| outputFile := flag.String("output", "", "Output file. Leave blank to go to stdout") |
| flag.Parse() |
| |
| tmpl := template.Must(template.ParseFiles(*templateFile)) |
| |
| // Prepare to generate types for mock schema and all Istio schemas |
| typeList := []ConfigData{} |
| for _, s := range collections.PilotGatewayAPI.Union(collections.Kube).All() { |
| c := MakeConfigData(s) |
| if c.ClientGroupPath == "" || c.ClientTypePath == "" || c.ClientImport == "" { |
| log.Fatalf("invalid config %+v", c) |
| } |
| typeList = append(typeList, c) |
| } |
| var buffer bytes.Buffer |
| if err := tmpl.Execute(&buffer, typeList); err != nil { |
| log.Fatal(fmt.Errorf("template: %v", err)) |
| } |
| |
| // Format source code. |
| out, err := format.Source(buffer.Bytes()) |
| if err != nil { |
| log.Fatal(err) |
| } |
| // Output |
| if outputFile == nil || *outputFile == "" { |
| fmt.Println(string(out)) |
| } else if err := os.WriteFile(*outputFile, out, 0o644); err != nil { |
| panic(err) |
| } |
| } |