assay.harbor
Harbor container registry. Projects, repositories, artifacts, vulnerability scanning. Client:
harbor.client(url, {api_key="..."}) or {username="...", password="..."}.
System (c.system)
c.system:health()→{status, components}— Check Harbor healthc.system:info()→{harbor_version, ...}— Get system informationc.system:statistics()→{private_project_count, ...}— Get registry statisticsc.system:is_healthy()→ bool — Check if all components report "healthy"
Projects (c.projects)
c.projects:list(opts?)→ [project] — List projects.opts:{name, public, page, page_size}c.projects:get(name_or_id)→ project — Get project by name or numeric ID
Repositories (c.repositories)
c.repositories:list(project_name, opts?)→ [repo] — List repos.opts:{page, page_size, q}c.repositories:get(project_name, repo_name)→ repo — Get repository
Artifacts (c.artifacts)
c.artifacts:list(project_name, repo_name, opts?)→ [artifact] — List artifacts.opts:{page, page_size, with_tag, with_scan_overview}c.artifacts:get(project_name, repo_name, reference)→ artifact — Get artifact by tag or digestc.artifacts:tags(project_name, repo_name, reference)→ [tag] — List artifact tagsc.artifacts:exists(project_name, repo_name, tag)→ bool — Check if image tag existsc.artifacts:latest(project_name, repo_name)→ artifact|nil — Get most recent artifact
Scan (c.scan)
c.scan:trigger(project_name, repo_name, reference)→ true — Trigger vulnerability scan (async)c.scan:vulnerabilities(project_name, repo_name, reference)→{total, fixable, critical, high, medium, low, negligible}|nil — Get vulnerability summary
Replication (c.replication)
c.replication:policies()→ [policy] — List replication policiesc.replication:executions(opts?)→ [execution] — List replication executions.opts:{policy_id}
Backward Compatibility
All legacy colon-style methods (c:health(), c:projects(), c:artifacts(), etc.) remain
available and delegate to the sub-objects above.
Example:
local harbor = require("assay.harbor")
local c = harbor.client("https://harbor.example.com", {username = "admin", password = env.get("HARBOR_PASS")})
-- New sub-object style
assert.eq(c.system:is_healthy(), true, "Harbor unhealthy")
c.scan:trigger("myproject", "myapp", "latest")
sleep(30)
local vulns = c.scan:vulnerabilities("myproject", "myapp", "latest")
assert.eq(vulns.critical, 0, "Critical vulnerabilities found!")
-- Legacy style still works
assert.eq(c:is_healthy(), true, "Harbor unhealthy")
c:scan_artifact("myproject", "myapp", "latest")