118 lines
4.9 KiB
PL/PgSQL
118 lines
4.9 KiB
PL/PgSQL
-- The store of Terraform modules, their instances and the instances' variable files: the tables tf_modules,
|
|
-- tf_instances and tf_variable_files, and the functions and procedures the store calls. The store applies the file on
|
|
-- its first use in the schema its connection's search path names; every statement can run again.
|
|
|
|
CREATE TABLE IF NOT EXISTS tf_modules (
|
|
name text PRIMARY KEY CHECK (name ~ '^[a-z][a-z0-9-]*$'),
|
|
root text NOT NULL CHECK (root <> ''),
|
|
description text NOT NULL DEFAULT '',
|
|
configurator_url text
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS tf_instances (
|
|
module text NOT NULL REFERENCES tf_modules (name),
|
|
name text NOT NULL CHECK (name ~ '^[a-z][a-z0-9-]*$'),
|
|
state_schema text NOT NULL UNIQUE CHECK (state_schema ~ '^[a-z_][a-z0-9_]*$'),
|
|
created timestamptz NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (module, name)
|
|
);
|
|
|
|
CREATE TABLE IF NOT EXISTS tf_variable_files (
|
|
module text NOT NULL,
|
|
instance text NOT NULL,
|
|
name text NOT NULL CHECK (name ~ '^[A-Za-z0-9_.-]+\.tfvars\.json$'),
|
|
content jsonb NOT NULL CHECK (jsonb_typeof(content) = 'object'),
|
|
previous jsonb CHECK (jsonb_typeof(previous) = 'object'),
|
|
updated timestamptz NOT NULL DEFAULT now(),
|
|
PRIMARY KEY (module, instance, name),
|
|
FOREIGN KEY (module, instance) REFERENCES tf_instances (module, name) ON DELETE CASCADE
|
|
);
|
|
|
|
-- The modules, by name.
|
|
CREATE OR REPLACE FUNCTION tf_modules_list()
|
|
RETURNS TABLE (name text, root text, description text, configurator_url text)
|
|
LANGUAGE sql STABLE
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
SELECT m.name, m.root, m.description, m.configurator_url FROM tf_modules m ORDER BY m.name
|
|
$$;
|
|
|
|
-- Creates a module, or changes the one of that name.
|
|
CREATE OR REPLACE PROCEDURE tf_module_put(module_name text, module_root text, module_description text, module_configurator_url text)
|
|
LANGUAGE sql
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
INSERT INTO tf_modules (name, root, description, configurator_url)
|
|
VALUES (module_name, module_root, module_description, module_configurator_url)
|
|
ON CONFLICT (name) DO UPDATE SET root = excluded.root, description = excluded.description, configurator_url = excluded.configurator_url
|
|
$$;
|
|
|
|
-- Deletes a module; the foreign key of tf_instances refuses it while the module has instances.
|
|
CREATE OR REPLACE PROCEDURE tf_module_delete(module_name text)
|
|
LANGUAGE sql
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
DELETE FROM tf_modules WHERE name = module_name
|
|
$$;
|
|
|
|
-- The instances of a module, by name.
|
|
CREATE OR REPLACE FUNCTION tf_instances_list(module_name text)
|
|
RETURNS TABLE (module text, name text, state_schema text, created timestamptz)
|
|
LANGUAGE sql STABLE
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
SELECT i.module, i.name, i.state_schema, i.created FROM tf_instances i WHERE i.module = module_name ORDER BY i.name
|
|
$$;
|
|
|
|
-- Creates an instance of a module with the schema of its state.
|
|
CREATE OR REPLACE PROCEDURE tf_instance_create(module_name text, instance_name text, instance_state_schema text)
|
|
LANGUAGE sql
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
INSERT INTO tf_instances (module, name, state_schema) VALUES (module_name, instance_name, instance_state_schema)
|
|
$$;
|
|
|
|
-- Deletes an instance with its variable files.
|
|
CREATE OR REPLACE PROCEDURE tf_instance_delete(module_name text, instance_name text)
|
|
LANGUAGE sql
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
DELETE FROM tf_instances WHERE module = module_name AND name = instance_name
|
|
$$;
|
|
|
|
-- The variable files of an instance, by name: content, whether the content it replaced is kept, and the time of the
|
|
-- last write.
|
|
CREATE OR REPLACE FUNCTION tf_variable_files_read(module_name text, instance_name text)
|
|
RETURNS TABLE (name text, content jsonb, previous boolean, updated timestamptz)
|
|
LANGUAGE sql STABLE
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
SELECT f.name, f.content, f.previous IS NOT NULL, f.updated FROM tf_variable_files f
|
|
WHERE f.module = module_name AND f.instance = instance_name ORDER BY f.name
|
|
$$;
|
|
|
|
-- Keeps other writers out until the end of the transaction, from the comparison of the version to the commit.
|
|
CREATE OR REPLACE PROCEDURE tf_variable_files_lock()
|
|
LANGUAGE sql
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
LOCK TABLE tf_variable_files IN EXCLUSIVE MODE
|
|
$$;
|
|
|
|
-- Writes a variable file of an instance, keeping the content it replaces as previous.
|
|
CREATE OR REPLACE PROCEDURE tf_variable_file_put(module_name text, instance_name text, file_name text, file_content jsonb)
|
|
LANGUAGE sql
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
INSERT INTO tf_variable_files (module, instance, name, content) VALUES (module_name, instance_name, file_name, file_content)
|
|
ON CONFLICT (module, instance, name) DO UPDATE SET previous = tf_variable_files.content, content = excluded.content, updated = now()
|
|
$$;
|
|
|
|
-- Deletes a variable file of an instance.
|
|
CREATE OR REPLACE PROCEDURE tf_variable_file_delete(module_name text, instance_name text, file_name text)
|
|
LANGUAGE sql
|
|
SET search_path FROM CURRENT
|
|
AS $$
|
|
DELETE FROM tf_variable_files WHERE module = module_name AND instance = instance_name AND name = file_name
|
|
$$;
|