local M = {}
function M.client(url, token)
local base_url = url:gsub("/+$", "")
local function headers()
return { ["Authorization"] = "Bearer " .. token }
end
local function api_get(path)
local resp = http.get(base_url .. path, { headers = headers() })
if resp.status == 404 then return nil end
if resp.status ~= 200 then
error("crossplane: GET " .. path .. " HTTP " .. resp.status .. ": " .. resp.body)
end
return json.parse(resp.body)
end
local function api_list(path)
local resp = http.get(base_url .. path, { headers = headers() })
if resp.status == 404 then return { items = {} } end
if resp.status ~= 200 then
error("crossplane: LIST " .. path .. " HTTP " .. resp.status .. ": " .. resp.body)
end
return json.parse(resp.body)
end
local function check_condition(resource, condition_type)
if not resource or not resource.status or not resource.status.conditions then
return false
end
for _, cond in ipairs(resource.status.conditions) do
if cond.type == condition_type then
return cond.status == "True"
end
end
return false
end
local c = {}
c.providers = {}
function c.providers:list()
return api_list("/apis/pkg.crossplane.io/v1/providers")
end
function c.providers:get(name)
return api_get("/apis/pkg.crossplane.io/v1/providers/" .. name)
end
function c.providers:is_healthy(name)
local p = c.providers:get(name)
return check_condition(p, "Healthy")
end
function c.providers:is_installed(name)
local p = c.providers:get(name)
return check_condition(p, "Installed")
end
function c.providers:status(name)
local p = c.providers:get(name)
if not p then
error("crossplane: provider not found: " .. name)
end
local installed = check_condition(p, "Installed")
local healthy = check_condition(p, "Healthy")
local current_revision = nil
if p.status and p.status.currentRevision then
current_revision = p.status.currentRevision
end
local conditions = {}
if p.status and p.status.conditions then
conditions = p.status.conditions
end
return {
installed = installed,
healthy = healthy,
current_revision = current_revision,
conditions = conditions,
}
end
function c.providers:all_healthy()
local list = c.providers:list()
local items = list.items or {}
local healthy = 0
local unhealthy = 0
local unhealthy_names = {}
for _, p in ipairs(items) do
if check_condition(p, "Healthy") then
healthy = healthy + 1
else
unhealthy = unhealthy + 1
local name = p.metadata and p.metadata.name or "unknown"
unhealthy_names[#unhealthy_names + 1] = name
end
end
return {
healthy = healthy,
unhealthy = unhealthy,
total = #items,
unhealthy_names = unhealthy_names,
}
end
c.provider_revisions = {}
function c.provider_revisions:list()
return api_list("/apis/pkg.crossplane.io/v1/providerrevisions")
end
function c.provider_revisions:get(name)
return api_get("/apis/pkg.crossplane.io/v1/providerrevisions/" .. name)
end
c.configurations = {}
function c.configurations:list()
return api_list("/apis/pkg.crossplane.io/v1/configurations")
end
function c.configurations:get(name)
return api_get("/apis/pkg.crossplane.io/v1/configurations/" .. name)
end
function c.configurations:is_healthy(name)
local cfg = c.configurations:get(name)
return check_condition(cfg, "Healthy")
end
function c.configurations:is_installed(name)
local cfg = c.configurations:get(name)
return check_condition(cfg, "Installed")
end
c.functions = {}
function c.functions:list()
return api_list("/apis/pkg.crossplane.io/v1beta1/functions")
end
function c.functions:get(name)
return api_get("/apis/pkg.crossplane.io/v1beta1/functions/" .. name)
end
function c.functions:is_healthy(name)
local fn_resource = c.functions:get(name)
return check_condition(fn_resource, "Healthy")
end
c.xrds = {}
function c.xrds:list()
return api_list("/apis/apiextensions.crossplane.io/v1/compositeresourcedefinitions")
end
function c.xrds:get(name)
return api_get("/apis/apiextensions.crossplane.io/v1/compositeresourcedefinitions/" .. name)
end
function c.xrds:is_established(name)
local x = c.xrds:get(name)
return check_condition(x, "Established")
end
function c.xrds:all_established()
local list = c.xrds:list()
local items = list.items or {}
local established = 0
local not_established = 0
for _, x in ipairs(items) do
if check_condition(x, "Established") then
established = established + 1
else
not_established = not_established + 1
end
end
return {
established = established,
not_established = not_established,
total = #items,
}
end
c.compositions = {}
function c.compositions:list()
return api_list("/apis/apiextensions.crossplane.io/v1/compositions")
end
function c.compositions:get(name)
return api_get("/apis/apiextensions.crossplane.io/v1/compositions/" .. name)
end
c.managed_resources = {}
function c.managed_resources:get(api_group, version, kind, name)
local path = "/apis/" .. api_group .. "/" .. version .. "/" .. kind .. "/" .. name
return api_get(path)
end
function c.managed_resources:is_ready(api_group, version, kind, name)
local r = c.managed_resources:get(api_group, version, kind, name)
return check_condition(r, "Ready")
end
function c.managed_resources:list(api_group, version, kind)
local path = "/apis/" .. api_group .. "/" .. version .. "/" .. kind
return api_list(path)
end
return c
end
return M