Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enh/target cluster by alias #185

Merged
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
Next Next commit
enh: validate gardenctl config on load
  • Loading branch information
sven-petersen committed Dec 12, 2022
commit e8a9c411e1603d87431ab647378fa84c6cc4244b
29 changes: 21 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ Attention `brew` users: `gardenctl-v2` uses the same binary name as the legacy `

### Install from Github Release

If you install via GitHub releases, you need to
- put the `gardenctl` binary on your path
- and [install gardenlogin](https://github.com/gardener/gardenlogin#installation).
If you install via GitHub releases, you need to

- put the `gardenctl` binary on your path
- and [install gardenlogin](https://github.com/gardener/gardenlogin#installation).

The other install methods do this for you.

Expand Down Expand Up @@ -61,7 +62,8 @@ sudo mv "./gardenctl_v2_${os}_${arch}" /usr/local/bin/gardenctl
You can modify this file directly using the `gardenctl config` command. It allows adding, modifying and deleting gardens.

Example `config` command:
``` bash

```bash
# Adapt the path to your kubeconfig file for the garden cluster
export KUBECONFIG=~/relative/path/to/kubeconfig.yaml

Expand All @@ -80,15 +82,17 @@ cluster_identity=$(echo ${identity_status#"$prefix"})
# Configure garden cluster
gardenctl config set-garden $cluster_identity --kubeconfig $KUBECONFIG
```

This command will create or update a garden with the provided identity and kubeconfig path of your garden cluster.

### Example Config

```yaml
gardens:
- identity: landscape-dev # Unique identity of the garden cluster. See cluster-identity ConfigMap in kube-system namespace of the garden cluster
kubeconfig: ~/relative/path/to/kubeconfig.yaml
# context: different-context # Overrides the current-context of the garden cluster kubeconfig
- identity: landscape-dev # Unique identity of the garden cluster. See cluster-identity ConfigMap in kube-system namespace of the garden cluster
kubeconfig: ~/relative/path/to/kubeconfig.yaml
# name: my-name # An alternative, unique garden name for targeting
# context: different-context # Overrides the current-context of the garden cluster kubeconfig
# patterns: ~ # List of regex patterns for pattern targeting
```

Expand All @@ -115,23 +119,27 @@ this leads to an error and gardenctl cannot be executed. The `target.yaml` and t

You can make sure that `GCTL_SESSION_ID` or `TERM_SESSION_ID` is always present by adding
the following code to your terminal profile `~/.profile`, `~/.bashrc` or comparable file.

```sh
bash and zsh: [ -n "$GCTL_SESSION_ID" ] || [ -n "$TERM_SESSION_ID" ] || export GCTL_SESSION_ID=$(uuidgen)
```

```sh
fish: [ -n "$GCTL_SESSION_ID" ] || [ -n "$TERM_SESSION_ID" ] || set -gx GCTL_SESSION_ID (uuidgen)
```

```ps
powershell: if ( !(Test-Path Env:GCTL_SESSION_ID) -and !(Test-Path Env:TERM_SESSION_ID) ) { $Env:GCTL_SESSION_ID = [guid]::NewGuid().ToString() }
```

### Completion

Gardenctl supports completion that will help you working with the CLI and save you typing effort.
It will also help you find clusters by providing suggestions for gardener resources such as shoots or projects.
It will also help you find clusters by providing suggestions for gardener resources such as shoots or projects.
Completion is supported for `bash`, `zsh`, `fish` and `powershell`.
You will find more information on how to configure your shell completion for gardenctl by executing the help for
your shell completion command. Example:

```bash
gardenctl completion bash --help
```
Expand All @@ -145,29 +153,34 @@ You can set a target to use it in subsequent commands. You can also overwrite th
Note that this will not affect your KUBECONFIG env variable. To update the KUBECONFIG env for your current target see [Configure KUBECONFIG](#configure-kubeconfig-for-shoot-clusters) section

Example:

```bash
# target control plane
gardenctl target --garden landscape-dev --project my-project --shoot my-shoot --control-plane
```

Find more information in the [documentation](docs/usage/targeting.md).

### Configure KUBECONFIG for Shoot Clusters

Generate a script that points KUBECONFIG to the targeted cluster for the specified shell. Use together with `eval` to configure your shell. Example for `bash`:

```bash
eval $(gardenctl kubectl-env bash)
```

### Configure Cloud Provider CLIs

Generate the cloud provider CLI configuration script for the specified shell. Use together with `eval` to configure your shell. Example for `bash`:

```bash
eval $(gardenctl provider-env bash)
```

### SSH

Establish an SSH connection to a Shoot cluster's node.

```bash
gardenctl ssh my-node
```
48 changes: 39 additions & 9 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,9 +99,46 @@ func LoadFromFile(filename string) (*Config, error) {
config.LinkKubeconfig = &val
}

if err := config.validate(); err != nil {
return nil, err
}
sven-petersen marked this conversation as resolved.
Show resolved Hide resolved

return config, nil
}

// validate checks the config for static errors. It does not check if the kubeconfig file exists.
func (config *Config) validate() error {
seen := make(map[string]bool, len(config.Gardens))

for i := range config.Gardens {
garden := config.Gardens[i]

if garden.Name == "" {
return fmt.Errorf("identity is required for gardens in the gardenctl configuration")
}

if garden.Kubeconfig == "" {
return fmt.Errorf("kubeconfig is required for gardens in the gardenctl configuration")
}

if seen[garden.Name] {
return fmt.Errorf("identity and alias must be unique but %q was found multiple times in gardenctl configuration", garden.Name)
}

if garden.Alias != "" {
if seen[garden.Alias] {
return fmt.Errorf("identity and alias must be unique but %q was found multiple times in gardenctl configuration", garden.Alias)
}

seen[garden.Alias] = true
}

seen[garden.Name] = true
}

return nil
}

// SymlinkTargetKubeconfig indicates if the kubeconfig of the current target should be always symlinked.
func (config *Config) SymlinkTargetKubeconfig() bool {
return config.LinkKubeconfig == nil || *config.LinkKubeconfig
Expand Down Expand Up @@ -157,16 +194,9 @@ func (config *Config) Garden(name string) (*Garden, error) {

for idx := range config.Gardens {
cfg := &config.Gardens[idx]

if name != cfg.Name && name != cfg.Alias {
continue
if name == cfg.Name || name == cfg.Alias {
sven-petersen marked this conversation as resolved.
Show resolved Hide resolved
return cfg, nil
}

if gardenConfig != nil {
return nil, fmt.Errorf("identity or alias %q must be unique but was found multiple times in gardenctl configuration", cfg.Name)
}

gardenConfig = cfg
}

if gardenConfig == nil {
Expand Down