Skip to content

Commit

Permalink
feat(kubernetes): Add styling based on current context (#4550)
Browse files Browse the repository at this point in the history
* feat(kubernetes): Add styling based on current context

Add an ability to customize the configuration of the kubernetes module style, based on the current context.

A new variable is added to the config section, called environments, which is a list of possible customizations. Each such customization is an object with a context_pattern regex, which matches context name, and an optional style and icon that will override the global configuration, if the currently used context matched the context_pattern.

Based on multiple attempts to add per-context styling and symbols to the kubernetes module.

- #1568 by @lht https://github.com/lht -> base
- #614 by @nomaed https://github.com/nomaed -> naming, symbol, some tests

Rebased and combined by @jankatins

Contains the following squasched commits

- Rename to contexts and move aliases into contexts
- Move deprecated functions to a submodule
- Cleanup: ignore None-valued KubeCtxComponents
- Add regex func + clean up matching-context search
- Placate paper clip

Closes: #570

Co-authored-by: =?UTF-8?q?Boris=20Aranovic=CC=8C?= <nomaed@gmail.com>
Co-authored-by: Jan Katins <jasc@gmx.net>
Co-authored-by: Kevin Song <chips@ksong.dev>

* refactor(kubernetes): Remove options and use clearer names

* test(kubernetes): Handle duplicated contexts right

* refactor(kubernetes): Cleaner user matching

* fix(kubernetes): Only show warning in case of problems

* feat(kubernetes): Add back alias replacements

* refactor(kubernetes): Cleanup rust usage

---------

Co-authored-by: Haitao Li <lihaitao@gmail.com>
Co-authored-by: =?UTF-8?q?Boris=20Aranovic=CC=8C?= <nomaed@gmail.com>
Co-authored-by: Kevin Song <chips@ksong.dev>
Co-authored-by: David Knaack <davidkna@users.noreply.github.com>
  • Loading branch information
5 people committed Sep 2, 2023
1 parent e867cda commit 6b444e0
Show file tree
Hide file tree
Showing 4 changed files with 747 additions and 131 deletions.
53 changes: 53 additions & 0 deletions .github/config-schema.json
Expand Up @@ -906,6 +906,7 @@
"kubernetes": {
"default": {
"context_aliases": {},
"contexts": [],
"detect_extensions": [],
"detect_files": [],
"detect_folders": [],
Expand Down Expand Up @@ -4013,6 +4014,58 @@
"items": {
"type": "string"
}
},
"contexts": {
"default": [],
"type": "array",
"items": {
"$ref": "#/definitions/KubernetesContextConfig"
}
}
},
"additionalProperties": false
},
"KubernetesContextConfig": {
"type": "object",
"properties": {
"context_pattern": {
"default": "",
"type": "string"
},
"user_pattern": {
"default": null,
"type": [
"string",
"null"
]
},
"symbol": {
"default": null,
"type": [
"string",
"null"
]
},
"style": {
"default": null,
"type": [
"string",
"null"
]
},
"context_alias": {
"default": null,
"type": [
"string",
"null"
]
},
"user_alias": {
"default": null,
"type": [
"string",
"null"
]
}
},
"additionalProperties": false
Expand Down
84 changes: 58 additions & 26 deletions docs/config/README.md
Expand Up @@ -2470,7 +2470,8 @@ kotlin_binary = 'kotlinc'
Displays the current [Kubernetes context](https://kubernetes.io/docs/concepts/configuration/organize-cluster-access-kubeconfig/#context) name and, if set, the namespace, user and cluster from the kubeconfig file.
The namespace needs to be set in the kubeconfig file, this can be done via
`kubectl config set-context starship-context --namespace astronaut`.
Similarly the user and cluster can be set with `kubectl config set-context starship-context --user starship-user` and `kubectl config set-context starship-context --cluster starship-cluster`.
Similarly, the user and cluster can be set with `kubectl config set-context starship-context --user starship-user`
and `kubectl config set-context starship-context --cluster starship-cluster`.
If the `$KUBECONFIG` env var is set the module will use that if not it will use the `~/.kube/config`.

::: tip
Expand All @@ -2486,18 +2487,45 @@ case the module will only be active in directories that match those conditions.

### Options

::: warning

The `context_aliases` and `user_aliases` options are deprecated. Use `contexts` and the corresponding `context_alias`
and `user_alias` options instead.

:::

| Option | Default | Description |
| ------------------- | -------------------------------------------------- | --------------------------------------------------------------------- |
| `symbol` | `'☸ '` | A format string representing the symbol displayed before the Cluster. |
| `format` | `'[$symbol$context( \($namespace\))]($style) in '` | The format for the module. |
| `style` | `'cyan bold'` | The style for the module. |
| `context_aliases` | `{}` | Table of context aliases to display. |
| `user_aliases` | `{}` | Table of user aliases to display. |
| `context_aliases`* | `{}` | Table of context aliases to display. |
| `user_aliases`* | `{}` | Table of user aliases to display. |
| `detect_extensions` | `[]` | Which extensions should trigger this module. |
| `detect_files` | `[]` | Which filenames should trigger this module. |
| `detect_folders` | `[]` | Which folders should trigger this modules. |
| `contexts` | `[]` | Customized styles and symbols for specific contexts. |
| `disabled` | `true` | Disables the `kubernetes` module. |

*: This option is deprecated, please add `contexts` with the corresponding `context_alias` and `user_alias` options instead.

To customize the style of the module for specific environments, use the following configuration as
part of the `contexts` list:

| Variable | Description |
| ----------------- | ---------------------------------------------------------------------------------------- |
| `context_pattern` | **Required** Regular expression to match current Kubernetes context name. |
| `user_pattern` | Regular expression to match current Kubernetes user name. |
| `context_alias` | Context alias to display instead of the full context name. |
| `user_alias` | User alias to display instead of the full user name. |
| `style` | The style for the module when using this context. If not set, will use module's style. |
| `symbol` | The symbol for the module when using this context. If not set, will use module's symbol. |

Note that all regular expression are anchored with `^<pattern>$` and so must match the whole string. The `*_pattern`
regular expressions may contain capture groups, which can be referenced in the corresponding alias via `$name` and `$N`
(see example below and the
[rust Regex::replace() documentation](https://docs.rs/regex/latest/regex/struct.Regex.html#method.replace)).

### Variables

| Variable | Example | Description |
Expand All @@ -2519,13 +2547,9 @@ case the module will only be active in directories that match those conditions.
[kubernetes]
format = 'on [⛵ ($user on )($cluster in )$context \($namespace\)](dimmed green) '
disabled = false
[kubernetes.context_aliases]
'dev.local.cluster.k8s' = 'dev'
'.*/openshift-cluster/.*' = 'openshift'
'gke_.*_(?P<var_cluster>[\w-]+)' = 'gke-$var_cluster'
[kubernetes.user_aliases]
'dev.local.cluster.k8s' = 'dev'
'root/.*' = 'root'
contexts = [
{ context_pattern = "dev.local.cluster.k8s", style = "green", symbol = "💔 " },
]
```

Only show the module in directories that contain a `k8s` file.
Expand All @@ -2538,29 +2562,37 @@ disabled = false
detect_files = ['k8s']
```

#### Regex Matching
#### Kubernetes Context specific config

Additional to simple aliasing, `context_aliases` and `user_aliases` also supports
extended matching and renaming using regular expressions.

The regular expression must match on the entire kube context,
capture groups can be referenced using `$name` and `$N` in the replacement.
This is more explained in the [regex crate](https://docs.rs/regex/1.5.4/regex/struct.Regex.html#method.replace) documentation.

Long and automatically generated cluster names can be identified
and shortened using regular expressions:
The `contexts` configuration option is used to customise what the current Kubernetes context name looks
like (style and symbol) if the name matches the defined regular expression.

```toml
[kubernetes.context_aliases]
# OpenShift contexts carry the namespace and user in the kube context: `namespace/name/user`:
'.*/openshift-cluster/.*' = 'openshift'
# Or better, to rename every OpenShift cluster at once:
'.*/(?P<var_cluster>[\w-]+)/.*' = '$var_cluster'
# ~/.config/starship.toml

[[kubernetes.contexts]]
# "bold red" style + default symbol when Kubernetes current context name equals "production" *and* the current user
# equals "admin_user"
context_pattern = "production"
user_pattern = "admin_user"
style = "bold red"
context_alias = "prod"
user_alias = "admin"

[[kubernetes.contexts]]
# "green" style + a different symbol when Kubernetes current context name contains openshift
context_pattern = ".*openshift.*"
style = "green"
symbol = "💔 "
context_alias = "openshift"

[[kubernetes.contexts]]
# Using capture groups
# Contexts from GKE, AWS and other cloud providers usually carry additional information, like the region/zone.
# The following entry matches on the GKE format (`gke_projectname_zone_cluster-name`)
# and renames every matching kube context into a more readable format (`gke-cluster-name`):
'gke_.*_(?P<var_cluster>[\w-]+)' = 'gke-$var_cluster'
context_pattern = "gke_.*_(?P<cluster>[\\w-]+)"
context_alias = "gke-$cluster"
```

## Line Break
Expand Down
18 changes: 18 additions & 0 deletions src/configs/kubernetes.rs
Expand Up @@ -18,6 +18,7 @@ pub struct KubernetesConfig<'a> {
pub detect_extensions: Vec<&'a str>,
pub detect_files: Vec<&'a str>,
pub detect_folders: Vec<&'a str>,
pub contexts: Vec<KubernetesContextConfig<'a>>,
}

impl<'a> Default for KubernetesConfig<'a> {
Expand All @@ -32,6 +33,23 @@ impl<'a> Default for KubernetesConfig<'a> {
detect_extensions: vec![],
detect_files: vec![],
detect_folders: vec![],
contexts: vec![],
}
}
}

#[derive(Clone, Deserialize, Serialize, Default)]
#[cfg_attr(
feature = "config-schema",
derive(schemars::JsonSchema),
schemars(deny_unknown_fields)
)]
#[serde(default)]
pub struct KubernetesContextConfig<'a> {
pub context_pattern: &'a str,
pub user_pattern: Option<&'a str>,
pub symbol: Option<&'a str>,
pub style: Option<&'a str>,
pub context_alias: Option<&'a str>,
pub user_alias: Option<&'a str>,
}

0 comments on commit 6b444e0

Please sign in to comment.