Skip to content

cub k8s refresh

cub k8s refresh

Bring cluster-side changes to one Kubernetes resource back into its unit

Synopsis

Read one Kubernetes resource from a live cluster, work out what changed in the cluster since the unit's configuration was last released, and write just that back into the unit.

The resource is traced back to its unit by the ConfigHub annotations the release stamped on it: confighub.com/origin, or the legacy confighub.com/SpaceID and confighub.com/UnitSlug pair. There is no --space flag; the annotations name the space.

What refresh actually does, in order:

  1. Reads the live resource and strips everything that is cluster state rather than configuration: status, managedFields, internal metadata, cluster-internal annotations and labels, and every field owned only by a controller (the workload controllers, HPA/VPA, cert-manager, the API server's own admission plugins). Resource quantities are normalized so "2000m" and "2" don't read as a change. "k8s-mf cleanup" shows exactly this transformation.
  2. Diffs what is left against the unit's LastReleasedRevisionNum -- the revision the cluster was actually given. Diffing against the released revision rather than the unit's head is what isolates cluster-side drift from changes made in ConfigHub since the release.
  3. Patches that drift onto the unit's head, restricted to this one resource and to the paths that actually changed. Paths the unit protects as local overrides are not overwritten, and are reported as conflicts instead.

A unit that has never been released has nothing to diff against, and refresh says so rather than treating the whole live object as a change.

Only the named resource is touched. Other resources in the same unit are left alone even when the unit holds several. Comments are left alone too: they live in the unit and never reach the cluster, so nothing the cluster says is evidence about them.

One caveat worth knowing about ArgoCD. Its default resource tracking stamps app.kubernetes.io/instance on everything it manages, and that is one of the Kubernetes recommended labels -- Helm charts and hand-written manifests set it as real configuration. Refresh cannot tell ArgoCD's bookkeeping copy from a value you meant, so it brings the label back like any other field. Switching ArgoCD to annotation tracking (application.resourceTrackingMethod: annotation in argocd-cm) avoids this: the argocd.argoproj.io/tracking-id annotation it writes instead is stripped as cluster state.

Examples:

  # Bring a deployment's cluster-side changes back into its unit
  cub k8s refresh deployment my-app --namespace my-namespace

  # See what refresh would change, without changing it
  cub k8s refresh deployment my-app -n prod --dry-run

  # A cluster-scoped resource
  cub k8s refresh clusterrole my-role

  # Read from a specific cluster
  cub k8s refresh deployment my-app --kubeconfig /path/to/config --kube-context prod
cub k8s refresh <type> <name> [flags]

Options

      --api-version string      API version of the resource (e.g., 'apps/v1', 'v1'). If not specified, common versions will be tried.
      --change-desc string      change description
      --clearance stringArray   class of guarded reason this change is cleared for, as KEY, KEY=VALUE[,VALUE...], KEY!=VALUE[,VALUE...], or !KEY to refuse any path carrying KEY (repeatable). A guarded path this does not cover is not written, and the withheld change is reported as a conflict
      --dry-run                 report what would change without writing it
      --guard stringArray       reason to record on the paths this change writes, as KEY=VALUE (repeatable). A later operation must be cleared for it before overwriting those paths. Adds and overwrites only; retiring a guard is cub unit set-guard --remove-guard
  -h, --help                    help for refresh
      --kube-context string     Kubernetes context to use
      --kubeconfig string       Path to the kubeconfig file to use for CLI requests
  -n, --namespace string        Namespace of the resource (ignored for cluster-scoped resources) (default "default")
  -o, --output string           Output format. One of: json, yaml, name, wide, mutations, jq=<expr>, yq=<expr>, custom-columns=<spec>
      --quiet                   No default output.
      --verbose                 Detailed output, additive with default output

Options inherited from parent commands

      --context string   The context to use for this command
      --debug            Debug output

SEE ALSO