Class: Pangea::Magma::Migration

Inherits:
Object
  • Object
show all
Defined in:
lib/pangea/magma/migration.rb

Overview

Typed state-organization migration — the load-bearing surgical operation per theory/PANGEA-MAGMA-ORCHESTRATION.md §III.3 + §V.

Migrations move resources from one workspace’s state to another without recreate, preserving identity (ARNs, UUIDs, etc.).

Authors:

migration = Pangea::Magma::Migration.declare(
  from: :k3s_permissions,
  to:   :platform_iam,
  resources: [
    { kind: :managed,
      address:     'aws_iam_role.k3s_node',
      new_address: 'aws_iam_role.platform_k3s_node' },
  ],
  preserve: [:resource_identity, :tags, :dependent_resources],
  dry_run: true,
)

plan = migration.plan
plan.summary    # human-readable summary
plan.apply!     # → `magma migrate <plan.json>`

The Rust-side ‘magma_migrate::Migration` + `magma migrate` subcommand land in M0.2; this Ruby-side declaration ships now against the typed plan-emission interface.

Defined Under Namespace

Classes: InvariantViolation, Plan, ResourceMove

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(from:, to:, resources:, preserve:, dry_run:, from_state_path: nil, to_state_path: nil) ⇒ Migration

Returns a new instance of Migration.



144
145
146
147
148
149
150
151
152
153
# File 'lib/pangea/magma/migration.rb', line 144

def initialize(from:, to:, resources:, preserve:, dry_run:,
               from_state_path: nil, to_state_path: nil)
  @from            = from
  @to              = to
  @resources       = resources
  @preserve        = preserve
  @dry_run         = dry_run
  @from_state_path = from_state_path
  @to_state_path   = to_state_path
end

Instance Attribute Details

#dry_runObject (readonly)

Returns the value of attribute dry_run.



141
142
143
# File 'lib/pangea/magma/migration.rb', line 141

def dry_run
  @dry_run
end

#fromObject (readonly)

Returns the value of attribute from.



141
142
143
# File 'lib/pangea/magma/migration.rb', line 141

def from
  @from
end

#from_state_pathObject (readonly)

Returns the value of attribute from_state_path.



141
142
143
# File 'lib/pangea/magma/migration.rb', line 141

def from_state_path
  @from_state_path
end

#preserveObject (readonly)

Returns the value of attribute preserve.



141
142
143
# File 'lib/pangea/magma/migration.rb', line 141

def preserve
  @preserve
end

#resourcesObject (readonly)

Returns the value of attribute resources.



141
142
143
# File 'lib/pangea/magma/migration.rb', line 141

def resources
  @resources
end

#toObject (readonly)

Returns the value of attribute to.



141
142
143
# File 'lib/pangea/magma/migration.rb', line 141

def to
  @to
end

#to_state_pathObject (readonly)

Returns the value of attribute to_state_path.



141
142
143
# File 'lib/pangea/magma/migration.rb', line 141

def to_state_path
  @to_state_path
end

Class Method Details

.declare(from:, to:, resources:, preserve: [:resource_identity], dry_run: true, from_state_path: nil, to_state_path: nil) ⇒ Object

Raises:

  • (ArgumentError)


128
129
130
131
132
133
134
135
136
137
138
# File 'lib/pangea/magma/migration.rb', line 128

def declare(from:, to:, resources:, preserve: [:resource_identity],
            dry_run: true, from_state_path: nil, to_state_path: nil)
  raise ArgumentError, 'from required' if from.nil?
  raise ArgumentError, 'to required'   if to.nil?
  raise ArgumentError, 'resources required, got empty' if resources.empty?

  moves = resources.map { |r| ResourceMove.new(**r) }
  new(from: from.to_sym, to: to.to_sym,
      resources: moves, preserve: preserve, dry_run: dry_run,
      from_state_path: from_state_path, to_state_path: to_state_path)
end

Instance Method Details

#planObject

Produce a typed Plan. M0.1 stub: emits a 1:1 action per declared ResourceMove + checks for obvious recreate triggers. M0.2 replaces this with a real ‘magma migrate plan` call.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
# File 'lib/pangea/magma/migration.rb', line 158

def plan
  actions = @resources.map do |r|
    ResourceMove.new(
      kind:        r.kind || :managed,
      address:     r.address,
      new_address: r.new_address || r.address,
      identity:    "<resolved-at-runtime>",
    )
  end
  # Identify any resource whose preserve flags can't be satisfied
  # at the declared level. M0.1 placeholder: empty list.
  would_recreate = []
  warnings = []
  warnings << "address-pattern moves require M0.2 magma migrate to expand" if
    @resources.any? { |r| r.new_address_pattern }

  Plan.new(migration: self, actions: actions,
           would_recreate: would_recreate, warnings: warnings)
end

#to_hObject



178
179
180
181
182
183
184
185
186
187
188
# File 'lib/pangea/magma/migration.rb', line 178

def to_h
  {
    from:            @from.to_s,
    to:              @to.to_s,
    resources:       @resources.map(&:to_h),
    preserve:        @preserve.map(&:to_s),
    dry_run:         @dry_run,
    from_state_path: @from_state_path,
    to_state_path:   @to_state_path,
  }.compact
end

#to_json(*args) ⇒ Object



190
191
192
# File 'lib/pangea/magma/migration.rb', line 190

def to_json(*args)
  to_h.to_json(*args)
end