Skip to content

Commit

Permalink
Allow specify the path for SDS k8s token (istio#11460)
Browse files Browse the repository at this point in the history
* Allow specify SDS token path

* Change the default value to empty string

* Rephrase the comment for sds token path

* Address review comments

* Change to use node metadata to pass SDS token path

* Address review comments (e.g., remove static variable)

* Use SDS token path if it is set
  • Loading branch information
lei-tang authored and smawson committed Feb 12, 2019
1 parent 10bff33 commit 5836158
Show file tree
Hide file tree
Showing 5 changed files with 36 additions and 26 deletions.
11 changes: 8 additions & 3 deletions pilot/pkg/model/authentication.go
Expand Up @@ -105,7 +105,7 @@ func ConstructSdsSecretConfigForGatewayListener(name, sdsUdsPath string) *auth.S
}

// ConstructSdsSecretConfig constructs SDS Sececret Configuration for workload proxy.
func ConstructSdsSecretConfig(name, sdsUdsPath string, useK8sSATrustworthyJwt, useK8sSANormalJwt bool) *auth.SdsSecretConfig {
func ConstructSdsSecretConfig(name, sdsUdsPath string, useK8sSATrustworthyJwt, useK8sSANormalJwt bool, metadata map[string]string) *auth.SdsSecretConfig {
if name == "" || sdsUdsPath == "" {
return nil
}
Expand All @@ -120,10 +120,15 @@ func ConstructSdsSecretConfig(name, sdsUdsPath string, useK8sSATrustworthyJwt, u
},
}

// If useK8sSATrustworthyJwt is set, envoy will fetch and pass k8s sa trustworthy jwt(which is available for k8s 1.10 or higher),
// If metadata[NodeMetadataSdsTokenPath] is non-empty, envoy will fetch tokens from metadata[NodeMetadataSdsTokenPath].
// Otherwise, if useK8sSATrustworthyJwt is set, envoy will fetch and pass k8s sa trustworthy jwt(which is available for k8s 1.10 or higher),
// pass it to SDS server to request key/cert; if trustworthy jwt isn't available, envoy will fetch and pass normal k8s sa jwt to
// request key/cert.
if useK8sSATrustworthyJwt {
if sdsTokenPath, found := metadata[NodeMetadataSdsTokenPath]; found && len(sdsTokenPath) > 0 {
log.Debugf("SDS token path is (%v)", sdsTokenPath)
gRPCConfig.CredentialsFactoryName = fileBasedMetadataPlugName
gRPCConfig.CallCredentials = constructgRPCCallCredentials(sdsTokenPath, k8sSAJwtTokenHeaderKey)
} else if useK8sSATrustworthyJwt {
gRPCConfig.CredentialsFactoryName = fileBasedMetadataPlugName
gRPCConfig.CallCredentials = constructgRPCCallCredentials(K8sSATrustworthyJwtFileName, k8sSAJwtTokenHeaderKey)
} else if useK8sSANormalJwt {
Expand Down
3 changes: 2 additions & 1 deletion pilot/pkg/model/authentication_test.go
Expand Up @@ -114,6 +114,7 @@ func TestConstructSdsSecretConfig(t *testing.T) {
expected *auth.SdsSecretConfig
useTrustworthyJwt bool
useNormalJwt bool
metadata map[string]string
}{
{
serviceAccount: "spiffe://cluster.local/ns/bar/sa/foo",
Expand Down Expand Up @@ -175,7 +176,7 @@ func TestConstructSdsSecretConfig(t *testing.T) {
}

for _, c := range cases {
if got := ConstructSdsSecretConfig(c.serviceAccount, c.sdsUdsPath, c.useTrustworthyJwt, c.useNormalJwt); !reflect.DeepEqual(got, c.expected) {
if got := ConstructSdsSecretConfig(c.serviceAccount, c.sdsUdsPath, c.useTrustworthyJwt, c.useNormalJwt, c.metadata); !reflect.DeepEqual(got, c.expected) {
t.Errorf("ConstructSdsSecretConfig: got(%#v) != want(%#v)\n", got, c.expected)
}
}
Expand Down
4 changes: 4 additions & 0 deletions pilot/pkg/model/context.go
Expand Up @@ -521,6 +521,10 @@ const (

// NodeMetadataInstanceIPs is the set of IPs attached to this proxy
NodeMetadataInstanceIPs = "INSTANCE_IPS"

// NodeMetadataSdsTokenPath specifies the path of the SDS token used by the Enovy proxy.
// If not set, Pilot uses the default SDS token path.
NodeMetadataSdsTokenPath = "SDS_TOKEN_PATH"
)

// TrafficInterceptionMode indicates how traffic to/from the workload is captured and
Expand Down
40 changes: 20 additions & 20 deletions pilot/pkg/networking/core/v1alpha3/cluster.go
Expand Up @@ -194,7 +194,7 @@ func (configgen *ConfigGeneratorImpl) buildOutboundClusters(env *model.Environme
discoveryType := convertResolution(service.Resolution)
clusterName := model.BuildSubsetKey(model.TrafficDirectionOutbound, "", service.Hostname, port.Port)
serviceAccounts := env.ServiceAccounts.GetIstioServiceAccounts(service.Hostname, []int{port.Port})
defaultCluster := buildDefaultCluster(env, clusterName, discoveryType, lbEndpoints, model.TrafficDirectionOutbound)
defaultCluster := buildDefaultCluster(env, clusterName, discoveryType, lbEndpoints, model.TrafficDirectionOutbound, proxy.Metadata)

updateEds(defaultCluster)
setUpstreamProtocol(defaultCluster, port)
Expand All @@ -204,7 +204,7 @@ func (configgen *ConfigGeneratorImpl) buildOutboundClusters(env *model.Environme
destinationRule := config.Spec.(*networking.DestinationRule)
defaultSni := model.BuildDNSSrvSubsetKey(model.TrafficDirectionOutbound, "", service.Hostname, port.Port)
applyTrafficPolicy(env, defaultCluster, destinationRule.TrafficPolicy, port, serviceAccounts,
defaultSni, DefaultClusterMode, model.TrafficDirectionOutbound)
defaultSni, DefaultClusterMode, model.TrafficDirectionOutbound, proxy.Metadata)
defaultCluster.Metadata = util.BuildConfigInfoMetadata(config.ConfigMeta)
for _, subset := range destinationRule.Subsets {
inputParams.Subset = subset.Name
Expand All @@ -216,13 +216,13 @@ func (configgen *ConfigGeneratorImpl) buildOutboundClusters(env *model.Environme
if discoveryType != apiv2.Cluster_EDS && len(subset.Labels) != 0 {
lbEndpoints = buildLocalityLbEndpoints(env, networkView, service, port.Port, []model.Labels{subset.Labels})
}
subsetCluster := buildDefaultCluster(env, subsetClusterName, discoveryType, lbEndpoints, model.TrafficDirectionOutbound)
subsetCluster := buildDefaultCluster(env, subsetClusterName, discoveryType, lbEndpoints, model.TrafficDirectionOutbound, proxy.Metadata)
updateEds(subsetCluster)
setUpstreamProtocol(subsetCluster, port)
applyTrafficPolicy(env, subsetCluster, destinationRule.TrafficPolicy, port, serviceAccounts, defaultSni,
DefaultClusterMode, model.TrafficDirectionOutbound)
DefaultClusterMode, model.TrafficDirectionOutbound, proxy.Metadata)
applyTrafficPolicy(env, subsetCluster, subset.TrafficPolicy, port, serviceAccounts, defaultSni,
DefaultClusterMode, model.TrafficDirectionOutbound)
DefaultClusterMode, model.TrafficDirectionOutbound, proxy.Metadata)
subsetCluster.Metadata = util.BuildConfigInfoMetadata(config.ConfigMeta)
// call plugins
for _, p := range configgen.Plugins {
Expand Down Expand Up @@ -260,31 +260,30 @@ func (configgen *ConfigGeneratorImpl) buildOutboundSniDnatClusters(env *model.En
discoveryType := convertResolution(service.Resolution)

clusterName := model.BuildDNSSrvSubsetKey(model.TrafficDirectionOutbound, "", service.Hostname, port.Port)
defaultCluster := buildDefaultCluster(env, clusterName, discoveryType, lbEndpoints, model.TrafficDirectionOutbound)
defaultCluster := buildDefaultCluster(env, clusterName, discoveryType, lbEndpoints, model.TrafficDirectionOutbound, proxy.Metadata)
defaultCluster.TlsContext = nil
updateEds(defaultCluster)
clusters = append(clusters, defaultCluster)

if config != nil {
destinationRule := config.Spec.(*networking.DestinationRule)
applyTrafficPolicy(env, defaultCluster, destinationRule.TrafficPolicy, port, nil, "",
SniDnatClusterMode, model.TrafficDirectionOutbound)
SniDnatClusterMode, model.TrafficDirectionOutbound, proxy.Metadata)
defaultCluster.Metadata = util.BuildConfigInfoMetadata(config.ConfigMeta)

for _, subset := range destinationRule.Subsets {
subsetClusterName := model.BuildDNSSrvSubsetKey(model.TrafficDirectionOutbound, subset.Name, service.Hostname, port.Port)
// clusters with discovery type STATIC, STRICT_DNS or LOGICAL_DNS rely on cluster.hosts field
// ServiceEntry's need to filter hosts based on subset.labels in order to perform weighted routing
if discoveryType != apiv2.Cluster_EDS && len(subset.Labels) != 0 {
lbEndpoints = buildLocalityLbEndpoints(env, networkView, service, port.Port, []model.Labels{subset.Labels})
}
subsetCluster := buildDefaultCluster(env, subsetClusterName, discoveryType, lbEndpoints, model.TrafficDirectionOutbound)
subsetCluster := buildDefaultCluster(env, subsetClusterName, discoveryType, lbEndpoints, model.TrafficDirectionOutbound, proxy.Metadata)
subsetCluster.TlsContext = nil
updateEds(subsetCluster)
applyTrafficPolicy(env, subsetCluster, destinationRule.TrafficPolicy, port, nil, "",
SniDnatClusterMode, model.TrafficDirectionOutbound)
SniDnatClusterMode, model.TrafficDirectionOutbound, proxy.Metadata)
applyTrafficPolicy(env, subsetCluster, subset.TrafficPolicy, port, nil, "",
SniDnatClusterMode, model.TrafficDirectionOutbound)
SniDnatClusterMode, model.TrafficDirectionOutbound, proxy.Metadata)
subsetCluster.Metadata = util.BuildConfigInfoMetadata(config.ConfigMeta)
clusters = append(clusters, subsetCluster)
}
Expand Down Expand Up @@ -419,7 +418,7 @@ func (configgen *ConfigGeneratorImpl) buildInboundClusters(env *model.Environmen
ManagementClusterHostname, port.Port)
localityLbEndpoints := buildInboundLocalityLbEndpoints(LocalhostAddress, port.Port)
mgmtCluster := buildDefaultCluster(env, clusterName, apiv2.Cluster_STATIC, localityLbEndpoints,
model.TrafficDirectionInbound)
model.TrafficDirectionInbound, proxy.Metadata)
setUpstreamProtocol(mgmtCluster, port)
clusters = append(clusters, mgmtCluster)
}
Expand Down Expand Up @@ -529,7 +528,7 @@ func (configgen *ConfigGeneratorImpl) buildInboundClusterForPortOrUDS(pluginPara
instance.Service.Hostname, instance.Endpoint.ServicePort.Port)
localityLbEndpoints := buildInboundLocalityLbEndpoints(pluginParams.Bind, instance.Endpoint.Port)
localCluster := buildDefaultCluster(pluginParams.Env, clusterName, apiv2.Cluster_STATIC, localityLbEndpoints,
model.TrafficDirectionInbound)
model.TrafficDirectionInbound, pluginParams.Node.Metadata)
setUpstreamProtocol(localCluster, instance.Endpoint.ServicePort)
// call plugins
for _, p := range configgen.Plugins {
Expand Down Expand Up @@ -648,15 +647,16 @@ const (
// FIXME: There are too many variables here. Create a clusterOpts struct and stick the values in it, just like
// listenerOpts
func applyTrafficPolicy(env *model.Environment, cluster *apiv2.Cluster, policy *networking.TrafficPolicy,
port *model.Port, serviceAccounts []string, defaultSni string, clusterMode ClusterMode, direction model.TrafficDirection) {
port *model.Port, serviceAccounts []string, defaultSni string, clusterMode ClusterMode, direction model.TrafficDirection,
metadata map[string]string) {
connectionPool, outlierDetection, loadBalancer, tls := SelectTrafficPolicyComponents(policy, port)

applyConnectionPool(env, cluster, connectionPool, direction)
applyOutlierDetection(cluster, outlierDetection)
applyLoadBalancer(cluster, loadBalancer)
if clusterMode != SniDnatClusterMode {
tls = conditionallyConvertToIstioMtls(tls, serviceAccounts, defaultSni)
applyUpstreamTLSSettings(env, cluster, tls)
applyUpstreamTLSSettings(env, cluster, tls, metadata)
}
}

Expand Down Expand Up @@ -851,7 +851,7 @@ func applyLocalityLBSetting(
}
}

func applyUpstreamTLSSettings(env *model.Environment, cluster *apiv2.Cluster, tls *networking.TLSSettings) {
func applyUpstreamTLSSettings(env *model.Environment, cluster *apiv2.Cluster, tls *networking.TLSSettings, metadata map[string]string) {
if tls == nil {
return
}
Expand Down Expand Up @@ -923,13 +923,13 @@ func applyUpstreamTLSSettings(env *model.Environment, cluster *apiv2.Cluster, tl
}
} else {
cluster.TlsContext.CommonTlsContext.TlsCertificateSdsSecretConfigs = append(cluster.TlsContext.CommonTlsContext.TlsCertificateSdsSecretConfigs,
model.ConstructSdsSecretConfig(model.SDSDefaultResourceName, env.Mesh.SdsUdsPath, env.Mesh.EnableSdsTokenMount, env.Mesh.SdsUseK8SSaJwt))
model.ConstructSdsSecretConfig(model.SDSDefaultResourceName, env.Mesh.SdsUdsPath, env.Mesh.EnableSdsTokenMount, env.Mesh.SdsUseK8SSaJwt, metadata))

cluster.TlsContext.CommonTlsContext.ValidationContextType = &auth.CommonTlsContext_CombinedValidationContext{
CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
DefaultValidationContext: &auth.CertificateValidationContext{VerifySubjectAltName: tls.SubjectAltNames},
ValidationContextSdsSecretConfig: model.ConstructSdsSecretConfig(model.SDSRootResourceName, env.Mesh.SdsUdsPath,
env.Mesh.EnableSdsTokenMount, env.Mesh.SdsUseK8SSaJwt),
env.Mesh.EnableSdsTokenMount, env.Mesh.SdsUseK8SSaJwt, metadata),
},
}
}
Expand Down Expand Up @@ -990,7 +990,7 @@ func buildDefaultPassthroughCluster() *apiv2.Cluster {
// TODO: supply LbEndpoints or even better, LocalityLbEndpoints here
// change all other callsites accordingly
func buildDefaultCluster(env *model.Environment, name string, discoveryType apiv2.Cluster_DiscoveryType,
localityLbEndpoints []endpoint.LocalityLbEndpoints, direction model.TrafficDirection) *apiv2.Cluster {
localityLbEndpoints []endpoint.LocalityLbEndpoints, direction model.TrafficDirection, metadata map[string]string) *apiv2.Cluster {
cluster := &apiv2.Cluster{
Name: name,
Type: discoveryType,
Expand All @@ -1010,7 +1010,7 @@ func buildDefaultCluster(env *model.Environment, name string, discoveryType apiv

defaultTrafficPolicy := buildDefaultTrafficPolicy(env, discoveryType)
applyTrafficPolicy(env, cluster, defaultTrafficPolicy, nil, nil, "",
DefaultClusterMode, direction)
DefaultClusterMode, direction, metadata)
return cluster
}

Expand Down
4 changes: 2 additions & 2 deletions pilot/pkg/networking/plugin/authn/authentication.go
Expand Up @@ -130,13 +130,13 @@ func setupFilterChains(authnPolicy *authn.Policy, sdsUdsPath string, sdsUseTrust
}
} else {
tls.CommonTlsContext.TlsCertificateSdsSecretConfigs = []*auth.SdsSecretConfig{
model.ConstructSdsSecretConfig(model.SDSDefaultResourceName, sdsUdsPath, sdsUseTrustworthyJwt, sdsUseNormalJwt),
model.ConstructSdsSecretConfig(model.SDSDefaultResourceName, sdsUdsPath, sdsUseTrustworthyJwt, sdsUseNormalJwt, meta),
}

tls.CommonTlsContext.ValidationContextType = &auth.CommonTlsContext_CombinedValidationContext{
CombinedValidationContext: &auth.CommonTlsContext_CombinedCertificateValidationContext{
DefaultValidationContext: &auth.CertificateValidationContext{VerifySubjectAltName: []string{} /*subjectAltNames*/},
ValidationContextSdsSecretConfig: model.ConstructSdsSecretConfig(model.SDSRootResourceName, sdsUdsPath, sdsUseTrustworthyJwt, sdsUseNormalJwt),
ValidationContextSdsSecretConfig: model.ConstructSdsSecretConfig(model.SDSRootResourceName, sdsUdsPath, sdsUseTrustworthyJwt, sdsUseNormalJwt, meta),
},
}
}
Expand Down

0 comments on commit 5836158

Please sign in to comment.