diff --git a/main.go b/main.go index 8daade8..3e54c91 100644 --- a/main.go +++ b/main.go @@ -36,23 +36,22 @@ import ( ) var ( - xdsServerUri = flag.String("xds-server-uri", "trafficdirector.googleapis.com:443", "override of server uri, for testing") - outputName = flag.String("output", "-", "output file name") - gcpProjectNumber = flag.Int64("gcp-project-number", 0, "the gcp project number. If unknown, can be found via 'gcloud projects list'") - vpcNetworkName = flag.String("vpc-network-name", "default", "VPC network name") - localityZone = flag.String("locality-zone", "", "the locality zone to use, instead of retrieving it from the metadata server. Useful when not running on GCP and/or for testing") - ignoreResourceDeletion = flag.Bool("ignore-resource-deletion-experimental", false, "assume missing resources notify operators when using Traffic Director, as in gRFC A53. This is not currently the case. This flag is EXPERIMENTAL and may be changed or removed in a later release.") - secretsDir = flag.String("secrets-dir", "/var/run/secrets/workload-spiffe-credentials", "path to a directory containing TLS certificates and keys required for PSM security") - includeDeploymentInfo = flag.Bool("include-deployment-info-experimental", false, "whether or not to generate config which contains deployment related information. This flag is EXPERIMENTAL and may be changed or removed in a later release.") - gkeClusterName = flag.String("gke-cluster-name", "", "GKE cluster name to use, instead of retrieving it from the metadata server.") - gkePodName = flag.String("gke-pod-name-experimental", "", "GKE pod name to use, instead of reading it from $HOSTNAME or /etc/hostname file. This flag is EXPERIMENTAL and may be changed or removed in a later release.") - gkeNamespace = flag.String("gke-namespace-experimental", "", "GKE namespace to use. This flag is EXPERIMENTAL and may be changed or removed in a later release.") - gkeLocation = flag.String("gke-location-experimental", "", "the location (region/zone) of the cluster from which to pull configuration, instead of retrieving it from the metadata server. This value is used to generate the mesh ID. Ignored if not used with --generate-mesh-id. This flag is EXPERIMENTAL and may be changed or removed in a later release.") - gceVM = flag.String("gce-vm-experimental", "", "GCE VM name to use, instead of reading it from the metadata server. This flag is EXPERIMENTAL and may be changed or removed in a later release.") - configMesh = flag.String("config-mesh", "", "Dictates which Mesh resource to use.") - generateMeshId = flag.Bool("generate-mesh-id", false, "When enabled, the CSM MeshID is generated. If config-mesh flag is specified, this flag would be ignored. Location and Cluster Name would be retrieved from the metadata server unless specified via gke-location and gke-cluster-name flags respectively.") - includeDirectPathAuthority = flag.Bool("include-directpath-authority-experimental", true, "whether or not to include DirectPath TD authority for xDS Federation. Ignored if not used with include-federation-support-experimental flag. This flag is EXPERIMENTAL and may be changed or removed in a later release.") - includeXDSTPNameInLDS = flag.Bool("include-xdstp-name-in-lds-experimental", false, "whether or not to use xdstp style name for listener resource name template. Ignored if not used with include-federation-support-experimental flag. This flag is EXPERIMENTAL and may be changed or removed in a later release.") + xdsServerUri = flag.String("xds-server-uri", "trafficdirector.googleapis.com:443", "override of server uri, for testing") + outputName = flag.String("output", "-", "output file name") + gcpProjectNumber = flag.Int64("gcp-project-number", 0, "the gcp project number. If unknown, can be found via 'gcloud projects list'") + vpcNetworkName = flag.String("vpc-network-name", "default", "VPC network name") + localityZone = flag.String("locality-zone", "", "the locality zone to use, instead of retrieving it from the metadata server. Useful when not running on GCP and/or for testing") + ignoreResourceDeletion = flag.Bool("ignore-resource-deletion-experimental", false, "assume missing resources notify operators when using Traffic Director, as in gRFC A53. This is not currently the case. This flag is EXPERIMENTAL and may be changed or removed in a later release.") + secretsDir = flag.String("secrets-dir", "/var/run/secrets/workload-spiffe-credentials", "path to a directory containing TLS certificates and keys required for PSM security") + includeDeploymentInfo = flag.Bool("include-deployment-info-experimental", false, "whether or not to generate config which contains deployment related information. This flag is EXPERIMENTAL and may be changed or removed in a later release.") + gkeClusterName = flag.String("gke-cluster-name", "", "GKE cluster name to use, instead of retrieving it from the metadata server.") + gkePodName = flag.String("gke-pod-name-experimental", "", "GKE pod name to use, instead of reading it from $HOSTNAME or /etc/hostname file. This flag is EXPERIMENTAL and may be changed or removed in a later release.") + gkeNamespace = flag.String("gke-namespace-experimental", "", "GKE namespace to use. This flag is EXPERIMENTAL and may be changed or removed in a later release.") + gkeLocation = flag.String("gke-location-experimental", "", "the location (region/zone) of the cluster from which to pull configuration, instead of retrieving it from the metadata server. This value is used to generate the mesh ID. Ignored if not used with --generate-mesh-id. This flag is EXPERIMENTAL and may be changed or removed in a later release.") + gceVM = flag.String("gce-vm-experimental", "", "GCE VM name to use, instead of reading it from the metadata server. This flag is EXPERIMENTAL and may be changed or removed in a later release.") + configMesh = flag.String("config-mesh", "", "Dictates which Mesh resource to use.") + generateMeshId = flag.Bool("generate-mesh-id", false, "When enabled, the CSM MeshID is generated. If config-mesh flag is specified, this flag would be ignored. Location and Cluster Name would be retrieved from the metadata server unless specified via gke-location and gke-cluster-name flags respectively.") + includeXDSTPNameInLDS = flag.Bool("include-xdstp-name-in-lds-experimental", false, "whether or not to use xdstp style name for listener resource name template. This flag is EXPERIMENTAL and may be changed or removed in a later release.") ) func main() { @@ -177,20 +176,19 @@ func main() { } input := configInput{ - xdsServerUri: *xdsServerUri, - gcpProjectNumber: *gcpProjectNumber, - vpcNetworkName: *vpcNetworkName, - ip: ip, - zone: zone, - ignoreResourceDeletion: *ignoreResourceDeletion, - secretsDir: *secretsDir, - metadataLabels: nodeMetadata, - deploymentInfo: deploymentInfo, - configMesh: meshId, - includeDirectPathAuthority: *includeDirectPathAuthority, - ipv6Capable: isIPv6Capable(), - includeXDSTPNameInLDS: *includeXDSTPNameInLDS, - gitCommitHash: gitCommitHash, + xdsServerUri: *xdsServerUri, + gcpProjectNumber: *gcpProjectNumber, + vpcNetworkName: *vpcNetworkName, + ip: ip, + zone: zone, + ignoreResourceDeletion: *ignoreResourceDeletion, + secretsDir: *secretsDir, + metadataLabels: nodeMetadata, + deploymentInfo: deploymentInfo, + configMesh: meshId, + ipv6Capable: isIPv6Capable(), + includeXDSTPNameInLDS: *includeXDSTPNameInLDS, + gitCommitHash: gitCommitHash, } if err := validate(input); err != nil { @@ -231,20 +229,19 @@ func main() { } type configInput struct { - xdsServerUri string - gcpProjectNumber int64 - vpcNetworkName string - ip string - zone string - ignoreResourceDeletion bool - secretsDir string - metadataLabels map[string]string - deploymentInfo map[string]string - configMesh string - includeDirectPathAuthority bool - ipv6Capable bool - includeXDSTPNameInLDS bool - gitCommitHash string + xdsServerUri string + gcpProjectNumber int64 + vpcNetworkName string + ip string + zone string + ignoreResourceDeletion bool + secretsDir string + metadataLabels map[string]string + deploymentInfo map[string]string + configMesh string + ipv6Capable bool + includeXDSTPNameInLDS bool + gitCommitHash string } func validate(in configInput) error { @@ -288,6 +285,7 @@ func generate(in configInput) ([]byte, error) { "TRAFFICDIRECTOR_GRPC_BOOTSTRAP_GENERATOR_SHA": in.gitCommitHash, }, }, + Authorities: make(map[string]Authority), } for k, v := range in.metadataLabels { @@ -315,9 +313,6 @@ func generate(in configInput) ([]byte, error) { } if in.includeXDSTPNameInLDS { - if c.Authorities == nil { - c.Authorities = make(map[string]Authority) - } tdAuthority := "traffic-director-global.xds.googleapis.com" c.Authorities[tdAuthority] = Authority{ // Listener Resource Name format for normal TD usecases looks like: @@ -326,24 +321,19 @@ func generate(in configInput) ([]byte, error) { } } - if in.includeDirectPathAuthority { - if c.Authorities == nil { - c.Authorities = make(map[string]Authority) - } - c2pAuthority := "traffic-director-c2p.xds.googleapis.com" - c.Authorities[c2pAuthority] = Authority{ - // In the case of DirectPath, it is safe to assume that the operator is notified of missing resources. - // In other words, "ignore_resource_deletion" server_features is always set. - XdsServers: []server{{ - ServerUri: "dns:///directpath-pa.googleapis.com", - ChannelCreds: []creds{{Type: "google_default"}}, - ServerFeatures: []string{"xds_v3", "ignore_resource_deletion"}, - }}, - ClientListenerResourceNameTemplate: fmt.Sprintf("xdstp://%s/envoy.config.listener.v3.Listener/%%s", c2pAuthority), - } - if in.ipv6Capable { - c.Node.Metadata["TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE"] = true - } + c2pAuthority := "traffic-director-c2p.xds.googleapis.com" + c.Authorities[c2pAuthority] = Authority{ + // In the case of DirectPath, it is safe to assume that the operator is notified of missing resources. + // In other words, "ignore_resource_deletion" server_features is always set. + XdsServers: []server{{ + ServerUri: "dns:///directpath-pa.googleapis.com", + ChannelCreds: []creds{{Type: "google_default"}}, + ServerFeatures: []string{"xds_v3", "ignore_resource_deletion"}, + }}, + ClientListenerResourceNameTemplate: fmt.Sprintf("xdstp://%s/envoy.config.listener.v3.Listener/%%s", c2pAuthority), + } + if in.ipv6Capable { + c.Node.Metadata["TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE"] = true } return json.MarshalIndent(c, "", " ") diff --git a/main_test.go b/main_test.go index 25dde27..c769ebb 100644 --- a/main_test.go +++ b/main_test.go @@ -128,6 +128,25 @@ func TestGenerate(t *testing.T) { ] } ], + "authorities": { + "traffic-director-c2p.xds.googleapis.com": { + "xds_servers": [ + { + "server_uri": "dns:///directpath-pa.googleapis.com", + "channel_creds": [ + { + "type": "google_default" + } + ], + "server_features": [ + "xds_v3", + "ignore_resource_deletion" + ] + } + ], + "client_listener_resource_name_template": "xdstp://traffic-director-c2p.xds.googleapis.com/envoy.config.listener.v3.Listener/%s" + } + }, "node": { "id": "projects/123456789012345/networks/thedefault/nodes/52fdfc07-2182-454f-963f-5f0f9a621d72", "cluster": "cluster", @@ -180,6 +199,25 @@ func TestGenerate(t *testing.T) { ] } ], + "authorities": { + "traffic-director-c2p.xds.googleapis.com": { + "xds_servers": [ + { + "server_uri": "dns:///directpath-pa.googleapis.com", + "channel_creds": [ + { + "type": "google_default" + } + ], + "server_features": [ + "xds_v3", + "ignore_resource_deletion" + ] + } + ], + "client_listener_resource_name_template": "xdstp://traffic-director-c2p.xds.googleapis.com/envoy.config.listener.v3.Listener/%s" + } + }, "node": { "id": "projects/123456789012345/networks/thedefault/nodes/52fdfc07-2182-454f-963f-5f0f9a621d72", "cluster": "cluster", @@ -237,6 +275,25 @@ func TestGenerate(t *testing.T) { ] } ], + "authorities": { + "traffic-director-c2p.xds.googleapis.com": { + "xds_servers": [ + { + "server_uri": "dns:///directpath-pa.googleapis.com", + "channel_creds": [ + { + "type": "google_default" + } + ], + "server_features": [ + "xds_v3", + "ignore_resource_deletion" + ] + } + ], + "client_listener_resource_name_template": "xdstp://traffic-director-c2p.xds.googleapis.com/envoy.config.listener.v3.Listener/%s" + } + }, "node": { "id": "projects/123456789012345/networks/thedefault/nodes/52fdfc07-2182-454f-963f-5f0f9a621d72", "cluster": "cluster", @@ -303,6 +360,25 @@ func TestGenerate(t *testing.T) { ] } ], + "authorities": { + "traffic-director-c2p.xds.googleapis.com": { + "xds_servers": [ + { + "server_uri": "dns:///directpath-pa.googleapis.com", + "channel_creds": [ + { + "type": "google_default" + } + ], + "server_features": [ + "xds_v3", + "ignore_resource_deletion" + ] + } + ], + "client_listener_resource_name_template": "xdstp://traffic-director-c2p.xds.googleapis.com/envoy.config.listener.v3.Listener/%s" + } + }, "node": { "id": "projects/123456789012345/networks/mesh:testmesh/nodes/52fdfc07-2182-454f-963f-5f0f9a621d72", "cluster": "cluster", @@ -362,57 +438,6 @@ func TestGenerate(t *testing.T) { ] } ], - "node": { - "id": "projects/123456789012345/networks/thedefault/nodes/52fdfc07-2182-454f-963f-5f0f9a621d72", - "cluster": "cluster", - "metadata": { - "INSTANCE_IP": "10.9.8.7", - "TRAFFICDIRECTOR_GRPC_BOOTSTRAP_GENERATOR_SHA": "7202b7c611ebd6d382b7b0240f50e9824200bffd" - }, - "locality": { - "zone": "uscentral-5" - } - }, - "certificate_providers": { - "google_cloud_private_spiffe": { - "plugin_name": "file_watcher", - "config": { - "certificate_file": "certificates.pem", - "private_key_file": "private_key.pem", - "ca_certificate_file": "ca_certificates.pem", - "refresh_interval": "600s" - } - } - }, - "server_listener_resource_name_template": "grpc/server?xds.resource.listening_address=%s" -}`, - }, - { - desc: "happy case with federation support of c2p authority included", - input: configInput{ - xdsServerUri: "example.com:443", - gcpProjectNumber: 123456789012345, - vpcNetworkName: "thedefault", - ip: "10.9.8.7", - zone: "uscentral-5", - includeDirectPathAuthority: true, - ipv6Capable: true, - gitCommitHash: "7202b7c611ebd6d382b7b0240f50e9824200bffd", - }, - wantOutput: `{ - "xds_servers": [ - { - "server_uri": "example.com:443", - "channel_creds": [ - { - "type": "google_default" - } - ], - "server_features": [ - "xds_v3" - ] - } - ], "authorities": { "traffic-director-c2p.xds.googleapis.com": { "xds_servers": [ @@ -437,7 +462,6 @@ func TestGenerate(t *testing.T) { "cluster": "cluster", "metadata": { "INSTANCE_IP": "10.9.8.7", - "TRAFFICDIRECTOR_DIRECTPATH_C2P_IPV6_CAPABLE": true, "TRAFFICDIRECTOR_GRPC_BOOTSTRAP_GENERATOR_SHA": "7202b7c611ebd6d382b7b0240f50e9824200bffd" }, "locality": { @@ -459,17 +483,16 @@ func TestGenerate(t *testing.T) { }`, }, { - desc: "happy case with federation support of c2p along with regular TD using xdstp style name", + desc: "happy case with federation support with TDOM using xdstp style name", input: configInput{ - xdsServerUri: "trafficdirector.googleapis.com:443", - gcpProjectNumber: 123456789012345, - vpcNetworkName: "thedefault", - ip: "10.9.8.7", - zone: "uscentral-5", - includeDirectPathAuthority: true, - ipv6Capable: true, - includeXDSTPNameInLDS: true, - gitCommitHash: "7202b7c611ebd6d382b7b0240f50e9824200bffd", + xdsServerUri: "trafficdirector.googleapis.com:443", + gcpProjectNumber: 123456789012345, + vpcNetworkName: "thedefault", + ip: "10.9.8.7", + zone: "uscentral-5", + ipv6Capable: true, + includeXDSTPNameInLDS: true, + gitCommitHash: "7202b7c611ebd6d382b7b0240f50e9824200bffd", }, wantOutput: `{ "xds_servers": [