diff --git a/infrastructure/longhorn/core/veles-recurring-jobs.yaml b/infrastructure/longhorn/core/veles-recurring-jobs.yaml index 434b94c6e..b7fe35142 100644 --- a/infrastructure/longhorn/core/veles-recurring-jobs.yaml +++ b/infrastructure/longhorn/core/veles-recurring-jobs.yaml @@ -28,33 +28,3 @@ spec: - veles-postgres retain: 8 concurrency: 1 ---- -apiVersion: longhorn.io/v1beta2 -kind: RecurringJob -metadata: - name: veles-artifacts-backup - namespace: longhorn-system -spec: - name: veles-artifacts-backup - cron: "45 5 * * *" - task: backup - groups: - - veles - - veles-artifacts - retain: 7 - concurrency: 1 ---- -apiVersion: longhorn.io/v1beta2 -kind: RecurringJob -metadata: - name: veles-artifacts-snapshot - namespace: longhorn-system -spec: - name: veles-artifacts-snapshot - cron: "15 */6 * * *" - task: snapshot - groups: - - veles - - veles-artifacts - retain: 8 - concurrency: 1 diff --git a/infrastructure/modules/base/storageclass/veles-oceanus-artifacts.yaml b/infrastructure/modules/base/storageclass/veles-oceanus-artifacts.yaml index fc5db859c..485017439 100644 --- a/infrastructure/modules/base/storageclass/veles-oceanus-artifacts.yaml +++ b/infrastructure/modules/base/storageclass/veles-oceanus-artifacts.yaml @@ -15,7 +15,6 @@ parameters: fsType: ext4 replicaAutoBalance: disabled dataLocality: strict-local - recurringJobSelector: '[{"name":"veles-artifacts-backup","isGroup":false},{"name":"veles-artifacts-snapshot","isGroup":false}]' reclaimPolicy: Retain allowVolumeExpansion: true volumeBindingMode: WaitForFirstConsumer diff --git a/services/keycloak/oneoffs/veles-gitea-oidc-secret-ensure-job.yaml b/services/keycloak/oneoffs/veles-gitea-oidc-secret-ensure-job.yaml index cca75f126..f6b0a94b0 100644 --- a/services/keycloak/oneoffs/veles-gitea-oidc-secret-ensure-job.yaml +++ b/services/keycloak/oneoffs/veles-gitea-oidc-secret-ensure-job.yaml @@ -1,12 +1,13 @@ # services/keycloak/oneoffs/veles-gitea-oidc-secret-ensure-job.yaml -# One-off job for sso/veles-gitea-oidc-secret-ensure-5. -# Purpose: create/update the Veles realm Gitea OIDC client and write the -# matching Gitea auth-source secret to Vault. -# Keep suspended until the Vault policy change has reconciled, then unsuspend once. +# One-off job for sso/veles-gitea-oidc-secret-ensure-1. +# Purpose: create/update the Keycloak veles realm Gitea OIDC client, ensure the +# veles-tester group exists, and write the client secret to Vault for Gitea. +# Run by setting spec.suspend to false, reconcile, then set it back to true. +# Safe to delete the finished Job/pod; it should not run continuously. apiVersion: batch/v1 kind: Job metadata: - name: veles-gitea-oidc-secret-ensure-5 + name: veles-gitea-oidc-secret-ensure-1 namespace: sso spec: suspend: true diff --git a/services/keycloak/oneoffs/veles-realm-ensure-job.yaml b/services/keycloak/oneoffs/veles-realm-ensure-job.yaml index 5176cae34..2b27db42c 100644 --- a/services/keycloak/oneoffs/veles-realm-ensure-job.yaml +++ b/services/keycloak/oneoffs/veles-realm-ensure-job.yaml @@ -1,11 +1,11 @@ # services/keycloak/oneoffs/veles-realm-ensure-job.yaml -# One-off job for sso/veles-realm-ensure-4. +# One-off job for sso/veles-realm-ensure-2. # Purpose: create the Veles realm, groups, OIDC client, SMTP settings, and Vault client secret. # Keep suspended until Veles Vault paths/policies have reconciled, then unsuspend once. apiVersion: batch/v1 kind: Job metadata: - name: veles-realm-ensure-4 + name: veles-realm-ensure-2 namespace: sso spec: suspend: true @@ -157,7 +157,7 @@ spec: create_payload = { "realm": realm, "enabled": True, - "registrationAllowed": True, + "registrationAllowed": False, "resetPasswordAllowed": True, "verifyEmail": True, "loginWithEmailAllowed": True, @@ -174,7 +174,7 @@ spec: realm_rep.update( { "enabled": True, - "registrationAllowed": True, + "registrationAllowed": False, "resetPasswordAllowed": True, "verifyEmail": True, "loginWithEmailAllowed": True, @@ -194,77 +194,14 @@ spec: ) if status != 200: raise SystemExit(f"Group search failed for {name}: status={status}") - for group in groups or []: - if group.get("name") == name: - return group["id"] + if any(group.get("name") == name for group in groups or []): + return status, body = request("POST", f"{base_url}/admin/realms/{realm}/groups", token, {"name": name}) if status not in (201, 204, 409): raise SystemExit(f"Group create failed for {name}: status={status} body={body}") - status, groups = request( - "GET", - f"{base_url}/admin/realms/{realm}/groups?search={urllib.parse.quote(name)}", - token, - ) - if status != 200: - raise SystemExit(f"Group lookup failed after create for {name}: status={status}") - for group in groups or []: - if group.get("name") == name: - return group["id"] - raise SystemExit(f"Group {name} not found after create") - def ensure_role(name): - status, role = request("GET", f"{base_url}/admin/realms/{realm}/roles/{urllib.parse.quote(name)}", token) - if status == 404: - status, body = request("POST", f"{base_url}/admin/realms/{realm}/roles", token, {"name": name}) - if status not in (201, 204, 409): - raise SystemExit(f"Role create failed for {name}: status={status} body={body}") - status, role = request( - "GET", - f"{base_url}/admin/realms/{realm}/roles/{urllib.parse.quote(name)}", - token, - ) - if status != 200 or not isinstance(role, dict): - raise SystemExit(f"Role lookup failed for {name}: status={status}") - return role - - def ensure_group_role(group_id, role): - status, mappings = request( - "GET", - f"{base_url}/admin/realms/{realm}/groups/{group_id}/role-mappings/realm", - token, - ) - if status != 200: - raise SystemExit(f"Group role mapping lookup failed: status={status}") - if any(mapping.get("name") == role["name"] for mapping in mappings or []): - return - status, body = request( - "POST", - f"{base_url}/admin/realms/{realm}/groups/{group_id}/role-mappings/realm", - token, - [role], - ) - if status not in (200, 204): - raise SystemExit(f"Group role mapping failed for {role['name']}: status={status} body={body}") - - def ensure_default_group(group_id, name): - status, groups = request("GET", f"{base_url}/admin/realms/{realm}/default-groups", token) - if status != 200: - raise SystemExit(f"Default group lookup failed: status={status}") - for group in groups or []: - if group.get("id") == group_id or group.get("name") == name: - return - status, body = request("PUT", f"{base_url}/admin/realms/{realm}/default-groups/{group_id}", token) - if status not in (200, 204): - raise SystemExit(f"Default group update failed for {name}: status={status} body={body}") - - alpha_group_id = ensure_group("alpha") - admin_group_id = ensure_group("admin") - alpha_role = ensure_role("alpha") - admin_role = ensure_role("admin") - ensure_group_role(alpha_group_id, alpha_role) - ensure_group_role(admin_group_id, alpha_role) - ensure_group_role(admin_group_id, admin_role) - ensure_default_group(alpha_group_id, "alpha") + ensure_group("alpha") + ensure_group("admin") status, clients = request( "GET", @@ -336,7 +273,6 @@ spec: raise SystemExit(f"Mapper lookup failed: status={status}") mapper_id = next((mapper.get("id") for mapper in mappers or [] if mapper.get("name") == "groups"), None) if mapper_id: - mapper_payload["id"] = mapper_id status, body = request( "PUT", f"{base_url}/admin/realms/{realm}/clients/{client_uuid}/protocol-mappers/models/{mapper_id}", diff --git a/services/keycloak/scripts/veles_gitea_oidc_secret_ensure.sh b/services/keycloak/scripts/veles_gitea_oidc_secret_ensure.sh old mode 100755 new mode 100644 index e08039d8a..c318b2d21 --- a/services/keycloak/scripts/veles_gitea_oidc_secret_ensure.sh +++ b/services/keycloak/scripts/veles_gitea_oidc_secret_ensure.sh @@ -9,8 +9,7 @@ CLIENT_ID="${KEYCLOAK_CLIENT_ID:-gitea}" PUBLIC_BASE_URL="${GITEA_PUBLIC_BASE_URL:-https://scm.bstein.dev}" AUTH_SOURCE_NAME="${GITEA_AUTH_SOURCE_NAME:-veles}" TESTER_GROUP="${VELES_GITEA_TESTER_GROUP:-veles-tester}" -VAULT_SECRET_PATH="${VAULT_SECRET_PATH:-gitea/gitea-veles-oidc}" -GROUP_TEAM_MAP="${GITEA_GROUP_TEAM_MAP:-{\"veles-tester\":{\"veles-alpha\":[\"testers\"]}}}" +VAULT_SECRET_PATH="${VAULT_SECRET_PATH:-kv/data/atlas/gitea/gitea-veles-oidc}" ACCESS_TOKEN="" for attempt in 1 2 3 4 5 6 7 8 9 10; do @@ -20,7 +19,6 @@ for attempt in 1 2 3 4 5 6 7 8 9 10; do echo "Waiting for Keycloak to be reachable (attempt ${attempt})" >&2 sleep $((attempt * 2)) done - for attempt in 1 2 3 4 5; do TOKEN_JSON="$(curl -sS -X POST "$KC_URL/realms/master/protocol/openid-connect/token" \ -H 'Content-Type: application/x-www-form-urlencoded' \ @@ -44,198 +42,21 @@ ensure_group() { group_name="$1" groups="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ "${KC_URL}/admin/realms/${REALM}/groups?search=$(printf '%s' "${group_name}" | jq -sRr @uri)" || true)" - group_id="$(echo "$groups" | jq -r --arg name "$group_name" '.[]? | select(.name == $name) | .id' | head -n1 || true)" - if [ -n "$group_id" ] && [ "$group_id" != "null" ]; then - printf '%s' "$group_id" + if echo "$groups" | jq -e --arg name "$group_name" '.[]? | select(.name == $name)' >/dev/null 2>&1; then return fi - status="$(curl -sS -o /tmp/keycloak-group-create.json -w "%{http_code}" -X POST \ + status="$(curl -sS -o /dev/null -w "%{http_code}" -X POST \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H 'Content-Type: application/json' \ -d "$(jq -nc --arg name "$group_name" '{name:$name}')" \ "${KC_URL}/admin/realms/${REALM}/groups")" if [ "$status" != "201" ] && [ "$status" != "204" ] && [ "$status" != "409" ]; then echo "Keycloak group create failed for ${group_name} (status ${status})" >&2 - cat /tmp/keycloak-group-create.json >&2 || true - exit 1 - fi - groups="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/groups?search=$(printf '%s' "${group_name}" | jq -sRr @uri)" || true)" - group_id="$(echo "$groups" | jq -r --arg name "$group_name" '.[]? | select(.name == $name) | .id' | head -n1 || true)" - if [ -z "$group_id" ] || [ "$group_id" = "null" ]; then - echo "Keycloak group ${group_name} not found after create" >&2 - exit 1 - fi - printf '%s' "$group_id" -} - -ensure_role() { - role_name="$1" - role="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/roles/$(printf '%s' "${role_name}" | jq -sRr @uri)" || true)" - if echo "$role" | jq -e --arg name "$role_name" '.name == $name' >/dev/null 2>&1; then - printf '%s' "$role" - return - fi - status="$(curl -sS -o /tmp/keycloak-role-create.json -w "%{http_code}" -X POST \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - -H 'Content-Type: application/json' \ - -d "$(jq -nc --arg name "$role_name" '{name:$name}')" \ - "${KC_URL}/admin/realms/${REALM}/roles")" - if [ "$status" != "201" ] && [ "$status" != "204" ] && [ "$status" != "409" ]; then - echo "Keycloak role create failed for ${role_name} (status ${status})" >&2 - cat /tmp/keycloak-role-create.json >&2 || true - exit 1 - fi - role="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/roles/$(printf '%s' "${role_name}" | jq -sRr @uri)" || true)" - if ! echo "$role" | jq -e --arg name "$role_name" '.name == $name' >/dev/null 2>&1; then - echo "Keycloak role ${role_name} not found after create" >&2 - exit 1 - fi - printf '%s' "$role" -} - -ensure_group_role() { - group_id="$1" - role_json="$2" - role_name="$(echo "$role_json" | jq -r '.name')" - mappings="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/groups/${group_id}/role-mappings/realm" || true)" - if echo "$mappings" | jq -e --arg name "$role_name" '.[]? | select(.name == $name)' >/dev/null 2>&1; then - return - fi - status="$(curl -sS -o /tmp/keycloak-group-role.json -w "%{http_code}" -X POST \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - -H 'Content-Type: application/json' \ - -d "[$role_json]" \ - "${KC_URL}/admin/realms/${REALM}/groups/${group_id}/role-mappings/realm")" - if [ "$status" != "200" ] && [ "$status" != "204" ]; then - echo "Keycloak group role mapping failed for ${role_name} (status ${status})" >&2 - cat /tmp/keycloak-group-role.json >&2 || true exit 1 fi } -ensure_mapper() { - client_uuid="$1" - mapper_name="$2" - mapper_payload="$3" - mappers="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/clients/${client_uuid}/protocol-mappers/models" || true)" - mapper_id="$(echo "$mappers" | jq -r --arg name "$mapper_name" '.[]? | select(.name == $name) | .id' | head -n1 || true)" - if [ -n "$mapper_id" ] && [ "$mapper_id" != "null" ]; then - mapper_payload="$(echo "$mapper_payload" | jq --arg id "$mapper_id" '. + {id:$id}')" - status="$(curl -sS -o /tmp/keycloak-mapper.json -w "%{http_code}" -X PUT \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - -H 'Content-Type: application/json' \ - -d "${mapper_payload}" \ - "${KC_URL}/admin/realms/${REALM}/clients/${client_uuid}/protocol-mappers/models/${mapper_id}")" - else - status="$(curl -sS -o /tmp/keycloak-mapper.json -w "%{http_code}" -X POST \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - -H 'Content-Type: application/json' \ - -d "${mapper_payload}" \ - "${KC_URL}/admin/realms/${REALM}/clients/${client_uuid}/protocol-mappers/models")" - fi - if [ "$status" != "200" ] && [ "$status" != "201" ] && [ "$status" != "204" ]; then - echo "Keycloak mapper ensure failed for ${mapper_name} (status ${status})" >&2 - cat /tmp/keycloak-mapper.json >&2 || true - exit 1 - fi -} - -ensure_client_scope() { - scope_name="$1" - scopes="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/client-scopes?search=$(printf '%s' "${scope_name}" | jq -sRr @uri)" || true)" - scope_id="$(echo "$scopes" | jq -r --arg name "$scope_name" '.[]? | select(.name == $name) | .id' | head -n1 || true)" - if [ -n "$scope_id" ] && [ "$scope_id" != "null" ]; then - printf '%s' "$scope_id" - return - fi - - scope_payload="$(jq -nc --arg name "$scope_name" '{name:$name,protocol:"openid-connect",attributes:{"include.in.token.scope":"true","display.on.consent.screen":"false"}}')" - status="$(curl -sS -o /tmp/keycloak-client-scope-create.json -w "%{http_code}" -X POST \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - -H 'Content-Type: application/json' \ - -d "${scope_payload}" \ - "${KC_URL}/admin/realms/${REALM}/client-scopes")" - if [ "$status" != "201" ] && [ "$status" != "204" ] && [ "$status" != "409" ]; then - echo "Keycloak client scope create failed for ${scope_name} (status ${status})" >&2 - cat /tmp/keycloak-client-scope-create.json >&2 || true - exit 1 - fi - - scopes="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/client-scopes?search=$(printf '%s' "${scope_name}" | jq -sRr @uri)" || true)" - scope_id="$(echo "$scopes" | jq -r --arg name "$scope_name" '.[]? | select(.name == $name) | .id' | head -n1 || true)" - if [ -z "$scope_id" ] || [ "$scope_id" = "null" ]; then - echo "Keycloak client scope ${scope_name} not found after create" >&2 - exit 1 - fi - printf '%s' "$scope_id" -} - -ensure_scope_mapper() { - scope_id="$1" - mapper_name="$2" - mapper_payload="$3" - mappers="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/client-scopes/${scope_id}/protocol-mappers/models" || true)" - mapper_id="$(echo "$mappers" | jq -r --arg name "$mapper_name" '.[]? | select(.name == $name) | .id' | head -n1 || true)" - if [ -n "$mapper_id" ] && [ "$mapper_id" != "null" ]; then - mapper_payload="$(echo "$mapper_payload" | jq --arg id "$mapper_id" '. + {id:$id}')" - status="$(curl -sS -o /tmp/keycloak-scope-mapper.json -w "%{http_code}" -X PUT \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - -H 'Content-Type: application/json' \ - -d "${mapper_payload}" \ - "${KC_URL}/admin/realms/${REALM}/client-scopes/${scope_id}/protocol-mappers/models/${mapper_id}")" - else - status="$(curl -sS -o /tmp/keycloak-scope-mapper.json -w "%{http_code}" -X POST \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - -H 'Content-Type: application/json' \ - -d "${mapper_payload}" \ - "${KC_URL}/admin/realms/${REALM}/client-scopes/${scope_id}/protocol-mappers/models")" - fi - if [ "$status" != "200" ] && [ "$status" != "201" ] && [ "$status" != "204" ]; then - echo "Keycloak client-scope mapper ensure failed for ${mapper_name} (status ${status})" >&2 - cat /tmp/keycloak-scope-mapper.json >&2 || true - exit 1 - fi -} - -ensure_client_optional_scope() { - client_uuid="$1" - scope_id="$2" - scope_name="$3" - default_scopes="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/clients/${client_uuid}/default-client-scopes" || true)" - optional_scopes="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/clients/${client_uuid}/optional-client-scopes" || true)" - - if echo "$default_scopes" | jq -e --arg name "$scope_name" '.[]? | select(.name == $name)' >/dev/null 2>&1 \ - || echo "$optional_scopes" | jq -e --arg name "$scope_name" '.[]? | select(.name == $name)' >/dev/null 2>&1; then - return - fi - - status="$(curl -sS -o /dev/null -w "%{http_code}" -X PUT \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/clients/${client_uuid}/optional-client-scopes/${scope_id}")" - if [ "$status" != "200" ] && [ "$status" != "201" ] && [ "$status" != "204" ]; then - status="$(curl -sS -o /dev/null -w "%{http_code}" -X POST \ - -H "Authorization: Bearer ${ACCESS_TOKEN}" \ - "${KC_URL}/admin/realms/${REALM}/clients/${client_uuid}/optional-client-scopes/${scope_id}")" - if [ "$status" != "200" ] && [ "$status" != "201" ] && [ "$status" != "204" ]; then - echo "Failed to attach ${scope_name} client scope to ${CLIENT_ID} (status ${status})" >&2 - exit 1 - fi - fi -} - -TESTER_GROUP_ID="$(ensure_group "${TESTER_GROUP}")" -TESTER_ROLE="$(ensure_role "${TESTER_GROUP}")" -ensure_group_role "${TESTER_GROUP_ID}" "${TESTER_ROLE}" +ensure_group "${TESTER_GROUP}" CLIENT_QUERY="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ "${KC_URL}/admin/realms/${REALM}/clients?clientId=$(printf '%s' "${CLIENT_ID}" | jq -sRr @uri)" || true)" @@ -245,17 +66,16 @@ client_payload="$(jq -nc \ --arg client_id "${CLIENT_ID}" \ --arg root_url "${PUBLIC_BASE_URL}" \ --arg callback "${PUBLIC_BASE_URL}/user/oauth2/${AUTH_SOURCE_NAME}/callback" \ - '{clientId:$client_id,enabled:true,protocol:"openid-connect",publicClient:false,standardFlowEnabled:true,implicitFlowEnabled:false,directAccessGrantsEnabled:false,serviceAccountsEnabled:false,redirectUris:[$callback],webOrigins:[$root_url],rootUrl:$root_url,baseUrl:"/",attributes:{"pkce.code.challenge.method":"","post.logout.redirect.uris":($root_url + "/*")}}')" + '{clientId:$client_id,enabled:true,protocol:"openid-connect",publicClient:false,standardFlowEnabled:true,implicitFlowEnabled:false,directAccessGrantsEnabled:false,serviceAccountsEnabled:false,redirectUris:[$callback],webOrigins:[$root_url],rootUrl:$root_url,baseUrl:"/",attributes:{"pkce.code.challenge.method":"S256","post.logout.redirect.uris":($root_url + "/*")}}')" if [ -z "$CLIENT_UUID" ] || [ "$CLIENT_UUID" = "null" ]; then - status="$(curl -sS -o /tmp/keycloak-client-create.json -w "%{http_code}" -X POST \ + status="$(curl -sS -o /dev/null -w "%{http_code}" -X POST \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H 'Content-Type: application/json' \ -d "${client_payload}" \ "${KC_URL}/admin/realms/${REALM}/clients")" if [ "$status" != "201" ] && [ "$status" != "204" ] && [ "$status" != "409" ]; then echo "Keycloak client create failed for ${CLIENT_ID} (status ${status})" >&2 - cat /tmp/keycloak-client-create.json >&2 || true exit 1 fi CLIENT_QUERY="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ @@ -268,26 +88,38 @@ if [ -z "$CLIENT_UUID" ] || [ "$CLIENT_UUID" = "null" ]; then exit 1 fi -status="$(curl -sS -o /tmp/keycloak-client-update.json -w "%{http_code}" -X PUT \ +status="$(curl -sS -o /dev/null -w "%{http_code}" -X PUT \ -H "Authorization: Bearer ${ACCESS_TOKEN}" \ -H 'Content-Type: application/json' \ -d "${client_payload}" \ "${KC_URL}/admin/realms/${REALM}/clients/${CLIENT_UUID}")" if [ "$status" != "200" ] && [ "$status" != "204" ]; then echo "Keycloak client update failed for ${CLIENT_ID} (status ${status})" >&2 - cat /tmp/keycloak-client-update.json >&2 || true exit 1 fi -groups_mapper_payload="$(jq -nc \ +mapper_payload="$(jq -nc \ '{name:"groups",protocol:"openid-connect",protocolMapper:"oidc-group-membership-mapper",consentRequired:false,config:{"full.path":"false","id.token.claim":"true","access.token.claim":"true","userinfo.token.claim":"true","claim.name":"groups","jsonType.label":"String"}}')" -roles_mapper_payload="$(jq -nc \ - '{name:"roles",protocol:"openid-connect",protocolMapper:"oidc-usermodel-realm-role-mapper",consentRequired:false,config:{"multivalued":"true","id.token.claim":"true","access.token.claim":"true","userinfo.token.claim":"true","claim.name":"roles","jsonType.label":"String"}}')" -ensure_mapper "${CLIENT_UUID}" groups "${groups_mapper_payload}" -ensure_mapper "${CLIENT_UUID}" roles "${roles_mapper_payload}" -GROUPS_SCOPE_ID="$(ensure_client_scope groups)" -ensure_scope_mapper "${GROUPS_SCOPE_ID}" groups "${groups_mapper_payload}" -ensure_client_optional_scope "${CLIENT_UUID}" "${GROUPS_SCOPE_ID}" groups +mappers="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ + "${KC_URL}/admin/realms/${REALM}/clients/${CLIENT_UUID}/protocol-mappers/models" || true)" +MAPPER_ID="$(echo "$mappers" | jq -r '.[]? | select(.name == "groups") | .id' | head -n1 || true)" +if [ -n "$MAPPER_ID" ] && [ "$MAPPER_ID" != "null" ]; then + status="$(curl -sS -o /dev/null -w "%{http_code}" -X PUT \ + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ + -H 'Content-Type: application/json' \ + -d "${mapper_payload}" \ + "${KC_URL}/admin/realms/${REALM}/clients/${CLIENT_UUID}/protocol-mappers/models/${MAPPER_ID}")" +else + status="$(curl -sS -o /dev/null -w "%{http_code}" -X POST \ + -H "Authorization: Bearer ${ACCESS_TOKEN}" \ + -H 'Content-Type: application/json' \ + -d "${mapper_payload}" \ + "${KC_URL}/admin/realms/${REALM}/clients/${CLIENT_UUID}/protocol-mappers/models")" +fi +if [ "$status" != "200" ] && [ "$status" != "201" ] && [ "$status" != "204" ]; then + echo "Keycloak groups mapper ensure failed (status ${status})" >&2 + exit 1 +fi CLIENT_SECRET="$(curl -sS -H "Authorization: Bearer ${ACCESS_TOKEN}" \ "${KC_URL}/admin/realms/${REALM}/clients/${CLIENT_UUID}/client-secret" | jq -r '.value' 2>/dev/null || true)" @@ -310,21 +142,16 @@ fi payload="$(jq -nc \ --arg client_id "${CLIENT_ID}" \ --arg client_secret "${CLIENT_SECRET}" \ + --arg discovery_url "${PUBLIC_BASE_URL}" \ --arg issuer "https://sso.bstein.dev/realms/${REALM}" \ --arg auto_discovery_url "https://sso.bstein.dev/realms/${REALM}/.well-known/openid-configuration" \ --arg auth_source_name "${AUTH_SOURCE_NAME}" \ --arg tester_group "${TESTER_GROUP}" \ - --arg group_team_map "${GROUP_TEAM_MAP}" \ - '{data:{client_id:$client_id,client_secret:$client_secret,issuer:$issuer,openid_auto_discovery_url:$auto_discovery_url,auth_source_name:$auth_source_name,required_claim_name:"groups",required_claim_value:$tester_group,group_claim_name:"groups",restricted_group:$tester_group,group_team_map:$group_team_map}}')" + --arg group_team_map "{\"${TESTER_GROUP}\":{\"veles-alpha\":[\"testers\"]}}" \ + '{data:{client_id:$client_id,client_secret:$client_secret,issuer:$issuer,openid_auto_discovery_url:$auto_discovery_url,auth_source_name:$auth_source_name,required_claim_name:"groups",required_claim_value:$tester_group,group_claim_name:"groups",restricted_group:$tester_group,group_team_map:$group_team_map,gitea_base_url:$discovery_url}}')" -write_status="$(curl -sS -o /tmp/veles-gitea-oidc-write.json -w "%{http_code}" -X POST \ - -H "X-Vault-Token: ${vault_token}" \ +curl -sS -X POST -H "X-Vault-Token: ${vault_token}" \ -H 'Content-Type: application/json' \ - -d "${payload}" "${vault_addr}/v1/kv/data/atlas/${VAULT_SECRET_PATH}")" -if [ "${write_status}" != "200" ] && [ "${write_status}" != "204" ]; then - echo "Vault write failed for ${VAULT_SECRET_PATH} (status ${write_status})" >&2 - cat /tmp/veles-gitea-oidc-write.json >&2 || true - exit 1 -fi + -d "${payload}" "${vault_addr}/v1/${VAULT_SECRET_PATH}" >/dev/null -echo "Veles Gitea OIDC client ready in Keycloak and Vault" +echo "Veles realm Gitea OIDC client ready" diff --git a/services/veles/artifacts-pvc.yaml b/services/veles/artifacts-pvc.yaml index 16b45dc68..341f7b0a1 100644 --- a/services/veles/artifacts-pvc.yaml +++ b/services/veles/artifacts-pvc.yaml @@ -7,11 +7,26 @@ metadata: labels: app.kubernetes.io/name: veles app.kubernetes.io/component: artifacts - veles.bstein.dev/backup: longhorn spec: accessModes: - ReadWriteOnce storageClassName: veles-oceanus-artifacts resources: requests: - storage: 200Gi + storage: 500Gi +--- +apiVersion: v1 +kind: PersistentVolumeClaim +metadata: + name: veles-engine-cache + namespace: veles + labels: + app.kubernetes.io/name: veles + app.kubernetes.io/component: engine-cache +spec: + accessModes: + - ReadWriteOnce + storageClassName: veles-oceanus-artifacts + resources: + requests: + storage: 100Gi diff --git a/services/veles/backend-deployment.yaml b/services/veles/backend-deployment.yaml index 66dd95da3..193aec15b 100644 --- a/services/veles/backend-deployment.yaml +++ b/services/veles/backend-deployment.yaml @@ -16,11 +16,30 @@ spec: metadata: labels: app: veles-backend + annotations: + vault.hashicorp.com/agent-inject: "true" + vault.hashicorp.com/agent-pre-populate-only: "true" + vault.hashicorp.com/role: "veles" + vault.hashicorp.com/agent-inject-secret-veles-env.sh: "kv/data/atlas/veles/veles-db" + vault.hashicorp.com/agent-inject-template-veles-env.sh: | + {{- with secret "kv/data/atlas/veles/veles-db" }} + export DATABASE_URL="{{ .Data.data.DATABASE_URL }}" + export VELES_DATABASE_USER="{{ .Data.data.POSTGRES_USER }}" + export VELES_DATABASE_PASSWORD="{{ .Data.data.POSTGRES_PASSWORD }}" + {{- end }} + {{- with secret "kv/data/atlas/veles/veles-oidc" }} + export VELES_OIDC_CLIENT_SECRET="{{ .Data.data.client_secret }}" + {{- end }} + {{- with secret "kv/data/atlas/veles/app-secrets" }} + export VELES_SESSION_SECRET="{{ .Data.data.VELES_SESSION_SECRET }}" + export VELES_BYOK_ENCRYPTION_KEY="{{ .Data.data.VELES_BYOK_ENCRYPTION_KEY }}" + {{- end }} spec: serviceAccountName: veles-backend priorityClassName: veles-core nodeSelector: veles.bstein.dev/node-pool: oceanus + kubernetes.io/arch: amd64 tolerations: - key: veles.bstein.dev/simulation operator: Equal @@ -32,41 +51,46 @@ spec: seccompProfile: type: RuntimeDefault initContainers: - - name: migrate-db - image: registry.bstein.dev/veles/veles-backend:0.3.15 # {"$imagepolicy": "veles:veles-backend"} + - name: database-init + image: registry.bstein.dev/veles/veles-backend:0.3.16 # {"$imagepolicy": "veles:veles-backend"} imagePullPolicy: IfNotPresent - command: ["veles-db"] - args: ["--init", "--json"] + command: ["/bin/sh", "-c"] + args: + - | + set -eu + if [ -f /vault/secrets/veles-env.sh ]; then + . /vault/secrets/veles-env.sh + fi + exec veles-db --init --wait-seconds 120 --bootstrap-meta --content-root /opt/veles-content envFrom: - configMapRef: - name: veles-app-config - - secretRef: - name: veles-runtime-secrets + name: veles-config resources: requests: - cpu: 100m - memory: 256Mi + cpu: 50m + memory: 128Mi limits: - cpu: 500m + cpu: 250m memory: 512Mi - securityContext: - runAsNonRoot: true - runAsUser: 10001 - runAsGroup: 10001 - allowPrivilegeEscalation: false - capabilities: - drop: ["ALL"] containers: - name: backend - image: registry.bstein.dev/veles/veles-backend:0.3.15 # {"$imagepolicy": "veles:veles-backend"} + image: registry.bstein.dev/veles/veles-backend:0.3.16 # {"$imagepolicy": "veles:veles-backend"} imagePullPolicy: IfNotPresent - env: - - name: VELES_SIM_IMAGE - value: registry.bstein.dev/veles/veles-sim-worker:0.3.15 # {"$imagepolicy": "veles:veles-sim-worker"} + command: ["/bin/sh", "-c"] + args: + - | + set -eu + if [ -f /vault/secrets/veles-env.sh ]; then + . /vault/secrets/veles-env.sh + fi + exec veles-web --host 0.0.0.0 --port 8796 --no-resume-queued ports: - name: http containerPort: 8796 protocol: TCP + envFrom: + - configMapRef: + name: veles-config readinessProbe: httpGet: path: /api/v1/ready @@ -79,18 +103,13 @@ spec: port: http initialDelaySeconds: 20 periodSeconds: 20 - envFrom: - - configMapRef: - name: veles-app-config - - secretRef: - name: veles-runtime-secrets resources: requests: cpu: 250m memory: 512Mi limits: cpu: "1" - memory: 2Gi + memory: 1Gi securityContext: runAsNonRoot: true runAsUser: 10001 diff --git a/services/veles/configmap.yaml b/services/veles/configmap.yaml index 6ddb8a772..505ee53e2 100644 --- a/services/veles/configmap.yaml +++ b/services/veles/configmap.yaml @@ -2,55 +2,44 @@ apiVersion: v1 kind: ConfigMap metadata: - name: veles-app-config + name: veles-config namespace: veles data: - VELES_ENV: alpha VELES_PROFILE: cluster VELES_AUTH_MODE: oidc VELES_SIM_RUNNER: kubernetes-job VELES_PUBLIC_URL: https://veles.bstein.dev VELES_PUBLIC_BASE_URL: https://veles.bstein.dev - VELES_BACKEND_HTTP_PORT: "8796" - VELES_FRONTEND_HTTP_PORT: "8080" + VELES_ALPHA_LABEL: ALPHA VELES_OIDC_ISSUER_URL: https://sso.bstein.dev/realms/veles VELES_OIDC_ISSUER: https://sso.bstein.dev/realms/veles VELES_OIDC_CLIENT_ID: veles-web - VELES_OIDC_ALLOWED_GROUPS: alpha,admin - VELES_OIDC_REQUIRED_GROUPS: alpha,admin + VELES_OIDC_ALLOWED_GROUPS: alpha,veles-tester,admin + VELES_OIDC_REQUIRED_GROUPS: alpha,veles-tester,admin VELES_OIDC_ADMIN_GROUPS: admin - VELES_OIDC_GROUPS_CLAIM: groups - VELES_OIDC_ROLES_CLAIM: realm_access.roles - VELES_DATABASE_HOST: veles-postgres.veles.svc.cluster.local - VELES_DATABASE_PORT: "5432" - VELES_DATABASE_NAME: veles - VELES_ARTIFACTS_PATH: /data/veles-artifacts - VELES_ARTIFACTS_MODE: rwo-backend-owned - VELES_LOG_ROOT: /data/veles-artifacts/logs - VELES_REPORT_ROOT: /data/veles-artifacts/reports - VELES_ARTIFACT_ROOT: /data/veles-artifacts/artifacts - VELES_RETENTION_DAYS: "30" - VELES_SIM_NAMESPACE: veles VELES_NAMESPACE: veles - VELES_SIM_IMAGE: registry.bstein.dev/veles/veles-sim-worker:0.3.15 # {"$imagepolicy": "veles:veles-sim-worker"} + VELES_SIM_IMAGE: registry.bstein.dev/veles/veles-sim-worker:0.3.16 # {"$imagepolicy": "veles:veles-sim-worker"} VELES_SIM_SERVICE_ACCOUNT: veles-sim VELES_SIM_PRIORITY_CLASS: veles-sim VELES_SIM_NODE_SELECTOR: veles.bstein.dev/node-pool=oceanus,kubernetes.io/arch=amd64 VELES_SIM_TOLERATIONS: veles.bstein.dev/simulation=true:NoSchedule - VELES_SIM_TOLERATION_KEY: veles.bstein.dev/simulation - VELES_SIM_TOLERATION_VALUE: "true" VELES_SIM_ACTIVE_DEADLINE_SECONDS: "7200" VELES_SIM_TTL_SECONDS: "3600" VELES_SIM_CPU_REQUEST: 500m VELES_SIM_CPU_LIMIT: "2" VELES_SIM_MEMORY_REQUEST: 1Gi VELES_SIM_MEMORY_LIMIT: 4Gi - VELES_SIM_ARTIFACT_PVC: veles-artifacts - VELES_SIM_ARTIFACT_MOUNT_PATH: /data/veles-artifacts VELES_SIM_FS_GROUP: "10001" VELES_MAX_ACTIVE_SIMS_PER_USER: "1" VELES_MAX_ACTIVE_SIMS_GLOBAL: "4" - VELES_RETENTION_NODE_SELECTOR: veles.bstein.dev/simulation=true - VELES_RETENTION_TOLERATION_KEY: veles.bstein.dev/simulation - VELES_RETENTION_TOLERATION_VALUE: "true" - VELES_LOG_RETENTION_DAYS: "30" + VELES_RETENTION_DAYS: "30" + VELES_LOG_ROOT: /data/veles-artifacts/logs + VELES_REPORT_ROOT: /data/veles-artifacts/reports + VELES_ARTIFACT_ROOT: /data/veles-artifacts/artifacts + VELES_SIM_ARTIFACT_PVC: veles-artifacts + VELES_SIM_ARTIFACT_MOUNT_PATH: /data/veles-artifacts + VELES_SIM_ENGINE_PVC: veles-engine-cache + VELES_SIM_ENGINE_MOUNT_PATH: /engine + VELES_SIM_CODEX_CLI_SECRET_PROVIDER_CLASS: veles-codex-cli + VELES_SIM_CODEX_CLI_MOUNT_PATH: /home/veles/.codex + VELES_SIM_CODEX_CLI_HOME: /home/veles/.codex diff --git a/services/veles/frontend-deployment.yaml b/services/veles/frontend-deployment.yaml index 5b068e985..e1e014990 100644 --- a/services/veles/frontend-deployment.yaml +++ b/services/veles/frontend-deployment.yaml @@ -19,6 +19,7 @@ spec: spec: serviceAccountName: veles-frontend priorityClassName: veles-core + automountServiceAccountToken: false affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: @@ -43,12 +44,11 @@ spec: values: ["rpi5"] securityContext: fsGroup: 101 - fsGroupChangePolicy: OnRootMismatch seccompProfile: type: RuntimeDefault containers: - name: frontend - image: registry.bstein.dev/veles/veles-frontend:0.3.15 # {"$imagepolicy": "veles:veles-frontend"} + image: registry.bstein.dev/veles/veles-frontend:0.3.16 # {"$imagepolicy": "veles:veles-frontend"} imagePullPolicy: IfNotPresent ports: - name: http @@ -66,20 +66,15 @@ spec: port: http initialDelaySeconds: 20 periodSeconds: 20 - envFrom: - - configMapRef: - name: veles-app-config resources: requests: - cpu: 100m - memory: 256Mi + cpu: 50m + memory: 64Mi limits: - cpu: 500m - memory: 512Mi + cpu: 250m + memory: 256Mi securityContext: runAsNonRoot: true - runAsUser: 101 - runAsGroup: 101 allowPrivilegeEscalation: false capabilities: drop: ["ALL"] diff --git a/services/veles/image.yaml b/services/veles/image.yaml index c57f81c2e..f038856aa 100644 --- a/services/veles/image.yaml +++ b/services/veles/image.yaml @@ -18,12 +18,9 @@ metadata: spec: imageRepositoryRef: name: veles-backend - filterTags: - pattern: '^(?P\d+\.\d+\.\d+)$' - extract: '$version' policy: semver: - range: ">=0.1.0" + range: ">=0.1.0-0" --- apiVersion: image.toolkit.fluxcd.io/v1 kind: ImageRepository @@ -44,12 +41,9 @@ metadata: spec: imageRepositoryRef: name: veles-frontend - filterTags: - pattern: '^(?P\d+\.\d+\.\d+)$' - extract: '$version' policy: semver: - range: ">=0.1.0" + range: ">=0.1.0-0" --- apiVersion: image.toolkit.fluxcd.io/v1 kind: ImageRepository @@ -70,9 +64,6 @@ metadata: spec: imageRepositoryRef: name: veles-sim-worker - filterTags: - pattern: '^(?P\d+\.\d+\.\d+)$' - extract: '$version' policy: semver: - range: ">=0.1.0" + range: ">=0.1.0-0" diff --git a/services/veles/kustomization.yaml b/services/veles/kustomization.yaml index 68dbabb84..764438c1e 100644 --- a/services/veles/kustomization.yaml +++ b/services/veles/kustomization.yaml @@ -17,6 +17,7 @@ resources: - services.yaml - backend-deployment.yaml - frontend-deployment.yaml + - retention-cronjob.yaml - image.yaml - ingress.yaml - oneoffs/veles-secrets-ensure-job.yaml diff --git a/services/veles/postgres-statefulset.yaml b/services/veles/postgres-statefulset.yaml index 199c3f487..3ae9a27ac 100644 --- a/services/veles/postgres-statefulset.yaml +++ b/services/veles/postgres-statefulset.yaml @@ -46,7 +46,7 @@ spec: type: RuntimeDefault containers: - name: postgres - image: postgres:15 + image: postgres:17 ports: - name: postgres containerPort: 5432 @@ -62,13 +62,15 @@ spec: value: veles resources: requests: - cpu: "2" - memory: 8Gi + cpu: "1" + memory: 2Gi limits: cpu: "4" - memory: 16Gi + memory: 8Gi securityContext: allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] volumeMounts: - name: postgres-data mountPath: /var/lib/postgresql/data @@ -83,4 +85,4 @@ spec: storageClassName: veles-oceanus-db resources: requests: - storage: 100Gi + storage: 200Gi diff --git a/services/veles/resourcequota.yaml b/services/veles/resourcequota.yaml index 6591a916e..d68c4a286 100644 --- a/services/veles/resourcequota.yaml +++ b/services/veles/resourcequota.yaml @@ -13,7 +13,7 @@ spec: pods: "60" count/jobs.batch: "100" persistentvolumeclaims: "8" - requests.storage: 300Gi + requests.storage: 1Ti --- apiVersion: v1 kind: ResourceQuota diff --git a/services/veles/retention-cronjob.yaml b/services/veles/retention-cronjob.yaml new file mode 100644 index 000000000..156c19d56 --- /dev/null +++ b/services/veles/retention-cronjob.yaml @@ -0,0 +1,67 @@ +# services/veles/retention-cronjob.yaml +apiVersion: batch/v1 +kind: CronJob +metadata: + name: veles-retention + namespace: veles + labels: + app: veles-retention +spec: + schedule: "17 4 * * *" + concurrencyPolicy: Forbid + successfulJobsHistoryLimit: 1 + failedJobsHistoryLimit: 3 + jobTemplate: + spec: + template: + metadata: + labels: + app: veles-retention + spec: + restartPolicy: Never + serviceAccountName: veles-retention + automountServiceAccountToken: false + priorityClassName: veles-core + nodeSelector: + veles.bstein.dev/node-pool: oceanus + kubernetes.io/arch: amd64 + tolerations: + - key: veles.bstein.dev/simulation + operator: Equal + value: "true" + effect: NoSchedule + securityContext: + fsGroup: 10001 + fsGroupChangePolicy: OnRootMismatch + seccompProfile: + type: RuntimeDefault + containers: + - name: retention + image: registry.bstein.dev/veles/veles-backend:0.3.16 # {"$imagepolicy": "veles:veles-backend"} + imagePullPolicy: IfNotPresent + command: ["veles-hygiene"] + args: ["--prune-artifacts"] + envFrom: + - configMapRef: + name: veles-config + volumeMounts: + - name: artifacts + mountPath: /data/veles-artifacts + resources: + requests: + cpu: 50m + memory: 128Mi + limits: + cpu: 250m + memory: 512Mi + securityContext: + runAsNonRoot: true + runAsUser: 10001 + runAsGroup: 10001 + allowPrivilegeEscalation: false + capabilities: + drop: ["ALL"] + volumes: + - name: artifacts + persistentVolumeClaim: + claimName: veles-artifacts diff --git a/services/veles/secretproviderclass.yaml b/services/veles/secretproviderclass.yaml index 56e04fe44..d39279a5b 100644 --- a/services/veles/secretproviderclass.yaml +++ b/services/veles/secretproviderclass.yaml @@ -13,22 +13,22 @@ spec: - objectName: "harbor-pull__dockerconfigjson" secretPath: "kv/data/atlas/shared/harbor-pull" secretKey: "dockerconfigjson" - - objectName: "veles-db__DATABASE_URL" + - objectName: "veles-db__database-url" secretPath: "kv/data/atlas/veles/veles-db" secretKey: "DATABASE_URL" - - objectName: "veles-db__POSTGRES_USER" + - objectName: "veles-db__user" secretPath: "kv/data/atlas/veles/veles-db" secretKey: "POSTGRES_USER" - - objectName: "veles-db__POSTGRES_PASSWORD" + - objectName: "veles-db__password" secretPath: "kv/data/atlas/veles/veles-db" secretKey: "POSTGRES_PASSWORD" - - objectName: "veles-oidc__client_secret" + - objectName: "veles-oidc__client-secret" secretPath: "kv/data/atlas/veles/veles-oidc" secretKey: "client_secret" - - objectName: "veles-app-secrets__VELES_SESSION_SECRET" + - objectName: "veles-app__session-secret" secretPath: "kv/data/atlas/veles/app-secrets" secretKey: "VELES_SESSION_SECRET" - - objectName: "veles-app-secrets__VELES_BYOK_ENCRYPTION_KEY" + - objectName: "veles-app__byok-encryption-key" secretPath: "kv/data/atlas/veles/app-secrets" secretKey: "VELES_BYOK_ENCRYPTION_KEY" secretObjects: @@ -40,15 +40,31 @@ spec: - secretName: veles-runtime-secrets type: Opaque data: - - objectName: veles-db__DATABASE_URL + - objectName: veles-db__database-url key: DATABASE_URL - - objectName: veles-db__POSTGRES_USER + - objectName: veles-db__user key: VELES_DATABASE_USER - - objectName: veles-db__POSTGRES_PASSWORD + - objectName: veles-db__password key: VELES_DATABASE_PASSWORD - - objectName: veles-oidc__client_secret + - objectName: veles-oidc__client-secret key: VELES_OIDC_CLIENT_SECRET - - objectName: veles-app-secrets__VELES_SESSION_SECRET + - objectName: veles-app__session-secret key: VELES_SESSION_SECRET - - objectName: veles-app-secrets__VELES_BYOK_ENCRYPTION_KEY + - objectName: veles-app__byok-encryption-key key: VELES_BYOK_ENCRYPTION_KEY +--- +apiVersion: secrets-store.csi.x-k8s.io/v1 +kind: SecretProviderClass +metadata: + name: veles-codex-cli + namespace: veles +spec: + provider: vault + parameters: + vaultAddress: "http://vault.vault.svc.cluster.local:8200" + roleName: "veles-sim" + objects: | + - objectName: "auth.json" + secretPath: "kv/data/atlas/veles/codex-cli" + secretKey: "auth.json" + filePermission: "0440" diff --git a/services/veles/serviceaccounts.yaml b/services/veles/serviceaccounts.yaml index e0b79580d..c14ff0f8d 100644 --- a/services/veles/serviceaccounts.yaml +++ b/services/veles/serviceaccounts.yaml @@ -12,6 +12,7 @@ kind: ServiceAccount metadata: name: veles-frontend namespace: veles +automountServiceAccountToken: false imagePullSecrets: - name: harbor-regcred --- @@ -25,6 +26,15 @@ imagePullSecrets: --- apiVersion: v1 kind: ServiceAccount +metadata: + name: veles-retention + namespace: veles +automountServiceAccountToken: false +imagePullSecrets: + - name: harbor-regcred +--- +apiVersion: v1 +kind: ServiceAccount metadata: name: veles-vault-sync namespace: veles diff --git a/services/veles/services.yaml b/services/veles/services.yaml index 41463591d..15e6385eb 100644 --- a/services/veles/services.yaml +++ b/services/veles/services.yaml @@ -11,7 +11,7 @@ spec: - name: http port: 80 protocol: TCP - targetPort: http + targetPort: 8796 selector: app: veles-backend --- @@ -27,6 +27,6 @@ spec: - name: http port: 80 protocol: TCP - targetPort: http + targetPort: 8080 selector: app: veles-frontend