Skip to content
This repository has been archived by the owner on Oct 30, 2024. It is now read-only.

✨ Add the --context option #427

Merged
merged 2 commits into from
Jun 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 5 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -156,9 +156,9 @@ kubeaudit all

### Local Mode

Kubeaudit will try to connect to a cluster using the local kubeconfig file (`$HOME/.kube/config`). A different kubeconfig location can be specified using the `-c/--kubeconfig` flag.
Kubeaudit will try to connect to a cluster using the local kubeconfig file (`$HOME/.kube/config`). A different kubeconfig location can be specified using the `--kubeconfig` flag. To specify a context of the kubeconfig, use the `-c/--context` flag.
```
kubeaudit all -c "/path/to/config"
kubeaudit all --kubeconfig "/path/to/config" --context my_cluster
```

For more information on kubernetes config files, see https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/
Expand Down Expand Up @@ -212,7 +212,8 @@ Auditors can also be run individually.
| Short | Long | Description |
| :---- | :----------------- | :----------------------------------------------------------------------------------------------------------------------------------------------------- |
| | --format | The output format to use (one of "pretty", "logrus", "json") (default is "pretty") |
| -c | --kubeconfig | Path to local Kubernetes config file. Only used in local mode (default is `$HOME/.kube/config`) |
| | --kubeconfig | Path to local Kubernetes config file. Only used in local mode (default is `$HOME/.kube/config`) |
| -c | --context | The name of the kubeconfig context to use |
| -f | --manifest | Path to the yaml configuration to audit. Only used in manifest mode. You may use `-` to read from stdin. |
| -n | --namespace | Only audit resources in the specified namespace. Not currently supported in manifest mode. |
| -g | --includegenerated | Include generated resources in scan (such as Pods generated by deployments). If you would like kubeaudit to produce results for generated resources (for example if you have custom resources or want to catch orphaned resources where the owner resource no longer exists) you can use this flag. |
Expand Down Expand Up @@ -263,7 +264,7 @@ auditors:
For more details about each auditor, including a description of the auditor-specific configuration in the config, see the [Auditor Docs](#auditors).
**Note**: The kubeaudit config is not the same as the kubeconfig file specified with the `-c/--kubeconfig` flag, which refers to the Kubernetes config file (see [Local Mode](/README.md#local-mode)). Also note that only the `all` and `autofix` commands support using a kubeaudit config. It will not work with other commands.
**Note**: The kubeaudit config is not the same as the kubeconfig file specified with the `--kubeconfig` flag, which refers to the Kubernetes config file (see [Local Mode](/README.md#local-mode)). Also note that only the `all` and `autofix` commands support using a kubeaudit config. It will not work with other commands.

**Note**: If flags are used in combination with the config file, flags will take precedence.

Expand Down
6 changes: 4 additions & 2 deletions cmd/commands/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ var rootConfig rootFlags
type rootFlags struct {
format string
kubeConfig string
context string
manifest string
namespace string
minSeverity string
Expand Down Expand Up @@ -47,7 +48,8 @@ func Execute() {
}

func init() {
RootCmd.PersistentFlags().StringVarP(&rootConfig.kubeConfig, "kubeconfig", "c", "", "Path to local Kubernetes config file. Only used in local mode (default is $HOME/.kube/config)")
RootCmd.PersistentFlags().StringVarP(&rootConfig.kubeConfig, "kubeconfig", "", "", "Path to local Kubernetes config file. Only used in local mode (default is $HOME/.kube/config)")
RootCmd.PersistentFlags().StringVarP(&rootConfig.context, "context", "c", "", "The name of the kubeconfig context to use")
RootCmd.PersistentFlags().StringVarP(&rootConfig.minSeverity, "minseverity", "m", "info", "Set the lowest severity level to report (one of \"error\", \"warning\", \"info\")")
RootCmd.PersistentFlags().StringVarP(&rootConfig.format, "format", "p", "pretty", "The output format to use (one of \"pretty\", \"logrus\", \"json\")")
RootCmd.PersistentFlags().StringVarP(&rootConfig.namespace, "namespace", "n", apiv1.NamespaceAll, "Only audit resources in the specified namespace. Not currently supported in manifest mode.")
Expand Down Expand Up @@ -118,7 +120,7 @@ func getReport(auditors ...kubeaudit.Auditable) *kubeaudit.Report {
return report
}

report, err := auditor.AuditLocal(rootConfig.kubeConfig, kubeaudit.AuditOptions{Namespace: rootConfig.namespace, IncludeGenerated: rootConfig.includeGenerated})
report, err := auditor.AuditLocal(rootConfig.kubeConfig, rootConfig.context, kubeaudit.AuditOptions{Namespace: rootConfig.namespace, IncludeGenerated: rootConfig.includeGenerated})
if err != nil {
log.WithError(err).Fatal("Error auditing cluster in local mode")
}
Expand Down
4 changes: 2 additions & 2 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ func Example_auditLocal() {
}

// Run the audit in local mode
report, err := auditor.AuditLocal("", kubeaudit.AuditOptions{})
report, err := auditor.AuditLocal("", "", kubeaudit.AuditOptions{})
if err != nil {
log.Fatal(err)
}
Expand Down Expand Up @@ -204,7 +204,7 @@ func Example_printOptions() {
log.Fatal(err)
}

report, err := auditor.AuditLocal("", kubeaudit.AuditOptions{})
report, err := auditor.AuditLocal("", "", kubeaudit.AuditOptions{})
if err != nil {
log.Fatal(err)
}
Expand Down
4 changes: 2 additions & 2 deletions internal/k8sinternal/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,14 +45,14 @@ func (kc k8sClient) InClusterConfig() (*rest.Config, error) {
}

// NewKubeClientLocal creates a new kube client for local mode
func NewKubeClientLocal(configPath string) (KubeClient, error) {
func NewKubeClientLocal(configPath string, context string) (KubeClient, error) {
var kubeconfig *rest.Config
var err error

if configPath == "" {
kubeconfig, err = clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
clientcmd.NewDefaultClientConfigLoadingRules(),
&clientcmd.ConfigOverrides{ClusterInfo: clientcmdapi.Cluster{Server: ""}},
&clientcmd.ConfigOverrides{CurrentContext: context, ClusterInfo: clientcmdapi.Cluster{Server: ""}},
).ClientConfig()
} else {
if _, err = os.Stat(configPath); err != nil {
Expand Down
6 changes: 3 additions & 3 deletions internal/k8sinternal/client_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,10 @@ func (kc *MockK8sClient) InClusterConfig() (*rest.Config, error) {
func TestKubeClientConfigLocal(t *testing.T) {
assert := assert.New(t)

_, err := k8sinternal.NewKubeClientLocal("/notarealfile")
_, err := k8sinternal.NewKubeClientLocal("/notarealfile", "")
assert.Equal(k8sinternal.ErrNoReadableKubeConfig, err)

_, err = k8sinternal.NewKubeClientLocal("client.go")
_, err = k8sinternal.NewKubeClientLocal("client.go", "")
assert.NotEqual(k8sinternal.ErrNoReadableKubeConfig, err)
assert.NotNil(err)
}
Expand Down Expand Up @@ -144,7 +144,7 @@ func TestIncludeGenerated(t *testing.T) {
test.CreateNamespace(t, namespace)
test.ApplyManifest(t, "./fixtures/include-generated.yml", namespace)

client, err := k8sinternal.NewKubeClientLocal("")
client, err := k8sinternal.NewKubeClientLocal("", "")
require.NoError(t, err)

// Test IncludeGenerated = false
Expand Down
2 changes: 1 addition & 1 deletion internal/test/test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,7 +111,7 @@ func GetReport(t *testing.T, fixtureDir, fixture string, auditables []kubeaudit.
defer DeleteNamespace(t, namespace)
CreateNamespace(t, namespace)
ApplyManifest(t, fixture, namespace)
report, err = auditor.AuditLocal("", k8sinternal.ClientOptions{Namespace: namespace})
report, err = auditor.AuditLocal("", "", k8sinternal.ClientOptions{Namespace: namespace})
}

require.NoError(err)
Expand Down
4 changes: 2 additions & 2 deletions kubeaudit.go
Original file line number Diff line number Diff line change
Expand Up @@ -185,8 +185,8 @@ func (a *Kubeaudit) AuditCluster(options AuditOptions) (*Report, error) {
}

// AuditLocal audits the Kubernetes resources found in the provided Kubernetes config file
func (a *Kubeaudit) AuditLocal(configpath string, options AuditOptions) (*Report, error) {
client, err := k8sinternal.NewKubeClientLocal(configpath)
func (a *Kubeaudit) AuditLocal(configpath string, context string, options AuditOptions) (*Report, error) {
client, err := k8sinternal.NewKubeClientLocal(configpath, context)
if err == k8sinternal.ErrNoReadableKubeConfig {
return nil, fmt.Errorf("failed to open kubeconfig file %s", configpath)
} else if err != nil {
Expand Down
7 changes: 5 additions & 2 deletions kubeaudit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,13 @@ func TestAuditLocal(t *testing.T) {
auditor, err := kubeaudit.New(allAuditors)
require.NoError(err)

_, err = auditor.AuditLocal("", k8sinternal.ClientOptions{})
_, err = auditor.AuditLocal("", "", k8sinternal.ClientOptions{})
require.NoError(err)

_, err = auditor.AuditLocal("invalid_path", k8sinternal.ClientOptions{})
_, err = auditor.AuditLocal("invalid_path", "", k8sinternal.ClientOptions{})
require.NotNil(err)

_, err = auditor.AuditLocal("", "invalid_context", k8sinternal.ClientOptions{})
require.NotNil(err)
}

Expand Down