Import pipeline operator enrollment
This commit is contained in:
@@ -90,6 +90,7 @@ group before the remaining configuration-bearing dependencies run.
|
|||||||
| --- | --- |
|
| --- | --- |
|
||||||
| `dnd_pipeline_runtime_user` | `narratio` |
|
| `dnd_pipeline_runtime_user` | `narratio` |
|
||||||
| `dnd_pipeline_runtime_group` | `narratio` |
|
| `dnd_pipeline_runtime_group` | `narratio` |
|
||||||
|
| `dnd_pipeline_operator_users` | `[]` |
|
||||||
| `dnd_pipeline_config_directory_mode` | `0755` |
|
| `dnd_pipeline_config_directory_mode` | `0755` |
|
||||||
| `dnd_pipeline_config_file_mode` | `0644` |
|
| `dnd_pipeline_config_file_mode` | `0644` |
|
||||||
|
|
||||||
@@ -259,8 +260,8 @@ inspection shows enabled sources, inferred dependencies, and generated family
|
|||||||
members; the diff shows the overlay's profile selections without modifying
|
members; the diff shows the overlay's profile selections without modifying
|
||||||
managed files.
|
managed files.
|
||||||
|
|
||||||
Storage and publishing, operator selection and group-membership management,
|
Storage and publishing, scheduling, and end-to-end external execution remain
|
||||||
scheduling, and end-to-end external execution remain deferred.
|
deferred.
|
||||||
|
|
||||||
### Shared execution filesystem
|
### Shared execution filesystem
|
||||||
|
|
||||||
@@ -269,27 +270,30 @@ scheduling, and end-to-end external execution remain deferred.
|
|||||||
`narratio:narratio` mode `2775` **setgid** directories. Their access and
|
`narratio:narratio` mode `2775` **setgid** directories. Their access and
|
||||||
default ACLs retain owner and group write access plus world read/traverse access
|
default ACLs retain owner and group write access plus world read/traverse access
|
||||||
for newly created content. The pipeline may run as `narratio` or as a human
|
for newly created content. The pipeline may run as `narratio` or as a human
|
||||||
account already in the selected runtime group; the production role neither
|
account in the selected runtime group. Consumers can enroll selected existing
|
||||||
selects people nor manages their group membership. For example, a consumer
|
human accounts through the role interface:
|
||||||
play can manage its selected operator separately:
|
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
- name: Add the selected operator to the pipeline group
|
dnd_pipeline_operator_users:
|
||||||
become: true
|
- eric
|
||||||
ansible.builtin.user:
|
- alice
|
||||||
name: "{{ pipeline_operator }}"
|
|
||||||
groups:
|
|
||||||
- "{{ dnd_pipeline_runtime_group }}"
|
|
||||||
append: true
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
Every selected account must already exist; the role does not create human
|
||||||
|
accounts or manage their identity and login policy. Enrollment adds the
|
||||||
|
selected runtime group without replacing other supplementary groups. Removing
|
||||||
|
or omitting a name later does not revoke membership. A newly enrolled operator
|
||||||
|
must begin a new login session before the operating system exposes the added
|
||||||
|
supplementary group to that session.
|
||||||
|
|
||||||
Configuration, transcripts, caches, generated artifacts, campaign data,
|
Configuration, transcripts, caches, generated artifacts, campaign data,
|
||||||
prompts, and logs are non-secret D&D content. Credentials use the restricted
|
prompts, and logs are non-secret D&D content. Credentials use the restricted
|
||||||
`/usr/local/etc/narratio/secrets` subtree, owned by the selected runtime user
|
`/usr/local/etc/narratio/secrets` subtree, owned by the selected runtime user
|
||||||
and group with mode `0750`; managed files use mode `0640`. Runtime-group
|
and group with mode `0750`; managed files use mode `0640`. Runtime-group
|
||||||
membership authorizes use of these shared credentials, while the subtree grants
|
membership, including enrollment through `dnd_pipeline_operator_users`,
|
||||||
no world access. Ordinary configuration remains world-readable and contains
|
authorizes use of these shared credentials, while the subtree grants no world
|
||||||
only reference names.
|
access. Ordinary configuration remains world-readable and contains only
|
||||||
|
reference names.
|
||||||
|
|
||||||
### Managed credentials
|
### Managed credentials
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ dnd_pipeline_go_snap_channel: 1.26/stable
|
|||||||
dnd_pipeline_go_binary: /snap/bin/go
|
dnd_pipeline_go_binary: /snap/bin/go
|
||||||
dnd_pipeline_runtime_user: narratio
|
dnd_pipeline_runtime_user: narratio
|
||||||
dnd_pipeline_runtime_group: narratio
|
dnd_pipeline_runtime_group: narratio
|
||||||
|
dnd_pipeline_operator_users: []
|
||||||
dnd_pipeline_secrets: {}
|
dnd_pipeline_secrets: {}
|
||||||
dnd_pipeline_config_directory_mode: "0755"
|
dnd_pipeline_config_directory_mode: "0755"
|
||||||
dnd_pipeline_config_file_mode: "0644"
|
dnd_pipeline_config_file_mode: "0644"
|
||||||
|
|||||||
@@ -43,6 +43,11 @@ argument_specs:
|
|||||||
type: str
|
type: str
|
||||||
required: true
|
required: true
|
||||||
description: Shared group for suite-managed configuration.
|
description: Shared group for suite-managed configuration.
|
||||||
|
dnd_pipeline_operator_users:
|
||||||
|
type: list
|
||||||
|
elements: str
|
||||||
|
required: true
|
||||||
|
description: Existing human accounts enrolled in the shared runtime group.
|
||||||
dnd_pipeline_secrets:
|
dnd_pipeline_secrets:
|
||||||
type: dict
|
type: dict
|
||||||
required: true
|
required: true
|
||||||
|
|||||||
@@ -1,4 +1,19 @@
|
|||||||
---
|
---
|
||||||
|
- name: Validate selected pipeline operator accounts
|
||||||
|
ansible.builtin.getent:
|
||||||
|
database: passwd
|
||||||
|
key: "{{ item }}"
|
||||||
|
loop: "{{ dnd_pipeline_operator_users }}"
|
||||||
|
|
||||||
|
- name: Enroll selected pipeline operators
|
||||||
|
become: true
|
||||||
|
ansible.builtin.user:
|
||||||
|
name: "{{ item }}"
|
||||||
|
groups: "{{ dnd_pipeline_runtime_group }}"
|
||||||
|
append: true
|
||||||
|
state: present
|
||||||
|
loop: "{{ dnd_pipeline_operator_users }}"
|
||||||
|
|
||||||
- name: Install ACL support
|
- name: Install ACL support
|
||||||
become: true
|
become: true
|
||||||
ansible.builtin.apt:
|
ansible.builtin.apt:
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ baseline_args=(
|
|||||||
-e "dnd_pipeline_prompt_library_repository_url=file://$prompt_library_repository"
|
-e "dnd_pipeline_prompt_library_repository_url=file://$prompt_library_repository"
|
||||||
-e "dnd_pipeline_prompt_library_revision=$prompt_library_revision"
|
-e "dnd_pipeline_prompt_library_revision=$prompt_library_revision"
|
||||||
-e "dnd_pipeline_prompt_library_root=$prompt_library_root"
|
-e "dnd_pipeline_prompt_library_root=$prompt_library_root"
|
||||||
|
-e "{\"dnd_pipeline_operator_users\":[\"$operator_user\"]}"
|
||||||
-e "{\"dnd_pipeline_secrets\":{\"AUDITA_LLM_API_KEY\":\"$synthetic_audita_api_key\",\"OPENROUTER_API_KEY\":\"$synthetic_notarius_api_key\"}}"
|
-e "{\"dnd_pipeline_secrets\":{\"AUDITA_LLM_API_KEY\":\"$synthetic_audita_api_key\",\"OPENROUTER_API_KEY\":\"$synthetic_notarius_api_key\"}}"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -38,8 +39,8 @@ cleanup() {
|
|||||||
exit_status=$?
|
exit_status=$?
|
||||||
trap - EXIT
|
trap - EXIT
|
||||||
/usr/bin/sudo /bin/rm -rf -- "$shared_fixture_root" || true
|
/usr/bin/sudo /bin/rm -rf -- "$shared_fixture_root" || true
|
||||||
/usr/bin/sudo /usr/sbin/userdel --remove "$operator_user" 2>/dev/null || true
|
|
||||||
"$ansible_playbook" -i "$inventory" "${baseline_args[@]}" "$converge" >/dev/null 2>&1 || true
|
"$ansible_playbook" -i "$inventory" "${baseline_args[@]}" "$converge" >/dev/null 2>&1 || true
|
||||||
|
/usr/bin/sudo /usr/sbin/userdel --remove "$operator_user" 2>/dev/null || true
|
||||||
rm -rf -- "$test_tmp"
|
rm -rf -- "$test_tmp"
|
||||||
exit "$exit_status"
|
exit "$exit_status"
|
||||||
}
|
}
|
||||||
@@ -70,6 +71,7 @@ printf '%s\n' \
|
|||||||
-p "$test_tmp/roles"
|
-p "$test_tmp/roles"
|
||||||
"$ansible_playbook" -i "$inventory" --syntax-check "$converge"
|
"$ansible_playbook" -i "$inventory" --syntax-check "$converge"
|
||||||
"$workspace_venv/bin/ansible-lint" --offline --profile production "$converge"
|
"$workspace_venv/bin/ansible-lint" --offline --profile production "$converge"
|
||||||
|
/usr/bin/sudo /usr/sbin/useradd --create-home --shell /usr/sbin/nologin "$operator_user"
|
||||||
|
|
||||||
baseline_log="$test_tmp/baseline.log"
|
baseline_log="$test_tmp/baseline.log"
|
||||||
run_converge "$baseline_log" "${baseline_args[@]}"
|
run_converge "$baseline_log" "${baseline_args[@]}"
|
||||||
@@ -116,8 +118,6 @@ grep -Fq 'lane_id: item-registry' "$narratio_effective_config"
|
|||||||
/usr/bin/sudo -u narratio /usr/local/bin/narratio config diff default testing \
|
/usr/bin/sudo -u narratio /usr/local/bin/narratio config diff default testing \
|
||||||
--config /usr/local/etc/narratio/pipeline.yml --campaign centaurs | \
|
--config /usr/local/etc/narratio/pipeline.yml --campaign centaurs | \
|
||||||
awk -F '\t' '$1 != "changed" || $2 !~ /\.profile_id$/ { invalid = 1 } END { exit invalid || NR == 0 }'
|
awk -F '\t' '$1 != "changed" || $2 !~ /\.profile_id$/ { invalid = 1 } END { exit invalid || NR == 0 }'
|
||||||
/usr/bin/sudo /usr/sbin/useradd --create-home --groups narratio \
|
|
||||||
--shell /usr/sbin/nologin "$operator_user"
|
|
||||||
/usr/bin/sudo -u "$operator_user" /usr/local/bin/narratio config validate \
|
/usr/bin/sudo -u "$operator_user" /usr/local/bin/narratio config validate \
|
||||||
--config /usr/local/etc/narratio/pipeline.yml --campaign centaurs
|
--config /usr/local/etc/narratio/pipeline.yml --campaign centaurs
|
||||||
/usr/bin/sudo -u "$operator_user" /usr/local/bin/notarius config validate \
|
/usr/bin/sudo -u "$operator_user" /usr/local/bin/notarius config validate \
|
||||||
|
|||||||
Reference in New Issue
Block a user