mirror of
https://github.com/coder/coder.git
synced 2026-06-02 20:48:20 +00:00
chore(coderd/database): enforce agent name unique within workspace build (#18052)
Adds a database trigger that runs on insert and update of the `workspace_agents` table. The trigger ensures that the agent name is unique within the context of the workspace build it is being inserted into.
This commit is contained in:
Generated
+43
@@ -316,6 +316,43 @@ CREATE TYPE workspace_transition AS ENUM (
|
||||
'delete'
|
||||
);
|
||||
|
||||
CREATE FUNCTION check_workspace_agent_name_unique() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
DECLARE
|
||||
workspace_build_id uuid;
|
||||
agents_with_name int;
|
||||
BEGIN
|
||||
-- Find the workspace build the workspace agent is being inserted into.
|
||||
SELECT workspace_builds.id INTO workspace_build_id
|
||||
FROM workspace_resources
|
||||
JOIN workspace_builds ON workspace_builds.job_id = workspace_resources.job_id
|
||||
WHERE workspace_resources.id = NEW.resource_id;
|
||||
|
||||
-- If the agent doesn't have a workspace build, we'll allow the insert.
|
||||
IF workspace_build_id IS NULL THEN
|
||||
RETURN NEW;
|
||||
END IF;
|
||||
|
||||
-- Count how many agents in this workspace build already have the given agent name.
|
||||
SELECT COUNT(*) INTO agents_with_name
|
||||
FROM workspace_agents
|
||||
JOIN workspace_resources ON workspace_resources.id = workspace_agents.resource_id
|
||||
JOIN workspace_builds ON workspace_builds.job_id = workspace_resources.job_id
|
||||
WHERE workspace_builds.id = workspace_build_id
|
||||
AND workspace_agents.name = NEW.name
|
||||
AND workspace_agents.id != NEW.id;
|
||||
|
||||
-- If there's already an agent with this name, raise an error
|
||||
IF agents_with_name > 0 THEN
|
||||
RAISE EXCEPTION 'workspace agent name "%" already exists in this workspace build', NEW.name
|
||||
USING ERRCODE = 'unique_violation';
|
||||
END IF;
|
||||
|
||||
RETURN NEW;
|
||||
END;
|
||||
$$;
|
||||
|
||||
CREATE FUNCTION compute_notification_message_dedupe_hash() RETURNS trigger
|
||||
LANGUAGE plpgsql
|
||||
AS $$
|
||||
@@ -2773,6 +2810,12 @@ CREATE TRIGGER update_notification_message_dedupe_hash BEFORE INSERT OR UPDATE O
|
||||
|
||||
CREATE TRIGGER user_status_change_trigger AFTER INSERT OR UPDATE ON users FOR EACH ROW EXECUTE FUNCTION record_user_status_change();
|
||||
|
||||
CREATE TRIGGER workspace_agent_name_unique_trigger BEFORE INSERT OR UPDATE OF name, resource_id ON workspace_agents FOR EACH ROW EXECUTE FUNCTION check_workspace_agent_name_unique();
|
||||
|
||||
COMMENT ON TRIGGER workspace_agent_name_unique_trigger ON workspace_agents IS 'Use a trigger instead of a unique constraint because existing data may violate
|
||||
the uniqueness requirement. A trigger allows us to enforce uniqueness going
|
||||
forward without requiring a migration to clean up historical data.';
|
||||
|
||||
ALTER TABLE ONLY api_keys
|
||||
ADD CONSTRAINT api_keys_user_id_uuid_fkey FOREIGN KEY (user_id) REFERENCES users(id) ON DELETE CASCADE;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user