Resource Management¶
omni_kube provides a comprehensive Postgres-based interface for managing Kubernetes resources through SQL views and functions. This system allows you to interact with Kubernetes API resources using standard SQL operations.
Overview¶
The resource management system consists of several key components:
- API Group Discovery: Views that expose Kubernetes API groups and versions
- Resource Introspection: Functions to discover available resources within API groups
- Dynamic Resource Views: Generated views that provide CRUD operations for specific Kubernetes resources
API Group Views¶
omni_kube.api_group
¶
Lists all available Kubernetes API groups with their preferred versions.
Columns:
name
(text): API group name ('core' for core Kubernetes resources)preferred_version
(text): The preferred version for this API group
omni_kube.api_group_version
¶
Shows all available versions for each API group.
Columns:
name
(text): API group nameversion
(text): Version identifier (e.g., 'v1', 'v1beta1')group_version
(text): Full group/version identifier
omni_kube.api_group_openapi_v3_url
¶
Maps API groups to their OpenAPI specification URLs.
Columns:
name
(text): API group namegroup_version
(text): Group/version identifierurl
(text): Server-relative URL for the API specification
Resource Discovery Functions¶
omni_kube.group_resources(group_version text)
¶
Returns detailed information about all resources available in a specific API group version.
Parameters:
group_version
: The group/version identifier (e.g., 'v1', 'apps/v1')
Returns:
name
(text): Resource name (e.g., 'pods', 'deployments')singular_name
(text): Singular form of the resource namenamespaced
(boolean): Whether the resource is namespace-scopedkind
(text): Kubernetes kind name (e.g., 'Pod', 'Deployment')verbs
(text[]): Supported operations (e.g., ['get', 'list', 'create', 'update', 'delete'])storage_version_hash
(text): Internal version hash
Example:
select name, kind, namespaced, verbs
from omni_kube.group_resources('apps/v1')
where name = 'deployments';
omni_kube.resources(group_version text, resource text[, label_selector text][, field_selector text])
¶
Retrieves the actual resource instances from the Kubernetes API.
Parameters:
group_version
: The group/version identifierresource
: The resource type namelabel_selector
: Optional label selector (e.g., 'app=web-app')field_selector
: Optional field selector (e.g., 'metadata.name=web-app')
Returns:
jsonb
: Complete resource definition as returned by the Kubernetes API
Example:
select resource -> 'metadata' ->> 'name' as name,
resource -> 'spec' ->> 'replicas' as replicas
from omni_kube.resources('apps/v1', 'deployments') resource;
Dynamic Resource Views¶
¶
omni_kube.resource_view(view_name name, group_version text, resource text[, label_selector text][, field_selector text])
Creates a dynamic view that provides a SQL interface for managing specific Kubernetes resources.
Parameters:
view_name
: Name for the generated viewgroup_version
: API group/version (e.g., 'v1', 'apps/v1')resource
: Resource type (e.g., 'pods', 'deployments')label_selector
: Optional label selector (e.g., 'app=web-app')field_selector
: Optional field selector (e.g., 'metadata.name=web-app')
Returns:
regclass
: The created view's object identifier
The generated view includes:
uid
(text): Kubernetes resource UIDname
(text): Resource namenamespace
(text): Resource namespace (null for cluster-scoped resources)resource
(jsonb): Complete resource specification
Generated View Operations¶
Insert Operations¶
Create new resources by inserting into the view:
-- create a view for pods
select omni_kube.resource_view('my_pods', 'v1', 'pods');
-- insert a new pod
insert into my_pods (resource)
values ('{
"metadata": {
"name": "nginx-pod-omni-kube"
},
"spec": {
"containers": [{
"name": "test",
"image": "nginx"
}]
}
}');
Insert Requirements:
uid
must be null (auto-generated by Kubernetes)name
can be specified in the view column or withinresource.metadata.name
namespace
must matchresource.metadata.namespace
if both are specifiedresource
must contain valid Kubernetes resource specification
Update Operation¶
Modify existing resources:
update my_pods
set resource = jsonb_set(
resource,
'{metadata,annotations}',
coalesce(resource -> 'metadata' -> 'annotations', '{}'::jsonb) || '{"test": "passed"}'::jsonb
)
where name = 'nginx-pod-omni-kube';
Update Requirements:
- Resource must exist (identified by name and namespace)
- Name and namespace consistency rules apply as with insert
Delete Operations¶
Remove resources:
Delete Requirements:
- Resource is identified by name and namespace from the view columns or resource metadata
Error Handling¶
The system includes comprehensive validation:
- Name/Namespace Consistency: Ensures view columns match resource metadata
- Required Fields: Validates that resources have required name field
- UID Restrictions: Prevents manual UID assignment for new resources
- Resource Existence: Validates resources exist before update/delete operations
Add this section to your Resource Discovery Functions section, after the omni_kube.resources()
function:
omni_kube.resources_metadata(group_version text, resource text)
¶
Retrieves only the metadata section from a Kubernetes resource collection, which is useful for getting information like resource versions without fetching the entire resource list.
Parameters:
group_version
: The group/version identifier (e.g., 'v1', 'apps/v1')resource
: The resource type name
Returns:
jsonb
: The metadata object from the Kubernetes API response, typically containing fields likeresourceVersion
.
Example:
-- Get the current resource version for pods
select omni_kube.resources_metadata('v1', 'pods') ->> 'resourceVersion' as current_version;
Resource Tables¶
The omni_kube.resource_table()
function provides an alternative to dynamic views by creating materialized tables that
cache Kubernetes resource data locally. Like resource_view()
, it accepts the same parameters for specifying the target
API group, version, and resource type. The key advantage of resource tables is performance and a stable view – they
store resource data locally in the database rather than making API calls on each query.
Each generated table has a corresponding refresh_<table_name>()
function that synchronizes the local data with the
current state of the Kubernetes cluster.
This refresh mechanism allows you to control when expensive API calls occur, making resource tables ideal for scenarios where you need to perform complex queries, joins, or analytics on Kubernetes data without the latency of repeated API requests. The refresh function can be called manually or scheduled for automated data synchronization.
Resource tables are particularly valuable for building Kubernetes operators and controllers, where you need to maintain local state, perform complex reconciliation logic across multiple resource types, or implement sophisticated filtering and aggregation operations that would be inefficient when executed against live API endpoints.
The function returns a table of (type text, object jsonb)
where type is ADDED
, MODIFIED
or DELETED
and object
is the object in question.
Transactional Resource Tables¶
Resource tables can be made transactional by passing transactional => true
to omni_kube.resource_table()
. This
simulates read committed
-style isolation of changes to the cluster. That is, if you refresh a table within a
transaction, it'll reflect current state of the cluster. All pending changes in the table are dry-run-verified but
pooled until commit time. Subsequent changes to the same resource override the entry in the pool (so, for example, an
update followed by another update is superseded; a deletion performed after update, wins, etc.)
This enables an approximation of atomic operations – a best-effort approach.
Important caveats
Commits may still fail due to conflicts with the actual cluster (newer resource versions in the cluster, resource deleted, etc.)
Commit operation can also fail due to HTTP errors and leave transaction's pending changes in an inconsistent state. A compensation mechanism can be devised (reconciling incomplete transaction). Future versions of this extension may provide tooling for this.
Usage Examples¶
Working with Deployments¶
-- create a deployments view
select omni_kube.resource_view('deployments', 'apps/v1', 'deployments');
-- list all deployments
select name,
namespace,
resource -> 'spec' ->> 'replicas' as desired_replicas,
resource -> 'status' ->> 'replicas' as current_replicas
from deployments;
-- create a new deployment
insert into deployments (resource)
values ('{
"metadata": {
"name": "web-app",
"labels": {
"app": "web-app",
"version": "1.0"
}
},
"spec": {
"replicas": 3,
"selector": {
"matchLabels": {
"app": "web-app"
}
},
"template": {
"metadata": {
"labels": {
"app": "web-app",
"version": "1.0"
}
},
"spec": {
"containers": [{
"name": "web",
"image": "nginx:1.21",
"ports": [{
"containerPort": 80
}],
"resources": {
"requests": {
"memory": "64Mi",
"cpu": "250m"
},
"limits": {
"memory": "128Mi",
"cpu": "500m"
}
}
}]
}
}
}
}');
-- scale the deployment
update deployments
set resource = jsonb_set(resource, '{spec,replicas}', '5'::jsonb)
where name = 'web-app';
Working with ConfigMaps¶
-- create a configmaps view
select omni_kube.resource_view('configmaps', 'v1', 'configmaps');
-- create a configuration
insert into configmaps (resource)
values ('{
"metadata": {
"name": "app-config"
},
"data": {
"database_url": "postgres://localhost:5432/mydb",
"debug": "true"
}
}');
-- update it
update configmaps
set resource = jsonb_set(resource, '{data,debug}', '"false"'::jsonb)
where name = 'app-config';
This system provides a powerful SQL interface to Kubernetes resources while maintaining full compatibility with the Kubernetes API and its validation rules.