mirror of
https://github.com/helm/helm.git
synced 2026-05-28 04:35:48 -04:00
Support impersonation via flags similar to kubectl --as="user"
Signed-off-by: leigh capili <leigh@null.net>
This commit is contained in:
parent
6f780bb750
commit
9429af8b39
6 changed files with 57 additions and 11 deletions
|
|
@ -154,7 +154,7 @@ func callPluginExecutable(pluginName string, main string, argv []string, out io.
|
|||
func manuallyProcessArgs(args []string) ([]string, []string) {
|
||||
known := []string{}
|
||||
unknown := []string{}
|
||||
kvargs := []string{"--kube-context", "--namespace", "-n", "--kubeconfig", "--kube-apiserver", "--kube-token", "--registry-config", "--repository-cache", "--repository-config"}
|
||||
kvargs := []string{"--kube-context", "--namespace", "-n", "--kubeconfig", "--kube-apiserver", "--kube-token", "--kube-as-user", "--kube-as-group", "--registry-config", "--repository-cache", "--repository-config"}
|
||||
knownArg := func(a string) bool {
|
||||
for _, pre := range kvargs {
|
||||
if strings.HasPrefix(a, pre+"=") {
|
||||
|
|
|
|||
|
|
@ -37,6 +37,9 @@ func TestManuallyProcessArgs(t *testing.T) {
|
|||
"--kubeconfig", "/home/foo",
|
||||
"--kube-context=test1",
|
||||
"--kube-context", "test1",
|
||||
"--kube-as-user", "pikachu",
|
||||
"--kube-as-group", "teatime",
|
||||
"--kube-as-group", "admins",
|
||||
"-n=test2",
|
||||
"-n", "test2",
|
||||
"--namespace=test2",
|
||||
|
|
@ -51,6 +54,9 @@ func TestManuallyProcessArgs(t *testing.T) {
|
|||
"--kubeconfig", "/home/foo",
|
||||
"--kube-context=test1",
|
||||
"--kube-context", "test1",
|
||||
"--kube-as-user", "pikachu",
|
||||
"--kube-as-group", "teatime",
|
||||
"--kube-as-group", "admins",
|
||||
"-n=test2",
|
||||
"-n", "test2",
|
||||
"--namespace=test2",
|
||||
|
|
|
|||
|
|
@ -60,6 +60,8 @@ Environment variables:
|
|||
| $HELM_REPOSITORY_CONFIG | set the path to the repositories file. |
|
||||
| $KUBECONFIG | set an alternative Kubernetes configuration file (default "~/.kube/config") |
|
||||
| $HELM_KUBEAPISERVER | set the Kubernetes API Server Endpoint for authentication |
|
||||
| $HELM_KUBEASGROUPS | set the Username to impersonate for the operation. |
|
||||
| $HELM_KUBEASUSER | set the Groups to use for impoersonation using a comma-separated list. |
|
||||
| $HELM_KUBECONTEXT | set the name of the kubeconfig context. |
|
||||
| $HELM_KUBETOKEN | set the Bearer KubeToken used for authentication. |
|
||||
|
||||
|
|
|
|||
2
cmd/helm/testdata/output/env-comp.txt
vendored
2
cmd/helm/testdata/output/env-comp.txt
vendored
|
|
@ -4,6 +4,8 @@ HELM_CONFIG_HOME
|
|||
HELM_DATA_HOME
|
||||
HELM_DEBUG
|
||||
HELM_KUBEAPISERVER
|
||||
HELM_KUBEASGROUPS
|
||||
HELM_KUBEASUSER
|
||||
HELM_KUBECONTEXT
|
||||
HELM_KUBETOKEN
|
||||
HELM_MAX_HISTORY
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ import (
|
|||
"fmt"
|
||||
"os"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/spf13/pflag"
|
||||
"k8s.io/cli-runtime/pkg/genericclioptions"
|
||||
|
|
@ -47,6 +48,10 @@ type EnvSettings struct {
|
|||
KubeContext string
|
||||
// Bearer KubeToken used for authentication
|
||||
KubeToken string
|
||||
// Username to impersonate for the operation
|
||||
KubeAsUser string
|
||||
// Groups to impersonate for the operation, multiple groups parsed from a comma delimited list
|
||||
KubeAsGroups []string
|
||||
// Kubernetes API Server Endpoint for authentication
|
||||
KubeAPIServer string
|
||||
// Debug indicates whether or not Helm is running in Debug mode.
|
||||
|
|
@ -69,6 +74,8 @@ func New() *EnvSettings {
|
|||
MaxHistory: envIntOr("HELM_MAX_HISTORY", defaultMaxHistory),
|
||||
KubeContext: os.Getenv("HELM_KUBECONTEXT"),
|
||||
KubeToken: os.Getenv("HELM_KUBETOKEN"),
|
||||
KubeAsUser: os.Getenv("HELM_KUBEASUSER"),
|
||||
KubeAsGroups: envCSV("HELM_KUBEASGROUPS"),
|
||||
KubeAPIServer: os.Getenv("HELM_KUBEAPISERVER"),
|
||||
PluginsDirectory: envOr("HELM_PLUGINS", helmpath.DataPath("plugins")),
|
||||
RegistryConfig: envOr("HELM_REGISTRY_CONFIG", helmpath.ConfigPath("registry.json")),
|
||||
|
|
@ -79,11 +86,13 @@ func New() *EnvSettings {
|
|||
|
||||
// bind to kubernetes config flags
|
||||
env.config = &genericclioptions.ConfigFlags{
|
||||
Namespace: &env.namespace,
|
||||
Context: &env.KubeContext,
|
||||
BearerToken: &env.KubeToken,
|
||||
APIServer: &env.KubeAPIServer,
|
||||
KubeConfig: &env.KubeConfig,
|
||||
Namespace: &env.namespace,
|
||||
Context: &env.KubeContext,
|
||||
BearerToken: &env.KubeToken,
|
||||
APIServer: &env.KubeAPIServer,
|
||||
KubeConfig: &env.KubeConfig,
|
||||
Impersonate: &env.KubeAsUser,
|
||||
ImpersonateGroup: &env.KubeAsGroups,
|
||||
}
|
||||
return env
|
||||
}
|
||||
|
|
@ -94,6 +103,8 @@ func (s *EnvSettings) AddFlags(fs *pflag.FlagSet) {
|
|||
fs.StringVar(&s.KubeConfig, "kubeconfig", "", "path to the kubeconfig file")
|
||||
fs.StringVar(&s.KubeContext, "kube-context", s.KubeContext, "name of the kubeconfig context to use")
|
||||
fs.StringVar(&s.KubeToken, "kube-token", s.KubeToken, "bearer token used for authentication")
|
||||
fs.StringVar(&s.KubeAsUser, "kube-as-user", s.KubeAsUser, "Username to impersonate for the operation")
|
||||
fs.StringArrayVar(&s.KubeAsGroups, "kube-as-group", s.KubeAsGroups, "Group to impersonate for the operation, this flag can be repeated to specify multiple groups.")
|
||||
fs.StringVar(&s.KubeAPIServer, "kube-apiserver", s.KubeAPIServer, "the address and the port for the Kubernetes API server")
|
||||
fs.BoolVar(&s.Debug, "debug", s.Debug, "enable verbose output")
|
||||
fs.StringVar(&s.RegistryConfig, "registry-config", s.RegistryConfig, "path to the registry config file")
|
||||
|
|
@ -120,6 +131,14 @@ func envIntOr(name string, def int) int {
|
|||
return ret
|
||||
}
|
||||
|
||||
func envCSV(name string) (ls []string) {
|
||||
trimmed := strings.Trim(os.Getenv(name), ", ")
|
||||
if trimmed != "" {
|
||||
ls = strings.Split(trimmed, ",")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
func (s *EnvSettings) EnvVars() map[string]string {
|
||||
envvars := map[string]string{
|
||||
"HELM_BIN": os.Args[0],
|
||||
|
|
@ -137,6 +156,8 @@ func (s *EnvSettings) EnvVars() map[string]string {
|
|||
// broken, these are populated from helm flags and not kubeconfig.
|
||||
"HELM_KUBECONTEXT": s.KubeContext,
|
||||
"HELM_KUBETOKEN": s.KubeToken,
|
||||
"HELM_KUBEASUSER": s.KubeAsUser,
|
||||
"HELM_KUBEASGROUPS": strings.Join(s.KubeAsGroups, ","),
|
||||
"HELM_KUBEAPISERVER": s.KubeAPIServer,
|
||||
}
|
||||
if s.KubeConfig != "" {
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ package cli
|
|||
|
||||
import (
|
||||
"os"
|
||||
"reflect"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
|
|
@ -36,6 +37,8 @@ func TestEnvSettings(t *testing.T) {
|
|||
ns, kcontext string
|
||||
debug bool
|
||||
maxhistory int
|
||||
kAsUser string
|
||||
kAsGroups []string
|
||||
}{
|
||||
{
|
||||
name: "defaults",
|
||||
|
|
@ -44,25 +47,31 @@ func TestEnvSettings(t *testing.T) {
|
|||
},
|
||||
{
|
||||
name: "with flags set",
|
||||
args: "--debug --namespace=myns",
|
||||
args: "--debug --namespace=myns --kube-as-user=poro --kube-as-group=admins --kube-as-group=teatime --kube-as-group=snackeaters",
|
||||
ns: "myns",
|
||||
debug: true,
|
||||
maxhistory: defaultMaxHistory,
|
||||
kAsUser: "poro",
|
||||
kAsGroups: []string{"admins", "teatime", "snackeaters"},
|
||||
},
|
||||
{
|
||||
name: "with envvars set",
|
||||
envvars: map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_MAX_HISTORY": "5"},
|
||||
envvars: map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_KUBEASUSER": "pikachu", "HELM_KUBEASGROUPS": ",,,operators,snackeaters,partyanimals", "HELM_MAX_HISTORY": "5"},
|
||||
ns: "yourns",
|
||||
maxhistory: 5,
|
||||
debug: true,
|
||||
kAsUser: "pikachu",
|
||||
kAsGroups: []string{"operators", "snackeaters", "partyanimals"},
|
||||
},
|
||||
{
|
||||
name: "with flags and envvars set",
|
||||
args: "--debug --namespace=myns",
|
||||
envvars: map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns"},
|
||||
args: "--debug --namespace=myns --kube-as-user=poro --kube-as-group=admins --kube-as-group=teatime --kube-as-group=snackeaters",
|
||||
envvars: map[string]string{"HELM_DEBUG": "1", "HELM_NAMESPACE": "yourns", "HELM_KUBEASUSER": "pikachu", "HELM_KUBEASGROUPS": ",,,operators,snackeaters,partyanimals", "HELM_MAX_HISTORY": "5"},
|
||||
ns: "myns",
|
||||
debug: true,
|
||||
maxhistory: defaultMaxHistory,
|
||||
maxhistory: 5,
|
||||
kAsUser: "poro",
|
||||
kAsGroups: []string{"admins", "teatime", "snackeaters"},
|
||||
},
|
||||
}
|
||||
|
||||
|
|
@ -92,6 +101,12 @@ func TestEnvSettings(t *testing.T) {
|
|||
if settings.MaxHistory != tt.maxhistory {
|
||||
t.Errorf("expected maxHistory %d, got %d", tt.maxhistory, settings.MaxHistory)
|
||||
}
|
||||
if tt.kAsUser != settings.KubeAsUser {
|
||||
t.Errorf("expected kAsUser %q, got %q", tt.kAsUser, settings.KubeAsUser)
|
||||
}
|
||||
if !reflect.DeepEqual(tt.kAsGroups, settings.KubeAsGroups) {
|
||||
t.Errorf("expected kAsGroups %+v, got %+v", len(tt.kAsGroups), len(settings.KubeAsGroups))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue