From e0471d56761b5468ec3e4b8b98233fa4f5218e3f Mon Sep 17 00:00:00 2001 From: Chad Woolley Date: Sun, 25 Aug 2024 11:16:17 -0700 Subject: [PATCH] Migrate remote_development_agent_configs table - Migrates from remote_development_agent_configs table to workspaces_agent_configs - Updates all API and code references, but leaves existing table and GraphQL API functional to support zero-downtime deploys with no ActiveRecord or client-side errors. - See https://gitlab.com/gitlab-org/gitlab/-/issues/480135 Changelog: changed --- db/docs/workspaces_agent_configs.yml | 16 + ...5000001_create_workspaces_agent_configs.rb | 30 ++ ...dd_workspaces_agent_configs_projects_fk.rb | 16 + ...kspaces_agent_configs_cluster_agents_fk.rb | 16 + ...dd_workspaces_agent_configs_constraints.rb | 26 ++ ...ent_configs_to_workspaces_agent_configs.rb | 59 ++++ db/schema_migrations/20240825000001 | 1 + db/schema_migrations/20240825000002 | 1 + db/schema_migrations/20240825000003 | 1 + db/schema_migrations/20240825000004 | 1 + db/schema_migrations/20240825000005 | 1 + db/structure.sql | 47 +++ doc/api/graphql/reference/index.md | 43 ++- .../components/get_project_details_query.vue | 8 +- .../get_group_cluster_agents.query.graphql | 2 +- ...e_development_cluster_agents.query.graphql | 2 +- ee/app/finders/ee/clusters/agents_finder.rb | 16 +- .../agent_configs_finder.rb | 10 +- ...remote_development_agent_configs_finder.rb | 36 ++ .../ee/resolvers/clusters/agents_resolver.rb | 7 +- .../graphql/ee/types/clusters/agent_type.rb | 10 +- ...opment_agent_config_for_agent_resolver.rb} | 5 +- ...kspaces_agent_config_for_agent_resolver.rb | 46 +++ .../remote_development_agent_config_type.rb | 3 +- .../workspaces_agent_config_type.rb | 51 +++ ee/app/models/ee/clusters/agent.rb | 14 +- .../remote_development_agent_config.rb | 21 +- ee/app/models/remote_development/workspace.rb | 30 +- .../workspaces_agent_config.rb | 51 +++ .../remote_development_agent_config_policy.rb | 3 +- .../workspaces_agent_config_policy.rb | 15 + ..._agent_configs_network_policy_egress.json} | 2 +- ...onfigs_workspace_container_resources.json} | 2 +- ...240825000001_workspaces_agent_configs.yml} | 10 +- ...ount_remote_agent_configurations_metric.rb | 19 - .../count_workspaces_agent_configs_metric.rb | 19 + .../agent_config_operations/updater.rb | 27 +- .../create/devfile_fetcher.rb | 4 +- .../create/workspace_creator.rb | 2 +- .../output/desired_config_generator.rb | 12 +- .../output/desired_config_generator_v2.rb | 8 +- ee/spec/factories/clusters/agents.rb | 4 +- .../remote_development_agent_configs.rb | 9 - .../remote_development/workspaces.rb | 4 +- .../workspaces_agent_configs.rb | 15 + .../remote_development/workspaces_spec.rb | 4 +- .../workspaces_dropdown_group_spec.rb | 2 +- .../remote_development/workspaces_spec.rb | 6 +- .../finders/ee/clusters/agents_finder_spec.rb | 30 +- .../agent_configs_finder_spec.rb | 4 +- .../cluster_agents_finder_spec.rb | 8 +- ...e_development_agent_configs_finder_spec.rb | 141 ++++++++ .../workspaces_finder_spec.rb | 4 +- .../get_project_details_query_spec.js | 10 +- .../frontend/workspaces/mock_data/index.js | 24 +- .../ee/types/clusters/agent_type_spec.rb | 44 ++- .../clusters/agents_resolver_spec.rb | 67 ++-- ...mote_development_agent_config_type_spec.rb | 3 +- .../workspaces_agent_config_type_spec.rb | 50 +++ ...remote_agent_configurations_metric_spec.rb | 17 - ...nt_workspaces_agent_configs_metric_spec.rb | 17 + .../main_integration_spec.rb | 32 +- .../agent_config_operations/updater_spec.rb | 333 +++++++++--------- .../create/creator_spec.rb | 2 +- .../create/devfile_fetcher_spec.rb | 6 +- .../create/main_integration_spec.rb | 8 +- .../create/workspace_creator_spec.rb | 4 +- .../reconcile/main_integration_spec.rb | 8 +- .../main_reconcile_scenarios_spec.rb | 2 +- .../output/desired_config_generator_spec.rb | 14 +- .../desired_config_generator_v2_spec.rb | 6 +- ...orkspaces_from_agent_infos_updater_spec.rb | 2 +- .../workspaces_to_be_returned_finder_spec.rb | 2 +- .../workspaces_to_be_returned_updater_spec.rb | 2 +- ee/spec/models/ee/clusters/agent_spec.rb | 34 +- .../remote_development_agent_config_spec.rb | 22 +- .../remote_development/workspace_spec.rb | 92 ++--- .../workspaces_agent_config_spec.rb | 132 +++++++ ...te_development_agent_config_policy_spec.rb | 8 +- .../workspace_policy_spec.rb | 2 +- .../workspaces_agent_config_policy_spec.rb | 43 +++ .../workspace_operations/create_spec.rb | 2 +- .../workspace_operations/update_spec.rb | 2 +- .../remote_development_agent_config_spec.rb | 5 +- .../with_available_filter_arg_spec.rb | 2 +- .../with_directly_mapped_filter_arg_spec.rb | 4 +- .../with_unmapped_filter_arg_spec.rb | 4 +- .../workspaces_agent_config_spec.rb | 91 +++++ .../api/graphql/remote_development/shared.rb | 4 +- .../requests/api/internal/kubernetes_spec.rb | 6 +- .../remote_development/integration_spec.rb | 12 +- locale/am_ET/gitlab.po | 5 +- locale/ar_SA/gitlab.po | 5 +- locale/as_IN/gitlab.po | 5 +- locale/az_AZ/gitlab.po | 5 +- locale/ba_RU/gitlab.po | 5 +- locale/be_BY/gitlab.po | 5 +- locale/bg/gitlab.po | 5 +- locale/bn_BD/gitlab.po | 5 +- locale/bn_IN/gitlab.po | 5 +- locale/br_FR/gitlab.po | 5 +- locale/bs_BA/gitlab.po | 5 +- locale/ca_ES/gitlab.po | 5 +- locale/cs_CZ/gitlab.po | 5 +- locale/cy_GB/gitlab.po | 5 +- locale/da_DK/gitlab.po | 5 +- locale/de/gitlab.po | 9 +- locale/el_GR/gitlab.po | 5 +- locale/en_GB/gitlab.po | 5 +- locale/eo/gitlab.po | 5 +- locale/es/gitlab.po | 5 +- locale/et_EE/gitlab.po | 5 +- locale/eu_ES/gitlab.po | 5 +- locale/fa_IR/gitlab.po | 5 +- locale/fi_FI/gitlab.po | 5 +- locale/fil_PH/gitlab.po | 5 +- locale/fr/gitlab.po | 9 +- locale/gitlab.pot | 4 +- locale/gl_ES/gitlab.po | 5 +- locale/he_IL/gitlab.po | 5 +- locale/hi_IN/gitlab.po | 5 +- locale/hr_HR/gitlab.po | 5 +- locale/hu_HU/gitlab.po | 5 +- locale/hy_AM/gitlab.po | 5 +- locale/id_ID/gitlab.po | 5 +- locale/ig_NG/gitlab.po | 5 +- locale/is_IS/gitlab.po | 5 +- locale/it/gitlab.po | 5 +- locale/ja/gitlab.po | 9 +- locale/ka_GE/gitlab.po | 5 +- locale/kab/gitlab.po | 5 +- locale/ko/gitlab.po | 5 +- locale/ku_TR/gitlab.po | 5 +- locale/ky_KG/gitlab.po | 5 +- locale/lt_LT/gitlab.po | 5 +- locale/mk_MK/gitlab.po | 5 +- locale/ml_IN/gitlab.po | 5 +- locale/mn_MN/gitlab.po | 5 +- locale/ms_MY/gitlab.po | 5 +- locale/nb_NO/gitlab.po | 5 +- locale/ne_NP/gitlab.po | 5 +- locale/nl_NL/gitlab.po | 5 +- locale/or_IN/gitlab.po | 5 +- locale/pa_IN/gitlab.po | 5 +- locale/pa_PK/gitlab.po | 5 +- locale/pl_PL/gitlab.po | 5 +- locale/pt_BR/gitlab.po | 5 +- locale/pt_PT/gitlab.po | 5 +- locale/ro_RO/gitlab.po | 5 +- locale/ru/gitlab.po | 5 +- locale/si_LK/gitlab.po | 5 +- locale/sk_SK/gitlab.po | 5 +- locale/sl_SI/gitlab.po | 5 +- locale/sq_AL/gitlab.po | 5 +- locale/sr_CS/gitlab.po | 5 +- locale/sr_SP/gitlab.po | 5 +- locale/sv_SE/gitlab.po | 5 +- locale/sw_KE/gitlab.po | 5 +- locale/ta_IN/gitlab.po | 5 +- locale/th_TH/gitlab.po | 5 +- locale/ti_ER/gitlab.po | 5 +- locale/tr_TR/gitlab.po | 5 +- locale/uk/gitlab.po | 5 +- locale/ur_PK/gitlab.po | 5 +- locale/uz_UZ/gitlab.po | 5 +- locale/vi_VN/gitlab.po | 5 +- locale/zh_CN/gitlab.po | 7 +- locale/zh_HK/gitlab.po | 5 +- locale/zh_TW/gitlab.po | 9 +- .../run-smoke-test-suite.sh | 2 + 170 files changed, 1685 insertions(+), 766 deletions(-) create mode 100644 db/docs/workspaces_agent_configs.yml create mode 100644 db/migrate/20240825000001_create_workspaces_agent_configs.rb create mode 100644 db/migrate/20240825000002_add_workspaces_agent_configs_projects_fk.rb create mode 100644 db/migrate/20240825000003_add_workspaces_agent_configs_cluster_agents_fk.rb create mode 100644 db/migrate/20240825000004_add_workspaces_agent_configs_constraints.rb create mode 100644 db/migrate/20240825000005_migrate_remote_development_agent_configs_to_workspaces_agent_configs.rb create mode 100644 db/schema_migrations/20240825000001 create mode 100644 db/schema_migrations/20240825000002 create mode 100644 db/schema_migrations/20240825000003 create mode 100644 db/schema_migrations/20240825000004 create mode 100644 db/schema_migrations/20240825000005 create mode 100644 ee/app/finders/remote_development/remote_development_agent_configs_finder.rb rename ee/app/graphql/resolvers/remote_development/{agent_config_for_agent_resolver.rb => remote_development_agent_config_for_agent_resolver.rb} (82%) create mode 100644 ee/app/graphql/resolvers/remote_development/workspaces_agent_config_for_agent_resolver.rb create mode 100644 ee/app/graphql/types/remote_development/workspaces_agent_config_type.rb create mode 100644 ee/app/models/remote_development/workspaces_agent_config.rb create mode 100644 ee/app/policies/remote_development/workspaces_agent_config_policy.rb rename ee/app/validators/json_schemas/{remote_development_agent_configs_network_policy_egress.json => workspaces_agent_configs_network_policy_egress.json} (77%) rename ee/app/validators/json_schemas/{remote_development_agent_configs_workspace_container_resources.json => workspaces_agent_configs_workspace_container_resources.json} (91%) rename ee/config/metrics/counts_all/{20230510151446_remote_agent_configurations.yml => 20240825000001_workspaces_agent_configs.yml} (58%) delete mode 100644 ee/lib/gitlab/usage/metrics/instrumentations/count_remote_agent_configurations_metric.rb create mode 100644 ee/lib/gitlab/usage/metrics/instrumentations/count_workspaces_agent_configs_metric.rb delete mode 100644 ee/spec/factories/remote_development/remote_development_agent_configs.rb create mode 100644 ee/spec/factories/remote_development/workspaces_agent_configs.rb create mode 100644 ee/spec/finders/remote_development/remote_development_agent_configs_finder_spec.rb create mode 100644 ee/spec/graphql/types/remote_development/workspaces_agent_config_type_spec.rb delete mode 100644 ee/spec/lib/gitlab/usage/metrics/instrumentations/count_remote_agent_configurations_metric_spec.rb create mode 100644 ee/spec/lib/gitlab/usage/metrics/instrumentations/count_workspaces_agent_configs_metric_spec.rb create mode 100644 ee/spec/models/remote_development/workspaces_agent_config_spec.rb create mode 100644 ee/spec/policies/remote_development/workspaces_agent_config_policy_spec.rb create mode 100644 ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/workspaces_agent_config_spec.rb diff --git a/db/docs/workspaces_agent_configs.yml b/db/docs/workspaces_agent_configs.yml new file mode 100644 index 00000000000000..1ebcdbbfc6856d --- /dev/null +++ b/db/docs/workspaces_agent_configs.yml @@ -0,0 +1,16 @@ +--- +table_name: workspaces_agent_configs +classes: +- RemoteDevelopment::RemoteDevelopmentAgentConfig +- RemoteDevelopment::WorkspacesAgentConfig +- Workspaces::WorkspacesAgentConfig +feature_categories: +- remote_development +description: Workspaces Cluster Agent Configs +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163846 +milestone: '17.4' +gitlab_schema: gitlab_main_cell +allow_cross_foreign_keys: +- gitlab_main_clusterwide +sharding_key: + project_id: projects diff --git a/db/migrate/20240825000001_create_workspaces_agent_configs.rb b/db/migrate/20240825000001_create_workspaces_agent_configs.rb new file mode 100644 index 00000000000000..356209a1ffe3ef --- /dev/null +++ b/db/migrate/20240825000001_create_workspaces_agent_configs.rb @@ -0,0 +1,30 @@ +# frozen_string_literal: true + +class CreateWorkspacesAgentConfigs < Gitlab::Database::Migration[2.2] + milestone "17.4" + + # noinspection RubyResolve -- RubyMine doesn't resolve t.bigint. TODO: Open ticket and link on https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/ + def change + create_table(:workspaces_agent_configs) do |t| + t.timestamps_with_timezone null: false + t.bigint "cluster_agent_id", null: false + t.bigint "workspaces_quota", default: -1, null: false + t.bigint "workspaces_per_user_quota", default: -1, null: false + t.bigint "project_id", null: false + t.column "default_max_hours_before_termination", :smallint, default: 24, null: false + t.column "max_hours_before_termination_limit", :smallint, default: 120, null: false + t.boolean "enabled", null: false + t.boolean "network_policy_enabled", default: true, null: false + t.text "dns_zone", limit: 256, null: false + # Kubernetes namespaces are limited to 63 characters + t.text "gitlab_workspaces_proxy_namespace", limit: 63, default: "gitlab-workspaces", null: false + t.jsonb "network_policy_egress", + default: [{ "allow" => "0.0.0.0/0", "except" => %w[10.0.0.0/8 172.16.0.0/12 192.168.0.0/16] }], null: false + t.jsonb "default_resources_per_workspace_container", default: {}, null: false + t.jsonb "max_resources_per_workspace", default: {}, null: false + + t.index :cluster_agent_id, unique: true, name: "index_workspaces_agent_configs_on_unique_cluster_agent_id" + t.index :project_id + end + end +end diff --git a/db/migrate/20240825000002_add_workspaces_agent_configs_projects_fk.rb b/db/migrate/20240825000002_add_workspaces_agent_configs_projects_fk.rb new file mode 100644 index 00000000000000..b37935cbd301ec --- /dev/null +++ b/db/migrate/20240825000002_add_workspaces_agent_configs_projects_fk.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddWorkspacesAgentConfigsProjectsFk < Gitlab::Database::Migration[2.2] + milestone "17.4" + disable_ddl_transaction! + + TABLE_NAME = :workspaces_agent_configs + + def up + add_concurrent_foreign_key TABLE_NAME, :projects, column: :project_id, on_delete: :cascade + end + + def down + with_lock_retries { remove_foreign_key TABLE_NAME, column: :project_id } + end +end diff --git a/db/migrate/20240825000003_add_workspaces_agent_configs_cluster_agents_fk.rb b/db/migrate/20240825000003_add_workspaces_agent_configs_cluster_agents_fk.rb new file mode 100644 index 00000000000000..c04fd2edb3de0c --- /dev/null +++ b/db/migrate/20240825000003_add_workspaces_agent_configs_cluster_agents_fk.rb @@ -0,0 +1,16 @@ +# frozen_string_literal: true + +class AddWorkspacesAgentConfigsClusterAgentsFk < Gitlab::Database::Migration[2.2] + milestone "17.4" + disable_ddl_transaction! + + TABLE_NAME = :workspaces_agent_configs + + def up + add_concurrent_foreign_key TABLE_NAME, :cluster_agents, column: :cluster_agent_id, on_delete: :cascade + end + + def down + with_lock_retries { remove_foreign_key TABLE_NAME, column: :cluster_agent_id } + end +end diff --git a/db/migrate/20240825000004_add_workspaces_agent_configs_constraints.rb b/db/migrate/20240825000004_add_workspaces_agent_configs_constraints.rb new file mode 100644 index 00000000000000..867fa2ae3e6a5d --- /dev/null +++ b/db/migrate/20240825000004_add_workspaces_agent_configs_constraints.rb @@ -0,0 +1,26 @@ +# frozen_string_literal: true + +class AddWorkspacesAgentConfigsConstraints < Gitlab::Database::Migration[2.2] + milestone "17.4" + disable_ddl_transaction! + + TABLE_NAME = :workspaces_agent_configs + + def constraint_1_name + check_constraint_name TABLE_NAME, :default_max_hours_before_termination, "max_size_1_year" + end + + def constraint_2_name + check_constraint_name TABLE_NAME, :max_hours_before_termination_limit, "max_size_1_year" + end + + def up + add_check_constraint TABLE_NAME, "default_max_hours_before_termination <= 8760", constraint_1_name + add_check_constraint TABLE_NAME, "max_hours_before_termination_limit <= 8760", constraint_2_name + end + + def down + remove_check_constraint TABLE_NAME, constraint_1_name + remove_check_constraint TABLE_NAME, constraint_2_name + end +end diff --git a/db/migrate/20240825000005_migrate_remote_development_agent_configs_to_workspaces_agent_configs.rb b/db/migrate/20240825000005_migrate_remote_development_agent_configs_to_workspaces_agent_configs.rb new file mode 100644 index 00000000000000..241a7952b10d0a --- /dev/null +++ b/db/migrate/20240825000005_migrate_remote_development_agent_configs_to_workspaces_agent_configs.rb @@ -0,0 +1,59 @@ +# frozen_string_literal: true + +class MigrateRemoteDevelopmentAgentConfigsToWorkspacesAgentConfigs < Gitlab::Database::Migration[2.2] + milestone "17.4" + disable_ddl_transaction! + + restrict_gitlab_migration gitlab_schema: :gitlab_main + + SELECTED_COLUMNS = %w[ + created_at + updated_at + cluster_agent_id + enabled + network_policy_enabled + workspaces_quota + workspaces_per_user_quota + project_id + default_max_hours_before_termination + max_hours_before_termination_limit + dns_zone + gitlab_workspaces_proxy_namespace + network_policy_egress + default_resources_per_workspace_container + max_resources_per_workspace + ].join(',') + + INSERTED_VALUES = %w[ + remote_development_agent_configs.created_at + remote_development_agent_configs.updated_at + cluster_agent_id + enabled + network_policy_enabled + workspaces_quota + workspaces_per_user_quota + cluster_agents.project_id + default_max_hours_before_termination + max_hours_before_termination_limit + dns_zone + gitlab_workspaces_proxy_namespace + network_policy_egress + default_resources_per_workspace_container + max_resources_per_workspace + ].join(',') + + def up + connection.execute(<<~SQL) + INSERT INTO workspaces_agent_configs (#{SELECTED_COLUMNS}) + SELECT #{INSERTED_VALUES} + FROM remote_development_agent_configs + JOIN cluster_agents ON remote_development_agent_configs.cluster_agent_id = cluster_agents.id + SQL + end + + def down + connection.execute(<<~SQL) + DELETE FROM workspaces_agent_configs + SQL + end +end diff --git a/db/schema_migrations/20240825000001 b/db/schema_migrations/20240825000001 new file mode 100644 index 00000000000000..a07f277bd1086f --- /dev/null +++ b/db/schema_migrations/20240825000001 @@ -0,0 +1 @@ +92c7c99daeef6c6c75ba99afa1883878db12980e2e16964b141cc77ce6186503 \ No newline at end of file diff --git a/db/schema_migrations/20240825000002 b/db/schema_migrations/20240825000002 new file mode 100644 index 00000000000000..65c26ac328e47f --- /dev/null +++ b/db/schema_migrations/20240825000002 @@ -0,0 +1 @@ +99a71bdbf4e693f9817a08214dc96e3c7b78b25c3c2d6c9be308b36289adc8f6 \ No newline at end of file diff --git a/db/schema_migrations/20240825000003 b/db/schema_migrations/20240825000003 new file mode 100644 index 00000000000000..65c3e93e68fbf5 --- /dev/null +++ b/db/schema_migrations/20240825000003 @@ -0,0 +1 @@ +0ef51524b9a8637664b4e3c4f853fcdcbde7bc599db36a506f7315024fad5fc0 \ No newline at end of file diff --git a/db/schema_migrations/20240825000004 b/db/schema_migrations/20240825000004 new file mode 100644 index 00000000000000..1d66171e3f11d9 --- /dev/null +++ b/db/schema_migrations/20240825000004 @@ -0,0 +1 @@ +1c8fe62730456b7dd13402ea375c5b91e6d04aaafe0eae9d611ccd527fbce9e8 \ No newline at end of file diff --git a/db/schema_migrations/20240825000005 b/db/schema_migrations/20240825000005 new file mode 100644 index 00000000000000..f920474ca6c6b5 --- /dev/null +++ b/db/schema_migrations/20240825000005 @@ -0,0 +1 @@ +40bf6d1eb91bd2fdfb7b66107bc7e8467211d3fca711e85c36d47b5d8219ce1c \ No newline at end of file diff --git a/db/structure.sql b/db/structure.sql index cab6be99970e3c..a7da0749a788a7 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -20443,6 +20443,38 @@ CREATE TABLE workspaces ( CONSTRAINT check_ffa8cad434 CHECK ((char_length(url_prefix) <= 256)) ); +CREATE TABLE workspaces_agent_configs ( + id bigint NOT NULL, + created_at timestamp with time zone NOT NULL, + updated_at timestamp with time zone NOT NULL, + cluster_agent_id bigint NOT NULL, + workspaces_quota bigint DEFAULT '-1'::integer NOT NULL, + workspaces_per_user_quota bigint DEFAULT '-1'::integer NOT NULL, + project_id bigint NOT NULL, + default_max_hours_before_termination smallint DEFAULT 24 NOT NULL, + max_hours_before_termination_limit smallint DEFAULT 120 NOT NULL, + enabled boolean NOT NULL, + network_policy_enabled boolean DEFAULT true NOT NULL, + dns_zone text NOT NULL, + gitlab_workspaces_proxy_namespace text DEFAULT 'gitlab-workspaces'::text NOT NULL, + network_policy_egress jsonb DEFAULT '[{"allow": "0.0.0.0/0", "except": ["10.0.0.0/8", "172.16.0.0/12", "192.168.0.0/16"]}]'::jsonb NOT NULL, + default_resources_per_workspace_container jsonb DEFAULT '{}'::jsonb NOT NULL, + max_resources_per_workspace jsonb DEFAULT '{}'::jsonb NOT NULL, + CONSTRAINT check_58759a890a CHECK ((char_length(dns_zone) <= 256)), + CONSTRAINT check_dca877fba1 CHECK ((default_max_hours_before_termination <= 8760)), + CONSTRAINT check_eab6e375ad CHECK ((max_hours_before_termination_limit <= 8760)), + CONSTRAINT check_ee2464835c CHECK ((char_length(gitlab_workspaces_proxy_namespace) <= 63)) +); + +CREATE SEQUENCE workspaces_agent_configs_id_seq + START WITH 1 + INCREMENT BY 1 + NO MINVALUE + NO MAXVALUE + CACHE 1; + +ALTER SEQUENCE workspaces_agent_configs_id_seq OWNED BY workspaces_agent_configs.id; + CREATE SEQUENCE workspaces_id_seq START WITH 1 INCREMENT BY 1 @@ -22299,6 +22331,8 @@ ALTER TABLE ONLY workspace_variables ALTER COLUMN id SET DEFAULT nextval('worksp ALTER TABLE ONLY workspaces ALTER COLUMN id SET DEFAULT nextval('workspaces_id_seq'::regclass); +ALTER TABLE ONLY workspaces_agent_configs ALTER COLUMN id SET DEFAULT nextval('workspaces_agent_configs_id_seq'::regclass); + ALTER TABLE ONLY x509_certificates ALTER COLUMN id SET DEFAULT nextval('x509_certificates_id_seq'::regclass); ALTER TABLE ONLY x509_commit_signatures ALTER COLUMN id SET DEFAULT nextval('x509_commit_signatures_id_seq'::regclass); @@ -25092,6 +25126,9 @@ ALTER TABLE ONLY work_item_widget_definitions ALTER TABLE ONLY workspace_variables ADD CONSTRAINT workspace_variables_pkey PRIMARY KEY (id); +ALTER TABLE ONLY workspaces_agent_configs + ADD CONSTRAINT workspaces_agent_configs_pkey PRIMARY KEY (id); + ALTER TABLE ONLY workspaces ADD CONSTRAINT workspaces_pkey PRIMARY KEY (id); @@ -30646,6 +30683,10 @@ CREATE INDEX index_workspace_variables_on_project_id ON workspace_variables USIN CREATE INDEX index_workspace_variables_on_workspace_id ON workspace_variables USING btree (workspace_id); +CREATE INDEX index_workspaces_agent_configs_on_project_id ON workspaces_agent_configs USING btree (project_id); + +CREATE UNIQUE INDEX index_workspaces_agent_configs_on_unique_cluster_agent_id ON workspaces_agent_configs USING btree (cluster_agent_id); + CREATE INDEX index_workspaces_on_cluster_agent_id ON workspaces USING btree (cluster_agent_id); CREATE UNIQUE INDEX index_workspaces_on_name ON workspaces USING btree (name); @@ -33655,6 +33696,9 @@ ALTER TABLE ONLY todos ALTER TABLE ONLY packages_debian_group_architectures ADD CONSTRAINT fk_92714bcab1 FOREIGN KEY (group_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY workspaces_agent_configs + ADD CONSTRAINT fk_94660551c8 FOREIGN KEY (cluster_agent_id) REFERENCES cluster_agents(id) ON DELETE CASCADE; + ALTER TABLE ONLY dast_site_profiles_builds ADD CONSTRAINT fk_94e80df60e FOREIGN KEY (dast_site_profile_id) REFERENCES dast_site_profiles(id) ON DELETE CASCADE; @@ -34282,6 +34326,9 @@ ALTER TABLE ONLY epic_user_mentions ALTER TABLE ONLY observability_metrics_issues_connections ADD CONSTRAINT fk_f218d84a14 FOREIGN KEY (namespace_id) REFERENCES namespaces(id) ON DELETE CASCADE; +ALTER TABLE ONLY workspaces_agent_configs + ADD CONSTRAINT fk_f25d0fbfae FOREIGN KEY (project_id) REFERENCES projects(id) ON DELETE CASCADE; + ALTER TABLE p_ci_pipeline_variables ADD CONSTRAINT fk_f29c5f4380_p FOREIGN KEY (partition_id, pipeline_id) REFERENCES ci_pipelines(partition_id, id) ON UPDATE CASCADE ON DELETE CASCADE; diff --git a/doc/api/graphql/reference/index.md b/doc/api/graphql/reference/index.md index 1f2d787439ca28..51247088bdeea1 100644 --- a/doc/api/graphql/reference/index.md +++ b/doc/api/graphql/reference/index.md @@ -19185,12 +19185,13 @@ GitLab CI/CD configuration template. | `id` | [`ID!`](#id) | ID of the cluster agent. | | `name` | [`String`](#string) | Name of the cluster agent. | | `project` | [`Project`](#project) | Project the cluster agent is associated with. | -| `remoteDevelopmentAgentConfig` | [`RemoteDevelopmentAgentConfig`](#remotedevelopmentagentconfig) | Remote development agent config for the cluster agent. | +| `remoteDevelopmentAgentConfig` **{warning-solid}** | [`RemoteDevelopmentAgentConfig`](#remotedevelopmentagentconfig) | **Deprecated** in GitLab 17.10. Use workspaces_agent_config field instead. | | `tokens` | [`ClusterAgentTokenConnection`](#clusteragenttokenconnection) | Tokens associated with the cluster agent. (see [Connections](#connections)) | | `updatedAt` | [`Time`](#time) | Timestamp the cluster agent was updated. | | `userAccessAuthorizations` | [`ClusterAgentAuthorizationUserAccess`](#clusteragentauthorizationuseraccess) | User access config for the cluster agent. | | `vulnerabilityImages` | [`VulnerabilityContainerImageConnection`](#vulnerabilitycontainerimageconnection) | Container images reported on the agent vulnerabilities. (see [Connections](#connections)) | | `webPath` | [`String`](#string) | Web path of the cluster agent. | +| `workspacesAgentConfig` | [`WorkspacesAgentConfig`](#workspacesagentconfig) | Workspaces agent config for the cluster agent. | #### Fields with arguments @@ -22927,9 +22928,10 @@ four standard [pagination arguments](#pagination-arguments): | Name | Type | Description | | ---- | ---- | ----------- | -| `hasRemoteDevelopmentAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated remote development agent config. | +| `hasRemoteDevelopmentAgentConfig` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in GitLab 17.10. Use has_workspaces_agent_config filter instead. | | `hasRemoteDevelopmentEnabled` | [`Boolean`](#boolean) | Returns only cluster agents which have been enabled with the remote development feature. | | `hasVulnerabilities` | [`Boolean`](#boolean) | Returns only cluster agents which have vulnerabilities. | +| `hasWorkspacesAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated workspaces agent config. | ##### `Group.codeCoverageActivities` @@ -24602,9 +24604,10 @@ four standard [pagination arguments](#pagination-arguments): | Name | Type | Description | | ---- | ---- | ----------- | -| `hasRemoteDevelopmentAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated remote development agent config. | +| `hasRemoteDevelopmentAgentConfig` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in GitLab 17.10. Use has_workspaces_agent_config filter instead. | | `hasRemoteDevelopmentEnabled` | [`Boolean`](#boolean) | Returns only cluster agents which have been enabled with the remote development feature. | | `hasVulnerabilities` | [`Boolean`](#boolean) | Returns only cluster agents which have vulnerabilities. | +| `hasWorkspacesAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated workspaces agent config. | ##### `InstanceSecurityDashboard.projects` @@ -29269,9 +29272,10 @@ Returns [`ClusterAgent`](#clusteragent). | Name | Type | Description | | ---- | ---- | ----------- | -| `hasRemoteDevelopmentAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated remote development agent config. | +| `hasRemoteDevelopmentAgentConfig` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in GitLab 17.10. Use has_workspaces_agent_config filter instead. | | `hasRemoteDevelopmentEnabled` | [`Boolean`](#boolean) | Returns only cluster agents which have been enabled with the remote development feature. | | `hasVulnerabilities` | [`Boolean`](#boolean) | Returns only cluster agents which have vulnerabilities. | +| `hasWorkspacesAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated workspaces agent config. | | `name` | [`String!`](#string) | Name of the cluster agent. | ##### `Project.clusterAgents` @@ -29288,9 +29292,10 @@ four standard [pagination arguments](#pagination-arguments): | Name | Type | Description | | ---- | ---- | ----------- | -| `hasRemoteDevelopmentAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated remote development agent config. | +| `hasRemoteDevelopmentAgentConfig` **{warning-solid}** | [`Boolean`](#boolean) | **Deprecated** in GitLab 17.10. Use has_workspaces_agent_config filter instead. | | `hasRemoteDevelopmentEnabled` | [`Boolean`](#boolean) | Returns only cluster agents which have been enabled with the remote development feature. | | `hasVulnerabilities` | [`Boolean`](#boolean) | Returns only cluster agents which have vulnerabilities. | +| `hasWorkspacesAgentConfig` | [`Boolean`](#boolean) | Returns only cluster agents which have an associated workspaces agent config. | ##### `Project.commitReferences` @@ -34821,6 +34826,28 @@ Represents a remote development workspace. | `url` | [`String!`](#string) | URL of the workspace. | | `user` | [`UserCore!`](#usercore) | Owner of the workspace. | +### `WorkspacesAgentConfig` + +Represents a workspaces agent config. + +#### Fields + +| Name | Type | Description | +| ---- | ---- | ----------- | +| `clusterAgent` | [`ClusterAgent!`](#clusteragent) | Cluster agent that the workspaces agent config belongs to. | +| `createdAt` | [`Time!`](#time) | Timestamp of when the workspaces agent config was created. | +| `defaultMaxHoursBeforeTermination` | [`Int!`](#int) | Default max hours before worksapce termination of the workspaces agent config. | +| `dnsZone` | [`String!`](#string) | DNS zone where workspaces are available. | +| `enabled` | [`Boolean!`](#boolean) | Indicates whether remote development is enabled for the GitLab agent. | +| `gitlabWorkspacesProxyNamespace` | [`String!`](#string) | Namespace where gitlab-workspaces-proxy is installed. | +| `id` | [`RemoteDevelopmentWorkspacesAgentConfigID!`](#remotedevelopmentworkspacesagentconfigid) | Global ID of the workspaces agent config. | +| `maxHoursBeforeTerminationLimit` | [`Int!`](#int) | Max hours before worksapce termination limit of the workspaces agent config. | +| `networkPolicyEnabled` | [`Boolean!`](#boolean) | Whether the network policy of the workspaces agent config is enabled. | +| `projectId` | [`ID`](#id) | ID of the project that the workspaces agent config belongs to. | +| `updatedAt` | [`Time!`](#time) | Timestamp of the last update to any mutable workspaces agent config property. | +| `workspacesPerUserQuota` | [`Int!`](#int) | Maximum number of workspaces per user. | +| `workspacesQuota` | [`Int!`](#int) | Maximum number of workspaces for the GitLab agent. | + ### `X509Certificate` Represents an X.509 certificate. @@ -39078,6 +39105,12 @@ A `RemoteDevelopmentWorkspaceID` is a global ID. It is encoded as a string. An example `RemoteDevelopmentWorkspaceID` is: `"gid://gitlab/RemoteDevelopment::Workspace/1"`. +### `RemoteDevelopmentWorkspacesAgentConfigID` + +A `RemoteDevelopmentWorkspacesAgentConfigID` is a global ID. It is encoded as a string. + +An example `RemoteDevelopmentWorkspacesAgentConfigID` is: `"gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/1"`. + ### `SecurityTrainingProviderID` A `SecurityTrainingProviderID` is a global ID. It is encoded as a string. diff --git a/ee/app/assets/javascripts/workspaces/common/components/get_project_details_query.vue b/ee/app/assets/javascripts/workspaces/common/components/get_project_details_query.vue index c0d33b1ca95b83..d35cfbf65de3f3 100644 --- a/ee/app/assets/javascripts/workspaces/common/components/get_project_details_query.vue +++ b/ee/app/assets/javascripts/workspaces/common/components/get_project_details_query.vue @@ -114,11 +114,11 @@ export default { return { clusterAgents: data.namespace?.remoteDevelopmentClusterAgents?.nodes.map( - ({ id, name, project, remoteDevelopmentAgentConfig }) => ({ + ({ id, name, project, workspacesAgentConfig }) => ({ value: id, text: `${project.nameWithNamespace} / ${name}`, defaultMaxHoursBeforeTermination: - remoteDevelopmentAgentConfig.defaultMaxHoursBeforeTermination, + workspacesAgentConfig.defaultMaxHoursBeforeTermination, }), ) || [], }; @@ -164,11 +164,11 @@ export default { return { result: data.group?.clusterAgents?.nodes.map( - ({ id, name, project, remoteDevelopmentAgentConfig }) => ({ + ({ id, name, project, workspacesAgentConfig }) => ({ value: id, text: `${project.nameWithNamespace} / ${name}`, defaultMaxHoursBeforeTermination: - remoteDevelopmentAgentConfig.defaultMaxHoursBeforeTermination, + workspacesAgentConfig.defaultMaxHoursBeforeTermination, }), ) || [], }; diff --git a/ee/app/assets/javascripts/workspaces/common/graphql/queries/get_group_cluster_agents.query.graphql b/ee/app/assets/javascripts/workspaces/common/graphql/queries/get_group_cluster_agents.query.graphql index 698a2329885fab..e0fff6bbf1572a 100644 --- a/ee/app/assets/javascripts/workspaces/common/graphql/queries/get_group_cluster_agents.query.graphql +++ b/ee/app/assets/javascripts/workspaces/common/graphql/queries/get_group_cluster_agents.query.graphql @@ -9,7 +9,7 @@ query getGroupClusterAgents($groupPath: ID!) { id nameWithNamespace } - remoteDevelopmentAgentConfig { + workspacesAgentConfig { id defaultMaxHoursBeforeTermination } diff --git a/ee/app/assets/javascripts/workspaces/common/graphql/queries/get_remote_development_cluster_agents.query.graphql b/ee/app/assets/javascripts/workspaces/common/graphql/queries/get_remote_development_cluster_agents.query.graphql index 5f3e653a627014..548fb3219419be 100644 --- a/ee/app/assets/javascripts/workspaces/common/graphql/queries/get_remote_development_cluster_agents.query.graphql +++ b/ee/app/assets/javascripts/workspaces/common/graphql/queries/get_remote_development_cluster_agents.query.graphql @@ -9,7 +9,7 @@ query getRemoteDevelopmentClusterAgents($namespace: ID!) { id nameWithNamespace } - remoteDevelopmentAgentConfig { + workspacesAgentConfig { id defaultMaxHoursBeforeTermination } diff --git a/ee/app/finders/ee/clusters/agents_finder.rb b/ee/app/finders/ee/clusters/agents_finder.rb index f17bf073593dc9..ddcf4bc518f03c 100644 --- a/ee/app/finders/ee/clusters/agents_finder.rb +++ b/ee/app/finders/ee/clusters/agents_finder.rb @@ -16,15 +16,21 @@ module AgentsFinder private override :filter_clusters + def filter_clusters(agents) agents = super(agents) agents = agents.has_vulnerabilities(params[:has_vulnerabilities]) unless params[:has_vulnerabilities].nil? - case params[:has_remote_development_agent_config] - when true - agents = agents.with_remote_development_agent_config - when false - agents = agents.without_remote_development_agent_config + # TODO: clusterAgent.hasRemoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 + if !params[:has_workspaces_agent_config].nil? || !params[:has_remote_development_agent_config].nil? + has_config = + params[:has_workspaces_agent_config] == true || params[:has_remote_development_agent_config] == true + case has_config + when true + agents = agents.with_workspaces_agent_config + when false + agents = agents.without_workspaces_agent_config + end end agents = agents.with_remote_development_enabled if params[:has_remote_development_enabled] diff --git a/ee/app/finders/remote_development/agent_configs_finder.rb b/ee/app/finders/remote_development/agent_configs_finder.rb index 9f784626653f03..30bf3079e7e3db 100644 --- a/ee/app/finders/remote_development/agent_configs_finder.rb +++ b/ee/app/finders/remote_development/agent_configs_finder.rb @@ -5,12 +5,12 @@ class AgentConfigsFinder # Executes a query to find agent configurations based on the provided filter arguments. # # @param [User] current_user The user making the request. Must have permission to access workspaces. - # @param [Array] ids A list of specific RemoteDevelopmentAgentConfig IDs to filter by (optional). + # @param [Array] ids A list of specific WorkspacesAgentConfig IDs to filter by (optional). # @param [Array] cluster_agent_ids A list of ClusterAgent IDs to filter by (optional). - # @return [ActiveRecord::Relation] - # A collection of filtered RemoteDevelopmentAgentConfig records ordered by ID descending. + # @return [ActiveRecord::Relation] + # A collection of filtered WorkspacesAgentConfig records ordered by ID descending. def self.execute(current_user:, ids: [], cluster_agent_ids: []) - return RemoteDevelopmentAgentConfig.none unless current_user.can?(:access_workspaces_feature) + return WorkspacesAgentConfig.none unless current_user.can?(:access_workspaces_feature) filter_arguments = { ids: ids, @@ -25,7 +25,7 @@ def self.execute(current_user:, ids: [], cluster_agent_ids: []) FilterArgumentValidator.validate_filter_argument_types!(filter_argument_types, filter_arguments) FilterArgumentValidator.validate_at_least_one_filter_argument_provided!(**filter_arguments) - collection_proxy = RemoteDevelopmentAgentConfig.all + collection_proxy = WorkspacesAgentConfig.all collection_proxy = collection_proxy.id_in(ids) if ids.present? collection_proxy = collection_proxy.by_cluster_agent_ids(cluster_agent_ids) if cluster_agent_ids.present? diff --git a/ee/app/finders/remote_development/remote_development_agent_configs_finder.rb b/ee/app/finders/remote_development/remote_development_agent_configs_finder.rb new file mode 100644 index 00000000000000..33e9c9ba386a81 --- /dev/null +++ b/ee/app/finders/remote_development/remote_development_agent_configs_finder.rb @@ -0,0 +1,36 @@ +# frozen_string_literal: true + +# TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 +module RemoteDevelopment + class RemoteDevelopmentAgentConfigsFinder + # Executes a query to find agent configurations based on the provided filter arguments. + # + # @param [User] current_user The user making the request. Must have permission to access workspaces. + # @param [Array] ids A list of specific RemoteDevelopmentAgentConfig IDs to filter by (optional). + # @param [Array] cluster_agent_ids A list of ClusterAgent IDs to filter by (optional). + # @return [ActiveRecord::Relation] + # A collection of filtered RemoteDevelopmentAgentConfig records ordered by ID descending. + def self.execute(current_user:, ids: [], cluster_agent_ids: []) + return RemoteDevelopmentAgentConfig.none unless current_user.can?(:access_workspaces_feature) + + filter_arguments = { + ids: ids, + cluster_agent_ids: cluster_agent_ids + } + + filter_argument_types = { + ids: Integer, + cluster_agent_ids: Integer + } + + FilterArgumentValidator.validate_filter_argument_types!(filter_argument_types, filter_arguments) + FilterArgumentValidator.validate_at_least_one_filter_argument_provided!(**filter_arguments) + + collection_proxy = RemoteDevelopmentAgentConfig.all + collection_proxy = collection_proxy.id_in(ids) if ids.present? + collection_proxy = collection_proxy.by_cluster_agent_ids(cluster_agent_ids) if cluster_agent_ids.present? + + collection_proxy.order_id_desc + end + end +end diff --git a/ee/app/graphql/ee/resolvers/clusters/agents_resolver.rb b/ee/app/graphql/ee/resolvers/clusters/agents_resolver.rb index c96af2bf2cea43..de318d001cc2e1 100644 --- a/ee/app/graphql/ee/resolvers/clusters/agents_resolver.rb +++ b/ee/app/graphql/ee/resolvers/clusters/agents_resolver.rb @@ -11,9 +11,14 @@ module AgentsResolver argument :has_vulnerabilities, GraphQL::Types::Boolean, required: false, description: 'Returns only cluster agents which have vulnerabilities.' + # TODO: clusterAgent.hasRemoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 argument :has_remote_development_agent_config, GraphQL::Types::Boolean, required: false, - description: 'Returns only cluster agents which have an associated remote development agent config.' + description: 'Returns only cluster agents which have an associated remote development agent config.', + deprecated: { reason: 'Use has_workspaces_agent_config filter instead', milestone: '17.10' } + argument :has_workspaces_agent_config, GraphQL::Types::Boolean, + required: false, + description: 'Returns only cluster agents which have an associated workspaces agent config.' argument :has_remote_development_enabled, GraphQL::Types::Boolean, required: false, description: 'Returns only cluster agents which have been enabled with the remote development feature.' diff --git a/ee/app/graphql/ee/types/clusters/agent_type.rb b/ee/app/graphql/ee/types/clusters/agent_type.rb index 2401fe4a2ed07c..e5794c43d7aaae 100644 --- a/ee/app/graphql/ee/types/clusters/agent_type.rb +++ b/ee/app/graphql/ee/types/clusters/agent_type.rb @@ -24,7 +24,15 @@ module AgentType extras: [:lookahead], null: true, description: 'Remote development agent config for the cluster agent.', - resolver: ::Resolvers::RemoteDevelopment::AgentConfigForAgentResolver + resolver: ::Resolvers::RemoteDevelopment::RemoteDevelopmentAgentConfigForAgentResolver, + deprecated: { reason: 'Use workspaces_agent_config field instead', milestone: '17.10' } + + field :workspaces_agent_config, + ::Types::RemoteDevelopment::WorkspacesAgentConfigType, + extras: [:lookahead], + null: true, + description: 'Workspaces agent config for the cluster agent.', + resolver: ::Resolvers::RemoteDevelopment::WorkspacesAgentConfigForAgentResolver end end end diff --git a/ee/app/graphql/resolvers/remote_development/agent_config_for_agent_resolver.rb b/ee/app/graphql/resolvers/remote_development/remote_development_agent_config_for_agent_resolver.rb similarity index 82% rename from ee/app/graphql/resolvers/remote_development/agent_config_for_agent_resolver.rb rename to ee/app/graphql/resolvers/remote_development/remote_development_agent_config_for_agent_resolver.rb index 12050da00a8985..62281046383add 100644 --- a/ee/app/graphql/resolvers/remote_development/agent_config_for_agent_resolver.rb +++ b/ee/app/graphql/resolvers/remote_development/remote_development_agent_config_for_agent_resolver.rb @@ -1,8 +1,9 @@ # frozen_string_literal: true +# TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 module Resolvers module RemoteDevelopment - class AgentConfigForAgentResolver < ::Resolvers::BaseResolver + class RemoteDevelopmentAgentConfigForAgentResolver < ::Resolvers::BaseResolver include Gitlab::Graphql::Authorize::AuthorizeResource include LooksAhead @@ -25,7 +26,7 @@ def resolve_with_lookahead(**_args) raise Gitlab::Access::AccessDeniedError unless can_read_remote_development_agent_config? BatchLoader::GraphQL.for(agent.id).batch do |agent_ids, loader| - agent_configs = ::RemoteDevelopment::AgentConfigsFinder.execute( + agent_configs = ::RemoteDevelopment::RemoteDevelopmentAgentConfigsFinder.execute( current_user: current_user, cluster_agent_ids: agent_ids ) diff --git a/ee/app/graphql/resolvers/remote_development/workspaces_agent_config_for_agent_resolver.rb b/ee/app/graphql/resolvers/remote_development/workspaces_agent_config_for_agent_resolver.rb new file mode 100644 index 00000000000000..462f73997b4307 --- /dev/null +++ b/ee/app/graphql/resolvers/remote_development/workspaces_agent_config_for_agent_resolver.rb @@ -0,0 +1,46 @@ +# frozen_string_literal: true + +module Resolvers + module RemoteDevelopment + class WorkspacesAgentConfigForAgentResolver < ::Resolvers::BaseResolver + include Gitlab::Graphql::Authorize::AuthorizeResource + include LooksAhead + + type Types::RemoteDevelopment::WorkspacesAgentConfigType, null: true + + alias_method :agent, :object + + # + # Resolve the workspaces agent config for the given agent. + # + # @param [Hash] **_args The arguments passed to the resolver, and do not in use here + # + # @return [WorkspacesAgentConfig] The workspaces agent config for the given agent + # + def resolve_with_lookahead(**_args) + unless License.feature_available?(:remote_development) + raise_resource_not_available_error! "'remote_development' licensed feature is not available" + end + + raise Gitlab::Access::AccessDeniedError unless can_read_workspaces_agent_config? + + BatchLoader::GraphQL.for(agent.id).batch do |agent_ids, loader| + agent_configs = ::RemoteDevelopment::AgentConfigsFinder.execute( + current_user: current_user, + cluster_agent_ids: agent_ids + ) + apply_lookahead(agent_configs).each do |agent_config| + loader.call(agent_config.cluster_agent_id, agent_config) + end + end + end + + private + + def can_read_workspaces_agent_config? + # noinspection RubyNilAnalysis - This is because the superclass #current_user uses #[], which can return nil + current_user.can?(:read_cluster_agent, agent) + end + end + end +end diff --git a/ee/app/graphql/types/remote_development/remote_development_agent_config_type.rb b/ee/app/graphql/types/remote_development/remote_development_agent_config_type.rb index 60b7b5462a9e5b..9d60a6e9d2602e 100644 --- a/ee/app/graphql/types/remote_development/remote_development_agent_config_type.rb +++ b/ee/app/graphql/types/remote_development/remote_development_agent_config_type.rb @@ -1,12 +1,13 @@ # frozen_string_literal: true +# TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 module Types module RemoteDevelopment class RemoteDevelopmentAgentConfigType < ::Types::BaseObject graphql_name 'RemoteDevelopmentAgentConfig' description 'Represents a remote development agent configuration' - authorize :read_remote_development_agent_config + authorize :read_workspaces_agent_config field :id, ::Types::GlobalIDType[::RemoteDevelopment::RemoteDevelopmentAgentConfig], null: false, description: 'Global ID of the remote development agent config.' diff --git a/ee/app/graphql/types/remote_development/workspaces_agent_config_type.rb b/ee/app/graphql/types/remote_development/workspaces_agent_config_type.rb new file mode 100644 index 00000000000000..7cc9eda9abf87a --- /dev/null +++ b/ee/app/graphql/types/remote_development/workspaces_agent_config_type.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module Types + module RemoteDevelopment + class WorkspacesAgentConfigType < ::Types::BaseObject + graphql_name 'WorkspacesAgentConfig' + description 'Represents a workspaces agent config' + + authorize :read_workspaces_agent_config + + field :id, ::Types::GlobalIDType[::RemoteDevelopment::WorkspacesAgentConfig], + null: false, description: 'Global ID of the workspaces agent config.' + + field :cluster_agent, ::Types::Clusters::AgentType, + null: false, description: 'Cluster agent that the workspaces agent config belongs to.' + + field :project_id, GraphQL::Types::ID, + null: true, description: 'ID of the project that the workspaces agent config belongs to.' + + field :enabled, GraphQL::Types::Boolean, + null: false, description: 'Indicates whether remote development is enabled for the GitLab agent.' + + field :dns_zone, GraphQL::Types::String, + null: false, description: 'DNS zone where workspaces are available.' + + field :network_policy_enabled, GraphQL::Types::Boolean, + null: false, description: 'Whether the network policy of the workspaces agent config is enabled.' + + field :gitlab_workspaces_proxy_namespace, GraphQL::Types::String, + null: false, description: 'Namespace where gitlab-workspaces-proxy is installed.' + + field :workspaces_quota, GraphQL::Types::Int, + null: false, description: 'Maximum number of workspaces for the GitLab agent.' + + field :workspaces_per_user_quota, GraphQL::Types::Int, # rubocop:disable GraphQL/ExtractType -- We don't want to extract this to a type, it's just an integer field + null: false, description: 'Maximum number of workspaces per user.' + + field :default_max_hours_before_termination, GraphQL::Types::Int, null: false, + description: 'Default max hours before worksapce termination of the workspaces agent config.' + + field :max_hours_before_termination_limit, GraphQL::Types::Int, null: false, + description: 'Max hours before worksapce termination limit of the workspaces agent config.' + + field :created_at, Types::TimeType, + null: false, description: 'Timestamp of when the workspaces agent config was created.' + + field :updated_at, Types::TimeType, null: false, + description: 'Timestamp of the last update to any mutable workspaces agent config property.' + end + end +end diff --git a/ee/app/models/ee/clusters/agent.rb b/ee/app/models/ee/clusters/agent.rb index d42fdfc541cf95..88839f3e46debc 100644 --- a/ee/app/models/ee/clusters/agent.rb +++ b/ee/app/models/ee/clusters/agent.rb @@ -13,23 +13,29 @@ module Agent foreign_key: 'cluster_agent_id', inverse_of: :agent + # TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 has_one :remote_development_agent_config, class_name: 'RemoteDevelopment::RemoteDevelopmentAgentConfig', inverse_of: :agent, foreign_key: :cluster_agent_id + has_one :workspaces_agent_config, + class_name: 'RemoteDevelopment::WorkspacesAgentConfig', + inverse_of: :agent, + foreign_key: :cluster_agent_id + has_many :remote_development_namespace_cluster_agent_mappings, class_name: 'RemoteDevelopment::RemoteDevelopmentNamespaceClusterAgentMapping', inverse_of: :agent, foreign_key: 'cluster_agent_id' scope :for_projects, ->(projects) { where(project: projects) } - scope :with_remote_development_agent_config, -> { joins(:remote_development_agent_config) } - scope :without_remote_development_agent_config, -> do - includes(:remote_development_agent_config).where(remote_development_agent_config: { cluster_agent_id: nil }) + scope :with_workspaces_agent_config, -> { joins(:workspaces_agent_config) } + scope :without_workspaces_agent_config, -> do + includes(:workspaces_agent_config).where(workspaces_agent_config: { cluster_agent_id: nil }) end scope :with_remote_development_enabled, -> do - with_remote_development_agent_config.where(remote_development_agent_config: { enabled: true }) + with_workspaces_agent_config.where(workspaces_agent_config: { enabled: true }) end end end diff --git a/ee/app/models/remote_development/remote_development_agent_config.rb b/ee/app/models/remote_development/remote_development_agent_config.rb index 1d20e755254096..7f2debafd28d9d 100644 --- a/ee/app/models/remote_development/remote_development_agent_config.rb +++ b/ee/app/models/remote_development/remote_development_agent_config.rb @@ -1,7 +1,10 @@ # frozen_string_literal: true +# TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 module RemoteDevelopment class RemoteDevelopmentAgentConfig < ApplicationRecord + self.table_name = "workspaces_agent_configs" + # NOTE: See the following comment for the reasoning behind the `RemoteDevelopment` prefix of this table/model: # https://gitlab.com/gitlab-org/gitlab/-/issues/410045#note_1385602915 include IgnorableColumns @@ -24,23 +27,27 @@ class RemoteDevelopmentAgentConfig < ApplicationRecord validates :enabled, inclusion: { in: [true, false] } validates :network_policy_egress, - json_schema: { filename: 'remote_development_agent_configs_network_policy_egress' } + json_schema: { filename: 'workspaces_agent_configs_network_policy_egress' } validates :network_policy_egress, 'remote_development/network_policy_egress': true validates :default_resources_per_workspace_container, - json_schema: { filename: 'remote_development_agent_configs_workspace_container_resources' } + json_schema: { filename: 'workspaces_agent_configs_workspace_container_resources' } validates :default_resources_per_workspace_container, 'remote_development/workspace_container_resources': true validates :max_resources_per_workspace, - json_schema: { filename: 'remote_development_agent_configs_workspace_container_resources' } + json_schema: { filename: 'workspaces_agent_configs_workspace_container_resources' } validates :max_resources_per_workspace, 'remote_development/workspace_container_resources': true validates :workspaces_quota, numericality: { only_integer: true, greater_than_or_equal_to: UNLIMITED_QUOTA } validates :workspaces_per_user_quota, numericality: { only_integer: true, greater_than_or_equal_to: UNLIMITED_QUOTA } validates :max_hours_before_termination_limit, - numericality: { only_integer: true, greater_than_or_equal_to: :default_max_hours_before_termination, - less_than_or_equal_to: MAXIMUM_HOURS_BEFORE_TERMINATION } + numericality: { + only_integer: true, greater_than_or_equal_to: :default_max_hours_before_termination, + less_than_or_equal_to: MAXIMUM_HOURS_BEFORE_TERMINATION + } validates :default_max_hours_before_termination, - numericality: { only_integer: true, greater_than_or_equal_to: MINIMUM_HOURS_BEFORE_TERMINATION, - less_than_or_equal_to: :max_hours_before_termination_limit } + numericality: { + only_integer: true, greater_than_or_equal_to: MINIMUM_HOURS_BEFORE_TERMINATION, + less_than_or_equal_to: :max_hours_before_termination_limit + } scope :by_cluster_agent_ids, ->(ids) { where(cluster_agent_id: ids) } end diff --git a/ee/app/models/remote_development/workspace.rb b/ee/app/models/remote_development/workspace.rb index 92380be79ec063..fc833fd70c7b4d 100644 --- a/ee/app/models/remote_development/workspace.rb +++ b/ee/app/models/remote_development/workspace.rb @@ -14,8 +14,12 @@ class Workspace < ApplicationRecord belongs_to :agent, class_name: 'Clusters::Agent', foreign_key: 'cluster_agent_id', inverse_of: :workspaces belongs_to :personal_access_token, inverse_of: :workspace + # TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 # noinspection RailsParamDefResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 has_one :remote_development_agent_config, through: :agent, source: :remote_development_agent_config + + # noinspection RailsParamDefResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 + has_one :workspaces_agent_config, through: :agent, source: :workspaces_agent_config has_many :workspace_variables, class_name: 'RemoteDevelopment::WorkspaceVariable', inverse_of: :workspace validates :user, presence: true @@ -23,11 +27,11 @@ class Workspace < ApplicationRecord validates :editor, presence: true validates :personal_access_token, presence: true - # Ensure that the associated agent has an existing RemoteDevelopmentAgentConfig before we allow it + # Ensure that the associated agent has an existing WorkspacesAgentConfig before we allow it # to be used to create a new workspace validate :validate_agent_config_present_and_enabled, on: :create - validate :validate_dns_zone_matches_remote_development_agent_config_dns_zone + validate :validate_dns_zone_matches_workspaces_agent_config_dns_zone # See https://gitlab.com/gitlab-org/remote-development/gitlab-remote-development-docs/blob/main/doc/architecture.md?plain=0#workspace-states # for state validation rules @@ -92,10 +96,10 @@ def workspaces_count_for_current_agent strong_memoize_attr :workspaces_count_for_current_agent def exceeds_workspaces_per_user_quota? - return unless remote_development_agent_config + return unless workspaces_agent_config # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 - quota = remote_development_agent_config.workspaces_per_user_quota + quota = workspaces_agent_config.workspaces_per_user_quota return true if quota == 0 return false if quota == -1 @@ -103,10 +107,10 @@ def exceeds_workspaces_per_user_quota? end def exceeds_workspaces_quota? - return unless remote_development_agent_config + return unless workspaces_agent_config # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 - quota = remote_development_agent_config.workspaces_quota + quota = workspaces_agent_config.workspaces_quota return true if quota == 0 return false if quota == -1 @@ -128,24 +132,24 @@ def max_hours_before_termination_limit end def validate_agent_config_present_and_enabled - unless agent&.remote_development_agent_config - errors.add(:agent, _('for Workspace must have an associated RemoteDevelopmentAgentConfig')) + unless agent&.workspaces_agent_config + errors.add(:agent, _('for Workspace must have an associated WorkspacesAgentConfig')) return false end - return true if agent.remote_development_agent_config.enabled + return true if agent.workspaces_agent_config.enabled errors.add(:agent, _("must have the 'enabled' flag set to true")) false end - def validate_dns_zone_matches_remote_development_agent_config_dns_zone + def validate_dns_zone_matches_workspaces_agent_config_dns_zone return if desired_state == TERMINATED - unless agent&.remote_development_agent_config&.dns_zone == dns_zone + unless agent&.workspaces_agent_config&.dns_zone == dns_zone errors.add( :dns_zone, - _('for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig')) + _('for Workspace must match the dns_zone of the associated WorkspacesAgentConfig')) return false end @@ -160,7 +164,7 @@ def enforce_permanent_termination # rubocop:disable Layout/LineLength -- Long messages for UI def enforce_quotas - agent_config = remote_development_agent_config + agent_config = workspaces_agent_config if exceeds_workspaces_per_user_quota? # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 errors.add :base, diff --git a/ee/app/models/remote_development/workspaces_agent_config.rb b/ee/app/models/remote_development/workspaces_agent_config.rb new file mode 100644 index 00000000000000..4ca652290ce94e --- /dev/null +++ b/ee/app/models/remote_development/workspaces_agent_config.rb @@ -0,0 +1,51 @@ +# frozen_string_literal: true + +module RemoteDevelopment + class WorkspacesAgentConfig < ApplicationRecord + # NOTE: See the following comment for the reasoning behind the `Workspaces` prefix of this table/model: + # https://gitlab.com/gitlab-org/gitlab/-/issues/410045#note_1385602915 + include IgnorableColumns + include Sortable + + UNLIMITED_QUOTA = -1 + MINIMUM_HOURS_BEFORE_TERMINATION = 1 + # NOTE: see the following issue for the reasoning behind this value being the hard maximum termination limit: + # https://gitlab.com/gitlab-org/gitlab/-/issues/471994 + MAXIMUM_HOURS_BEFORE_TERMINATION = 8760 + + belongs_to :agent, + class_name: 'Clusters::Agent', foreign_key: 'cluster_agent_id', inverse_of: :workspaces_agent_config + + # noinspection RailsParamDefResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 + has_many :workspaces, through: :agent, source: :workspaces + + validates :agent, presence: true + validates :dns_zone, hostname: true + validates :enabled, inclusion: { in: [true, false] } + + validates :network_policy_egress, + json_schema: { filename: 'workspaces_agent_configs_network_policy_egress' } + validates :network_policy_egress, 'remote_development/network_policy_egress': true + validates :default_resources_per_workspace_container, + json_schema: { filename: 'workspaces_agent_configs_workspace_container_resources' } + validates :default_resources_per_workspace_container, 'remote_development/workspace_container_resources': true + validates :max_resources_per_workspace, + json_schema: { filename: 'workspaces_agent_configs_workspace_container_resources' } + validates :max_resources_per_workspace, 'remote_development/workspace_container_resources': true + validates :workspaces_quota, numericality: { only_integer: true, greater_than_or_equal_to: UNLIMITED_QUOTA } + validates :workspaces_per_user_quota, + numericality: { only_integer: true, greater_than_or_equal_to: UNLIMITED_QUOTA } + validates :max_hours_before_termination_limit, + numericality: { + only_integer: true, greater_than_or_equal_to: :default_max_hours_before_termination, + less_than_or_equal_to: MAXIMUM_HOURS_BEFORE_TERMINATION + } + validates :default_max_hours_before_termination, + numericality: { + only_integer: true, greater_than_or_equal_to: MINIMUM_HOURS_BEFORE_TERMINATION, + less_than_or_equal_to: :max_hours_before_termination_limit + } + + scope :by_cluster_agent_ids, ->(ids) { where(cluster_agent_id: ids) } + end +end diff --git a/ee/app/policies/remote_development/remote_development_agent_config_policy.rb b/ee/app/policies/remote_development/remote_development_agent_config_policy.rb index 61e726be22f2e8..cf4559c93bc085 100644 --- a/ee/app/policies/remote_development/remote_development_agent_config_policy.rb +++ b/ee/app/policies/remote_development/remote_development_agent_config_policy.rb @@ -1,10 +1,11 @@ # frozen_string_literal: true module RemoteDevelopment + # TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 class RemoteDevelopmentAgentConfigPolicy < BasePolicy condition(:can_read_cluster_agent) { can?(:read_cluster_agent, agent) } - rule { can_read_cluster_agent }.enable :read_remote_development_agent_config + rule { can_read_cluster_agent }.enable :read_workspaces_agent_config private diff --git a/ee/app/policies/remote_development/workspaces_agent_config_policy.rb b/ee/app/policies/remote_development/workspaces_agent_config_policy.rb new file mode 100644 index 00000000000000..f5ec8d98c73c08 --- /dev/null +++ b/ee/app/policies/remote_development/workspaces_agent_config_policy.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +module RemoteDevelopment + class WorkspacesAgentConfigPolicy < BasePolicy + condition(:can_read_cluster_agent) { can?(:read_cluster_agent, agent) } + + rule { can_read_cluster_agent }.enable :read_workspaces_agent_config + + private + + def agent + @subject.agent + end + end +end diff --git a/ee/app/validators/json_schemas/remote_development_agent_configs_network_policy_egress.json b/ee/app/validators/json_schemas/workspaces_agent_configs_network_policy_egress.json similarity index 77% rename from ee/app/validators/json_schemas/remote_development_agent_configs_network_policy_egress.json rename to ee/app/validators/json_schemas/workspaces_agent_configs_network_policy_egress.json index be2ed83402c12e..92050efef9027e 100644 --- a/ee/app/validators/json_schemas/remote_development_agent_configs_network_policy_egress.json +++ b/ee/app/validators/json_schemas/workspaces_agent_configs_network_policy_egress.json @@ -1,5 +1,5 @@ { - "description": "Network Policy Egress rules for Remote Development Agent Configs", + "description": "Network Policy Egress rules for Workspaces Agent Configs", "type": "array", "items": { "type": "object", diff --git a/ee/app/validators/json_schemas/remote_development_agent_configs_workspace_container_resources.json b/ee/app/validators/json_schemas/workspaces_agent_configs_workspace_container_resources.json similarity index 91% rename from ee/app/validators/json_schemas/remote_development_agent_configs_workspace_container_resources.json rename to ee/app/validators/json_schemas/workspaces_agent_configs_workspace_container_resources.json index 3e4d5fd51c669d..5b29fc0c3a3fac 100644 --- a/ee/app/validators/json_schemas/remote_development_agent_configs_workspace_container_resources.json +++ b/ee/app/validators/json_schemas/workspaces_agent_configs_workspace_container_resources.json @@ -1,5 +1,5 @@ { - "description": "Default/max resources of the workspace pod/container for Remote Development Agent Configs", + "description": "Default/max resources of the workspace pod/container for Workspaces Agent Configs", "type": "object", "properties": { "limits": { diff --git a/ee/config/metrics/counts_all/20230510151446_remote_agent_configurations.yml b/ee/config/metrics/counts_all/20240825000001_workspaces_agent_configs.yml similarity index 58% rename from ee/config/metrics/counts_all/20230510151446_remote_agent_configurations.yml rename to ee/config/metrics/counts_all/20240825000001_workspaces_agent_configs.yml index 5564a459f4869f..ecf476a11ba3ce 100644 --- a/ee/config/metrics/counts_all/20230510151446_remote_agent_configurations.yml +++ b/ee/config/metrics/counts_all/20240825000001_workspaces_agent_configs.yml @@ -1,15 +1,15 @@ --- -key_path: counts.remote_agent_configurations -description: Count of remote agent configurations +key_path: counts.workspaces_agent_configs +description: Count of workspaces agent configs product_group: remote_development value_type: number status: active -milestone: "16.0" -introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/120341 +milestone: "17.4" +introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/163846 time_frame: all data_source: database data_category: optional -instrumentation_class: CountRemoteAgentConfigurationsMetric +instrumentation_class: CountWorkspacesAgentConfigsMetric performance_indicator_type: [] distribution: - ee diff --git a/ee/lib/gitlab/usage/metrics/instrumentations/count_remote_agent_configurations_metric.rb b/ee/lib/gitlab/usage/metrics/instrumentations/count_remote_agent_configurations_metric.rb deleted file mode 100644 index 3dcf2626709182..00000000000000 --- a/ee/lib/gitlab/usage/metrics/instrumentations/count_remote_agent_configurations_metric.rb +++ /dev/null @@ -1,19 +0,0 @@ -# frozen_string_literal: true - -module Gitlab - module Usage - module Metrics - module Instrumentations - class CountRemoteAgentConfigurationsMetric < DatabaseMetric - operation :distinct_count, column: :cluster_agent_id - - # TODO: Do we only want to consider agents that have successfully connected? - relation { RemoteDevelopment::RemoteDevelopmentAgentConfig } - - start { RemoteDevelopment::RemoteDevelopmentAgentConfig.minimum(:cluster_agent_id) } - finish { RemoteDevelopment::RemoteDevelopmentAgentConfig.maximum(:cluster_agent_id) } - end - end - end - end -end diff --git a/ee/lib/gitlab/usage/metrics/instrumentations/count_workspaces_agent_configs_metric.rb b/ee/lib/gitlab/usage/metrics/instrumentations/count_workspaces_agent_configs_metric.rb new file mode 100644 index 00000000000000..340b238d1401da --- /dev/null +++ b/ee/lib/gitlab/usage/metrics/instrumentations/count_workspaces_agent_configs_metric.rb @@ -0,0 +1,19 @@ +# frozen_string_literal: true + +module Gitlab + module Usage + module Metrics + module Instrumentations + class CountWorkspacesAgentConfigsMetric < DatabaseMetric + operation :distinct_count, column: :cluster_agent_id + + # TODO: Do we only want to consider agents that have successfully connected? + relation { RemoteDevelopment::WorkspacesAgentConfig } + + start { RemoteDevelopment::WorkspacesAgentConfig.minimum(:cluster_agent_id) } + finish { RemoteDevelopment::WorkspacesAgentConfig.maximum(:cluster_agent_id) } + end + end + end + end +end diff --git a/ee/lib/remote_development/agent_config_operations/updater.rb b/ee/lib/remote_development/agent_config_operations/updater.rb index aff7fab5a557a6..b9d0422ab55f85 100644 --- a/ee/lib/remote_development/agent_config_operations/updater.rb +++ b/ee/lib/remote_development/agent_config_operations/updater.rb @@ -17,7 +17,7 @@ def self.update(context) ) end - remote_development_agent_config = find_or_initialize_remote_development_agent_config( + workspaces_agent_config = find_or_initialize_workspaces_agent_config( agent: agent, config_from_agent_config_file: config_from_agent_config_file ) @@ -26,10 +26,10 @@ def self.update(context) workspaces_update_all_error = nil ApplicationRecord.transaction do - # First, create or update the remote_development_agent_config record + # First, create or update the workspaces_agent_config record - unless remote_development_agent_config.save - model_errors = remote_development_agent_config.errors + unless workspaces_agent_config.save + model_errors = workspaces_agent_config.errors raise ActiveRecord::Rollback end @@ -38,13 +38,13 @@ def self.update(context) workspaces_update_fields = { force_include_all_resources: true } # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 - if remote_development_agent_config.dns_zone_previously_was - workspaces_update_fields[:dns_zone] = remote_development_agent_config.dns_zone + if workspaces_agent_config.dns_zone_previously_was + workspaces_update_fields[:dns_zone] = workspaces_agent_config.dns_zone end begin - remote_development_agent_config.workspaces.desired_state_not_terminated.touch_all - remote_development_agent_config.workspaces.desired_state_not_terminated.update_all(workspaces_update_fields) + workspaces_agent_config.workspaces.desired_state_not_terminated.touch_all + workspaces_agent_config.workspaces.desired_state_not_terminated.update_all(workspaces_update_fields) rescue ActiveRecord::ActiveRecordError => e workspaces_update_all_error = "Error updating associated workspaces with update_all: #{e.message}" raise ActiveRecord::Rollback @@ -58,15 +58,15 @@ def self.update(context) end Gitlab::Fp::Result.ok( - AgentConfigUpdateSuccessful.new({ remote_development_agent_config: remote_development_agent_config }) + AgentConfigUpdateSuccessful.new({ workspaces_agent_config: workspaces_agent_config }) ) end # @param [Clusters::Agent] agent # @param [Hash] config_from_agent_config_file - # @return [RemoteDevelopment::RemoteDevelopmentAgentConfig] - def self.find_or_initialize_remote_development_agent_config(agent:, config_from_agent_config_file:) - model_instance = RemoteDevelopmentAgentConfig.find_or_initialize_by(agent: agent) # rubocop:todo CodeReuse/ActiveRecord -- Use a finder class here + # @return [RemoteDevelopment::WorkspacesAgentConfig] + def self.find_or_initialize_workspaces_agent_config(agent:, config_from_agent_config_file:) + model_instance = WorkspacesAgentConfig.find_or_initialize_by(agent: agent) # rubocop:todo CodeReuse/ActiveRecord -- Use a finder class here normalized_config_from_file = config_from_agent_config_file.dup.to_h.transform_keys(&:to_sym) @@ -106,6 +106,7 @@ def self.find_or_initialize_remote_development_agent_config(agent:, config_from_ # remains hardcoded here. model_instance.enabled = agent_config_values.fetch(:enabled, false) + model_instance.project_id = agent.project_id model_instance.workspaces_quota = agent_config_values.fetch(:workspaces_quota) model_instance.workspaces_per_user_quota = agent_config_values.fetch(:workspaces_per_user_quota) model_instance.dns_zone = agent_config_values[:dns_zone] @@ -123,7 +124,7 @@ def self.find_or_initialize_remote_development_agent_config(agent:, config_from_ model_instance end - private_class_method :find_or_initialize_remote_development_agent_config + private_class_method :find_or_initialize_workspaces_agent_config end end end diff --git a/ee/lib/remote_development/workspace_operations/create/devfile_fetcher.rb b/ee/lib/remote_development/workspace_operations/create/devfile_fetcher.rb index 942205b2a1da0e..7e38988303eafe 100644 --- a/ee/lib/remote_development/workspace_operations/create/devfile_fetcher.rb +++ b/ee/lib/remote_development/workspace_operations/create/devfile_fetcher.rb @@ -20,9 +20,9 @@ def self.fetch(context) devfile_path: String => devfile_path } - unless agent.remote_development_agent_config + unless agent.workspaces_agent_config return Gitlab::Fp::Result.err(WorkspaceCreateParamsValidationFailed.new( - details: "No RemoteDevelopmentAgentConfig found for agent '#{agent.name}'" + details: "No WorkspacesAgentConfig found for agent '#{agent.name}'" )) end diff --git a/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb b/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb index ae68a950dfd07c..1304901d0760ad 100644 --- a/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb +++ b/ee/lib/remote_development/workspace_operations/create/workspace_creator.rb @@ -52,7 +52,7 @@ def self.create(context) set_workspace_url( workspace: workspace, - agent_dns_zone: agent.remote_development_agent_config.dns_zone, + agent_dns_zone: agent.workspaces_agent_config.dns_zone, project_dir: project_dir ) diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb index 1953a255726b72..8ab74ed082bf35 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator.rb @@ -24,11 +24,11 @@ def self.generate_desired_config(workspace:, include_all_resources:, logger:) domain_template = get_domain_template_annotation(name: workspace.name, dns_zone: workspace.dns_zone) inventory_name = "#{workspace.name}-workspace-inventory" - remote_development_agent_config = workspace.agent.remote_development_agent_config + workspaces_agent_config = workspace.agent.workspaces_agent_config max_resources_per_workspace = - remote_development_agent_config.max_resources_per_workspace.deep_symbolize_keys + workspaces_agent_config.max_resources_per_workspace.deep_symbolize_keys default_resources_per_workspace_container = - remote_development_agent_config.default_resources_per_workspace_container.deep_symbolize_keys + workspaces_agent_config.default_resources_per_workspace_container.deep_symbolize_keys labels, annotations = get_labels_and_annotations( agent_id: workspace.agent.id, @@ -66,15 +66,15 @@ def self.generate_desired_config(workspace:, include_all_resources:, logger:) desired_config.append(k8s_inventory_for_workspace_core, *k8s_resources_for_workspace_core) - if remote_development_agent_config.network_policy_enabled - gitlab_workspaces_proxy_namespace = remote_development_agent_config.gitlab_workspaces_proxy_namespace + if workspaces_agent_config.network_policy_enabled + gitlab_workspaces_proxy_namespace = workspaces_agent_config.gitlab_workspaces_proxy_namespace network_policy = get_network_policy( name: workspace.name, namespace: workspace.namespace, labels: labels, annotations: annotations, gitlab_workspaces_proxy_namespace: gitlab_workspaces_proxy_namespace, - egress_ip_rules: remote_development_agent_config.network_policy_egress + egress_ip_rules: workspaces_agent_config.network_policy_egress ) desired_config.append(network_policy) end diff --git a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_v2.rb b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_v2.rb index 595a7dde80c9e4..1a5dbcfab79e4e 100644 --- a/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_v2.rb +++ b/ee/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_v2.rb @@ -54,16 +54,16 @@ def self.generate_desired_config(workspace:, include_all_resources:, logger:) desired_config.append(k8s_inventory_for_workspace_core, *k8s_resources_for_workspace_core) - remote_development_agent_config = workspace.agent.remote_development_agent_config - if remote_development_agent_config.network_policy_enabled - gitlab_workspaces_proxy_namespace = remote_development_agent_config.gitlab_workspaces_proxy_namespace + workspaces_agent_config = workspace.agent.workspaces_agent_config + if workspaces_agent_config.network_policy_enabled + gitlab_workspaces_proxy_namespace = workspaces_agent_config.gitlab_workspaces_proxy_namespace network_policy = get_network_policy( name: workspace.name, namespace: workspace.namespace, labels: labels, annotations: annotations, gitlab_workspaces_proxy_namespace: gitlab_workspaces_proxy_namespace, - egress_ip_rules: remote_development_agent_config.network_policy_egress + egress_ip_rules: workspaces_agent_config.network_policy_egress ) desired_config.append(network_policy) end diff --git a/ee/spec/factories/clusters/agents.rb b/ee/spec/factories/clusters/agents.rb index ee57ddcef9d532..03b881c8d0ee53 100644 --- a/ee/spec/factories/clusters/agents.rb +++ b/ee/spec/factories/clusters/agents.rb @@ -2,8 +2,8 @@ FactoryBot.define do factory :ee_cluster_agent, class: 'Clusters::Agent', parent: :cluster_agent do - trait :with_remote_development_agent_config do - remote_development_agent_config + trait :with_existing_workspaces_agent_config do + workspaces_agent_config end end end diff --git a/ee/spec/factories/remote_development/remote_development_agent_configs.rb b/ee/spec/factories/remote_development/remote_development_agent_configs.rb deleted file mode 100644 index 411443e489e13c..00000000000000 --- a/ee/spec/factories/remote_development/remote_development_agent_configs.rb +++ /dev/null @@ -1,9 +0,0 @@ -# frozen_string_literal: true - -FactoryBot.define do - factory :remote_development_agent_config, class: 'RemoteDevelopment::RemoteDevelopmentAgentConfig' do - agent factory: :cluster_agent - enabled { true } - dns_zone { 'workspaces.localdev.me' } - end -end diff --git a/ee/spec/factories/remote_development/workspaces.rb b/ee/spec/factories/remote_development/workspaces.rb index 003306f9c0f35a..8a446bf835e559 100644 --- a/ee/spec/factories/remote_development/workspaces.rb +++ b/ee/spec/factories/remote_development/workspaces.rb @@ -5,7 +5,7 @@ factory :workspace, class: 'RemoteDevelopment::Workspace' do association :project, :in_group user - agent factory: [:ee_cluster_agent, :with_remote_development_agent_config] + agent factory: [:ee_cluster_agent, :with_existing_workspaces_agent_config] personal_access_token name { "workspace-#{agent.id}-#{user.id}-#{random_string}" } @@ -57,7 +57,7 @@ user = workspace.user workspace.project.add_developer(user) workspace.agent.project.add_developer(user) - workspace.dns_zone = workspace.agent.remote_development_agent_config&.dns_zone || 'example.com' + workspace.dns_zone ||= workspace.agent.workspaces_agent_config&.dns_zone || 'example.com' workspace.url_prefix ||= "60001-#{workspace.name}" workspace.url_query_string ||= "folder=dir%2Ffile" end diff --git a/ee/spec/factories/remote_development/workspaces_agent_configs.rb b/ee/spec/factories/remote_development/workspaces_agent_configs.rb new file mode 100644 index 00000000000000..0e9f9955773d61 --- /dev/null +++ b/ee/spec/factories/remote_development/workspaces_agent_configs.rb @@ -0,0 +1,15 @@ +# frozen_string_literal: true + +FactoryBot.define do + # noinspection RailsParamDefResolve -- RubyMine doesn't recognize a String as a valid type for `class:` + # TODO: Open ticket and link on https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/ + factory :workspaces_agent_config, class: 'RemoteDevelopment::WorkspacesAgentConfig' do + agent factory: :cluster_agent + enabled { true } + dns_zone { 'workspaces.localdev.me' } + + after(:build) do |workspaces_agent_config, _evaluator| + workspaces_agent_config.project_id = workspaces_agent_config.agent.project_id + end + end +end diff --git a/ee/spec/features/groups/settings/remote_development/workspaces_spec.rb b/ee/spec/features/groups/settings/remote_development/workspaces_spec.rb index cf721af51c35ff..6b3cd913571caa 100644 --- a/ee/spec/features/groups/settings/remote_development/workspaces_spec.rb +++ b/ee/spec/features/groups/settings/remote_development/workspaces_spec.rb @@ -12,7 +12,7 @@ end let_it_be(:agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: project, created_by_user: user) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: project, created_by_user: user) end before_all do @@ -51,7 +51,7 @@ context 'when there are mapped and unmapped agents' do let_it_be(:agent_two) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: project, created_by_user: user) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: project, created_by_user: user) end let_it_be(:cluster_agent_mapping) do diff --git a/ee/spec/features/remote_development/workspaces_dropdown_group_spec.rb b/ee/spec/features/remote_development/workspaces_dropdown_group_spec.rb index f774cec96de62b..e502d5f4f74666 100644 --- a/ee/spec/features/remote_development/workspaces_dropdown_group_spec.rb +++ b/ee/spec/features/remote_development/workspaces_dropdown_group_spec.rb @@ -17,7 +17,7 @@ end let_it_be(:agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: project, created_by_user: user) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: project, created_by_user: user) end let_it_be(:agent_token) { create(:cluster_agent_token, agent: agent, created_by_user: user) } diff --git a/ee/spec/features/remote_development/workspaces_spec.rb b/ee/spec/features/remote_development/workspaces_spec.rb index 408e974339867d..5357b0d4be2bd7 100644 --- a/ee/spec/features/remote_development/workspaces_spec.rb +++ b/ee/spec/features/remote_development/workspaces_spec.rb @@ -19,7 +19,7 @@ end let_it_be(:agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: project, created_by_user: user) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: project, created_by_user: user) end let_it_be(:agent_token) { create(:cluster_agent_token, agent: agent, created_by_user: user) } @@ -63,7 +63,7 @@ # this field should be auto-fill when selecting agent expect(page).to have_field( 'Workspace automatically terminates after', - with: agent.remote_development_agent_config.default_max_hours_before_termination + with: agent.workspaces_agent_config.default_max_hours_before_termination ) fill_in 'Workspace automatically terminates after', with: '20' click_button 'Add variable' @@ -93,7 +93,7 @@ additional_args_for_expected_config_to_apply = build_additional_args_for_expected_config_to_apply( network_policy_enabled: true, - dns_zone: agent.remote_development_agent_config.dns_zone, + dns_zone: agent.workspaces_agent_config.dns_zone, namespace_path: group.path, project_name: project.path ) diff --git a/ee/spec/finders/ee/clusters/agents_finder_spec.rb b/ee/spec/finders/ee/clusters/agents_finder_spec.rb index aa304c84e40daa..5fc9045e4bd193 100644 --- a/ee/spec/finders/ee/clusters/agents_finder_spec.rb +++ b/ee/spec/finders/ee/clusters/agents_finder_spec.rb @@ -48,13 +48,13 @@ end end - context 'filtering by has_remote_development_agent_config' do - let(:params) { { has_remote_development_agent_config: has_remote_development_agent_config } } - let_it_be(:agent_with_remote_development_agent_config) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: project) + context 'filtering by has_workspaces_agent_config' do + let(:params) { { has_workspaces_agent_config: has_workspaces_agent_config } } + let_it_be(:agent_with_workspaces_agent_config) do + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: project) end - let_it_be(:agent_without_remote_development_agent_config) do + let_it_be(:agent_without_workspaces_agent_config) do create(:ee_cluster_agent, project: project) end @@ -65,22 +65,22 @@ it do is_expected.to contain_exactly( - agent_without_remote_development_agent_config, - agent_with_remote_development_agent_config + agent_without_workspaces_agent_config, + agent_with_workspaces_agent_config ) end end - context 'when has_remote_development_agent_config is set to true' do - let(:has_remote_development_agent_config) { true } + context 'when has_workspaces_agent_config is set to true' do + let(:has_workspaces_agent_config) { true } - it { is_expected.to contain_exactly(agent_with_remote_development_agent_config) } + it { is_expected.to contain_exactly(agent_with_workspaces_agent_config) } end - context 'when has_remote_development_agent_config is set to false' do - let(:has_remote_development_agent_config) { false } + context 'when has_workspaces_agent_config is set to false' do + let(:has_workspaces_agent_config) { false } - it { is_expected.to contain_exactly(agent_without_remote_development_agent_config) } + it { is_expected.to contain_exactly(agent_without_workspaces_agent_config) } end end @@ -91,11 +91,11 @@ let_it_be(:agent_without_enabled_config) { create(:ee_cluster_agent, project: project) } let_it_be(:config_for_enabled_agent) do - create(:remote_development_agent_config, agent: agent_with_enabled_config, enabled: true) + create(:workspaces_agent_config, agent: agent_with_enabled_config, enabled: true) end let_it_be(:config_for_disabled_agent) do - create(:remote_development_agent_config, agent: agent_without_enabled_config, enabled: false) + create(:workspaces_agent_config, agent: agent_without_enabled_config, enabled: false) end subject { described_class.new(project, user, params: params).execute } diff --git a/ee/spec/finders/remote_development/agent_configs_finder_spec.rb b/ee/spec/finders/remote_development/agent_configs_finder_spec.rb index 3cd9f05b0bc84d..5d7c24eaa9c8fe 100644 --- a/ee/spec/finders/remote_development/agent_configs_finder_spec.rb +++ b/ee/spec/finders/remote_development/agent_configs_finder_spec.rb @@ -15,11 +15,11 @@ end let_it_be(:agent_config_a) do - create(:remote_development_agent_config, agent: agent_a) + create(:workspaces_agent_config, agent: agent_a) end let_it_be(:agent_config_b) do - create(:remote_development_agent_config, agent: agent_b) + create(:workspaces_agent_config, agent: agent_b) end subject(:collection_proxy) do diff --git a/ee/spec/finders/remote_development/cluster_agents_finder_spec.rb b/ee/spec/finders/remote_development/cluster_agents_finder_spec.rb index d8da7aa3f1b21e..eaf00d4f7429bd 100644 --- a/ee/spec/finders/remote_development/cluster_agents_finder_spec.rb +++ b/ee/spec/finders/remote_development/cluster_agents_finder_spec.rb @@ -7,7 +7,7 @@ let_it_be(:maintainer) { create(:user) } let_it_be(:user) { developer } let_it_be(:root_agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, name: "agent-1-root-mapped") + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, name: "agent-1-root-mapped") end let_it_be(:root_agent_with_remote_dev_disabled) do @@ -17,18 +17,18 @@ let_it_be(:unmapped_root_agent) do create( :ee_cluster_agent, - :with_remote_development_agent_config, + :with_existing_workspaces_agent_config, project: root_agent.project, name: "agent-3-root-unmapped" ) end let_it_be(:nested_agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, name: "agent-4-nested") + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, name: "agent-4-nested") end let_it_be(:migrated_nested_agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, name: "agent-5-nested-migrated") + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, name: "agent-5-nested-migrated") end let_it_be_with_reload(:root_namespace) do diff --git a/ee/spec/finders/remote_development/remote_development_agent_configs_finder_spec.rb b/ee/spec/finders/remote_development/remote_development_agent_configs_finder_spec.rb new file mode 100644 index 00000000000000..82ac07a6dccc8c --- /dev/null +++ b/ee/spec/finders/remote_development/remote_development_agent_configs_finder_spec.rb @@ -0,0 +1,141 @@ +# frozen_string_literal: true + +require "spec_helper" + +# TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 +RSpec.describe RemoteDevelopment::RemoteDevelopmentAgentConfigsFinder, feature_category: :remote_development do + let_it_be(:current_user) { create(:user) } + + let_it_be(:cluster_admin_user) { create(:user) } + let_it_be(:agent_a) do + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, created_by_user: cluster_admin_user) + end + + let_it_be(:agent_b) do + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, created_by_user: cluster_admin_user) + end + + let_it_be(:agent_config_a) { agent_a.remote_development_agent_config } + let_it_be(:agent_config_b) { agent_b.remote_development_agent_config } + + subject(:collection_proxy) do + described_class.execute(current_user: current_user, **filter_arguments) + end + + before do + stub_licensed_features(remote_development: true) + allow(::RemoteDevelopment::FilterArgumentValidator).to receive(:validate_filter_argument_types!).and_return(true) + allow(::RemoteDevelopment::FilterArgumentValidator).to receive( + :validate_at_least_one_filter_argument_provided! + ).and_return(true) + end + + context "with ids argument" do + let(:filter_arguments) { { ids: [agent_config_a.id] } } + + it "returns only agent configs matching the specified IDs" do + expect(collection_proxy).to contain_exactly(agent_config_a) + end + end + + context "with cluster_agent_ids argument" do + let(:filter_arguments) { { cluster_agent_ids: [agent_a.id] } } + + it "returns only agent configs matching the specified agent IDs" do + expect(collection_proxy).to contain_exactly(agent_config_a) + end + end + + context "with multiple arguments" do + let(:filter_arguments) do + { + ids: [agent_config_a.id], + cluster_agent_ids: [agent_a.id, agent_b.id] + } + end + + it "handles multiple arguments and still returns all agent configs which match all filter arguments" do + expect(collection_proxy).to contain_exactly(agent_config_a) + end + end + + context "with extra empty filter arguments" do + let(:filter_arguments) do + { + ids: [agent_config_a.id], + cluster_agent_ids: [] + } + end + + it "still uses existing filter arguments" do + expect(collection_proxy).to contain_exactly(agent_config_a) + end + end + + describe "validations" do + context "when no filter arguments are provided" do + before do + allow(::RemoteDevelopment::FilterArgumentValidator).to receive( + :validate_at_least_one_filter_argument_provided! + ).and_raise(ArgumentError.new("At least one filter argument must be provided")) + end + + let(:filter_arguments) { {} } + + it "raises an ArgumentError" do + expect { collection_proxy }.to raise_error(ArgumentError, "At least one filter argument must be provided") + end + end + + context "when an invalid filter argument type is provided" do + let(:expected_exception_message) do + "'ids' must be an Array of 'Integer', " \ + "'cluster_agent_ids' must be an Array of 'Integer'" + end + + before do + allow(::RemoteDevelopment::FilterArgumentValidator).to receive( + :validate_filter_argument_types! + ).and_raise(RuntimeError.new(expected_exception_message)) + end + + context "when argument is not an array" do + let(:filter_arguments) do + { + ids: 1, + cluster_agent_ids: 1 + } + end + + it "raises an RuntimeError", :unlimited_max_formatted_output_length do + expect { collection_proxy.to_a }.to raise_error(RuntimeError, expected_exception_message) + end + end + + context "when array content is wrong type" do + let(:filter_arguments) do + { + ids: %w[a b], + cluster_agent_ids: %w[a b] + } + end + + it "raises an RuntimeError", :unlimited_max_formatted_output_length do + expect { collection_proxy.to_a }.to raise_error(RuntimeError, expected_exception_message) + end + end + end + end + + describe "no workspaces feature" do + before do + stub_licensed_features(remote_development: false) + end + + let(:filter_arguments) { { ids: [agent_config_a.id] } } + + it "returns no agent config" do + expect(collection_proxy).to eq([]) + end + end +end diff --git a/ee/spec/finders/remote_development/workspaces_finder_spec.rb b/ee/spec/finders/remote_development/workspaces_finder_spec.rb index 94390aa6097d14..94a6b3dd57f62b 100644 --- a/ee/spec/finders/remote_development/workspaces_finder_spec.rb +++ b/ee/spec/finders/remote_development/workspaces_finder_spec.rb @@ -9,11 +9,11 @@ let_it_be(:cluster_admin_user) { create(:user) } let_it_be(:agent_a) do - create(:ee_cluster_agent, :with_remote_development_agent_config, created_by_user: cluster_admin_user) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, created_by_user: cluster_admin_user) end let_it_be(:agent_b) do - create(:ee_cluster_agent, :with_remote_development_agent_config, created_by_user: cluster_admin_user) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, created_by_user: cluster_admin_user) end let_it_be(:workspace_owner_user) { create(:user) } diff --git a/ee/spec/frontend/workspaces/common/components/get_project_details_query_spec.js b/ee/spec/frontend/workspaces/common/components/get_project_details_query_spec.js index 30b28af0671f4c..64797527c02141 100644 --- a/ee/spec/frontend/workspaces/common/components/get_project_details_query_spec.js +++ b/ee/spec/frontend/workspaces/common/components/get_project_details_query_spec.js @@ -83,11 +83,10 @@ describe('workspaces/common/components/get_project_details_query', () => { const transformGroupClusterAgentGraphQLResultToClusterAgents = (clusterAgentsGraphQLResult) => clusterAgentsGraphQLResult.data.group.clusterAgents.nodes.map( - ({ id, name, project, remoteDevelopmentAgentConfig }) => ({ + ({ id, name, project, workspacesAgentConfig }) => ({ text: `${project.nameWithNamespace} / ${name}`, value: id, - defaultMaxHoursBeforeTermination: - remoteDevelopmentAgentConfig.defaultMaxHoursBeforeTermination, + defaultMaxHoursBeforeTermination: workspacesAgentConfig.defaultMaxHoursBeforeTermination, }), ); @@ -95,11 +94,10 @@ describe('workspaces/common/components/get_project_details_query', () => { clusterAgentsGraphQLResult, ) => clusterAgentsGraphQLResult.data.namespace.remoteDevelopmentClusterAgents.nodes.map( - ({ id, name, project, remoteDevelopmentAgentConfig }) => ({ + ({ id, name, project, workspacesAgentConfig }) => ({ text: `${project.nameWithNamespace} / ${name}`, value: id, - defaultMaxHoursBeforeTermination: - remoteDevelopmentAgentConfig.defaultMaxHoursBeforeTermination, + defaultMaxHoursBeforeTermination: workspacesAgentConfig.defaultMaxHoursBeforeTermination, }), ); diff --git a/ee/spec/frontend/workspaces/mock_data/index.js b/ee/spec/frontend/workspaces/mock_data/index.js index 3ec93ce40e5d17..62e22f97d982ec 100644 --- a/ee/spec/frontend/workspaces/mock_data/index.js +++ b/ee/spec/frontend/workspaces/mock_data/index.js @@ -371,8 +371,8 @@ export const GET_GROUP_CLUSTER_AGENTS_QUERY_RESULT_ROOTGROUP_ONE_AGENT = { id: 'gid://gitlab/Project/101', nameWithNamespace: 'GitLab Org / GitLab', }, - remoteDevelopmentAgentConfig: { - id: 'gid://gitlab/RemoteDevelopment::RemoteDevelopmentAgentConfig/999', + workspacesAgentConfig: { + id: 'gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/999', defaultMaxHoursBeforeTermination: 99, maxHoursBeforeTerminationLimit: 999, }, @@ -409,8 +409,8 @@ export const GET_GROUP_CLUSTER_AGENTS_QUERY_RESULT_SUBGROUP_ONE_AGENT = { id: 'gid://gitlab/Project/102', nameWithNamespace: 'GitLab Org / Subgroup / GitLab', }, - remoteDevelopmentAgentConfig: { - id: 'gid://gitlab/RemoteDevelopment::RemoteDevelopmentAgentConfig/999', + workspacesAgentConfig: { + id: 'gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/999', defaultMaxHoursBeforeTermination: 99, maxHoursBeforeTerminationLimit: 999, }, @@ -464,8 +464,8 @@ export const GET_REMOTE_DEVELOPMENT_CLUSTER_AGENTS_QUERY_RESULT_TWO_AGENTS = { id: 'gid://gitlab/Project/101', nameWithNamespace: 'GitLab Org / GitLab Agent One', }, - remoteDevelopmentAgentConfig: { - id: 'gid://gitlab/RemoteDevelopment::RemoteDevelopmentAgentConfig/999', + workspacesAgentConfig: { + id: 'gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/999', defaultMaxHoursBeforeTermination: 99, maxHoursBeforeTerminationLimit: 999, }, @@ -477,8 +477,8 @@ export const GET_REMOTE_DEVELOPMENT_CLUSTER_AGENTS_QUERY_RESULT_TWO_AGENTS = { id: 'gid://gitlab/Project/102', nameWithNamespace: 'GitLab Org / GitLab Agent Two', }, - remoteDevelopmentAgentConfig: { - id: 'gid://gitlab/RemoteDevelopment::RemoteDevelopmentAgentConfig/998', + workspacesAgentConfig: { + id: 'gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/998', defaultMaxHoursBeforeTermination: 98, maxHoursBeforeTerminationLimit: 998, }, @@ -502,8 +502,8 @@ export const GET_AGENTS_WITH_MAPPING_STATUS_QUERY_RESULT = { id: 'gid://gitlab/Project/101', nameWithNamespace: 'GitLab Org / GitLab Agent One', }, - remoteDevelopmentAgentConfig: { - id: 'gid://gitlab/RemoteDevelopment::RemoteDevelopmentAgentConfig/999', + workspacesAgentConfig: { + id: 'gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/999', defaultMaxHoursBeforeTermination: 99, maxHoursBeforeTerminationLimit: 999, }, @@ -519,8 +519,8 @@ export const GET_AGENTS_WITH_MAPPING_STATUS_QUERY_RESULT = { id: 'gid://gitlab/Project/102', nameWithNamespace: 'GitLab Org / GitLab Agent Two', }, - remoteDevelopmentAgentConfig: { - id: 'gid://gitlab/RemoteDevelopment::RemoteDevelopmentAgentConfig/999', + workspacesAgentConfig: { + id: 'gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/999', defaultMaxHoursBeforeTermination: 99, maxHoursBeforeTerminationLimit: 999, }, diff --git a/ee/spec/graphql/ee/types/clusters/agent_type_spec.rb b/ee/spec/graphql/ee/types/clusters/agent_type_spec.rb index 63fce64edd8708..75f426ff2f8e99 100644 --- a/ee/spec/graphql/ee/types/clusters/agent_type_spec.rb +++ b/ee/spec/graphql/ee/types/clusters/agent_type_spec.rb @@ -7,7 +7,9 @@ expect(described_class).to have_graphql_fields( :vulnerability_images, :workspaces, - :remote_development_agent_config + # TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 + :remote_development_agent_config, + :workspaces_agent_config ).at_least end @@ -64,13 +66,13 @@ end end - describe 'remote_development_agent_config' do + describe 'workspaces_agent_config' do let_it_be(:group) { create(:group) } let_it_be(:project) { create(:project, group: group) } let_it_be(:user) { create(:user) } let_it_be(:cluster_agent) { create(:cluster_agent, project: project) } - let_it_be(:remote_development_agent_config) do - create(:remote_development_agent_config, cluster_agent_id: cluster_agent.id, project_id: project.id) + let_it_be(:workspaces_agent_config) do + create(:workspaces_agent_config, cluster_agent_id: cluster_agent.id, project_id: project.id) end let_it_be(:remote_development_namespace_cluster_agent_mapping) do @@ -86,6 +88,9 @@ remoteDevelopmentAgentConfig { defaultMaxHoursBeforeTermination } + workspacesAgentConfig { + defaultMaxHoursBeforeTermination + } } } } @@ -101,19 +106,40 @@ stub_licensed_features(remote_development: true) end - subject(:remote_development_agent_config_result) do + # TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 + describe "for remote_development_agent_config" do + subject(:remote_development_agent_config_result) do + result = GitlabSchema.execute(query, context: { current_user: current_user }).as_json + result.dig('data', 'namespace', 'remoteDevelopmentClusterAgents', 'nodes', 0, 'remoteDevelopmentAgentConfig') + end + + context 'when user is logged in' do + let(:current_user) { user } + let(:expected_default_max_hours_before_termination) do + workspaces_agent_config.default_max_hours_before_termination + end + + it 'returns associated workspaces agent config' do + expect(remote_development_agent_config_result).to eq( + 'defaultMaxHoursBeforeTermination' => expected_default_max_hours_before_termination + ) + end + end + end + + subject(:workspaces_agent_config_result) do result = GitlabSchema.execute(query, context: { current_user: current_user }).as_json - result.dig('data', 'namespace', 'remoteDevelopmentClusterAgents', 'nodes', 0, 'remoteDevelopmentAgentConfig') + result.dig('data', 'namespace', 'remoteDevelopmentClusterAgents', 'nodes', 0, 'workspacesAgentConfig') end context 'when user is logged in' do let(:current_user) { user } let(:expected_default_max_hours_before_termination) do - remote_development_agent_config.default_max_hours_before_termination + workspaces_agent_config.default_max_hours_before_termination end - it 'returns associated remote development agent config' do - expect(remote_development_agent_config_result).to eq( + it 'returns associated workspaces agent config' do + expect(workspaces_agent_config_result).to eq( 'defaultMaxHoursBeforeTermination' => expected_default_max_hours_before_termination ) end diff --git a/ee/spec/graphql/resolvers/clusters/agents_resolver_spec.rb b/ee/spec/graphql/resolvers/clusters/agents_resolver_spec.rb index 99f66eae6bb82c..3964fdddb8e2fc 100644 --- a/ee/spec/graphql/resolvers/clusters/agents_resolver_spec.rb +++ b/ee/spec/graphql/resolvers/clusters/agents_resolver_spec.rb @@ -2,7 +2,7 @@ require 'spec_helper' -RSpec.describe Resolvers::Clusters::AgentsResolver do +RSpec.describe Resolvers::Clusters::AgentsResolver, feature_category: :environment_management do include GraphqlHelpers specify do @@ -65,33 +65,58 @@ end end - context 'when has_remote_development_agent_config argument is provided' do - let(:params) do - { has_remote_development_agent_config: has_remote_development_agent_config } - end - - let_it_be(:agent_with_remote_development_agent_config) do - create(:ee_cluster_agent, :with_remote_development_agent_config, + context 'for agents with and without workspaces agent config' do + let_it_be(:agent_with_workspaces_agent_config) do + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: project) end - let_it_be(:agent_without_remote_development_agent_config) do + let_it_be(:agent_without_workspaces_agent_config) do create(:ee_cluster_agent, project: project) end - context 'when has_remote_development_agent_config is set to true' do - let(:has_remote_development_agent_config) { true } + # TODO: clusterAgent.hasRemoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 + context 'when has_remote_development_agent_config argument is provided' do + let(:params) do + { has_remote_development_agent_config: has_remote_development_agent_config } + end + + context 'when has_remote_development_agent_config is set to true' do + let(:has_remote_development_agent_config) { true } + + it 'returns only agents with remote_development_agent_config' do + expect(subject).to contain_exactly(agent_with_workspaces_agent_config) + end + end + + context 'when has_remote_development_agent_config is set to false' do + let(:has_remote_development_agent_config) { false } - it 'returns only agents with remote_development_agent_config' do - expect(subject).to contain_exactly(agent_with_remote_development_agent_config) + it 'returns only agents without remote_development_agent_config' do + expect(subject).to contain_exactly(agent_without_workspaces_agent_config) + end end end - context 'when has_remote_development_agent_config is set to false' do - let(:has_remote_development_agent_config) { false } + context 'when has_workspaces_agent_config argument is provided' do + let(:params) do + { has_workspaces_agent_config: has_workspaces_agent_config } + end + + context 'when has_workspaces_agent_config is set to true' do + let(:has_workspaces_agent_config) { true } + + it 'returns only agents with workspaces_agent_config' do + expect(subject).to contain_exactly(agent_with_workspaces_agent_config) + end + end + + context 'when has_workspaces_agent_config is set to false' do + let(:has_workspaces_agent_config) { false } - it 'returns only agents without remote_development_agent_config' do - expect(subject).to contain_exactly(agent_without_remote_development_agent_config) + it 'returns only agents without workspaces_agent_config' do + expect(subject).to contain_exactly(agent_without_workspaces_agent_config) + end end end end @@ -103,17 +128,17 @@ let_it_be(:agent_without_enabled_config) { create(:ee_cluster_agent, project: project) } let_it_be(:config_for_enabled_agent) do - create(:remote_development_agent_config, agent: agent_with_enabled_config, enabled: true) + create(:workspaces_agent_config, agent: agent_with_enabled_config, enabled: true) end let_it_be(:config_for_disabled_agent) do - create(:remote_development_agent_config, agent: agent_without_enabled_config, enabled: false) + create(:workspaces_agent_config, agent: agent_without_enabled_config, enabled: false) end - context 'when has_remote_development_agent_config is set to true' do + context 'when has_workspaces_agent_config is set to true' do let(:has_remote_development_enabled) { true } - it 'returns only agents with remote_development_agent_config' do + it 'returns only agents with workspaces_agent_config' do expect(subject).to contain_exactly(agent_with_enabled_config) end end diff --git a/ee/spec/graphql/types/remote_development/remote_development_agent_config_type_spec.rb b/ee/spec/graphql/types/remote_development/remote_development_agent_config_type_spec.rb index d8d15b57288a81..4d7007a11399a9 100644 --- a/ee/spec/graphql/types/remote_development/remote_development_agent_config_type_spec.rb +++ b/ee/spec/graphql/types/remote_development/remote_development_agent_config_type_spec.rb @@ -2,6 +2,7 @@ require 'spec_helper' +# TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 RSpec.describe GitlabSchema.types['RemoteDevelopmentAgentConfig'], feature_category: :remote_development do let(:fields) do %i[ @@ -15,7 +16,7 @@ specify { expect(described_class).to have_graphql_fields(fields) } - specify { expect(described_class).to require_graphql_authorizations(:read_remote_development_agent_config) } + specify { expect(described_class).to require_graphql_authorizations(:read_workspaces_agent_config) } describe 'remote_development_agent_config' do let_it_be(:group) { create(:group) } diff --git a/ee/spec/graphql/types/remote_development/workspaces_agent_config_type_spec.rb b/ee/spec/graphql/types/remote_development/workspaces_agent_config_type_spec.rb new file mode 100644 index 00000000000000..ea194576b524be --- /dev/null +++ b/ee/spec/graphql/types/remote_development/workspaces_agent_config_type_spec.rb @@ -0,0 +1,50 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe GitlabSchema.types['WorkspacesAgentConfig'], feature_category: :remote_development do + let(:fields) do + %i[ + id cluster_agent project_id enabled dns_zone network_policy_enabled gitlab_workspaces_proxy_namespace + workspaces_quota workspaces_per_user_quota default_max_hours_before_termination max_hours_before_termination_limit + created_at updated_at + ] + end + + specify { expect(described_class.graphql_name).to eq('WorkspacesAgentConfig') } + + specify { expect(described_class).to have_graphql_fields(fields) } + + specify { expect(described_class).to require_graphql_authorizations(:read_workspaces_agent_config) } + + describe 'workspaces_agent_config' do + let_it_be(:group) { create(:group) } + + let_it_be(:query) do + %( + query { + namespace(fullPath: "#{group.full_path}") { + remoteDevelopmentClusterAgents(filter: AVAILABLE) { + nodes { + workspacesAgentConfig { + defaultMaxHoursBeforeTermination + } + } + } + } + } + ) + end + + subject(:workspaces_agent_config_result) do + result = GitlabSchema.execute(query, context: { current_user: current_user }).as_json + result.dig('data', 'namespace', 'remoteDevelopmentClusterAgents', 'nodes', 0, 'workspacesAgentConfig') + end + + context 'when user is not logged in' do + let(:current_user) { nil } + + it { is_expected.to be_nil } + end + end +end diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_remote_agent_configurations_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_remote_agent_configurations_metric_spec.rb deleted file mode 100644 index 6d99ce0ac1754e..00000000000000 --- a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_remote_agent_configurations_metric_spec.rb +++ /dev/null @@ -1,17 +0,0 @@ -# frozen_string_literal: true - -require 'spec_helper' - -RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountRemoteAgentConfigurationsMetric, feature_category: :remote_development do - before do - create_list(:remote_development_agent_config, 2) - end - - it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all', data_source: 'database' } do - let(:expected_value) { 2 } - let(:expected_query) do - 'SELECT COUNT(DISTINCT "remote_development_agent_configs"."cluster_agent_id") ' \ - 'FROM "remote_development_agent_configs"' - end - end -end diff --git a/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_workspaces_agent_configs_metric_spec.rb b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_workspaces_agent_configs_metric_spec.rb new file mode 100644 index 00000000000000..3b9d3fd58bd023 --- /dev/null +++ b/ee/spec/lib/gitlab/usage/metrics/instrumentations/count_workspaces_agent_configs_metric_spec.rb @@ -0,0 +1,17 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe Gitlab::Usage::Metrics::Instrumentations::CountWorkspacesAgentConfigsMetric, feature_category: :remote_development do + before do + create_list(:workspaces_agent_config, 2) + end + + it_behaves_like 'a correct instrumented metric value and query', { time_frame: 'all', data_source: 'database' } do + let(:expected_value) { 2 } + let(:expected_query) do + 'SELECT COUNT(DISTINCT "workspaces_agent_configs"."cluster_agent_id") ' \ + 'FROM "workspaces_agent_configs"' + end + end +end diff --git a/ee/spec/lib/remote_development/agent_config_operations/main_integration_spec.rb b/ee/spec/lib/remote_development/agent_config_operations/main_integration_spec.rb index fd598ae98d965e..76929fd63af039 100644 --- a/ee/spec/lib/remote_development/agent_config_operations/main_integration_spec.rb +++ b/ee/spec/lib/remote_development/agent_config_operations/main_integration_spec.rb @@ -25,14 +25,14 @@ allow(License).to receive(:feature_available?).with(:remote_development).and_return(true) end - context "when a remote_development_agent_config record does not already exist" do + context "when a workspaces_agent_config record does not already exist" do let_it_be(:agent) { create(:cluster_agent) } context 'when config passed is empty' do let(:config) { {} } it 'does not create a config record' do - expect { response }.to not_change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } + expect { response }.to not_change { RemoteDevelopment::WorkspacesAgentConfig.count } expect(response).to eq({ status: :success, @@ -41,13 +41,13 @@ end end - context 'when config passed results in updates to the remote_development_agent_config record' do + context 'when config passed results in updates to the workspaces_agent_config record' do it 'creates a config record' do - expect { response }.to change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count }.by(1) + expect { response }.to change { RemoteDevelopment::WorkspacesAgentConfig.count }.by(1) expect(response).to eq({ status: :success, - payload: { remote_development_agent_config: agent.reload.remote_development_agent_config } + payload: { workspaces_agent_config: agent.reload.workspaces_agent_config } }) end end @@ -56,7 +56,7 @@ let(:dns_zone) { "invalid dns zone" } it 'does not create the record and returns error' do - expect { response }.to not_change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } + expect { response }.to not_change { RemoteDevelopment::WorkspacesAgentConfig.count } expect(response).to eq({ status: :error, @@ -64,20 +64,20 @@ reason: :bad_request }) - config_instance = agent.reload.remote_development_agent_config + config_instance = agent.reload.workspaces_agent_config expect(config_instance).to be_nil end end end - context "when a remote_development_agent_config record already exists" do - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + context "when a workspaces_agent_config record already exists" do + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } context 'when config passed is empty' do let(:config) { {} } it 'does not create a config record' do - expect { response }.to not_change { agent.reload.remote_development_agent_config.attributes } + expect { response }.to not_change { agent.reload.workspaces_agent_config.attributes } expect(response).to eq({ status: :success, @@ -86,14 +86,14 @@ end end - context 'when config passed results in updates to the remote_development_agent_config record' do + context 'when config passed results in updates to the workspaces_agent_config record' do it 'updates the config record' do expect(response).to eq({ status: :success, - payload: { remote_development_agent_config: agent.reload.remote_development_agent_config } + payload: { workspaces_agent_config: agent.reload.workspaces_agent_config } }) - expect(agent.reload.remote_development_agent_config.dns_zone).to eq(dns_zone) + expect(agent.reload.workspaces_agent_config.dns_zone).to eq(dns_zone) end end @@ -101,7 +101,7 @@ let(:dns_zone) { "invalid dns zone" } it 'does not update the record and returns error' do - expect { response }.to not_change { agent.reload.remote_development_agent_config.attributes } + expect { response }.to not_change { agent.reload.workspaces_agent_config.attributes } expect(response).to eq({ status: :error, @@ -135,9 +135,9 @@ context 'when associated workspaces cannot be updated' do before do # rubocop:disable RSpec/AnyInstanceOf -- allow_next_instance_of does not work here - allow_any_instance_of(RemoteDevelopment::RemoteDevelopmentAgentConfig) + allow_any_instance_of(RemoteDevelopment::WorkspacesAgentConfig) .to receive_message_chain(:workspaces, :desired_state_not_terminated, :touch_all) - allow_any_instance_of(RemoteDevelopment::RemoteDevelopmentAgentConfig) + allow_any_instance_of(RemoteDevelopment::WorkspacesAgentConfig) .to receive_message_chain(:workspaces, :desired_state_not_terminated, :update_all) .and_raise(ActiveRecord::ActiveRecordError, "SOME ERROR") # rubocop:enable RSpec/AnyInstanceOf -- allow_next_instance_of does not work here diff --git a/ee/spec/lib/remote_development/agent_config_operations/updater_spec.rb b/ee/spec/lib/remote_development/agent_config_operations/updater_spec.rb index b71d24e13501c8..c2a7567e5b58ab 100644 --- a/ee/spec/lib/remote_development/agent_config_operations/updater_spec.rb +++ b/ee/spec/lib/remote_development/agent_config_operations/updater_spec.rb @@ -7,7 +7,7 @@ include ResultMatchers let(:enabled) { true } - let(:dns_zone) { 'my-awesome-domain.me' } + let_it_be(:dns_zone) { 'my-awesome-domain.me' } let(:termination_limits_sets) { false } let(:default_unlimited_quota) { -1 } let(:saved_quota) { 5 } @@ -51,14 +51,14 @@ let(:max_hours_before_termination_limit) { 120 } - let_it_be(:agent) { create(:cluster_agent) } - let_it_be(:workspace1) { create(:workspace, force_include_all_resources: false) } - let_it_be(:workspace2) { create(:workspace, force_include_all_resources: false) } + let_it_be(:agent, refind: true) { create(:cluster_agent) } + + let(:dns_zone_in_config) { dns_zone } let(:config) do remote_development_config = { 'enabled' => enabled, - 'dns_zone' => dns_zone + 'dns_zone' => dns_zone_in_config } remote_development_config['network_policy'] = network_policy if network_policy_present remote_development_config['gitlab_workspaces_proxy'] = gitlab_workspaces_proxy if gitlab_workspaces_proxy_present @@ -122,7 +122,7 @@ let(:config) { {} } it "does not update and returns an ok Result containing a hash indicating update was skipped" do - expect { result }.to not_change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } + expect { result }.to not_change { RemoteDevelopment::WorkspacesAgentConfig.count } expect(result) .to be_ok_result(RemoteDevelopment::Messages::AgentConfigUpdateSkippedBecauseNoConfigFileEntryFound.new( @@ -134,11 +134,12 @@ context 'when config passed is not empty' do shared_examples 'successful update' do it 'creates a config record and returns an ok Result containing the agent config' do - expect { result }.to change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } + expect { result }.to change { RemoteDevelopment::WorkspacesAgentConfig.count }.by(expected_configs_created) - config_instance = agent.reload.remote_development_agent_config + config_instance = agent.reload.workspaces_agent_config expect(config_instance.enabled).to eq(enabled) - expect(config_instance.dns_zone).to eq(dns_zone) + expect(config_instance.project_id).to eq(agent.project_id) + expect(config_instance.dns_zone).to eq(expected_dns_zone) expect(config_instance.network_policy_enabled).to eq(network_policy_enabled) expect(config_instance.network_policy_egress.map(&:deep_symbolize_keys)).to eq(network_policy_egress) expect(config_instance.gitlab_workspaces_proxy_namespace).to eq(gitlab_workspaces_proxy_namespace) @@ -155,221 +156,209 @@ expect(result) .to be_ok_result(RemoteDevelopment::Messages::AgentConfigUpdateSuccessful.new( - { remote_development_agent_config: config_instance } + { workspaces_agent_config: config_instance } )) - expect(config_instance.workspaces).to all(have_attributes(force_include_all_resources: true)) + + expect(config_instance.workspaces.desired_state_not_terminated) + .to all(have_attributes(force_include_all_resources: true)) end end context 'when a config file is valid' do - it_behaves_like 'successful update' + let(:expected_dns_zone) { dns_zone } + let(:expected_configs_created) { 1 } + + context "without existing workspaces_agent_config" do + it_behaves_like 'successful update' - context 'when enabled is not present in the config passed' do - let(:config) { { remote_development: { dns_zone: dns_zone } } } + context 'when enabled is not present in the config passed' do + let(:config) { { remote_development: { dns_zone: dns_zone } } } - it 'creates a config record with a default context of enabled as false' do - expect { result }.to change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } - expect(result).to be_ok_result - expect(agent.reload.remote_development_agent_config.enabled).to eq(false) + it 'creates a config record with a default context of enabled as false' do + expect { result }.to change { RemoteDevelopment::WorkspacesAgentConfig.count } + expect(result).to be_ok_result + expect(agent.reload.workspaces_agent_config.enabled).to eq(false) + end end - end - context 'when network_policy key is present in the config passed' do - let(:network_policy_present) { true } + context 'when network_policy key is present in the config passed' do + let(:network_policy_present) { true } - context 'when network_policy key is empty hash in the config passed' do - let(:network_policy) { {} } + context 'when network_policy key is empty hash in the config passed' do + let(:network_policy) { {} } - it_behaves_like 'successful update' - end + it_behaves_like 'successful update' + end - context 'when network_policy.enabled is explicitly specified in the config passed' do - let(:network_policy_enabled) { false } + context 'when network_policy.enabled is explicitly specified in the config passed' do + let(:network_policy_enabled) { false } - it_behaves_like 'successful update' - end + it_behaves_like 'successful update' + end - context 'when network_policy.egress is explicitly specified in the config passed' do - let(:network_policy_egress) do - [ - { - allow: "0.0.0.0/0", - except: %w[10.0.0.0/8] - } - ].freeze + context 'when network_policy.egress is explicitly specified in the config passed' do + let(:network_policy_egress) do + [ + { + allow: "0.0.0.0/0", + except: %w[10.0.0.0/8] + } + ].freeze + end + + let(:network_policy) { network_policy_with_egress } + + it_behaves_like 'successful update' end - let(:network_policy) { network_policy_with_egress } + context 'when default and max_hours_before_termination are explicitly specified in the config passed' do + let(:termination_limits_sets) { true } + let(:default_max_hours_before_termination) { 20 } + let(:max_hours_before_termination_limit) { 220 } - it_behaves_like 'successful update' + it_behaves_like 'successful update' + end end - context 'when default and max_hours_before_termination are explicitly specified in the config passed' do - let(:termination_limits_sets) { true } - let(:default_max_hours_before_termination) { 20 } - let(:max_hours_before_termination_limit) { 220 } + context 'when gitlab_workspaces_proxy is present in the config passed' do + let(:gitlab_workspaces_proxy_present) { true } - it_behaves_like 'successful update' - end - end + context 'when gitlab_workspaces_proxy is empty hash in the config passed' do + let(:gitlab_workspaces_proxy) { {} } - context 'when gitlab_workspaces_proxy is present in the config passed' do - let(:gitlab_workspaces_proxy_present) { true } + it_behaves_like 'successful update' + end - context 'when gitlab_workspaces_proxy is empty hash in the config passed' do - let(:gitlab_workspaces_proxy) { {} } + context 'when gitlab_workspaces_proxy.namespace is explicitly specified in the config passed' do + let(:gitlab_workspaces_proxy_namespace) { 'gitlab-workspaces-specified' } - it_behaves_like 'successful update' + it_behaves_like 'successful update' + end end - context 'when gitlab_workspaces_proxy.namespace is explicitly specified in the config passed' do - let(:gitlab_workspaces_proxy_namespace) { 'gitlab-workspaces-specified' } + context 'when default_resources_per_workspace_container is present in the config passed' do + context 'when gitlab_workspaces_proxy is empty hash in the config passed' do + let(:default_resources_per_workspace_container) { {} } - it_behaves_like 'successful update' - end - end + it_behaves_like 'successful update' + end - context 'when default_resources_per_workspace_container is present in the config passed' do - context 'when gitlab_workspaces_proxy is empty hash in the config passed' do - let(:default_resources_per_workspace_container) { {} } + context 'when default_resources_per_workspace_container is explicitly specified in the config passed' do + let(:default_resources_per_workspace_container) do + { limits: { cpu: "500m", memory: "1Gi" }, requests: { cpu: "200m", memory: "0.5Gi" } } + end - it_behaves_like 'successful update' + it_behaves_like 'successful update' + end end - context 'when default_resources_per_workspace_container is explicitly specified in the config passed' do - let(:default_resources_per_workspace_container) do - { limits: { cpu: "500m", memory: "1Gi" }, requests: { cpu: "200m", memory: "0.5Gi" } } - end + context 'when max_resources_per_workspace is present in the config passed' do + context 'when gitlab_workspaces_proxy is empty hash in the config passed' do + let(:max_resources_per_workspace) { {} } - it_behaves_like 'successful update' - end - end + it_behaves_like 'successful update' + end - context 'when max_resources_per_workspace is present in the config passed' do - context 'when gitlab_workspaces_proxy is empty hash in the config passed' do - let(:max_resources_per_workspace) { {} } + context 'when max_resources_per_workspace is explicitly specified in the config passed' do + let(:max_resources_per_workspace) do + { limits: { cpu: "500m", memory: "1Gi" }, requests: { cpu: "200m", memory: "0.5Gi" } } + end - it_behaves_like 'successful update' + it_behaves_like 'successful update' + end end - context 'when max_resources_per_workspace is explicitly specified in the config passed' do - let(:max_resources_per_workspace) do - { limits: { cpu: "500m", memory: "1Gi" }, requests: { cpu: "200m", memory: "0.5Gi" } } - end + context 'when workspace quotas are not explicitly specified in the config passed' do + let(:quota) { nil } + let(:saved_quota) { -1 } it_behaves_like 'successful update' end end - context 'when workspace quotas are not explicitly specified in the config passed' do - let(:quota) { nil } - let(:saved_quota) { -1 } - - it_behaves_like 'successful update' - end - - context 'when the dns_zone has been updated' do # rubocop:disable RSpec/MultipleMemoizedHelpers -- Need helpers for scenarios - let_it_be(:old_dns_zone) { 'old-dns-zone.test' } - let_it_be(:new_dns_zone) { 'new-dns-zone.test' } - let_it_be(:dns_zone) { new_dns_zone } - - let_it_be(:non_terminated_workspace) do - create( - :workspace, - agent: agent, - actual_state: RemoteDevelopment::WorkspaceOperations::States::RUNNING, - desired_state: RemoteDevelopment::WorkspaceOperations::States::RUNNING, - dns_zone: old_dns_zone, - force_include_all_resources: false - ) + context "with existing workspaces_agent_config" do + let(:expected_configs_created) { 0 } + let_it_be(:workspaces_agent_config, refind: true) do + create(:workspaces_agent_config, dns_zone: dns_zone, agent: agent) end - let_it_be(:terminated_workspace) do - create( - :workspace, - agent: agent, - actual_state: RemoteDevelopment::WorkspaceOperations::States::RUNNING, - desired_state: RemoteDevelopment::WorkspaceOperations::States::TERMINATED, - dns_zone: old_dns_zone, - force_include_all_resources: false - ) + before do + agent.reload end - let_it_be(:new_config) do - { - remote_development: { - enabled: true, - dns_zone: new_dns_zone - } - } - end + it_behaves_like 'successful update' - before do - described_class.update(agent: agent, config: config) # rubocop:disable Rails/SaveBang -- this isn't ActiveRecord - end + context 'when the dns_zone has been updated' do + let_it_be(:new_dns_zone) { 'new-dns-zone.test' } + let(:expected_dns_zone) { new_dns_zone } + let(:dns_zone_in_config) { new_dns_zone } - it 'updates the dns_zone' do - expect { result }.not_to change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } - config_instance = agent.reload.remote_development_agent_config - expect(result) - .to be_ok_result(RemoteDevelopment::Messages::AgentConfigUpdateSuccessful.new( - { remote_development_agent_config: config_instance } - )) - expect(config_instance.dns_zone).to eq(new_dns_zone) - end + it_behaves_like 'successful update' - context 'when workspaces are present' do # rubocop:disable RSpec/MultipleMemoizedHelpers -- Need helpers for scenarios - it 'updates workspaces in a non-terminated state to force update' do - expect { result }.not_to change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } - config_instance = agent.reload.remote_development_agent_config - expect(result) - .to be_ok_result(RemoteDevelopment::Messages::AgentConfigUpdateSuccessful.new( - { remote_development_agent_config: config_instance } - )) - expect(non_terminated_workspace.reload.force_include_all_resources).to eq(true) + it 'updates the dns_zone' do + expect { result }.to change { workspaces_agent_config.reload.dns_zone }.from(dns_zone).to(new_dns_zone) end - it 'updates the dns_zone of a workspace with desired_state non-terminated' do - expect { result }.not_to change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } - config_instance = agent.reload.remote_development_agent_config - expect(result) - .to be_ok_result(RemoteDevelopment::Messages::AgentConfigUpdateSuccessful.new( - { remote_development_agent_config: config_instance } - )) - expect(non_terminated_workspace.reload.dns_zone).to eq(new_dns_zone) - end + context 'when workspaces are present' do + let_it_be(:non_terminated_workspace, refind: true) do + create( + :workspace, + agent: agent, + actual_state: RemoteDevelopment::WorkspaceOperations::States::RUNNING, + desired_state: RemoteDevelopment::WorkspaceOperations::States::RUNNING, + dns_zone: dns_zone, + force_include_all_resources: false + ) + end - it 'does not update workspaces with desired_state terminated' do - expect { result }.not_to change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } - config_instance = agent.reload.remote_development_agent_config - expect(result) - .to be_ok_result(RemoteDevelopment::Messages::AgentConfigUpdateSuccessful.new( - { remote_development_agent_config: config_instance } - )) - expect(terminated_workspace.reload.force_include_all_resources).to eq(false) - end + let_it_be(:terminated_workspace, refind: true) do + create( + :workspace, + agent: agent, + actual_state: RemoteDevelopment::WorkspaceOperations::States::RUNNING, + desired_state: RemoteDevelopment::WorkspaceOperations::States::TERMINATED, + dns_zone: dns_zone, + force_include_all_resources: false + ) + end - context 'when workspaces update_all fails' do # rubocop:disable RSpec/MultipleMemoizedHelpers -- Need helpers for scenarios - before do - # rubocop:disable RSpec/AnyInstanceOf -- allow_next_instance_of does not work here - allow_any_instance_of(RemoteDevelopment::RemoteDevelopmentAgentConfig) - .to receive_message_chain(:workspaces, :desired_state_not_terminated, :touch_all) - allow_any_instance_of(RemoteDevelopment::RemoteDevelopmentAgentConfig) - .to receive_message_chain(:workspaces, :desired_state_not_terminated, :update_all) - .and_raise(ActiveRecord::ActiveRecordError, "SOME ERROR") - # rubocop:enable RSpec/AnyInstanceOf + it_behaves_like 'successful update' + + it 'updates workspaces in a non-terminated state to force update' do + expect { result } + .to change { non_terminated_workspace.reload.force_include_all_resources }.from(false).to(true) + end + + it 'updates the dns_zone of a workspace with desired_state non-terminated' do + expect { result }.to change { non_terminated_workspace.reload.dns_zone }.from(dns_zone).to(new_dns_zone) end - it 'returns an error result' do - expect { result }.not_to change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } - expect(result).to be_err_result do |message| - expect(message).to be_a(RemoteDevelopment::Messages::AgentConfigUpdateFailed) - message.content => { details: String => details } - expect(details).to eq( - "Error updating associated workspaces with update_all: SOME ERROR" - ) + it 'does not update workspaces in a terminated state to force update' do + expect { result }.not_to change { terminated_workspace.reload.force_include_all_resources } + end + + context 'when workspaces update_all fails' do + before do + # rubocop:disable RSpec/AnyInstanceOf -- allow_next_instance_of does not work here + allow_any_instance_of(RemoteDevelopment::WorkspacesAgentConfig) + .to receive_message_chain(:workspaces, :desired_state_not_terminated, :touch_all) + allow_any_instance_of(RemoteDevelopment::WorkspacesAgentConfig) + .to receive_message_chain(:workspaces, :desired_state_not_terminated, :update_all) + .and_raise(ActiveRecord::ActiveRecordError, "SOME ERROR") + # rubocop:enable RSpec/AnyInstanceOf + end + + it 'returns an error result' do + expect { result }.not_to change { RemoteDevelopment::WorkspacesAgentConfig.count } + expect(result).to be_err_result do |message| + expect(message).to be_a(RemoteDevelopment::Messages::AgentConfigUpdateFailed) + message.content => { details: String => details } + expect(details).to eq( + "Error updating associated workspaces with update_all: SOME ERROR" + ) + end + expect(terminated_workspace.reload.force_include_all_resources).to eq(false) end - expect(terminated_workspace.reload.force_include_all_resources).to eq(false) end end end @@ -381,8 +370,8 @@ let(:dns_zone) { "invalid dns zone" } it 'does not create the record and returns error' do - expect { result }.to not_change { RemoteDevelopment::RemoteDevelopmentAgentConfig.count } - expect(agent.reload.remote_development_agent_config).to be_nil + expect { result }.to not_change { RemoteDevelopment::WorkspacesAgentConfig.count } + expect(agent.reload.workspaces_agent_config).to be_nil expect(result).to be_err_result do |message| expect(message).to be_a(RemoteDevelopment::Messages::AgentConfigUpdateFailed) diff --git a/ee/spec/lib/remote_development/workspace_operations/create/creator_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/creator_spec.rb index 4a3cffc5e46ed7..1d1134d356b6c4 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/creator_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/creator_spec.rb @@ -14,7 +14,7 @@ end let_it_be(:user) { create(:user) } - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let(:random_string) { 'abcdef' } let(:params) do diff --git a/ee/spec/lib/remote_development/workspace_operations/create/devfile_fetcher_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/devfile_fetcher_spec.rb index 2465ed8bbd197e..07627690b1f868 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/devfile_fetcher_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/devfile_fetcher_spec.rb @@ -13,7 +13,7 @@ let_it_be(:user) { create(:user) } let_it_be(:project) { create(:project, :in_group, :repository) } - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let(:random_string) { 'abcdef' } let(:devfile_ref) { 'main' } let(:devfile_path) { '.devfile.yaml' } @@ -60,12 +60,12 @@ it 'returns an err Result containing error details' do # sanity check on fixture - expect(agent.remote_development_agent_config).to be_nil + expect(agent.workspaces_agent_config).to be_nil expect(result).to be_err_result do |message| expect(message).to be_a(RemoteDevelopment::Messages::WorkspaceCreateParamsValidationFailed) message.content => { details: String => error_details } - expect(error_details).to eq("No RemoteDevelopmentAgentConfig found for agent '#{agent.name}'") + expect(error_details).to eq("No WorkspacesAgentConfig found for agent '#{agent.name}'") end end end diff --git a/ee/spec/lib/remote_development/workspace_operations/create/main_integration_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/main_integration_spec.rb index b4f1f1cb15f709..a6cf82a8f75740 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/main_integration_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/main_integration_spec.rb @@ -34,7 +34,7 @@ end let(:agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: project, created_by_user: user) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: project, created_by_user: user) end let(:params) do @@ -113,7 +113,7 @@ expect(workspace.namespace).to eq("gl-rd-ns-#{agent.id}-#{user.id}-#{random_string}") expect(workspace.editor).to eq('webide') expect(workspace.url).to eq(URI::HTTPS.build({ - host: "60001-#{workspace.name}.#{workspace.agent.remote_development_agent_config.dns_zone}", + host: "60001-#{workspace.name}.#{workspace.agent.workspaces_agent_config.dns_zone}", query: { folder: "#{workspace_root}/#{project.path}" }.to_query @@ -177,13 +177,13 @@ it 'does not create the workspace and returns error' do # sanity check on fixture - expect(agent.remote_development_agent_config).to be_nil + expect(agent.workspaces_agent_config).to be_nil expect { response }.not_to change { RemoteDevelopment::Workspace.count } expect(response).to eq({ status: :error, - message: "Workspace create params validation failed: No RemoteDevelopmentAgentConfig found for agent '007'", + message: "Workspace create params validation failed: No WorkspacesAgentConfig found for agent '007'", reason: :bad_request }) end diff --git a/ee/spec/lib/remote_development/workspace_operations/create/workspace_creator_spec.rb b/ee/spec/lib/remote_development/workspace_operations/create/workspace_creator_spec.rb index 7bce6cc5a68e71..39bda07dd6aeac 100644 --- a/ee/spec/lib/remote_development/workspace_operations/create/workspace_creator_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/create/workspace_creator_spec.rb @@ -9,7 +9,7 @@ let_it_be(:user) { create(:user) } let_it_be(:project, reload: true) { create(:project, :in_group, :repository) } - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let_it_be(:personal_access_token) { create(:personal_access_token, user: user) } let(:random_string) { 'abcdef' } let(:devfile_path) { '.devfile.yaml' } @@ -68,7 +68,7 @@ it 'creates the workspace with the right url components' do expect(result).to be_ok_result do |message| message => { workspace: RemoteDevelopment::Workspace => workspace } - expected_url = "https://60001-#{workspace.name}.#{agent.remote_development_agent_config.dns_zone}" \ + expected_url = "https://60001-#{workspace.name}.#{agent.workspaces_agent_config.dns_zone}" \ "?folder=%2Fprojects%2F#{project.path}" expect(workspace.url).to eq(expected_url) end diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/main_integration_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/main_integration_spec.rb index cbff65e082076c..010d7be879a3e3 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/main_integration_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/main_integration_spec.rb @@ -27,11 +27,11 @@ end let_it_be(:user) { create(:user) } - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } - let(:egress_ip_rules) { agent.remote_development_agent_config.network_policy_egress } - let(:max_resources_per_workspace) { agent.remote_development_agent_config.max_resources_per_workspace } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } + let(:egress_ip_rules) { agent.workspaces_agent_config.network_policy_egress } + let(:max_resources_per_workspace) { agent.workspaces_agent_config.max_resources_per_workspace } let(:default_resources_per_workspace_container) do - agent.remote_development_agent_config.default_resources_per_workspace_container + agent.workspaces_agent_config.default_resources_per_workspace_container end let(:full_reconciliation_interval_seconds) { 3600 } diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/main_reconcile_scenarios_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/main_reconcile_scenarios_spec.rb index 4d275649036e9e..c7b1fd0020d5f4 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/main_reconcile_scenarios_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/main_reconcile_scenarios_spec.rb @@ -13,7 +13,7 @@ let(:logger) { instance_double(::Logger) } let_it_be(:user) { create(:user) } - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } before do allow(logger).to receive(:debug) diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_spec.rb index aab4f34a8b1e07..4b2946e6be2941 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_spec.rb @@ -8,7 +8,7 @@ describe '#generate_desired_config' do let(:logger) { instance_double(Logger) } let(:user) { create(:user) } - let(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let(:desired_state) { RemoteDevelopment::WorkspaceOperations::States::RUNNING } let(:actual_state) { RemoteDevelopment::WorkspaceOperations::States::STOPPED } let(:started) { true } @@ -16,10 +16,10 @@ let(:deployment_resource_version_from_agent) { workspace.deployment_resource_version } let(:network_policy_enabled) { true } let(:gitlab_workspaces_proxy_namespace) { 'gitlab-workspaces' } - let(:egress_ip_rules) { agent.remote_development_agent_config.network_policy_egress } - let(:max_resources_per_workspace) { agent.remote_development_agent_config.max_resources_per_workspace } + let(:egress_ip_rules) { agent.workspaces_agent_config.network_policy_egress } + let(:max_resources_per_workspace) { agent.workspaces_agent_config.max_resources_per_workspace } let(:default_resources_per_workspace_container) do - agent.remote_development_agent_config.default_resources_per_workspace_container + agent.workspaces_agent_config.default_resources_per_workspace_container end let(:workspace) do @@ -51,7 +51,7 @@ end before do - allow(agent.remote_development_agent_config) + allow(agent.workspaces_agent_config) .to receive(:network_policy_enabled).and_return(network_policy_enabled) end @@ -102,7 +102,7 @@ end before do - allow(agent.remote_development_agent_config).to receive(:default_resources_per_workspace_container) { + allow(agent.workspaces_agent_config).to receive(:default_resources_per_workspace_container) { default_resources_per_workspace_container } end @@ -137,7 +137,7 @@ end before do - allow(agent.remote_development_agent_config).to receive(:max_resources_per_workspace) { + allow(agent.workspaces_agent_config).to receive(:max_resources_per_workspace) { max_resources_per_workspace } end diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_v2_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_v2_spec.rb index 58596c6d34aaeb..a6900be3656072 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_v2_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/output/desired_config_generator_v2_spec.rb @@ -8,7 +8,7 @@ describe '#generate_desired_config' do let(:logger) { instance_double(Logger) } let(:user) { create(:user) } - let(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let(:desired_state) { RemoteDevelopment::WorkspaceOperations::States::RUNNING } let(:actual_state) { RemoteDevelopment::WorkspaceOperations::States::STOPPED } let(:started) { true } @@ -16,7 +16,7 @@ let(:deployment_resource_version_from_agent) { workspace.deployment_resource_version } let(:network_policy_enabled) { true } let(:gitlab_workspaces_proxy_namespace) { 'gitlab-workspaces' } - let(:egress_ip_rules) { agent.remote_development_agent_config.network_policy_egress } + let(:egress_ip_rules) { agent.workspaces_agent_config.network_policy_egress } let(:workspace) do create( @@ -46,7 +46,7 @@ end before do - allow(agent.remote_development_agent_config) + allow(agent.workspaces_agent_config) .to receive(:network_policy_enabled).and_return(network_policy_enabled) end diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_from_agent_infos_updater_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_from_agent_infos_updater_spec.rb index ba9e06f6964098..6f1e35ac426091 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_from_agent_infos_updater_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_from_agent_infos_updater_spec.rb @@ -6,7 +6,7 @@ include_context 'with remote development shared fixtures' let_it_be(:user) { create(:user) } - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let(:desired_state) { RemoteDevelopment::WorkspaceOperations::States::RUNNING } let(:actual_state) { RemoteDevelopment::WorkspaceOperations::States::STARTING } diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_to_be_returned_finder_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_to_be_returned_finder_spec.rb index 91ff3a0f49e0d4..d0bc5e09dd5a6a 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_to_be_returned_finder_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_to_be_returned_finder_spec.rb @@ -5,7 +5,7 @@ # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 RSpec.describe RemoteDevelopment::WorkspaceOperations::Reconcile::Persistence::WorkspacesToBeReturnedFinder, feature_category: :remote_development do let_it_be(:user) { create(:user) } - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let_it_be(:workspace_only_returned_by_full_update, reload: true) do create( diff --git a/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_to_be_returned_updater_spec.rb b/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_to_be_returned_updater_spec.rb index 7442f0ef954412..07753fccabd2ec 100644 --- a/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_to_be_returned_updater_spec.rb +++ b/ee/spec/lib/remote_development/workspace_operations/reconcile/persistence/workspaces_to_be_returned_updater_spec.rb @@ -4,7 +4,7 @@ RSpec.describe RemoteDevelopment::WorkspaceOperations::Reconcile::Persistence::WorkspacesToBeReturnedUpdater, feature_category: :remote_development do let_it_be(:user) { create(:user) } - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let_it_be(:workspace1) do create( diff --git a/ee/spec/models/ee/clusters/agent_spec.rb b/ee/spec/models/ee/clusters/agent_spec.rb index 9a23348da4ee9b..5fc1483a4a578c 100644 --- a/ee/spec/models/ee/clusters/agent_spec.rb +++ b/ee/spec/models/ee/clusters/agent_spec.rb @@ -16,40 +16,40 @@ end end - describe 'remote_development_agent_config scopes' do - let_it_be(:agent_with_remote_development_config_enabled) do - create(:ee_cluster_agent, :with_remote_development_agent_config).tap do |agent| - agent.remote_development_agent_config.update!(enabled: true) + describe 'workspaces_agent_config scopes' do + let_it_be(:agent_with_remote_development_enabled) do + create(:ee_cluster_agent, :with_existing_workspaces_agent_config).tap do |agent| + agent.workspaces_agent_config.update!(enabled: true) end end let_it_be(:agent_with_remote_development_config_disabled) do - create(:ee_cluster_agent, :with_remote_development_agent_config).tap do |agent| - agent.remote_development_agent_config.update!(enabled: false) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config).tap do |agent| + agent.workspaces_agent_config.update!(enabled: false) end end - describe '.with_remote_development_agent_config' do - it 'return agents with remote_development_agent_config' do - expect(described_class.with_remote_development_agent_config) + describe '.with_workspaces_agent_config' do + it 'return agents with workspaces_agent_config' do + expect(described_class.with_workspaces_agent_config) .to contain_exactly( - agent_with_remote_development_config_enabled, agent_with_remote_development_config_disabled) - expect(described_class.with_remote_development_agent_config).not_to include(agent_1, agent_2, agent_3) + agent_with_remote_development_enabled, agent_with_remote_development_config_disabled) + expect(described_class.with_workspaces_agent_config).not_to include(agent_1, agent_2, agent_3) end end - describe '.without_remote_development_agent_config' do - it 'return agents without remote_development_agent_config' do - expect(described_class.without_remote_development_agent_config) - .not_to include(agent_with_remote_development_config_enabled, agent_with_remote_development_config_disabled) - expect(described_class.without_remote_development_agent_config).to include(agent_1, agent_2, agent_3) + describe '.without_workspaces_agent_config' do + it 'return agents without workspaces_agent_config' do + expect(described_class.without_workspaces_agent_config) + .not_to include(agent_with_remote_development_enabled, agent_with_remote_development_config_disabled) + expect(described_class.without_workspaces_agent_config).to include(agent_1, agent_2, agent_3) end end describe '.with_remote_development_enabled' do it 'returns agents with with_remote_development_enabled' do expect(described_class.with_remote_development_enabled) - .to contain_exactly(agent_with_remote_development_config_enabled) + .to contain_exactly(agent_with_remote_development_enabled) expect(described_class.with_remote_development_enabled).not_to include( agent_1, agent_2, agent_3, agent_with_remote_development_config_disabled) end diff --git a/ee/spec/models/remote_development/remote_development_agent_config_spec.rb b/ee/spec/models/remote_development/remote_development_agent_config_spec.rb index e0c52f6a979d18..d482d02e2e57c6 100644 --- a/ee/spec/models/remote_development/remote_development_agent_config_spec.rb +++ b/ee/spec/models/remote_development/remote_development_agent_config_spec.rb @@ -2,8 +2,12 @@ require 'spec_helper' +# TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 RSpec.describe RemoteDevelopment::RemoteDevelopmentAgentConfig, feature_category: :remote_development do - let_it_be_with_reload(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be_with_reload(:agent) do + create(:ee_cluster_agent, :with_existing_workspaces_agent_config) + end + let(:default_default_resources_per_workspace_container) { {} } let(:default_max_resources_per_workspace) { {} } let(:default_network_policy_egress) do @@ -22,7 +26,7 @@ let(:default_max_hours_before_termination_default_value) { 24 } let(:max_hours_before_termination_limit_default_value) { 120 } - subject(:config) { agent.remote_development_agent_config } + subject(:config) { agent.workspaces_agent_config } describe 'associations' do it { is_expected.to belong_to(:agent) } @@ -34,14 +38,14 @@ it 'has correct associations from factory' do expect(config.reload.workspaces).to contain_exactly(workspace_1, workspace_2) - expect(workspace_1.remote_development_agent_config).to eq(config) + expect(workspace_1.remote_development_agent_config).to eq(agent.remote_development_agent_config) end end end describe 'validations' do context 'when config has an invalid dns_zone' do - subject(:config) { build(:remote_development_agent_config, dns_zone: "invalid dns zone") } + subject(:config) { build(:workspaces_agent_config, dns_zone: "invalid dns zone") } it 'prevents config from being created' do expect { config.save! }.to raise_error( @@ -117,16 +121,16 @@ it 'allows numerical values for max_hours_before_termination_limit greater or equal to' \ 'default_max_hours_before_termination and less than or equal to 8760' do is_expected.to validate_numericality_of(:max_hours_before_termination_limit) - .only_integer - .is_less_than_or_equal_to(8760) - .is_greater_than_or_equal_to(default_max_hours_before_termination_default_value) + .only_integer + .is_less_than_or_equal_to(8760) + .is_greater_than_or_equal_to(default_max_hours_before_termination_default_value) end it 'allows numerical values for default_max_hours_before_termination greater or equal to 1' \ 'and less than or equal to max_hours_before_termination_limit' do is_expected.to validate_numericality_of(:default_max_hours_before_termination) - .only_integer.is_less_than_or_equal_to(max_hours_before_termination_limit_default_value) - .is_greater_than_or_equal_to(1) + .only_integer.is_less_than_or_equal_to(max_hours_before_termination_limit_default_value) + .is_greater_than_or_equal_to(1) end end end diff --git a/ee/spec/models/remote_development/workspace_spec.rb b/ee/spec/models/remote_development/workspace_spec.rb index 8b7d81bff4a312..95a486dafc981e 100644 --- a/ee/spec/models/remote_development/workspace_spec.rb +++ b/ee/spec/models/remote_development/workspace_spec.rb @@ -4,7 +4,7 @@ RSpec.describe RemoteDevelopment::Workspace, feature_category: :remote_development do let_it_be(:user) { create(:user) } - let_it_be(:agent, reload: true) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent, reload: true) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let_it_be(:project) { create(:project, :in_group) } let_it_be(:personal_access_token) { create(:personal_access_token, user: user) } @@ -18,7 +18,7 @@ describe 'associations' do context "for has_one" do - it { is_expected.to have_one(:remote_development_agent_config) } + it { is_expected.to have_one(:workspaces_agent_config) } end context "for has_many" do @@ -44,10 +44,10 @@ expect(workspace.project).to eq(project) expect(workspace.agent).to eq(agent) expect(workspace.personal_access_token).to eq(personal_access_token) - expect(workspace.remote_development_agent_config).to eq(agent.remote_development_agent_config) - expect(agent.remote_development_agent_config.workspaces.first).to eq(workspace) + expect(workspace.workspaces_agent_config).to eq(agent.workspaces_agent_config) + expect(agent.workspaces_agent_config.workspaces.first).to eq(workspace) expect(workspace.url_prefix).to eq("60001-#{workspace.name}") - expect(workspace.dns_zone).to eq(agent.remote_development_agent_config.dns_zone) + expect(workspace.dns_zone).to eq(agent.workspaces_agent_config.dns_zone) # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 expect(workspace.url_query_string).to eq("folder=dir%2Ffile") end @@ -58,7 +58,7 @@ subject(:workspace) { build(:workspace) } it 'returns calculated url' do - expect(workspace.url).to eq("https://60001-#{workspace.name}.#{agent.remote_development_agent_config.dns_zone}?folder=dir%2Ffile") + expect(workspace.url).to eq("https://60001-#{workspace.name}.#{agent.workspaces_agent_config.dns_zone}?folder=dir%2Ffile") end end @@ -131,7 +131,7 @@ end end - context 'on remote_development_agent_config' do + context 'on workspaces_agent_config' do context 'when no config is present' do let(:agent_with_no_remote_development_config) { create(:cluster_agent) } @@ -139,13 +139,13 @@ build(:workspace, user: user, agent: agent_with_no_remote_development_config, project: project) end - it 'validates presence of agent.remote_development_agent_config' do + it 'validates presence of agent.workspaces_agent_config' do # sanity check of fixture - expect(agent_with_no_remote_development_config.remote_development_agent_config).not_to be_present + expect(agent_with_no_remote_development_config.workspaces_agent_config).not_to be_present expect(invalid_workspace).not_to be_valid expect(invalid_workspace.errors[:agent]) - .to include('for Workspace must have an associated RemoteDevelopmentAgentConfig') + .to include('for Workspace must have an associated WorkspacesAgentConfig') end it "is only validated on create" do @@ -162,20 +162,20 @@ context 'when agent is enabled' do before do - agent.remote_development_agent_config.enabled = true + agent.workspaces_agent_config.enabled = true end - it 'validates presence of agent.remote_development_agent_config' do + it 'validates presence of agent.workspaces_agent_config' do expect(workspace).to be_valid end end context 'when agent is disabled' do before do - agent.remote_development_agent_config.enabled = false + agent.workspaces_agent_config.enabled = false end - it 'validates agent.remote_development_agent_config is enabled' do + it 'validates agent.workspaces_agent_config is enabled' do expect(workspace).not_to be_valid expect(workspace.errors[:agent]) .to include("must have the 'enabled' flag set to true") @@ -200,10 +200,10 @@ # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 workspace.dns_zone = 'zone1' # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 - agent.remote_development_agent_config.dns_zone = 'zone1' + agent.workspaces_agent_config.dns_zone = 'zone1' end - it 'validates presence of agent.remote_development_agent_config' do + it 'validates presence of agent.workspaces_agent_config' do expect(workspace).to be_valid end end @@ -213,7 +213,7 @@ # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 workspace.dns_zone = 'zone1' # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 - agent.remote_development_agent_config.dns_zone = 'zone2' + agent.workspaces_agent_config.dns_zone = 'zone2' end context "when workspace is in desired_state Terminated" do @@ -221,7 +221,7 @@ workspace.desired_state = ::RemoteDevelopment::WorkspaceOperations::States::TERMINATED end - it 'does not validate dns_zone matches agent.remote_development_agent_config.dns_zone' do + it 'does not validate dns_zone matches agent.workspaces_agent_config.dns_zone' do expect(workspace).to be_valid end end @@ -231,10 +231,10 @@ workspace.desired_state = ::RemoteDevelopment::WorkspaceOperations::States::RUNNING end - it 'validates dns_zone matches agent.remote_development_agent_config.dns_zone' do + it 'validates dns_zone matches agent.workspaces_agent_config.dns_zone' do expect(workspace).not_to be_valid expect(workspace.errors[:dns_zone]) - .to include("for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig") + .to include("for Workspace must match the dns_zone of the associated WorkspacesAgentConfig") end end end @@ -258,8 +258,8 @@ let_it_be(:user1) { create(:user) } let_it_be(:user2) { create(:user) } let_it_be(:user3) { create(:user) } - let_it_be(:agent1, reload: true) { create(:ee_cluster_agent, :with_remote_development_agent_config) } - let_it_be(:agent2, reload: true) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent1, reload: true) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } + let_it_be(:agent2, reload: true) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let_it_be(:workspace1) do create(:workspace, user: user1, agent: agent1, desired_state: ::RemoteDevelopment::WorkspaceOperations::States::RUNNING) @@ -294,8 +294,8 @@ end describe "#workspaces_count_for_current_agent" do - let_it_be(:agent1, reload: true) { create(:ee_cluster_agent, :with_remote_development_agent_config) } - let_it_be(:agent2, reload: true) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent1, reload: true) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } + let_it_be(:agent2, reload: true) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let_it_be(:workspace1) do create(:workspace, agent: agent1, desired_state: ::RemoteDevelopment::WorkspaceOperations::States::RUNNING) end @@ -326,18 +326,18 @@ describe "#exceeds_workspaces_per_user_quota?" do let(:workspace) { create(:workspace) } - context "when remote_development_agent_config is nil" do + context "when workspaces_agent_config is nil" do it "returns false" do - workspace.remote_development_agent_config = nil + workspace.workspaces_agent_config = nil expect(workspace.exceeds_workspaces_per_user_quota?).to be nil end end - context "when remote_development_agent_config is present" do + context "when workspaces_agent_config is present" do context "when workspaces_per_user_quota is 0" do before do - allow(workspace).to receive(:remote_development_agent_config).and_return(instance_double( - RemoteDevelopment::RemoteDevelopmentAgentConfig, workspaces_per_user_quota: 0)) + allow(workspace).to receive(:workspaces_agent_config).and_return(instance_double( + RemoteDevelopment::WorkspacesAgentConfig, workspaces_per_user_quota: 0)) end it "returns true" do @@ -347,8 +347,8 @@ context "when workspaces_per_user_quota is -1" do before do - allow(workspace).to receive(:remote_development_agent_config).and_return(instance_double( - RemoteDevelopment::RemoteDevelopmentAgentConfig, workspaces_per_user_quota: -1)) + allow(workspace).to receive(:workspaces_agent_config).and_return(instance_double( + RemoteDevelopment::WorkspacesAgentConfig, workspaces_per_user_quota: -1)) end it "returns false" do @@ -358,8 +358,8 @@ context "when workspaces_per_user_quota is greater than 0" do before do - allow(workspace).to receive(:remote_development_agent_config).and_return(instance_double( - RemoteDevelopment::RemoteDevelopmentAgentConfig, workspaces_per_user_quota: 2)) + allow(workspace).to receive(:workspaces_agent_config).and_return(instance_double( + RemoteDevelopment::WorkspacesAgentConfig, workspaces_per_user_quota: 2)) end it "returns true if the workspaces count for current user and agent is greater than or equal to the quota" do @@ -378,18 +378,18 @@ describe "#exceeds_workspaces_quota?" do let(:workspace) { create(:workspace) } - context "when remote_development_agent_config is nil" do + context "when workspaces_agent_config is nil" do it "returns false" do - workspace.remote_development_agent_config = nil + workspace.workspaces_agent_config = nil expect(workspace.exceeds_workspaces_quota?).to be nil end end - context "when remote_development_agent_config is present" do + context "when workspaces_agent_config is present" do context "when workspaces_quota is 0" do before do - allow(workspace).to receive(:remote_development_agent_config).and_return(instance_double( - RemoteDevelopment::RemoteDevelopmentAgentConfig, workspaces_quota: 0)) + allow(workspace).to receive(:workspaces_agent_config).and_return(instance_double( + RemoteDevelopment::WorkspacesAgentConfig, workspaces_quota: 0)) end it "returns true" do @@ -399,8 +399,8 @@ context "when workspaces_quota is -1" do before do - allow(workspace).to receive(:remote_development_agent_config).and_return(instance_double( - RemoteDevelopment::RemoteDevelopmentAgentConfig, workspaces_quota: -1)) + allow(workspace).to receive(:workspaces_agent_config).and_return(instance_double( + RemoteDevelopment::WorkspacesAgentConfig, workspaces_quota: -1)) end it "returns false" do @@ -410,8 +410,8 @@ context "when workspaces_quota is greater than 0" do before do - allow(workspace).to receive(:remote_development_agent_config).and_return(instance_double( - RemoteDevelopment::RemoteDevelopmentAgentConfig, workspaces_quota: 2)) + allow(workspace).to receive(:workspaces_agent_config).and_return(instance_double( + RemoteDevelopment::WorkspacesAgentConfig, workspaces_quota: 2)) end it "returns true if the workspaces count for the current agent is greater than or equal to the quota" do @@ -447,8 +447,8 @@ end it 'adds base error when per user quota exceeded' do - allow(workspace).to receive(:remote_development_agent_config).and_return(instance_double( - ::RemoteDevelopment::RemoteDevelopmentAgentConfig, workspaces_per_user_quota: 5)) + allow(workspace).to receive(:workspaces_agent_config).and_return(instance_double( + ::RemoteDevelopment::WorkspacesAgentConfig, workspaces_per_user_quota: 5)) allow(workspace).to receive(:workspaces_count_for_current_user_and_agent).and_return(6) allow(workspace).to receive(:exceeds_workspaces_per_user_quota?).and_return(true) workspace.validate @@ -458,8 +458,8 @@ end it 'adds base error when total quota exceeded' do - allow(workspace).to receive(:remote_development_agent_config).and_return(instance_double( - ::RemoteDevelopment::RemoteDevelopmentAgentConfig, workspaces_quota: 3)) + allow(workspace).to receive(:workspaces_agent_config).and_return(instance_double( + ::RemoteDevelopment::WorkspacesAgentConfig, workspaces_quota: 3)) allow(workspace).to receive(:workspaces_count_for_current_agent).and_return(3) allow(workspace).to receive(:exceeds_workspaces_quota?).and_return(true) workspace.validate diff --git a/ee/spec/models/remote_development/workspaces_agent_config_spec.rb b/ee/spec/models/remote_development/workspaces_agent_config_spec.rb new file mode 100644 index 00000000000000..1eec7e492fb298 --- /dev/null +++ b/ee/spec/models/remote_development/workspaces_agent_config_spec.rb @@ -0,0 +1,132 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe RemoteDevelopment::WorkspacesAgentConfig, feature_category: :remote_development do + let_it_be_with_reload(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } + let(:default_default_resources_per_workspace_container) { {} } + let(:default_max_resources_per_workspace) { {} } + let(:default_network_policy_egress) do + [ + { + allow: "0.0.0.0/0", + except: [ + - "10.0.0.0/8", + - "172.16.0.0/12", + - "192.168.0.0/16" + ] + }.deep_stringify_keys + ] + end + + let(:default_max_hours_before_termination_default_value) { 24 } + let(:max_hours_before_termination_limit_default_value) { 120 } + + subject(:config) { agent.workspaces_agent_config } + + describe 'associations' do + it { is_expected.to belong_to(:agent) } + it { is_expected.to have_many(:workspaces) } + + context 'with associated workspaces' do + let(:workspace_1) { create(:workspace, agent: agent) } + let(:workspace_2) { create(:workspace, agent: agent) } + + it 'has correct associations from factory' do + expect(config.reload.workspaces).to contain_exactly(workspace_1, workspace_2) + expect(workspace_1.workspaces_agent_config).to eq(config) + end + end + end + + describe 'validations' do + context 'when config has an invalid dns_zone' do + subject(:config) { build(:workspaces_agent_config, dns_zone: "invalid dns zone") } + + it 'prevents config from being created' do + expect { config.save! }.to raise_error( + ActiveRecord::RecordInvalid, + "Validation failed: Dns zone contains invalid characters (valid characters: [a-z0-9\\-])" + ) + end + end + + it 'when network_policy_egress is not specified explicitly' do + expect(config).to be_valid + expect(config.network_policy_egress).to eq(default_network_policy_egress) + end + + it 'when network_policy_egress is nil' do + # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 + config.network_policy_egress = nil + expect(config).not_to be_valid + expect(config.errors[:network_policy_egress]).to include( + 'must be a valid json schema', + 'must be an array' + ) + end + + it 'when default_resources_per_workspace_container is not specified explicitly' do + expect(config).to be_valid + expect(config.default_resources_per_workspace_container).to eq(default_default_resources_per_workspace_container) + end + + it 'when default_resources_per_workspace_container is nil' do + # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 + config.default_resources_per_workspace_container = nil + expect(config).not_to be_valid + expect(config.errors[:default_resources_per_workspace_container]).to include( + 'must be a valid json schema', + 'must be a hash' + ) + end + + it 'when max_resources_per_workspace is not specified explicitly' do + expect(config).to be_valid + expect(config.max_resources_per_workspace).to eq(default_max_resources_per_workspace) + end + + it 'when default_max_hours_before_termination is not specified explicitly' do + expect(config).to be_valid + expect(config.default_max_hours_before_termination).to eq(default_max_hours_before_termination_default_value) + end + + it 'when max_hours_before_termination_limit is not specified explicitly' do + expect(config).to be_valid + expect(config.max_hours_before_termination_limit).to eq(max_hours_before_termination_limit_default_value) + end + + it 'when default_resources_per_workspace_container is nil' do + # noinspection RubyResolve - https://handbook.gitlab.com/handbook/tools-and-tips/editors-and-ides/jetbrains-ides/tracked-jetbrains-issues/#ruby-31542 + config.max_resources_per_workspace = nil + expect(config).not_to be_valid + expect(config.errors[:max_resources_per_workspace]).to include( + 'must be a valid json schema', + 'must be a hash' + ) + end + + it 'allows numerical values for workspaces_quota greater or equal to -1' do + is_expected.to validate_numericality_of(:workspaces_quota).only_integer.is_greater_than_or_equal_to(-1) + end + + it 'allows numerical values for workspaces_per_user_quota greater or equal to -1' do + validate_numericality_of(:workspaces_per_user_quota).only_integer.is_greater_than_or_equal_to(-1) + end + + it 'allows numerical values for max_hours_before_termination_limit greater or equal to' \ + 'default_max_hours_before_termination and less than or equal to 8760' do + is_expected.to validate_numericality_of(:max_hours_before_termination_limit) + .only_integer + .is_less_than_or_equal_to(8760) + .is_greater_than_or_equal_to(default_max_hours_before_termination_default_value) + end + + it 'allows numerical values for default_max_hours_before_termination greater or equal to 1' \ + 'and less than or equal to max_hours_before_termination_limit' do + is_expected.to validate_numericality_of(:default_max_hours_before_termination) + .only_integer.is_less_than_or_equal_to(max_hours_before_termination_limit_default_value) + .is_greater_than_or_equal_to(1) + end + end +end diff --git a/ee/spec/policies/remote_development/remote_development_agent_config_policy_spec.rb b/ee/spec/policies/remote_development/remote_development_agent_config_policy_spec.rb index ea364205a3eb3b..cd9159cbe57261 100644 --- a/ee/spec/policies/remote_development/remote_development_agent_config_policy_spec.rb +++ b/ee/spec/policies/remote_development/remote_development_agent_config_policy_spec.rb @@ -6,10 +6,10 @@ let_it_be(:agent_project_creator, refind: true) { create(:user) } let_it_be(:agent_project, refind: true) { create(:project, creator: agent_project_creator) } let_it_be(:agent, refind: true) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: agent_project) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: agent_project) end - let_it_be(:agent_config) { agent.remote_development_agent_config } + let_it_be(:agent_config) { agent.workspaces_agent_config } subject(:policy_instance) { described_class.new(user, agent_config) } @@ -23,7 +23,7 @@ end it 'allows reading the corrosponding agent config' do - expect(policy_instance).to be_allowed(:read_remote_development_agent_config) + expect(policy_instance).to be_allowed(:read_workspaces_agent_config) end end @@ -37,7 +37,7 @@ end it 'disallows reading the corrosponding agent config' do - expect(policy_instance).to be_disallowed(:read_remote_development_agent_config) + expect(policy_instance).to be_disallowed(:read_workspaces_agent_config) end end end diff --git a/ee/spec/policies/remote_development/workspace_policy_spec.rb b/ee/spec/policies/remote_development/workspace_policy_spec.rb index 85a7da573b523b..cf1ed5c2312c03 100644 --- a/ee/spec/policies/remote_development/workspace_policy_spec.rb +++ b/ee/spec/policies/remote_development/workspace_policy_spec.rb @@ -9,7 +9,7 @@ let_it_be(:agent_project_creator, refind: true) { create(:user) } let_it_be(:agent_project, refind: true) { create(:project, creator: agent_project_creator) } let_it_be(:agent, refind: true) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: agent_project) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: agent_project) end let_it_be(:workspace_project_creator, refind: true) { create(:user) } diff --git a/ee/spec/policies/remote_development/workspaces_agent_config_policy_spec.rb b/ee/spec/policies/remote_development/workspaces_agent_config_policy_spec.rb new file mode 100644 index 00000000000000..36aef0baf96305 --- /dev/null +++ b/ee/spec/policies/remote_development/workspaces_agent_config_policy_spec.rb @@ -0,0 +1,43 @@ +# frozen_string_literal: true + +require 'spec_helper' + +RSpec.describe RemoteDevelopment::WorkspacesAgentConfigPolicy, feature_category: :remote_development do + let_it_be(:agent_project_creator, refind: true) { create(:user) } + let_it_be(:agent_project, refind: true) { create(:project, creator: agent_project_creator) } + let_it_be(:agent, refind: true) do + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: agent_project) + end + + let_it_be(:agent_config) { agent.workspaces_agent_config } + + subject(:policy_instance) { described_class.new(user, agent_config) } + + context 'when user can read a cluster agent' do + let(:user) { agent_project_creator } + + before do + allow_next_instance_of(described_class) do |policy| + allow(policy).to receive(:can?).with(:read_cluster_agent, agent).and_return(true) + end + end + + it 'allows reading the corrosponding agent config' do + expect(policy_instance).to be_allowed(:read_workspaces_agent_config) + end + end + + context 'when user can not read a cluster agent' do + let(:user) { create(:admin) } + + before do + allow_next_instance_of(described_class) do |policy| + allow(policy).to receive(:can?).with(:read_cluster_agent, agent).and_return(false) + end + end + + it 'disallows reading the corrosponding agent config' do + expect(policy_instance).to be_disallowed(:read_workspaces_agent_config) + end + end +end diff --git a/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/create_spec.rb b/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/create_spec.rb index 31cefd9fc1763f..5701fd6176cf79 100644 --- a/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/create_spec.rb +++ b/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/create_spec.rb @@ -24,7 +24,7 @@ end let_it_be(:agent, reload: true) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: agent_project) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: agent_project) end let_it_be(:agent_project_in_different_root_namespace, reload: true) do diff --git a/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/update_spec.rb b/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/update_spec.rb index 2a580af443aef6..4520b1022744bd 100644 --- a/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/update_spec.rb +++ b/ee/spec/requests/api/graphql/mutations/remote_development/workspace_operations/update_spec.rb @@ -13,7 +13,7 @@ let_it_be(:agent) do create(:ee_cluster_agent, - :with_remote_development_agent_config).tap { |agent| agent.project.add_developer(user) } + :with_existing_workspaces_agent_config).tap { |agent| agent.project.add_developer(user) } end let_it_be(:workspace, refind: true) do diff --git a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/remote_development_agent_config_spec.rb b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/remote_development_agent_config_spec.rb index cfbb9cd11d9c94..0b1fab82109ea8 100644 --- a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/remote_development_agent_config_spec.rb +++ b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/remote_development_agent_config_spec.rb @@ -3,7 +3,8 @@ require 'spec_helper' require_relative './shared' -RSpec.describe 'Query.namespace.remote_development_cluster_agents(filter: AVAILABLE)', feature_category: :remote_development do +# TODO: clusterAgent.remoteDevelopmentAgentConfig GraphQL is deprecated - remove in 17.10 - https://gitlab.com/gitlab-org/gitlab/-/issues/480769 +RSpec.describe 'Query.namespace.remote_development_cluster_agents(filter: AVAILABLE) for deprecated remote_development_agent_config field', feature_category: :remote_development do include GraphqlHelpers include StubFeatureFlags @@ -11,7 +12,7 @@ let(:agent_config_id) { subject['id'] } let_it_be(:current_user) { user } let_it_be(:available_agent) do - create(:ee_cluster_agent, :in_group, :with_remote_development_agent_config).tap do |agent| + create(:ee_cluster_agent, :in_group, :with_existing_workspaces_agent_config).tap do |agent| agent.project.namespace.add_maintainer(user) end end diff --git a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_available_filter_arg_spec.rb b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_available_filter_arg_spec.rb index 59540eefb23eac..03466d56e27ce6 100644 --- a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_available_filter_arg_spec.rb +++ b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_available_filter_arg_spec.rb @@ -14,7 +14,7 @@ # to be able to receive the agent when calling the API i.e. the user has Developer access # to the agent project ONLY (and not a group-level access) let_it_be(:agent) do - create(:ee_cluster_agent, :in_group, :with_remote_development_agent_config).tap do |agent| + create(:ee_cluster_agent, :in_group, :with_existing_workspaces_agent_config).tap do |agent| agent.project.add_developer(user) end end diff --git a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_directly_mapped_filter_arg_spec.rb b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_directly_mapped_filter_arg_spec.rb index 98934a3f501572..0021857761f6fe 100644 --- a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_directly_mapped_filter_arg_spec.rb +++ b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_directly_mapped_filter_arg_spec.rb @@ -14,13 +14,13 @@ # to be able to retrieve directly mapped agent when calling the API i.e. # the user has Maintainer access for the group let_it_be(:mapped_agent) do - create(:ee_cluster_agent, :in_group, :with_remote_development_agent_config).tap do |agent| + create(:ee_cluster_agent, :in_group, :with_existing_workspaces_agent_config).tap do |agent| agent.project.namespace.add_maintainer(user) end end let_it_be(:unmapped_agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: mapped_agent.project) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: mapped_agent.project) end let_it_be(:namespace) { mapped_agent.project.namespace } diff --git a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_unmapped_filter_arg_spec.rb b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_unmapped_filter_arg_spec.rb index b6c6b85e42f07b..5096320e1ac7d4 100644 --- a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_unmapped_filter_arg_spec.rb +++ b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/with_unmapped_filter_arg_spec.rb @@ -11,13 +11,13 @@ let_it_be(:user) { create(:user) } let_it_be(:current_user) { user } let_it_be(:mapped_agent) do - create(:ee_cluster_agent, :in_group, :with_remote_development_agent_config).tap do |agent| + create(:ee_cluster_agent, :in_group, :with_existing_workspaces_agent_config).tap do |agent| agent.project.namespace.add_maintainer(user) end end let_it_be(:unmapped_agent) do - create(:ee_cluster_agent, :with_remote_development_agent_config, project: mapped_agent.project) + create(:ee_cluster_agent, :with_existing_workspaces_agent_config, project: mapped_agent.project) end let_it_be(:namespace) { mapped_agent.project.namespace } diff --git a/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/workspaces_agent_config_spec.rb b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/workspaces_agent_config_spec.rb new file mode 100644 index 00000000000000..137adaa62286a2 --- /dev/null +++ b/ee/spec/requests/api/graphql/remote_development/namespace/remote_development_cluster_agents/workspaces_agent_config_spec.rb @@ -0,0 +1,91 @@ +# frozen_string_literal: true + +require 'spec_helper' +require_relative './shared' + +RSpec.describe 'Query.namespace.remote_development_cluster_agents(filter: AVAILABLE)', feature_category: :remote_development do + include GraphqlHelpers + include StubFeatureFlags + + let_it_be(:user) { create(:user) } + let(:agent_config_id) { subject['id'] } + let_it_be(:current_user) { user } + let_it_be(:available_agent) do + create(:ee_cluster_agent, :in_group, :with_existing_workspaces_agent_config).tap do |agent| + agent.project.namespace.add_maintainer(user) + end + end + + let_it_be(:agent_config) { available_agent.workspaces_agent_config } + let_it_be(:namespace) { available_agent.project.namespace } + let_it_be(:namespace_agent_mapping) do + create( + :remote_development_namespace_cluster_agent_mapping, + user: user, + agent: available_agent, + namespace: namespace + ) + end + + let(:fields) do + <<~QUERY + nodes { + workspacesAgentConfig { + #{all_graphql_fields_for('workspaces_agent_config'.classify, max_depth: 1)} + } + } + QUERY + end + + let(:query) do + graphql_query_for( + :namespace, + { full_path: namespace.full_path }, + query_graphql_field( + :remote_development_cluster_agents, + { filter: :AVAILABLE }, + fields + ) + ) + end + + subject do + graphql_data.dig('namespace', 'remoteDevelopmentClusterAgents', 'nodes', 0, 'workspacesAgentConfig') + end + + before do + stub_licensed_features(remote_development: true) + end + + context 'when the params are valid' do + let(:expected_agent_config_id) do + "gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/" \ + "#{agent_config.id}" + end + + let(:expected_agent_config) do + { + 'id' => expected_agent_config_id, + 'projectId' => agent_config.project_id, + 'enabled' => agent_config.enabled, + 'dnsZone' => agent_config.dns_zone, + 'networkPolicyEnabled' => agent_config.network_policy_enabled, + 'gitlabWorkspacesProxyNamespace' => agent_config.gitlab_workspaces_proxy_namespace, + 'workspacesQuota' => agent_config.workspaces_quota, + 'workspacesPerUserQuota' => agent_config.workspaces_per_user_quota, + 'defaultMaxHoursBeforeTermination' => agent_config.default_maxHours_before_termination, + 'maxHoursBeforeTerminationLimit' => agent_config.max_hours_before_termination_limit, + 'createdAt' => agent_config.created_at, + 'updatedAt' => agent_config.updated_at + } + end + + it 'returns cluster agents that are available for remote development in the namespace' do + get_graphql(query, current_user: current_user) + + expect(agent_config_id).to eq(expected_agent_config_id) + end + end + + include_examples "checks for remote_development licensed feature" +end diff --git a/ee/spec/requests/api/graphql/remote_development/shared.rb b/ee/spec/requests/api/graphql/remote_development/shared.rb index 9221229954d682..ce4c26aa9e214e 100644 --- a/ee/spec/requests/api/graphql/remote_development/shared.rb +++ b/ee/spec/requests/api/graphql/remote_development/shared.rb @@ -62,7 +62,7 @@ RSpec.shared_context 'with agent_ids argument' do include_context 'with unauthorized workspace created' - let_it_be(:agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let_it_be(:workspace, reload: true) { create(:workspace, agent: agent, name: 'matching-workspace') } include_context 'with non_matching_workspace associated with other agent created' @@ -204,7 +204,7 @@ RSpec.shared_context 'with non_matching_workspace associated with other agent created' do # create workspace associated with different agent but owned by same user, to ensure isn't returned by the query - let_it_be(:other_agent) { create(:ee_cluster_agent, :with_remote_development_agent_config) } + let_it_be(:other_agent) { create(:ee_cluster_agent, :with_existing_workspaces_agent_config) } let_it_be(:non_matching_workspace, reload: true) do create(:workspace, agent: other_agent, user: workspace.user, name: 'non-matching-workspace') end diff --git a/ee/spec/requests/api/internal/kubernetes_spec.rb b/ee/spec/requests/api/internal/kubernetes_spec.rb index 797499c187af3a..8d67925dfc81f0 100644 --- a/ee/spec/requests/api/internal/kubernetes_spec.rb +++ b/ee/spec/requests/api/internal/kubernetes_spec.rb @@ -165,8 +165,8 @@ def send_request(headers: {}, params: {}) it 'creates the remote dev configuration' do send_request(params: { agent_id: agent.id, agent_config: config }) expect(response).to have_gitlab_http_status(:no_content) - expect(agent.reload.remote_development_agent_config).to be_enabled - expect(agent.reload.remote_development_agent_config.dns_zone).to eq(dns_zone) + expect(agent.reload.workspaces_agent_config).to be_enabled + expect(agent.reload.workspaces_agent_config.dns_zone).to eq(dns_zone) end context 'when remote_development feature is unlicensed' do @@ -177,7 +177,7 @@ def send_request(headers: {}, params: {}) it 'creates the remote dev configuration' do send_request(params: { agent_id: agent.id, agent_config: config }) expect(response).to have_gitlab_http_status(:no_content) - expect(agent.reload.remote_development_agent_config).to be_nil + expect(agent.reload.workspaces_agent_config).to be_nil end end end diff --git a/ee/spec/requests/remote_development/integration_spec.rb b/ee/spec/requests/remote_development/integration_spec.rb index df91d31f79da2e..b2f7d7da91b47c 100644 --- a/ee/spec/requests/remote_development/integration_spec.rb +++ b/ee/spec/requests/remote_development/integration_spec.rb @@ -20,7 +20,7 @@ remoteDevelopmentClusterAgents(filter: AVAILABLE) { nodes { id - remoteDevelopmentAgentConfig { + workspacesAgentConfig { id projectId enabled @@ -49,7 +49,7 @@ let(:expected_agent_config) do { - "id" => "gid://gitlab/RemoteDevelopment::RemoteDevelopmentAgentConfig/#{remote_development_agent_config.id}", + "id" => "gid://gitlab/RemoteDevelopment::WorkspacesAgentConfig/#{workspaces_agent_config.id}", "projectId" => agent_project.id.to_s, "enabled" => true, "gitlabWorkspacesProxyNamespace" => "gitlab-workspaces", @@ -144,13 +144,13 @@ create(:ee_cluster_agent, project: agent_project, created_by_user: agent_admin_user, project_id: agent_project.id) end - # TODO: We should create the remote_development_agent_config via an API call to update the agent config + # TODO: We should create the workspaces_agent_config via an API call to update the agent config # with the relevant fixture values in its config file to represent a remote_development enabled agent. # And, as we migrate the settings from the agent config file to the settings UI, we should add # simulated API calls for setting the values that way too. - let!(:remote_development_agent_config) do + let!(:workspaces_agent_config) do create( - :remote_development_agent_config, + :workspaces_agent_config, agent: agent, gitlab_workspaces_proxy_namespace: gitlab_workspaces_proxy_namespace, dns_zone: dns_zone, @@ -190,7 +190,7 @@ def fetch_agent_config get_graphql(cluster_agents_query, current_user: agent_admin_user) expect( - graphql_data_at(:namespace, :remoteDevelopmentClusterAgents, :nodes, 0, :remoteDevelopmentAgentConfig) + graphql_data_at(:namespace, :remoteDevelopmentClusterAgents, :nodes, 0, :workspacesAgentConfig) ).to eq(expected_agent_config) graphql_data_at(:namespace, :remoteDevelopmentClusterAgents, :nodes, 0, :id) diff --git a/locale/am_ET/gitlab.po b/locale/am_ET/gitlab.po index 9f7c6f00c75c0a..66f679effc6e72 100644 --- a/locale/am_ET/gitlab.po +++ b/locale/am_ET/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ar_SA/gitlab.po b/locale/ar_SA/gitlab.po index 2a94f2fcccfb0a..82963b40c57da6 100644 --- a/locale/ar_SA/gitlab.po +++ b/locale/ar_SA/gitlab.po @@ -62662,10 +62662,10 @@ msgstr[5] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -64182,4 +64182,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/as_IN/gitlab.po b/locale/as_IN/gitlab.po index d1a8054f871a55..e066a08a578780 100644 --- a/locale/as_IN/gitlab.po +++ b/locale/as_IN/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/az_AZ/gitlab.po b/locale/az_AZ/gitlab.po index ea95f43848071d..83f847e88f159b 100644 --- a/locale/az_AZ/gitlab.po +++ b/locale/az_AZ/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ba_RU/gitlab.po b/locale/ba_RU/gitlab.po index abecea317a8366..49c4e6fc65c69c 100644 --- a/locale/ba_RU/gitlab.po +++ b/locale/ba_RU/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/be_BY/gitlab.po b/locale/be_BY/gitlab.po index cb9e840c7e77b3..bae253774ad17b 100644 --- a/locale/be_BY/gitlab.po +++ b/locale/be_BY/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/bg/gitlab.po b/locale/bg/gitlab.po index 3947d995245225..d2f8bfb43c8936 100644 --- a/locale/bg/gitlab.po +++ b/locale/bg/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/bn_BD/gitlab.po b/locale/bn_BD/gitlab.po index f29f1728362329..fce1d13c131d51 100644 --- a/locale/bn_BD/gitlab.po +++ b/locale/bn_BD/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/bn_IN/gitlab.po b/locale/bn_IN/gitlab.po index 412d39f080ebb8..f778b57bfac697 100644 --- a/locale/bn_IN/gitlab.po +++ b/locale/bn_IN/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/br_FR/gitlab.po b/locale/br_FR/gitlab.po index a76966778d9791..a59622532917af 100644 --- a/locale/br_FR/gitlab.po +++ b/locale/br_FR/gitlab.po @@ -62312,10 +62312,10 @@ msgstr[4] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63814,4 +63814,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/bs_BA/gitlab.po b/locale/bs_BA/gitlab.po index fc7016c2e2d763..14402013c840fe 100644 --- a/locale/bs_BA/gitlab.po +++ b/locale/bs_BA/gitlab.po @@ -61612,10 +61612,10 @@ msgstr[2] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63078,4 +63078,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ca_ES/gitlab.po b/locale/ca_ES/gitlab.po index 755c3d3c9f1e10..e16cc9776f80e7 100644 --- a/locale/ca_ES/gitlab.po +++ b/locale/ca_ES/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/cs_CZ/gitlab.po b/locale/cs_CZ/gitlab.po index 2954b65eba04e3..49d15fa99b5135 100644 --- a/locale/cs_CZ/gitlab.po +++ b/locale/cs_CZ/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/cy_GB/gitlab.po b/locale/cy_GB/gitlab.po index 46133f5882e99f..ac841c30188015 100644 --- a/locale/cy_GB/gitlab.po +++ b/locale/cy_GB/gitlab.po @@ -62662,10 +62662,10 @@ msgstr[5] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -64182,4 +64182,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/da_DK/gitlab.po b/locale/da_DK/gitlab.po index e7c9ddae5cee68..6787bdb6b4974e 100644 --- a/locale/da_DK/gitlab.po +++ b/locale/da_DK/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "filer" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "{projekt}" msgid "✔" msgstr "" - diff --git a/locale/de/gitlab.po b/locale/de/gitlab.po index 964df11dbd9d28..ad869e4aaa41da 100644 --- a/locale/de/gitlab.po +++ b/locale/de/gitlab.po @@ -61262,11 +61262,11 @@ msgstr[1] "Dateien" msgid "finding is not found or is already attached to a vulnerability" msgstr "Fund wurde nicht gefunden oder ist bereits mit einer Sicherheitslücke verknüpft." -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" -msgstr "für den Arbeitsbereich muss eine zugehörige RemoteDevelopmentAgentConfig vorhanden sein" +msgid "for Workspace must have an associated WorkspacesAgentConfig" +msgstr "für den Arbeitsbereich muss eine zugehörige WorkspacesAgentConfig vorhanden sein" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" -msgstr "für den Workspace muss mit der dns_zone der zugehörigen RemoteDevelopmentAgentConfig übereinstimmen" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" +msgstr "für den Workspace muss mit der dns_zone der zugehörigen WorkspacesAgentConfig übereinstimmen" msgid "for this project" msgstr "für dieses Projekt" @@ -62710,4 +62710,3 @@ msgstr "{Projekt}" msgid "✔" msgstr "✔" - diff --git a/locale/el_GR/gitlab.po b/locale/el_GR/gitlab.po index bda1744d0d9ad9..d0b715e79b255f 100644 --- a/locale/el_GR/gitlab.po +++ b/locale/el_GR/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/en_GB/gitlab.po b/locale/en_GB/gitlab.po index 3bed0e595d6add..6e0f239069ba02 100644 --- a/locale/en_GB/gitlab.po +++ b/locale/en_GB/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/eo/gitlab.po b/locale/eo/gitlab.po index 8a49be719d99b6..4b04bc3ec7aef2 100644 --- a/locale/eo/gitlab.po +++ b/locale/eo/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/es/gitlab.po b/locale/es/gitlab.po index 20d86863f48c8e..ded9c9c1ca194a 100644 --- a/locale/es/gitlab.po +++ b/locale/es/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "archivos" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "{project}" msgid "✔" msgstr "✔" - diff --git a/locale/et_EE/gitlab.po b/locale/et_EE/gitlab.po index c6d2466a2d52b8..ca3eb560b329a7 100644 --- a/locale/et_EE/gitlab.po +++ b/locale/et_EE/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/eu_ES/gitlab.po b/locale/eu_ES/gitlab.po index a044fc2d2b9277..df5d82a39d6f8b 100644 --- a/locale/eu_ES/gitlab.po +++ b/locale/eu_ES/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/fa_IR/gitlab.po b/locale/fa_IR/gitlab.po index 0db8b129117d24..185d63627a3449 100644 --- a/locale/fa_IR/gitlab.po +++ b/locale/fa_IR/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/fi_FI/gitlab.po b/locale/fi_FI/gitlab.po index 8fa8ea8fa5e5d5..677df27e2d497e 100644 --- a/locale/fi_FI/gitlab.po +++ b/locale/fi_FI/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/fil_PH/gitlab.po b/locale/fil_PH/gitlab.po index 341c33896300ee..b08d9a54312d9f 100644 --- a/locale/fil_PH/gitlab.po +++ b/locale/fil_PH/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/fr/gitlab.po b/locale/fr/gitlab.po index 385061dc1ece90..b8d6c9d6be2f19 100644 --- a/locale/fr/gitlab.po +++ b/locale/fr/gitlab.po @@ -61262,11 +61262,11 @@ msgstr[1] "fichiers" msgid "finding is not found or is already attached to a vulnerability" msgstr "la découverte est introuvable ou est déjà rattachée à une vulnérabilité" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" -msgstr "dans un espace de travail doit avoir un RemoteDevelopmentAgentConfig associé" +msgid "for Workspace must have an associated WorkspacesAgentConfig" +msgstr "dans un espace de travail doit avoir un WorkspacesAgentConfig associé" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" -msgstr "pour l'espace de travail doit correspondre à dns_zone du RemoteDevelopmentAgentConfig associé" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" +msgstr "pour l'espace de travail doit correspondre à dns_zone du WorkspacesAgentConfig associé" msgid "for this project" msgstr "pour ce projet" @@ -62710,4 +62710,3 @@ msgstr "{project}" msgid "✔" msgstr "✔" - diff --git a/locale/gitlab.pot b/locale/gitlab.pot index 2dd31315d575b9..90ce0f4cd13e85 100644 --- a/locale/gitlab.pot +++ b/locale/gitlab.pot @@ -63908,10 +63908,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" diff --git a/locale/gl_ES/gitlab.po b/locale/gl_ES/gitlab.po index f037129f07aab7..30fd856676eea4 100644 --- a/locale/gl_ES/gitlab.po +++ b/locale/gl_ES/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/he_IL/gitlab.po b/locale/he_IL/gitlab.po index a75188d36de6b9..2125d19f5b2ec3 100644 --- a/locale/he_IL/gitlab.po +++ b/locale/he_IL/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/hi_IN/gitlab.po b/locale/hi_IN/gitlab.po index 3b851f471ad02f..31ca6f0c17d420 100644 --- a/locale/hi_IN/gitlab.po +++ b/locale/hi_IN/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/hr_HR/gitlab.po b/locale/hr_HR/gitlab.po index ee04999cf7f5f6..b25f202b3ea25f 100644 --- a/locale/hr_HR/gitlab.po +++ b/locale/hr_HR/gitlab.po @@ -61612,10 +61612,10 @@ msgstr[2] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63078,4 +63078,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/hu_HU/gitlab.po b/locale/hu_HU/gitlab.po index 92d9ed66f7d739..cded67374686db 100644 --- a/locale/hu_HU/gitlab.po +++ b/locale/hu_HU/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/hy_AM/gitlab.po b/locale/hy_AM/gitlab.po index 78c327eef3d07e..89d723c8b40026 100644 --- a/locale/hy_AM/gitlab.po +++ b/locale/hy_AM/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/id_ID/gitlab.po b/locale/id_ID/gitlab.po index 466dc0bf3bf1f5..f79cf35ddb708d 100644 --- a/locale/id_ID/gitlab.po +++ b/locale/id_ID/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ig_NG/gitlab.po b/locale/ig_NG/gitlab.po index ab127c5e39a6fa..ae7124a838b8ef 100644 --- a/locale/ig_NG/gitlab.po +++ b/locale/ig_NG/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/is_IS/gitlab.po b/locale/is_IS/gitlab.po index 607450671f89a9..925ebacea1f1be 100644 --- a/locale/is_IS/gitlab.po +++ b/locale/is_IS/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/it/gitlab.po b/locale/it/gitlab.po index 5ee1045a3f6ad4..7543c82d431316 100644 --- a/locale/it/gitlab.po +++ b/locale/it/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ja/gitlab.po b/locale/ja/gitlab.po index d879fc4d2f0697..60192696cfaa6b 100644 --- a/locale/ja/gitlab.po +++ b/locale/ja/gitlab.po @@ -60912,11 +60912,11 @@ msgstr[0] "ファイル" msgid "finding is not found or is already attached to a vulnerability" msgstr "発見されないか、すでに脆弱性に関連付けられています" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" -msgstr "ワークスペースにはRemoteDevelopmentAgentConfigが関連付けられている必要があるため" +msgid "for Workspace must have an associated WorkspacesAgentConfig" +msgstr "ワークスペースにはWorkspacesAgentConfigが関連付けられている必要があるため" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" -msgstr "ワークスペースの場合、関連付けれられたRemoteDevelopmentAgentConfigのdns_zoneと一致する必要があります" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" +msgstr "ワークスペースの場合、関連付けれられたWorkspacesAgentConfigのdns_zoneと一致する必要があります" msgid "for this project" msgstr "このプロジェクトでは" @@ -62342,4 +62342,3 @@ msgstr "{プロジェクト}" msgid "✔" msgstr "✔" - diff --git a/locale/ka_GE/gitlab.po b/locale/ka_GE/gitlab.po index 6a1861c454da16..56c4fc8e1fb31d 100644 --- a/locale/ka_GE/gitlab.po +++ b/locale/ka_GE/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/kab/gitlab.po b/locale/kab/gitlab.po index 3b292091d2ebd4..e70e961cc33910 100644 --- a/locale/kab/gitlab.po +++ b/locale/kab/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ko/gitlab.po b/locale/ko/gitlab.po index b366ba08b52bbd..1d69828c721912 100644 --- a/locale/ko/gitlab.po +++ b/locale/ko/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "파일" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "{프로젝트}" msgid "✔" msgstr "" - diff --git a/locale/ku_TR/gitlab.po b/locale/ku_TR/gitlab.po index 220057026546fb..3138c534038c2c 100644 --- a/locale/ku_TR/gitlab.po +++ b/locale/ku_TR/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ky_KG/gitlab.po b/locale/ky_KG/gitlab.po index e8dd0a87cc1b38..979dda763304d0 100644 --- a/locale/ky_KG/gitlab.po +++ b/locale/ky_KG/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/lt_LT/gitlab.po b/locale/lt_LT/gitlab.po index 1897aea800c8b1..11a7215ec8e0fb 100644 --- a/locale/lt_LT/gitlab.po +++ b/locale/lt_LT/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/mk_MK/gitlab.po b/locale/mk_MK/gitlab.po index 28971b9dab1095..0a765789d4ff86 100644 --- a/locale/mk_MK/gitlab.po +++ b/locale/mk_MK/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ml_IN/gitlab.po b/locale/ml_IN/gitlab.po index 2f7f051efd78e7..3b1ebdb433e752 100644 --- a/locale/ml_IN/gitlab.po +++ b/locale/ml_IN/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/mn_MN/gitlab.po b/locale/mn_MN/gitlab.po index ec4852f3ef9f08..1c5fd270d0a430 100644 --- a/locale/mn_MN/gitlab.po +++ b/locale/mn_MN/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ms_MY/gitlab.po b/locale/ms_MY/gitlab.po index 3194f2f9a0fa36..2331447f63ec88 100644 --- a/locale/ms_MY/gitlab.po +++ b/locale/ms_MY/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/nb_NO/gitlab.po b/locale/nb_NO/gitlab.po index 4891d8119d3ac6..4ab81df9a771ab 100644 --- a/locale/nb_NO/gitlab.po +++ b/locale/nb_NO/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "filer" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "✔" - diff --git a/locale/ne_NP/gitlab.po b/locale/ne_NP/gitlab.po index ab57fdc0ac15d9..6985ac59b295dc 100644 --- a/locale/ne_NP/gitlab.po +++ b/locale/ne_NP/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/nl_NL/gitlab.po b/locale/nl_NL/gitlab.po index dd2cbe7fb741d1..4bfa54a0cd7608 100644 --- a/locale/nl_NL/gitlab.po +++ b/locale/nl_NL/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/or_IN/gitlab.po b/locale/or_IN/gitlab.po index 6e70904f090be3..a993051eca2aff 100644 --- a/locale/or_IN/gitlab.po +++ b/locale/or_IN/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/pa_IN/gitlab.po b/locale/pa_IN/gitlab.po index b522501635920a..2541cc41a7ec67 100644 --- a/locale/pa_IN/gitlab.po +++ b/locale/pa_IN/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/pa_PK/gitlab.po b/locale/pa_PK/gitlab.po index 9d85f65a188ceb..a17486b09371ba 100644 --- a/locale/pa_PK/gitlab.po +++ b/locale/pa_PK/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/pl_PL/gitlab.po b/locale/pl_PL/gitlab.po index cce3cd733baf36..04121912a7cf86 100644 --- a/locale/pl_PL/gitlab.po +++ b/locale/pl_PL/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/pt_BR/gitlab.po b/locale/pt_BR/gitlab.po index 88fafba5cdaba2..dba7846c48de00 100644 --- a/locale/pt_BR/gitlab.po +++ b/locale/pt_BR/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "arquivos" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "{project}" msgid "✔" msgstr "" - diff --git a/locale/pt_PT/gitlab.po b/locale/pt_PT/gitlab.po index 041b03e46390a5..946deea5c695f3 100644 --- a/locale/pt_PT/gitlab.po +++ b/locale/pt_PT/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ro_RO/gitlab.po b/locale/ro_RO/gitlab.po index bfc5971cacb107..560c0f87af154f 100644 --- a/locale/ro_RO/gitlab.po +++ b/locale/ro_RO/gitlab.po @@ -61612,10 +61612,10 @@ msgstr[2] "de fișiere" msgid "finding is not found or is already attached to a vulnerability" msgstr "constatarea nu este găsită sau este deja atașată unei vulnerabilități" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63078,4 +63078,3 @@ msgstr "{proiect}" msgid "✔" msgstr "✔" - diff --git a/locale/ru/gitlab.po b/locale/ru/gitlab.po index 3d773b8baf33a7..47af9704065eee 100644 --- a/locale/ru/gitlab.po +++ b/locale/ru/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "файлов" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/si_LK/gitlab.po b/locale/si_LK/gitlab.po index a14e6c8c5f2abf..f427f5618644c6 100644 --- a/locale/si_LK/gitlab.po +++ b/locale/si_LK/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "ගොනු" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "{project}" msgid "✔" msgstr "✔" - diff --git a/locale/sk_SK/gitlab.po b/locale/sk_SK/gitlab.po index 9480d8aba5bf11..774996b06a4807 100644 --- a/locale/sk_SK/gitlab.po +++ b/locale/sk_SK/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/sl_SI/gitlab.po b/locale/sl_SI/gitlab.po index fdcee8caf47a4f..339f19f3dea7d5 100644 --- a/locale/sl_SI/gitlab.po +++ b/locale/sl_SI/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/sq_AL/gitlab.po b/locale/sq_AL/gitlab.po index 924d3b0e2ae1cf..a3d45df3d3e3fa 100644 --- a/locale/sq_AL/gitlab.po +++ b/locale/sq_AL/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/sr_CS/gitlab.po b/locale/sr_CS/gitlab.po index d8fb8c8ed44679..6e6b2b3d3654b3 100644 --- a/locale/sr_CS/gitlab.po +++ b/locale/sr_CS/gitlab.po @@ -61612,10 +61612,10 @@ msgstr[2] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63078,4 +63078,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/sr_SP/gitlab.po b/locale/sr_SP/gitlab.po index 86b48fe0859c55..a873a85aa8391d 100644 --- a/locale/sr_SP/gitlab.po +++ b/locale/sr_SP/gitlab.po @@ -61612,10 +61612,10 @@ msgstr[2] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63078,4 +63078,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/sv_SE/gitlab.po b/locale/sv_SE/gitlab.po index 9f1dae29c4e4c7..28fb2cf0858b40 100644 --- a/locale/sv_SE/gitlab.po +++ b/locale/sv_SE/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "filer" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "{projekt}" msgid "✔" msgstr "✔" - diff --git a/locale/sw_KE/gitlab.po b/locale/sw_KE/gitlab.po index 337d58c84c88db..7487acc95fa3d8 100644 --- a/locale/sw_KE/gitlab.po +++ b/locale/sw_KE/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ta_IN/gitlab.po b/locale/ta_IN/gitlab.po index 7caddfc9e33857..0bbe0548ab8958 100644 --- a/locale/ta_IN/gitlab.po +++ b/locale/ta_IN/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/th_TH/gitlab.po b/locale/th_TH/gitlab.po index 82547dde8199d3..7ca56d4a140427 100644 --- a/locale/th_TH/gitlab.po +++ b/locale/th_TH/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/ti_ER/gitlab.po b/locale/ti_ER/gitlab.po index 3b6a5b87ab9318..4c31e2080a04c7 100644 --- a/locale/ti_ER/gitlab.po +++ b/locale/ti_ER/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/tr_TR/gitlab.po b/locale/tr_TR/gitlab.po index 06b1d681299acd..446350c30d9ddd 100644 --- a/locale/tr_TR/gitlab.po +++ b/locale/tr_TR/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "dosya" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/uk/gitlab.po b/locale/uk/gitlab.po index 801752e3ad52dc..577f0ca02ca877 100644 --- a/locale/uk/gitlab.po +++ b/locale/uk/gitlab.po @@ -61962,10 +61962,10 @@ msgstr[3] "файлів" msgid "finding is not found or is already attached to a vulnerability" msgstr "знахідку втрачено або вже закріплено за вразливістю" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -63446,4 +63446,3 @@ msgstr "{project}" msgid "✔" msgstr "✔" - diff --git a/locale/ur_PK/gitlab.po b/locale/ur_PK/gitlab.po index d88cd09a70e03d..4e8ada88f1399f 100644 --- a/locale/ur_PK/gitlab.po +++ b/locale/ur_PK/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/uz_UZ/gitlab.po b/locale/uz_UZ/gitlab.po index 6d8b258b7df168..cb9fb13d74a74d 100644 --- a/locale/uz_UZ/gitlab.po +++ b/locale/uz_UZ/gitlab.po @@ -61262,10 +61262,10 @@ msgstr[1] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62710,4 +62710,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/vi_VN/gitlab.po b/locale/vi_VN/gitlab.po index 3ddd7da566f9ab..a10bf9d87e19e6 100644 --- a/locale/vi_VN/gitlab.po +++ b/locale/vi_VN/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/zh_CN/gitlab.po b/locale/zh_CN/gitlab.po index 68d9a7cc55a138..9ec44222f113e2 100644 --- a/locale/zh_CN/gitlab.po +++ b/locale/zh_CN/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "文件" msgid "finding is not found or is already attached to a vulnerability" msgstr "结果无法找到或已与漏洞关联。" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" -msgstr "对于必须具有关联的 RemoteDevelopmentAgentConfig 的工作区" +msgid "for Workspace must have an associated WorkspacesAgentConfig" +msgstr "对于必须具有关联的 WorkspacesAgentConfig 的工作区" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "{project}" msgid "✔" msgstr "✔" - diff --git a/locale/zh_HK/gitlab.po b/locale/zh_HK/gitlab.po index 2dc005c94d80d8..d813cbceb63a28 100644 --- a/locale/zh_HK/gitlab.po +++ b/locale/zh_HK/gitlab.po @@ -60912,10 +60912,10 @@ msgstr[0] "" msgid "finding is not found or is already attached to a vulnerability" msgstr "" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" msgstr "" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" msgstr "" msgid "for this project" @@ -62342,4 +62342,3 @@ msgstr "" msgid "✔" msgstr "" - diff --git a/locale/zh_TW/gitlab.po b/locale/zh_TW/gitlab.po index b41e6327564afc..c5f16cf8cb98c2 100644 --- a/locale/zh_TW/gitlab.po +++ b/locale/zh_TW/gitlab.po @@ -60912,11 +60912,11 @@ msgstr[0] "文件" msgid "finding is not found or is already attached to a vulnerability" msgstr "結果無法找到或已與漏洞關聯。" -msgid "for Workspace must have an associated RemoteDevelopmentAgentConfig" -msgstr "工作區必須有關聯的 RemoteDevelopmentAgentConfig" +msgid "for Workspace must have an associated WorkspacesAgentConfig" +msgstr "工作區必須有關聯的 WorkspacesAgentConfig" -msgid "for Workspace must match the dns_zone of the associated RemoteDevelopmentAgentConfig" -msgstr "工作區必須與關聯的 RemoteDevelopmentAgentConfig 的 dns_zone 匹配" +msgid "for Workspace must match the dns_zone of the associated WorkspacesAgentConfig" +msgstr "工作區必須與關聯的 WorkspacesAgentConfig 的 dns_zone 匹配" msgid "for this project" msgstr "對於這個專案" @@ -62342,4 +62342,3 @@ msgstr "{project}" msgid "✔" msgstr "✔" - diff --git a/scripts/remote_development/run-smoke-test-suite.sh b/scripts/remote_development/run-smoke-test-suite.sh index d61369b4cdf874..1ba83daeb3d1fe 100755 --- a/scripts/remote_development/run-smoke-test-suite.sh +++ b/scripts/remote_development/run-smoke-test-suite.sh @@ -93,8 +93,10 @@ function run_rspec_rails_non_fast { done < <(git grep -L -E '^require .fast_spec_helper' -- '**/remote_development/*_spec.rb' | grep -v 'qa/qa' | grep -v '/features/') files_for_rails+=( + "ee/spec/graphql/resolvers/clusters/agents_resolver_spec.rb" "ee/spec/graphql/types/query_type_spec.rb" "ee/spec/graphql/types/subscription_type_spec.rb" + "ee/spec/models/ee/clusters/agent_spec.rb" "ee/spec/requests/api/internal/kubernetes_spec.rb" "spec/graphql/types/subscription_type_spec.rb" "spec/support_specs/matchers/result_matchers_spec.rb" -- GitLab