Introduce tap-admin ClusterRole, web privs flag (#3203)

The web dashboard will be migrating to the new Tap APIService, which
requires RBAC privileges to access.

Introduce a new ClusterRole, `linkerd-linkerd-tap-admin`, which gives
cluster-wide tap privileges. Also introduce a new ClusterRoleBinding,
`linkerd-linkerd-web-admin` which binds the `linkerd-web` service
account to the new tap ClusterRole. This ClusterRoleBinding is enabled
by default, but may be disabled via a new `linkerd install` flag
`--restrict-dashboard-privileges`.

Fixes #3177

Signed-off-by: Andrew Seigner <siggy@buoyant.io>
This commit is contained in:
Andrew Seigner 2019-08-08 10:28:35 -07:00 committed by GitHub
parent 5d7662fd90
commit 0ff39ddf8d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
17 changed files with 437 additions and 93 deletions

View File

@ -22,6 +22,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-{{.Namespace}}-tap-admin
labels:
{{.ControllerComponentLabel}}: tap
{{.ControllerNamespaceLabel}}: {{.Namespace}}
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -4,6 +4,24 @@
### Web RBAC
###
---
{{- if not .RestrictDashboardPrivileges }}
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-{{.Namespace}}-web-admin
labels:
{{.ControllerComponentLabel}}: web
{{.ControllerNamespaceLabel}}: {{.Namespace}}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-{{.Namespace}}-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: {{.Namespace}}
---
{{- end}}
kind: ServiceAccount
apiVersion: v1
metadata:

View File

@ -22,6 +22,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: linkerd-{{.Namespace}}-tap-admin
labels:
{{.ControllerComponentLabel}}: tap
{{.ControllerNamespaceLabel}}: {{.Namespace}}
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:

View File

@ -4,6 +4,24 @@
### Web RBAC
###
---
{{- if not .RestrictDashboardPrivileges }}
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: linkerd-{{.Namespace}}-web-admin
labels:
{{.ControllerComponentLabel}}: web
{{.ControllerNamespaceLabel}}: {{.Namespace}}
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-{{.Namespace}}-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: {{.Namespace}}
---
{{- end}}
kind: ServiceAccount
apiVersion: v1
metadata:

View File

@ -71,7 +71,7 @@ func (options *checkOptions) validate() error {
return nil
}
// newCmdInstallConfig is a subcommand for `linkerd check config`
// newCmdCheckConfig is a subcommand for `linkerd check config`
func newCmdCheckConfig(options *checkOptions) *cobra.Command {
cmd := &cobra.Command{
Use: "config [flags]",

View File

@ -57,6 +57,7 @@ type (
NoInitContainer bool
WebhookFailurePolicy string
OmitWebhookSideEffects bool
RestrictDashboardPrivileges bool
HeartbeatSchedule string
Configs configJSONs
@ -134,6 +135,7 @@ type (
noInitContainer bool
skipChecks bool
omitWebhookSideEffects bool
restrictDashboardPrivileges bool
identityOptions *installIdentityOptions
*proxyConfigOptions
@ -198,6 +200,7 @@ func newInstallOptionsWithDefaults() *installOptions {
disableH2Upgrade: false,
noInitContainer: false,
omitWebhookSideEffects: false,
restrictDashboardPrivileges: false,
proxyConfigOptions: &proxyConfigOptions{
proxyVersion: version.Version,
ignoreCluster: false,
@ -258,6 +261,19 @@ func newInstallIdentityOptionsWithDefaults() *installIdentityOptions {
}
}
// Flag configuration matrix
//
// | recordableFlagSet | allStageFlagSet | installOnlyFlagSet | installPersistentFlagSet | upgradeOnlyFlagSet | "skip-checks" |
// `linkerd install` | X | X | X | X | | |
// `linkerd install config` | | X | | X | | |
// `linkerd install control-plane` | X | X | X | X | | X |
// `linkerd upgrade` | X | X | | | X | |
// `linkerd upgrade config` | | X | | | | |
// `linkerd upgrade control-plane` | X | X | | | X | |
//
// allStageFlagSet is a subset of recordableFlagSet, but is also added to `linkerd [install|upgrade] config`
// proxyConfigOptions.flagSet is a subset of recordableFlagSet, and is used by `linkerd inject`.
// newCmdInstallConfig is a subcommand for `linkerd install config`
func newCmdInstallConfig(options *installOptions, parentFlags *pflag.FlagSet) *cobra.Command {
cmd := &cobra.Command{
@ -284,14 +300,13 @@ resources for the Linkerd control plane. This command should be followed by
},
}
cniEnabledFlag := parentFlags.Lookup("linkerd-cni-enabled")
cmd.Flags().AddFlag(cniEnabledFlag)
cmd.Flags().AddFlagSet(options.allStageFlagSet())
return cmd
}
// newCmdInstallControlPlane is a subcommand for `linkerd install control-plane`
func newCmdInstallControlPlane(options *installOptions, parentFlags *pflag.FlagSet) *cobra.Command {
func newCmdInstallControlPlane(options *installOptions) *cobra.Command {
// The base flags are recorded separately so that they can be serialized into
// the configuration in validateAndBuild.
flags := options.recordableFlagSet()
@ -327,9 +342,6 @@ control plane. It should be run after "linkerd install config".`,
},
}
cniEnabledFlag := parentFlags.Lookup("linkerd-cni-enabled")
cmd.Flags().AddFlag(cniEnabledFlag)
cmd.PersistentFlags().BoolVar(
&options.skipChecks, "skip-checks", options.skipChecks,
`Skip checks for namespace existence`,
@ -383,7 +395,7 @@ control plane.`,
cmd.PersistentFlags().AddFlagSet(installPersistentFlags)
cmd.AddCommand(newCmdInstallConfig(options, flags))
cmd.AddCommand(newCmdInstallControlPlane(options, flags))
cmd.AddCommand(newCmdInstallControlPlane(options))
return cmd
}
@ -447,16 +459,13 @@ func (options *installOptions) recordableFlagSet() *pflag.FlagSet {
flags := pflag.NewFlagSet("install", e)
flags.AddFlagSet(options.proxyConfigOptions.flagSet(e))
flags.AddFlagSet(options.allStageFlagSet())
flags.UintVar(
&options.controllerReplicas, "controller-replicas", options.controllerReplicas,
"Replicas of the controller to deploy",
)
flags.BoolVar(&options.noInitContainer, "linkerd-cni-enabled", options.noInitContainer,
"Experimental: Omit the NET_ADMIN capability in the PSP and the proxy-init container when injecting the proxy; requires the linkerd-cni plugin to already be installed",
)
flags.StringVar(
&options.controllerLogLevel, "controller-log-level", options.controllerLogLevel,
"Log level for the controller and web components",
@ -492,6 +501,24 @@ func (options *installOptions) recordableFlagSet() *pflag.FlagSet {
return flags
}
// allStageFlagSet returns flags usable for single and multi-stage installs and
// upgrades. For multi-stage installs, users must set these flags consistently
// across commands.
func (options *installOptions) allStageFlagSet() *pflag.FlagSet {
flags := pflag.NewFlagSet("all-stage", pflag.ExitOnError)
flags.BoolVar(&options.noInitContainer, "linkerd-cni-enabled", options.noInitContainer,
"Experimental: Omit the NET_ADMIN capability in the PSP and the proxy-init container when injecting the proxy; requires the linkerd-cni plugin to already be installed",
)
flags.BoolVar(
&options.restrictDashboardPrivileges, "restrict-dashboard-privileges", options.restrictDashboardPrivileges,
"Restrict the Linkerd Dashboard's default privileges to disallow Tap",
)
return flags
}
// installOnlyFlagSet includes flags that are only accessible at install-time
// and not at upgrade-time.
func (options *installOptions) installOnlyFlagSet() *pflag.FlagSet {
@ -636,6 +663,7 @@ func (options *installOptions) buildValuesWithoutIdentity(configs *pb.All) (*ins
NoInitContainer: options.noInitContainer,
WebhookFailurePolicy: "Ignore",
OmitWebhookSideEffects: options.omitWebhookSideEffects,
RestrictDashboardPrivileges: options.restrictDashboardPrivileges,
PrometheusLogLevel: toPromLogLevel(strings.ToLower(options.controllerLogLevel)),
HeartbeatSchedule: options.heartbeatSchedule(),

View File

@ -54,8 +54,11 @@ func TestRender(t *testing.T) {
LinkerdNamespaceLabel: "LinkerdNamespaceLabel",
ControllerUID: 2103,
EnableH2Upgrade: true,
HighAvailability: false,
NoInitContainer: false,
WebhookFailurePolicy: "WebhookFailurePolicy",
OmitWebhookSideEffects: false,
RestrictDashboardPrivileges: false,
Configs: configJSONs{
Global: "GlobalConfig",
Proxy: "ProxyConfig",

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-web-admin
labels:
linkerd.io/control-plane-component: web
linkerd.io/control-plane-ns: linkerd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-linkerd-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: linkerd
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-tap-admin
labels:
linkerd.io/control-plane-component: tap
linkerd.io/control-plane-ns: linkerd
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-web-admin
labels:
linkerd.io/control-plane-component: web
linkerd.io/control-plane-ns: linkerd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-linkerd-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: linkerd
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-tap-admin
labels:
linkerd.io/control-plane-component: tap
linkerd.io/control-plane-ns: linkerd
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-web-admin
labels:
linkerd.io/control-plane-component: web
linkerd.io/control-plane-ns: linkerd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-linkerd-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: linkerd
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-tap-admin
labels:
linkerd.io/control-plane-component: tap
linkerd.io/control-plane-ns: linkerd
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-web-admin
labels:
linkerd.io/control-plane-component: web
linkerd.io/control-plane-ns: linkerd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-linkerd-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: linkerd
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-tap-admin
labels:
linkerd.io/control-plane-component: tap
linkerd.io/control-plane-ns: linkerd
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-web-admin
labels:
linkerd.io/control-plane-component: web
linkerd.io/control-plane-ns: linkerd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-linkerd-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: linkerd
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-tap-admin
labels:
linkerd.io/control-plane-component: tap
linkerd.io/control-plane-ns: linkerd
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-Namespace-web-admin
labels:
ControllerComponentLabel: web
ControllerNamespaceLabel: Namespace
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-Namespace-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: Namespace
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-Namespace-tap-admin
labels:
ControllerComponentLabel: tap
ControllerNamespaceLabel: Namespace
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-web-admin
labels:
linkerd.io/control-plane-component: web
linkerd.io/control-plane-ns: linkerd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-linkerd-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: linkerd
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-tap-admin
labels:
linkerd.io/control-plane-component: tap
linkerd.io/control-plane-ns: linkerd
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-web-admin
labels:
linkerd.io/control-plane-component: web
linkerd.io/control-plane-ns: linkerd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-linkerd-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: linkerd
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-tap-admin
labels:
linkerd.io/control-plane-component: tap
linkerd.io/control-plane-ns: linkerd
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -152,6 +152,22 @@ metadata:
### Web RBAC
###
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-web-admin
labels:
linkerd.io/control-plane-component: web
linkerd.io/control-plane-ns: linkerd
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: linkerd-linkerd-tap-admin
subjects:
- kind: ServiceAccount
name: linkerd-web
namespace: linkerd
---
kind: ServiceAccount
apiVersion: v1
metadata:
@ -465,6 +481,18 @@ rules:
resources: ["jobs"]
verbs: ["list" , "get", "watch"]
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
name: linkerd-linkerd-tap-admin
labels:
linkerd.io/control-plane-component: tap
linkerd.io/control-plane-ns: linkerd
rules:
- apiGroups: ["tap.linkerd.io"]
resources: ["*/tap"]
verbs: ["watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:

View File

@ -56,7 +56,6 @@ func (options *upgradeOptions) upgradeOnlyFlagSet() *pflag.FlagSet {
// newCmdUpgradeConfig is a subcommand for `linkerd upgrade config`
func newCmdUpgradeConfig(options *upgradeOptions) *cobra.Command {
flags := options.recordableFlagSet()
cmd := &cobra.Command{
Use: "config [flags]",
Args: cobra.NoArgs,
@ -67,10 +66,12 @@ Note that this command should be followed by "linkerd upgrade control-plane".`,
Example: ` # Default upgrade.
linkerd upgrade config | kubectl apply -f -`,
RunE: func(cmd *cobra.Command, args []string) error {
return upgradeRunE(options, configStage, flags)
return upgradeRunE(options, configStage, options.recordableFlagSet())
},
}
cmd.Flags().AddFlagSet(options.allStageFlagSet())
return cmd
}