Update check to use new linkerd-config.values (#5023)

This branch updates the check functionality to read
the new `linkerd-config.values` which contains the full
Values struct showing the current state of the Linkerd
installation. (being added in #5020 )

This is done by adding a new `FetchCurrentConfiguraiton`
which first tries to get the latest, if not falls back
to the older `linkerd-config` protobuf format.`

Signed-off-by: Tarun Pothulapati <tarunpothulapati@outlook.com>
This commit is contained in:
Tarun Pothulapati 2020-10-01 23:49:25 +05:30 committed by GitHub
parent 6b7a39c9fa
commit faf77798f0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 466 additions and 45 deletions

View File

@ -27,12 +27,12 @@ support, verify "kubectl api-versions" outputs "linkerd.io/v1alpha2".`,
return err
}
_, configs, err := healthcheck.FetchLinkerdConfigMap(cmd.Context(), k8sAPI, controlPlaneNamespace)
_, values, err := healthcheck.FetchCurrentConfiguration(cmd.Context(), k8sAPI, controlPlaneNamespace)
if err != nil {
return err
}
clusterDomain := configs.GetGlobal().GetClusterDomain()
clusterDomain := values.Global.ClusterDomain
if clusterDomain == "" {
clusterDomain = defaultClusterDomain
}

View File

@ -1124,7 +1124,7 @@ func errIfLinkerdConfigConfigMapExists(ctx context.Context) error {
return err
}
_, _, err = healthcheck.FetchLinkerdConfigMap(ctx, kubeAPI, controlPlaneNamespace)
_, _, err = healthcheck.FetchCurrentConfiguration(ctx, kubeAPI, controlPlaneNamespace)
if err != nil {
if kerrors.IsNotFound(err) {
return nil

View File

@ -9,9 +9,9 @@ import (
"strings"
"github.com/linkerd/linkerd2/cli/table"
configPb "github.com/linkerd/linkerd2/controller/gen/config"
pb "github.com/linkerd/linkerd2/controller/gen/public"
"github.com/linkerd/linkerd2/pkg/charts"
"github.com/linkerd/linkerd2/pkg/charts/linkerd2"
"github.com/linkerd/linkerd2/pkg/charts/multicluster"
mccharts "github.com/linkerd/linkerd2/pkg/charts/multicluster"
"github.com/linkerd/linkerd2/pkg/healthcheck"
@ -116,18 +116,18 @@ func newLinkOptionsWithDefault() (*linkOptions, error) {
}, nil
}
func getLinkerdConfigMap(ctx context.Context) (*configPb.All, error) {
func getLinkerdConfigMap(ctx context.Context) (*linkerd2.Values, error) {
kubeAPI, err := k8s.NewAPI(kubeconfigPath, kubeContext, impersonate, impersonateGroup, 0)
if err != nil {
return nil, err
}
_, global, err := healthcheck.FetchLinkerdConfigMap(ctx, kubeAPI, controlPlaneNamespace)
_, values, err := healthcheck.FetchCurrentConfiguration(ctx, kubeAPI, controlPlaneNamespace)
if err != nil {
return nil, err
}
return global, nil
return values, nil
}
func buildServiceMirrorValues(opts *linkOptions) (*multicluster.Values, error) {
@ -165,7 +165,7 @@ func buildServiceMirrorValues(opts *linkOptions) (*multicluster.Values, error) {
func buildMulticlusterInstallValues(ctx context.Context, opts *multiclusterInstallOptions) (*multicluster.Values, error) {
global, err := getLinkerdConfigMap(ctx)
values, err := getLinkerdConfigMap(ctx)
if err != nil {
if kerrors.IsNotFound(err) {
return nil, errors.New("you need Linkerd to be installed in order to install multicluster addons")
@ -193,9 +193,9 @@ func buildMulticlusterInstallValues(ctx context.Context, opts *multiclusterInsta
defaults.GatewayProbePort = opts.gatewayProbePort
defaults.GatewayNginxImage = opts.gatewayNginxImage
defaults.GatewayNginxImageVersion = opts.gatewayNginxVersion
defaults.IdentityTrustDomain = global.Global.IdentityContext.TrustDomain
defaults.IdentityTrustDomain = values.Global.IdentityTrustDomain
defaults.LinkerdNamespace = controlPlaneNamespace
defaults.ProxyOutboundPort = global.Proxy.OutboundPort.Port
defaults.ProxyOutboundPort = uint32(values.Global.Proxy.Ports.Outbound)
defaults.LinkerdVersion = version.Version
defaults.RemoteMirrorServiceAccount = opts.remoteMirrorCredentials

View File

@ -105,12 +105,12 @@ func newCmdProfile() *cobra.Command {
return err
}
_, configs, err := healthcheck.FetchLinkerdConfigMap(cmd.Context(), k8sAPI, controlPlaneNamespace)
_, values, err := healthcheck.FetchCurrentConfiguration(cmd.Context(), k8sAPI, controlPlaneNamespace)
if err != nil {
return err
}
clusterDomain := configs.GetGlobal().GetClusterDomain()
clusterDomain := values.Global.ClusterDomain
if clusterDomain == "" {
clusterDomain = defaultClusterDomain
}

View File

@ -8,6 +8,7 @@ import (
"github.com/golang/protobuf/jsonpb"
"github.com/golang/protobuf/proto"
pb "github.com/linkerd/linkerd2/controller/gen/config"
l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
log "github.com/sirupsen/logrus"
)
@ -96,3 +97,110 @@ func ToJSON(configs *pb.All) (global, proxy, install string, err error) {
install, err = m.MarshalToString(configs.GetInstall())
return
}
// ToValues converts configuration into a Values struct, i.e to be consumed by check
// TODO: Remove this once the newer configuration becomes the default i.e 2.10
func ToValues(configs *pb.All) *l5dcharts.Values {
// convert install flags into values
values := &l5dcharts.Values{
Global: &l5dcharts.Global{
CNIEnabled: configs.GetGlobal().GetCniEnabled(),
Namespace: configs.GetGlobal().GetLinkerdNamespace(),
IdentityTrustAnchorsPEM: configs.GetGlobal().GetIdentityContext().GetTrustAnchorsPem(),
IdentityTrustDomain: configs.GetGlobal().GetIdentityContext().GetTrustDomain(),
ClusterDomain: configs.GetGlobal().GetClusterDomain(),
LinkerdVersion: configs.GetGlobal().GetVersion(),
Proxy: &l5dcharts.Proxy{
Image: &l5dcharts.Image{
Name: configs.GetProxy().GetProxyImage().GetImageName(),
PullPolicy: configs.GetProxy().GetProxyImage().GetPullPolicy(),
Version: configs.GetProxy().GetProxyVersion(),
},
Ports: &l5dcharts.Ports{
Control: int32(configs.GetProxy().GetControlPort().GetPort()),
Inbound: int32(configs.GetProxy().GetInboundPort().GetPort()),
Admin: int32(configs.GetProxy().GetAdminPort().GetPort()),
Outbound: int32(configs.GetProxy().GetOutboundPort().GetPort()),
},
Resources: &l5dcharts.Resources{
CPU: l5dcharts.Constraints{
Limit: configs.GetProxy().GetResource().GetLimitCpu(),
Request: configs.GetProxy().GetResource().GetRequestCpu(),
},
Memory: l5dcharts.Constraints{
Limit: configs.GetProxy().GetResource().GetLimitMemory(),
Request: configs.GetProxy().GetResource().GetRequestMemory(),
},
},
EnableExternalProfiles: !configs.Proxy.GetDisableExternalProfiles(),
DestinationGetNetworks: configs.GetProxy().GetDestinationGetNetworks(),
LogFormat: configs.GetProxy().GetLogFormat(),
OutboundConnectTimeout: configs.GetProxy().GetOutboundConnectTimeout(),
InboundConnectTimeout: configs.GetProxy().GetInboundConnectTimeout(),
},
ProxyInit: &l5dcharts.ProxyInit{
IgnoreInboundPorts: toString(configs.GetProxy().GetIgnoreInboundPorts()),
IgnoreOutboundPorts: toString(configs.GetProxy().GetIgnoreOutboundPorts()),
Image: &l5dcharts.Image{
Name: configs.GetProxy().GetProxyInitImage().GetImageName(),
PullPolicy: configs.GetProxy().GetProxyInitImage().GetPullPolicy(),
Version: configs.GetProxy().GetProxyInitImageVersion(),
},
},
},
Identity: &l5dcharts.Identity{
Issuer: &l5dcharts.Issuer{
Scheme: configs.GetGlobal().GetIdentityContext().GetScheme(),
},
},
OmitWebhookSideEffects: configs.GetGlobal().GetOmitWebhookSideEffects(),
DebugContainer: &l5dcharts.DebugContainer{
Image: &l5dcharts.Image{
Name: configs.GetProxy().GetDebugImage().GetImageName(),
PullPolicy: configs.GetProxy().GetDebugImage().GetPullPolicy(),
Version: configs.GetProxy().GetDebugImageVersion(),
},
},
}
// for non-primitive types set only if they are not nil
if configs.GetGlobal().GetIdentityContext().GetIssuanceLifetime() != nil {
values.Identity.Issuer.IssuanceLifetime = configs.GetGlobal().GetIdentityContext().GetIssuanceLifetime().String()
}
if configs.GetGlobal().GetIdentityContext().GetClockSkewAllowance() != nil {
values.Identity.Issuer.ClockSkewAllowance = configs.GetGlobal().GetIdentityContext().GetClockSkewAllowance().String()
}
if configs.GetProxy().GetLogLevel() != nil {
values.Global.Proxy.LogLevel = configs.GetProxy().GetLogLevel().String()
}
// set HA, and Heartbeat flags as health-check needs them for old config installs
for _, flag := range configs.GetInstall().GetFlags() {
if flag.GetName() == "ha" && flag.GetValue() == "true" {
values.Global.HighAvailability = true
}
if flag.GetName() == "disable-heartbeat" && flag.GetValue() == "true" {
values.DisableHeartBeat = true
}
}
return values
}
func toString(portRanges []*pb.PortRange) string {
var portRangeString string
if len(portRanges) > 0 {
for i := 0; i < len(portRanges)-1; i++ {
portRangeString += portRanges[i].GetPortRange() + ","
}
portRangeString += portRanges[len(portRanges)-1].GetPortRange()
}
return portRangeString
}

View File

@ -15,6 +15,7 @@ import (
healthcheckPb "github.com/linkerd/linkerd2/controller/gen/common/healthcheck"
configPb "github.com/linkerd/linkerd2/controller/gen/config"
pb "github.com/linkerd/linkerd2/controller/gen/public"
l5dcharts "github.com/linkerd/linkerd2/pkg/charts/linkerd2"
"github.com/linkerd/linkerd2/pkg/config"
"github.com/linkerd/linkerd2/pkg/identity"
"github.com/linkerd/linkerd2/pkg/issuercerts"
@ -371,7 +372,7 @@ type HealthChecker struct {
apiClient public.APIClient
latestVersions version.Channels
serverVersion string
linkerdConfig *configPb.All
linkerdConfig *l5dcharts.Values
uuid string
issuerCert *tls.Cred
trustAnchors []*x509.Certificate
@ -617,8 +618,9 @@ func (hc *HealthChecker) allCategories() []category {
fatal: true,
check: func(ctx context.Context) (err error) {
hc.uuid, hc.linkerdConfig, err = hc.checkLinkerdConfigConfigMap(ctx)
if hc.linkerdConfig != nil {
hc.CNIEnabled = hc.linkerdConfig.Global.CniEnabled
hc.CNIEnabled = hc.linkerdConfig.Global.CNIEnabled
}
return
},
@ -1385,7 +1387,7 @@ func (hc *HealthChecker) checkMinReplicasAvailable(ctx context.Context) error {
}
func (hc *HealthChecker) issuerIdentity() string {
return fmt.Sprintf("identity.%s.%s", hc.ControlPlaneNamespace, hc.linkerdConfig.Global.IdentityContext.TrustDomain)
return fmt.Sprintf("identity.%s.%s", hc.ControlPlaneNamespace, hc.linkerdConfig.Global.IdentityTrustDomain)
}
// Add adds an arbitrary checker. This should only be used for testing. For
@ -1572,13 +1574,13 @@ func (hc *HealthChecker) PublicAPIClient() public.APIClient {
return hc.apiClient
}
func (hc *HealthChecker) checkLinkerdConfigConfigMap(ctx context.Context) (string, *configPb.All, error) {
cm, configPB, err := FetchLinkerdConfigMap(ctx, hc.kubeAPI, hc.ControlPlaneNamespace)
func (hc *HealthChecker) checkLinkerdConfigConfigMap(ctx context.Context) (string, *l5dcharts.Values, error) {
configMap, values, err := FetchCurrentConfiguration(ctx, hc.kubeAPI, hc.ControlPlaneNamespace)
if err != nil {
return "", nil, err
}
return string(cm.GetUID()), configPB, nil
return string(configMap.GetUID()), values, nil
}
// Checks whether the configuration of the linkerd-identity-issuer is correct. This means:
@ -1587,20 +1589,19 @@ func (hc *HealthChecker) checkLinkerdConfigConfigMap(ctx context.Context) (strin
// 3. The trust anchors (if scheme == kubernetes.io/tls) in the secret equal the ones in config
// 4. The certs and key are parsable
func (hc *HealthChecker) checkCertificatesConfig(ctx context.Context) (*tls.Cred, []*x509.Certificate, error) {
_, configPB, err := FetchLinkerdConfigMap(ctx, hc.kubeAPI, hc.ControlPlaneNamespace)
_, values, err := FetchCurrentConfiguration(ctx, hc.kubeAPI, hc.ControlPlaneNamespace)
if err != nil {
return nil, nil, err
}
idctx := configPB.Global.IdentityContext
var data *issuercerts.IssuerCertData
if idctx.Scheme == "" || idctx.Scheme == k8s.IdentityIssuerSchemeLinkerd {
data, err = issuercerts.FetchIssuerData(ctx, hc.kubeAPI, idctx.TrustAnchorsPem, hc.ControlPlaneNamespace)
if values.Identity.Issuer.Scheme == "" || values.Identity.Issuer.Scheme == k8s.IdentityIssuerSchemeLinkerd {
data, err = issuercerts.FetchIssuerData(ctx, hc.kubeAPI, values.Global.IdentityTrustAnchorsPEM, hc.ControlPlaneNamespace)
} else {
data, err = issuercerts.FetchExternalIssuerData(ctx, hc.kubeAPI, hc.ControlPlaneNamespace)
// ensure trust anchors in config matches what's in the secret
if data != nil && strings.TrimSpace(idctx.TrustAnchorsPem) != strings.TrimSpace(data.TrustAnchors) {
if data != nil && strings.TrimSpace(values.Global.IdentityTrustAnchorsPEM) != strings.TrimSpace(data.TrustAnchors) {
errFormat := "IdentityContext.TrustAnchorsPem does not match %s in %s"
err = fmt.Errorf(errFormat, k8s.IdentityIssuerTrustAnchorsNameExternal, k8s.IdentityIssuerSecretName)
}
@ -1623,6 +1624,29 @@ func (hc *HealthChecker) checkCertificatesConfig(ctx context.Context) (*tls.Cred
return issuerCreds, anchors, nil
}
// FetchCurrentConfiguration retrieves the current Linkerd configuration
func FetchCurrentConfiguration(ctx context.Context, k kubernetes.Interface, controlPlaneNamespace string) (*corev1.ConfigMap, *l5dcharts.Values, error) {
// Get the linkerd-config values if present
configMap, configPb, err := FetchLinkerdConfigMap(ctx, k, controlPlaneNamespace)
if err != nil {
return nil, nil, err
}
if rawValues := configMap.Data["values"]; rawValues != "" {
var fullValues l5dcharts.Values
err = yaml.Unmarshal([]byte(rawValues), &fullValues)
if err != nil {
return nil, nil, err
}
return configMap, &fullValues, nil
}
// fall back to the older configMap
// TODO: remove this once the newer config override secret becomes the default i.e 2.10
return configMap, config.ToValues(configPb), nil
}
func (hc *HealthChecker) fetchProxyInjectorCaBundle(ctx context.Context) ([]*x509.Certificate, error) {
mwh, err := hc.getProxyInjectorMutatingWebhook(ctx)
if err != nil {
@ -1846,21 +1870,11 @@ func (hc *HealthChecker) checkClusterRoleBindings(ctx context.Context, shouldExi
}
func (hc *HealthChecker) isHA() bool {
for _, flag := range hc.linkerdConfig.GetInstall().GetFlags() {
if flag.GetName() == "ha" && flag.GetValue() == "true" {
return true
}
}
return false
return hc.linkerdConfig.Global.HighAvailability
}
func (hc *HealthChecker) isHeartbeatDisabled() bool {
for _, flag := range hc.linkerdConfig.GetInstall().GetFlags() {
if flag.GetName() == "disable-heartbeat" && flag.GetValue() == "true" {
return true
}
}
return false
return hc.linkerdConfig.DisableHeartBeat
}
func (hc *HealthChecker) checkServiceAccounts(ctx context.Context, saNames []string, ns, labelSelector string) error {
@ -2013,12 +2027,12 @@ func (hc *HealthChecker) checkDataPlaneProxiesCertificate(ctx context.Context) e
return err
}
_, configPB, err := FetchLinkerdConfigMap(ctx, hc.kubeAPI, hc.ControlPlaneNamespace)
_, values, err := FetchCurrentConfiguration(ctx, hc.kubeAPI, hc.ControlPlaneNamespace)
if err != nil {
return err
}
trustAnchorsPem := configPB.GetGlobal().GetIdentityContext().GetTrustAnchorsPem()
trustAnchorsPem := values.Global.IdentityTrustAnchorsPEM
offendingPods := []string{}
for _, pod := range meshedPods {
if strings.TrimSpace(pod.Anchors) != strings.TrimSpace(trustAnchorsPem) {

View File

@ -341,7 +341,7 @@ func (hc *HealthChecker) checkRemoteClusterConnectivity(ctx context.Context) err
}
func (hc *HealthChecker) checkRemoteClusterAnchors(ctx context.Context) error {
localAnchors, err := tls.DecodePEMCertificates(hc.linkerdConfig.Global.IdentityContext.TrustAnchorsPem)
localAnchors, err := tls.DecodePEMCertificates(hc.linkerdConfig.Global.IdentityTrustAnchorsPEM)
if err != nil {
return fmt.Errorf("Cannot parse source trust anchors: %s", err)
}
@ -373,13 +373,13 @@ func (hc *HealthChecker) checkRemoteClusterAnchors(ctx context.Context) error {
continue
}
_, cfMap, err := FetchLinkerdConfigMap(ctx, remoteAPI, link.TargetClusterLinkerdNamespace)
_, values, err := FetchCurrentConfiguration(ctx, remoteAPI, link.TargetClusterLinkerdNamespace)
if err != nil {
errors = append(errors, fmt.Sprintf("* %s: unable to fetch anchors: %s", link.TargetClusterName, err))
continue
}
remoteAnchors, err := tls.DecodePEMCertificates(cfMap.Global.IdentityContext.TrustAnchorsPem)
remoteAnchors, err := tls.DecodePEMCertificates(values.Global.IdentityTrustAnchorsPEM)
if err != nil {
errors = append(errors, fmt.Sprintf("* %s: cannot parse trust anchors", link.TargetClusterName))
continue

View File

@ -11,18 +11,18 @@ import (
"testing"
"time"
"github.com/linkerd/linkerd2/pkg/issuercerts"
"github.com/linkerd/linkerd2/pkg/tls"
"github.com/linkerd/linkerd2/testutil"
"github.com/golang/protobuf/proto"
"github.com/golang/protobuf/ptypes/duration"
"github.com/linkerd/linkerd2/controller/api/public"
healthcheckPb "github.com/linkerd/linkerd2/controller/gen/common/healthcheck"
configPb "github.com/linkerd/linkerd2/controller/gen/config"
pb "github.com/linkerd/linkerd2/controller/gen/public"
"github.com/linkerd/linkerd2/pkg/charts/linkerd2"
"github.com/linkerd/linkerd2/pkg/identity"
"github.com/linkerd/linkerd2/pkg/issuercerts"
"github.com/linkerd/linkerd2/pkg/k8s"
"github.com/linkerd/linkerd2/pkg/tls"
"github.com/linkerd/linkerd2/testutil"
"google.golang.org/protobuf/proto"
corev1 "k8s.io/api/core/v1"
k8sErrors "k8s.io/apimachinery/pkg/api/errors"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
@ -2522,6 +2522,305 @@ data:
}
}
func TestFetchCurrentConfiguration(t *testing.T) {
defaultValues, err := linkerd2.NewValues(false)
if err != nil {
t.Fatalf("Unexpected error validating options: %v", err)
}
testCases := []struct {
k8sConfigs []string
expected *linkerd2.Values
err error
}{
{
[]string{`
kind: ConfigMap
apiVersion: v1
metadata:
name: linkerd-config
namespace: linkerd
data:
global: |
{"linkerdNamespace":"linkerd","cniEnabled":false,"version":"install-control-plane-version","identityContext":{"trustDomain":"cluster.local","trustAnchorsPem":"fake-trust-anchors-pem","issuanceLifetime":"86400s","clockSkewAllowance":"20s"}}
proxy: |
{"proxyImage":{"imageName":"ghcr.io/linkerd/proxy","pullPolicy":"IfNotPresent"},"proxyInitImage":{"imageName":"ghcr.io/linkerd/proxy-init","pullPolicy":"IfNotPresent"},"controlPort":{"port":4190},"ignoreInboundPorts":[],"ignoreOutboundPorts":[],"inboundPort":{"port":4143},"adminPort":{"port":4191},"outboundPort":{"port":4140},"resource":{"requestCpu":"","requestMemory":"","limitCpu":"","limitMemory":""},"proxyUid":"2102","logLevel":{"level":"warn,linkerd=info"},"disableExternalProfiles":true,"proxyVersion":"install-proxy-version","proxy_init_image_version":"v1.3.6","debugImage":{"imageName":"ghcr.io/linkerd/debug","pullPolicy":"IfNotPresent"},"debugImageVersion":"install-debug-version"}
install: |
{"cliVersion":"dev-undefined","flags":[]}
values: |
controllerImage: ControllerImage
controllerImageVersion: ""
controllerReplicas: 1
controllerUID: 2103
dashboard:
replicas: 1
debugContainer: null
destinationProxyResources: null
destinationResources: null
disableHeartBeat: false
enableH2Upgrade: true
enablePodAntiAffinity: false
global:
cliVersion: CliVersion
clusterDomain: cluster.local
cniEnabled: false
controlPlaneTracing: false
controllerComponentLabel: ControllerComponentLabel
controllerImageVersion: ControllerImageVersion
controllerLogLevel: ControllerLogLevel
controllerNamespaceLabel: ControllerNamespaceLabel
createdByAnnotation: CreatedByAnnotation
enableEndpointSlices: false
grafanaUrl: ""
highAvailability: false
identityTrustDomain: cluster.local
imagePullPolicy: ImagePullPolicy
imagePullSecrets: null
linkerdNamespaceLabel: LinkerdNamespaceLabel
linkerdVersion: ""
namespace: Namespace
prometheusUrl: ""
proxy:
capabilities: null
component: linkerd-controller
destinationGetNetworks: DestinationGetNetworks
disableIdentity: false
disableTap: false
enableExternalProfiles: false
image:
name: ProxyImageName
pullPolicy: ImagePullPolicy
version: ProxyVersion
inboundConnectTimeout: ""
isGateway: false
logFormat: plain
logLevel: warn,linkerd=info
opaquePorts: ""
outboundConnectTimeout: ""
ports:
admin: 4191
control: 4190
inbound: 4143
outbound: 4140
requireIdentityOnInboundPorts: ""
resources: null
saMountPath: null
trace:
collectorSvcAccount: ""
collectorSvcAddr: ""
uid: 2102
waitBeforeExitSeconds: 0
workloadKind: deployment
proxyContainerName: ProxyContainerName
proxyInit:
capabilities: null
closeWaitTimeoutSecs: 0
ignoreInboundPorts: ""
ignoreOutboundPorts: ""
image:
name: ProxyInitImageName
pullPolicy: ImagePullPolicy
version: ProxyInitVersion
resources:
cpu:
limit: 100m
request: 10m
memory:
limit: 50Mi
request: 10Mi
saMountPath: null
xtMountPath:
mountPath: /run
name: linkerd-proxy-init-xtables-lock
readOnly: false
proxyInjectAnnotation: ProxyInjectAnnotation
proxyInjectDisabled: ProxyInjectDisabled
workloadNamespaceLabel: WorkloadNamespaceLabel
grafana:
enabled: true
heartbeatResources: null
heartbeatSchedule: ""
identityProxyResources: null
identityResources: null
installNamespace: true
nodeSelector:
beta.kubernetes.io/os: linux
omitWebhookSideEffects: false
prometheus:
enabled: true
image: PrometheusImage
proxyInjectorProxyResources: null
proxyInjectorResources: null
publicAPIProxyResources: null
publicAPIResources: null
restrictDashboardPrivileges: false
spValidatorProxyResources: null
spValidatorResources: null
stage: ""
tapProxyResources: null
tapResources: null
tolerations: null
tracing:
enabled: false
webImage: WebImage
webProxyResources: null
webResources: null
webhookFailurePolicy: WebhookFailurePolicy
`,
},
&linkerd2.Values{
ControllerImage: "ControllerImage",
WebImage: "WebImage",
ControllerUID: 2103,
EnableH2Upgrade: true,
WebhookFailurePolicy: "WebhookFailurePolicy",
OmitWebhookSideEffects: false,
RestrictDashboardPrivileges: false,
InstallNamespace: true,
NodeSelector: defaultValues.NodeSelector,
Tolerations: defaultValues.Tolerations,
Global: &linkerd2.Global{
Namespace: "Namespace",
ClusterDomain: "cluster.local",
ImagePullPolicy: "ImagePullPolicy",
CliVersion: "CliVersion",
ControllerComponentLabel: "ControllerComponentLabel",
ControllerLogLevel: "ControllerLogLevel",
ControllerImageVersion: "ControllerImageVersion",
ControllerNamespaceLabel: "ControllerNamespaceLabel",
WorkloadNamespaceLabel: "WorkloadNamespaceLabel",
CreatedByAnnotation: "CreatedByAnnotation",
ProxyInjectAnnotation: "ProxyInjectAnnotation",
ProxyInjectDisabled: "ProxyInjectDisabled",
LinkerdNamespaceLabel: "LinkerdNamespaceLabel",
ProxyContainerName: "ProxyContainerName",
CNIEnabled: false,
IdentityTrustDomain: defaultValues.Global.IdentityTrustDomain,
Proxy: &linkerd2.Proxy{
Component: "linkerd-controller",
DestinationGetNetworks: "DestinationGetNetworks",
Image: &linkerd2.Image{
Name: "ProxyImageName",
PullPolicy: "ImagePullPolicy",
Version: "ProxyVersion",
},
LogLevel: "warn,linkerd=info",
LogFormat: "plain",
Ports: &linkerd2.Ports{
Admin: 4191,
Control: 4190,
Inbound: 4143,
Outbound: 4140,
},
UID: 2102,
Trace: &linkerd2.Trace{},
},
ProxyInit: &linkerd2.ProxyInit{
Image: &linkerd2.Image{
Name: "ProxyInitImageName",
PullPolicy: "ImagePullPolicy",
Version: "ProxyInitVersion",
},
Resources: &linkerd2.Resources{
CPU: linkerd2.Constraints{
Limit: "100m",
Request: "10m",
},
Memory: linkerd2.Constraints{
Limit: "50Mi",
Request: "10Mi",
},
},
XTMountPath: &linkerd2.VolumeMountPath{
MountPath: "/run",
Name: "linkerd-proxy-init-xtables-lock",
},
},
},
ControllerReplicas: 1,
Dashboard: &linkerd2.Dashboard{
Replicas: 1,
},
Prometheus: linkerd2.Prometheus{
"enabled": true,
"image": "PrometheusImage",
},
Tracing: map[string]interface{}{
"enabled": false,
},
Grafana: defaultValues.Grafana,
},
nil,
},
{
[]string{`
kind: ConfigMap
apiVersion: v1
metadata:
name: linkerd-config
namespace: linkerd
data:
global: |
{"linkerdNamespace":"ns","identityContext":null, "cniEnabled": true}
proxy: |
{"proxyImage":{"imageName":"registry", "pullPolicy":"Always"}}
install: |
{"flags":[{"name":"ha","value":"true"}]}`,
},
&linkerd2.Values{
Global: &linkerd2.Global{
Namespace: "ns",
CNIEnabled: true,
HighAvailability: true,
Proxy: &linkerd2.Proxy{
EnableExternalProfiles: true,
Image: &linkerd2.Image{
Name: "registry",
PullPolicy: "Always",
},
LogLevel: "",
Ports: &linkerd2.Ports{},
Resources: &linkerd2.Resources{
CPU: linkerd2.Constraints{},
Memory: linkerd2.Constraints{},
},
},
ProxyInit: &linkerd2.ProxyInit{
Image: &linkerd2.Image{},
},
},
Identity: &linkerd2.Identity{
Issuer: &linkerd2.Issuer{},
},
DebugContainer: &linkerd2.DebugContainer{
Image: &linkerd2.Image{},
},
},
nil,
},
}
for i, tc := range testCases {
tc := tc // pin
t.Run(fmt.Sprintf("%d", i), func(t *testing.T) {
clientset, err := k8s.NewFakeAPI(tc.k8sConfigs...)
if err != nil {
t.Fatalf("Unexpected error: %s", err)
}
_, values, err := FetchCurrentConfiguration(context.Background(), clientset, "linkerd")
if !reflect.DeepEqual(err, tc.err) {
t.Fatalf("Expected \"%+v\", got \"%+v\"", tc.err, err)
}
if !reflect.DeepEqual(values, tc.expected) {
t.Fatalf("Unexpected values:\nExpected:\n%+v\nGot:\n%+v", tc.expected, values)
}
})
}
}
func getFakeConfigMap(scheme string, issuerCerts *issuercerts.IssuerCertData) string {
anchors, _ := json.Marshal(issuerCerts.TrustAnchors)
return fmt.Sprintf(`