Skip to content

Commit a90a38a

Browse files
committed
Prevent runtime deletion when configured as primary runtime
1 parent d263360 commit a90a38a

8 files changed

Lines changed: 36 additions & 2 deletions

File tree

app/models/runtime.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ class Runtime < ApplicationRecord
1212
has_many :project_assignments, class_name: 'NamespaceProjectRuntimeAssignment', inverse_of: :runtime
1313
has_many :projects, class_name: 'NamespaceProject', through: :project_assignments, source: :namespace_project,
1414
inverse_of: :runtimes
15+
has_many :primary_projects, class_name: 'NamespaceProject', inverse_of: :primary_runtime
1516

1617
has_many :data_types, inverse_of: :runtime
1718
has_many :data_type_identifiers, inverse_of: :runtime

app/services/error_code.rb

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ def self.error_codes
2222
runtime_mismatch: { description: 'Resources are from different runtimes' },
2323
generic_key_not_found: { description: 'The given key was not found in the data type' },
2424
no_primary_runtime: { description: 'The project does not have a primary runtime' },
25+
is_primary_runtime: { description: 'This runtime is the primary runtime of a project' },
2526
invalid_external_identity: { description: 'This external identity is invalid' },
2627
external_identity_does_not_exist: { description: 'This external identity does not exist' },
2728
identity_validation_failed: { description: 'Failed to validate the external identity' },

app/services/runtimes/delete_service.rb

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,11 +16,18 @@ def execute
1616
return ServiceResponse.error(message: 'Missing permissions', error_code: :missing_permission)
1717
end
1818

19+
if runtime.primary_projects.any?
20+
return ServiceResponse.error(
21+
message: 'Runtime is primary runtime in some projects',
22+
error_code: :is_primary_runtime
23+
)
24+
end
25+
1926
transactional do |t|
2027
runtime.delete
2128

2229
if runtime.persisted?
23-
t.rollback_and_return! ServiceResponse.error(message: 'Failed to delete organization',
30+
t.rollback_and_return! ServiceResponse.error(message: 'Failed to delete runtime',
2431
error_code: :invalid_runtime,
2532
details: runtime.errors)
2633
end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# frozen_string_literal: true
2+
3+
class ChangePrimaryRuntimeFkToRestrict < Code0::ZeroTrack::Database::Migration[1.0]
4+
def change
5+
remove_foreign_key :namespace_projects,
6+
:runtimes,
7+
column: :primary_runtime_id,
8+
on_delete: :cascade
9+
10+
add_foreign_key :namespace_projects,
11+
:runtimes,
12+
column: :primary_runtime_id,
13+
on_delete: :restrict
14+
end
15+
end
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2dd6de5b55c1dd2c8dd5fd084e9e0ec5bfed0d4eb804bea4f2a730eecac7b431

db/structure.sql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1417,7 +1417,7 @@ ALTER TABLE ONLY data_type_rules
14171417
ADD CONSTRAINT fk_rails_7759633ff8 FOREIGN KEY (data_type_id) REFERENCES data_types(id) ON DELETE CASCADE;
14181418

14191419
ALTER TABLE ONLY namespace_projects
1420-
ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES runtimes(id) ON DELETE CASCADE;
1420+
ADD CONSTRAINT fk_rails_79012c5895 FOREIGN KEY (primary_runtime_id) REFERENCES runtimes(id) ON DELETE RESTRICT;
14211421

14221422
ALTER TABLE ONLY flows
14231423
ADD CONSTRAINT fk_rails_7de9ce6578 FOREIGN KEY (starting_node_id) REFERENCES node_functions(id) ON DELETE SET NULL;

docs/graphql/enum/errorcodeenum.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ Represents the available error responses
5858
| `INVALID_USER_IDENTITY` | The user identity is invalid because of active model errors |
5959
| `INVALID_USER_SESSION` | The user session is invalid because of active model errors |
6060
| `INVALID_VERIFICATION_CODE` | Invalid verification code provided |
61+
| `IS_PRIMARY_RUNTIME` | This runtime is the primary runtime of a project |
6162
| `LICENSE_NOT_FOUND` | The namespace license with the given identifier was not found |
6263
| `LOADING_IDENTITY_FAILED` | Failed to load user identity from external provider |
6364
| `MFA_FAILED` | Invalid MFA data provided |

spec/services/runtimes/delete_service_spec.rb

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,5 +65,13 @@
6565
target_type: 'Namespace'
6666
)
6767
end
68+
69+
context 'when runtime is primary runtime of a project' do
70+
before do
71+
create(:namespace_project, primary_runtime: runtime, namespace: runtime.namespace)
72+
end
73+
74+
it { expect(service_response.payload[:error_code]).to eq(:is_primary_runtime) }
75+
end
6876
end
6977
end

0 commit comments

Comments
 (0)