Class: RKSeal::Commands::EditLocal

Inherits:
Object
  • Object
show all
Defined in:
lib/rkseal/commands/edit_local.rb

Overview

Orchestrates the offline ‘rkseal edit –local <namespace> <secret-name>` flow: edit a SealedSecret that exists only as a local `<name>.yaml` and was never deployed, so there is no unsealed cluster Secret to recover values from.

A SealedSecret cannot be decrypted client-side, so this flow never shows current values. Instead SealedSecret renders a redacted buffer (every existing key shown as SealedSecret::REDACTED_PLACEHOLDER), and the saved buffer is classified per key:

- **keep:** value left as the placeholder -> the existing ciphertext is
  left byte-for-byte untouched (no rehash, no plaintext needed);
- **reseal:** value replaced, or a brand-new key added -> the new value
  is sealed and merged in via `kubeseal --merge-into`;
- **remove:** an existing key deleted from the buffer -> dropped from
  `spec.encryptedData`.

The ‘type` may also be edited (written to `spec.template.type`). Scope and name/namespace are fixed: kept ciphertext cannot be re-sealed under a different scope/identity without the plaintext rkseal does not have.

The cluster is contacted only to obtain the controller’s PUBLIC cert when a reseal is actually needed (offline if it is already cached) and, with an opt-in ‘–deploy`, to apply the result. Reading current state never hits the cluster.

rubocop:disable Metrics/ClassLength – this flow is a single cohesive orchestration (read local -> redacted buffer -> classify keep/reseal/ remove -> merge/rewrite -> optional deploy); the extra lines are docstrings and small, focused private helpers, each independently testable. Splitting it into verb classes is the anti-pattern this gem avoids.

Examples:

keep/replace/add keys offline, write only

RKSeal::Commands::EditLocal.new(namespace: "app", name: "db").call

Defined Under Namespace

Classes: LocalPlan

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(namespace:, name:, deploy: false, assume_yes: false, string_data: false, kubectl: Kubectl.new, kubeseal: Kubeseal.new, editor: Editor.new, context_guard: nil, prompt: Thor::Shell::Basic.new, workspace: SecureWorkspace, output_dir: Dir.pwd) ⇒ EditLocal

Returns a new instance of EditLocal.

Parameters:

  • namespace (String)

    target namespace (positional CLI arg).

  • name (String)

    Secret name (positional CLI arg).

  • deploy (Boolean) (defaults to: false)

    opt-in deploy after writing; defaults to false.

  • assume_yes (Boolean) (defaults to: false)

    skip the deploy confirmation (with deploy:).

  • string_data (Boolean) (defaults to: false)

    show the redacted keys under ‘stringData` (plaintext) instead of `data` (base64); defaults to false.

  • kubectl (RKSeal::Kubectl) (defaults to: Kubectl.new)

    cluster adapter (apply only).

  • kubeseal (RKSeal::Kubeseal) (defaults to: Kubeseal.new)

    sealing adapter (merge_into).

  • editor (RKSeal::Editor) (defaults to: Editor.new)

    editor launcher.

  • context_guard (RKSeal::ContextGuard, nil) (defaults to: nil)

    deploy gatekeeper.

  • prompt (Thor::Shell::Basic) (defaults to: Thor::Shell::Basic.new)

    shell for the deploy confirmation.

  • workspace (#with) (defaults to: SecureWorkspace)

    RAM-backed scratch provider (block-scoped).

  • output_dir (String) (defaults to: Dir.pwd)

    directory the manifest is read from / written to (CWD).



65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
# File 'lib/rkseal/commands/edit_local.rb', line 65

def initialize(namespace:, name:, deploy: false, assume_yes: false, string_data: false,
               kubectl: Kubectl.new, kubeseal: Kubeseal.new, editor: Editor.new,
               context_guard: nil, prompt: Thor::Shell::Basic.new,
               workspace: SecureWorkspace, output_dir: Dir.pwd)
  @namespace = namespace
  @name = name
  @deploy = deploy
  @assume_yes = assume_yes
  @string_data = string_data
  @kubectl = kubectl
  @kubeseal = kubeseal
  @editor = editor
  @context_guard = context_guard
  @prompt = prompt
  @workspace = workspace
  @output_dir = output_dir
end

Instance Attribute Details

#deployBoolean (readonly)

Returns whether to deploy after writing the manifest.

Returns:

  • (Boolean)

    whether to deploy after writing the manifest.



49
50
51
# File 'lib/rkseal/commands/edit_local.rb', line 49

def deploy
  @deploy
end

#nameString (readonly)

Returns:

  • (String)


47
48
49
# File 'lib/rkseal/commands/edit_local.rb', line 47

def name
  @name
end

#namespaceString (readonly)

Returns:

  • (String)


45
46
47
# File 'lib/rkseal/commands/edit_local.rb', line 45

def namespace
  @namespace
end

Instance Method Details

#callRKSeal::Commands::Result

Run the local edit flow end to end.

Returns:

Raises:



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
# File 'lib/rkseal/commands/edit_local.rb', line 93

def call
  @kubeseal.ensure_available!
  @kubectl.ensure_available! if @deploy

  sealed = SealedSecret.parse(read_local!)
  plan = build_plan(sealed, edit(sealed))
  return unchanged_result unless plan.changes?

  ensure_nonempty!(sealed, plan)
  apply(plan, scope: sealed.scope)

  path = File.expand_path(manifest_path)
  deployed = @deploy && deploy_confirmed?
  @kubectl.apply(file: path) if deployed
  Result.new(secret_name: @name, namespace: @namespace, output_path: path, deployed: deployed)
end