fix: resolve 4 unhealthy services from fresh volume rebuild
- router-gateway: sync 10 missing jobengine routes to local config (prevent array merge bleed-through) - findings-ledger-web: add VulnExplorer tables to postgres-init bootstrap script - timeline-web: replace competing migration hosted service with standard AddStartupMigrations - graph-api: handle null PostgresGraphRepository gracefully, add graph schema to init - scheduler-web: add failure_signatures table to init bootstrap Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -313,13 +313,15 @@ export VAULT_TOKEN=stellaops-dev-root-token-2026
|
||||
vault kv put secret/harbor robot-account="harbor-robot-token"
|
||||
vault kv put secret/github app-private-key="your-key"
|
||||
vault kv put secret/gitea api-token="your-gitea-token"
|
||||
vault kv put secret/gitlab access-token="glpat-your-token"
|
||||
vault kv put secret/gitlab access-token="glpat-your-token" registry-basic="root:glpat-your-token"
|
||||
vault kv put secret/jenkins api-token="user:token"
|
||||
vault kv put secret/nexus admin-password="your-password"
|
||||
```
|
||||
|
||||
Gitea is now bootstrapped by the compose service itself: a fresh `stellaops-gitea-data` volume creates the default local admin user and the repository root before the container reports healthy. Personal access tokens remain a manual step because Gitea only reveals the token value when it is created.
|
||||
|
||||
When you enable the optional GitLab registry surface (`GITLAB_ENABLE_REGISTRY=true`), register it through the `GitLabContainerRegistry` provider with `authref://vault/gitlab#registry-basic`. The local Docker registry connector now follows the registry's Bearer challenge and exchanges that `username:personal-access-token` secret against `jwt/auth` before retrying catalog and tag probes.
|
||||
|
||||
`docker-compose.testing.yml` is a separate infrastructure-test lane. It starts `postgres-test`, `valkey-test`, mocks, and an isolated Gitea profile on different ports; it does not start Consul or GitLab. Use `docker-compose.integrations.yml` only when you need real third-party providers for connector validation.
|
||||
|
||||
**Backend connector plugins** (8 total, loaded in Integrations service):
|
||||
|
||||
@@ -10,6 +10,7 @@ CREATE SCHEMA IF NOT EXISTS notify;
|
||||
CREATE SCHEMA IF NOT EXISTS notifier;
|
||||
CREATE SCHEMA IF NOT EXISTS evidence;
|
||||
CREATE SCHEMA IF NOT EXISTS findings;
|
||||
CREATE SCHEMA IF NOT EXISTS graph;
|
||||
CREATE SCHEMA IF NOT EXISTS timeline;
|
||||
CREATE SCHEMA IF NOT EXISTS doctor;
|
||||
CREATE SCHEMA IF NOT EXISTS issuer_directory;
|
||||
|
||||
@@ -563,3 +563,86 @@ BEGIN
|
||||
END $$;
|
||||
|
||||
COMMENT ON TABLE ledger_snapshots IS 'Point-in-time snapshots of ledger state for time-travel queries';
|
||||
|
||||
-- ============================================================================
|
||||
-- 010_vex_fix_audit_tables.sql - VulnExplorer persistence tables
|
||||
-- ============================================================================
|
||||
|
||||
BEGIN;
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vex_decisions (
|
||||
id UUID NOT NULL,
|
||||
tenant_id TEXT NOT NULL,
|
||||
vulnerability_id TEXT NOT NULL,
|
||||
subject_type TEXT NOT NULL,
|
||||
subject_name TEXT NOT NULL,
|
||||
subject_digest JSONB NOT NULL DEFAULT '{}'::JSONB,
|
||||
subject_sbom_node_id TEXT,
|
||||
status TEXT NOT NULL,
|
||||
justification_type TEXT NOT NULL,
|
||||
justification_text TEXT,
|
||||
evidence_refs JSONB,
|
||||
scope_environments TEXT[],
|
||||
scope_projects TEXT[],
|
||||
valid_not_before TIMESTAMPTZ,
|
||||
valid_not_after TIMESTAMPTZ,
|
||||
attestation_ref_id TEXT,
|
||||
attestation_ref_digest JSONB,
|
||||
attestation_ref_storage TEXT,
|
||||
signed_override JSONB,
|
||||
supersedes_decision_id UUID,
|
||||
created_by_id TEXT NOT NULL,
|
||||
created_by_name TEXT NOT NULL,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ,
|
||||
CONSTRAINT pk_vex_decisions PRIMARY KEY (tenant_id, id)
|
||||
) PARTITION BY LIST (tenant_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS vex_decisions_default PARTITION OF vex_decisions DEFAULT;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_vex_decisions_vuln
|
||||
ON vex_decisions (tenant_id, vulnerability_id, created_at DESC);
|
||||
CREATE INDEX IF NOT EXISTS ix_vex_decisions_status
|
||||
ON vex_decisions (tenant_id, status);
|
||||
CREATE INDEX IF NOT EXISTS ix_vex_decisions_subject
|
||||
ON vex_decisions (tenant_id, subject_name);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fix_verifications (
|
||||
id UUID NOT NULL DEFAULT gen_random_uuid(),
|
||||
tenant_id TEXT NOT NULL,
|
||||
cve_id TEXT NOT NULL,
|
||||
component_purl TEXT NOT NULL,
|
||||
artifact_digest TEXT,
|
||||
verdict TEXT NOT NULL DEFAULT 'pending',
|
||||
transitions JSONB NOT NULL DEFAULT '[]'::JSONB,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT pk_fix_verifications PRIMARY KEY (tenant_id, id),
|
||||
CONSTRAINT uq_fix_verifications_cve UNIQUE (tenant_id, cve_id)
|
||||
) PARTITION BY LIST (tenant_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS fix_verifications_default PARTITION OF fix_verifications DEFAULT;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_fix_verifications_cve
|
||||
ON fix_verifications (tenant_id, cve_id);
|
||||
CREATE INDEX IF NOT EXISTS ix_fix_verifications_verdict
|
||||
ON fix_verifications (tenant_id, verdict);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS audit_bundles (
|
||||
id UUID NOT NULL DEFAULT gen_random_uuid(),
|
||||
tenant_id TEXT NOT NULL,
|
||||
bundle_id TEXT NOT NULL,
|
||||
decision_ids UUID[] NOT NULL,
|
||||
attestation_digest TEXT,
|
||||
evidence_refs TEXT[] NOT NULL DEFAULT '{}',
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
CONSTRAINT pk_audit_bundles PRIMARY KEY (tenant_id, id),
|
||||
CONSTRAINT uq_audit_bundles_bundle_id UNIQUE (tenant_id, bundle_id)
|
||||
) PARTITION BY LIST (tenant_id);
|
||||
|
||||
CREATE TABLE IF NOT EXISTS audit_bundles_default PARTITION OF audit_bundles DEFAULT;
|
||||
|
||||
CREATE INDEX IF NOT EXISTS ix_audit_bundles_created
|
||||
ON audit_bundles (tenant_id, created_at DESC);
|
||||
|
||||
COMMIT;
|
||||
|
||||
@@ -690,3 +690,26 @@ ALTER TABLE scheduler.scheduler_exceptions FORCE ROW LEVEL SECURITY;
|
||||
CREATE POLICY scheduler_exceptions_tenant_isolation ON scheduler.scheduler_exceptions FOR ALL
|
||||
USING (tenant_id = scheduler_app.require_current_tenant())
|
||||
WITH CHECK (tenant_id = scheduler_app.require_current_tenant());
|
||||
|
||||
-- ============================================================================
|
||||
-- failure_signatures - Scheduler failure signature tracking
|
||||
-- ============================================================================
|
||||
|
||||
CREATE TABLE IF NOT EXISTS scheduler.failure_signatures (
|
||||
signature_id UUID NOT NULL,
|
||||
tenant_id TEXT NOT NULL,
|
||||
signature_key TEXT NOT NULL,
|
||||
pattern TEXT NOT NULL,
|
||||
severity TEXT NOT NULL DEFAULT 'medium',
|
||||
description TEXT,
|
||||
remediation TEXT,
|
||||
auto_retry BOOLEAN NOT NULL DEFAULT false,
|
||||
max_retries INT NOT NULL DEFAULT 0,
|
||||
created_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
updated_at TIMESTAMPTZ NOT NULL DEFAULT NOW(),
|
||||
created_by TEXT,
|
||||
CONSTRAINT failure_signatures_pkey PRIMARY KEY (signature_id)
|
||||
);
|
||||
|
||||
CREATE UNIQUE INDEX IF NOT EXISTS idx_scheduler_failure_signatures_key
|
||||
ON scheduler.failure_signatures(tenant_id, signature_key);
|
||||
|
||||
@@ -84,6 +84,16 @@
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/release-control(.*)", "IsRegex": true, "TranslatesTo": "http://platform.stella-ops.local/api/v1/release-control$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/gateway/rate-limits(.*)", "IsRegex": true, "TranslatesTo": "http://platform.stella-ops.local/api/v1/gateway/rate-limits$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/quotas(.*)", "IsRegex": true, "TranslatesTo": "http://platform.stella-ops.local/api/v1/jobengine/quotas$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/registry/packs(.*)", "IsRegex": true, "TranslatesTo": "http://packsregistry.stella-ops.local/api/v1/packs$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/deadletter(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/deadletter$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/jobs(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/jobs$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/runs(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/runs$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/dag(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/dag$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/pack-runs(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/pack-runs$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/stream(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/stream$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/audit(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/audit$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/sources(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/sources$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/jobengine/slos(.*)", "IsRegex": true, "TranslatesTo": "http://release-orchestrator.stella-ops.local/api/v1/jobengine/slos$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/reachability(.*)", "IsRegex": true, "TranslatesTo": "http://reachgraph.stella-ops.local/api/v1/reachability$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/timeline(.*)", "IsRegex": true, "TranslatesTo": "http://timeline.stella-ops.local/api/v1/timeline$1" },
|
||||
{ "Type": "Microservice", "Path": "^/api/v1/audit(.*)", "IsRegex": true, "TranslatesTo": "http://timeline.stella-ops.local/api/v1/audit$1" },
|
||||
|
||||
Reference in New Issue
Block a user