types

package
v0.41.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 30, 2026 License: Apache-2.0 Imports: 3 Imported by: 0

Documentation

Overview

Package types provides common type definitions used across the GitOps Reverser.

Index

Examples

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type ResourceIdentifier

type ResourceIdentifier struct {
	Group     string // e.g., "apps", "" for core resources
	Version   string // e.g., "v1"
	Resource  string // Plural form, e.g., "deployments", "pods"
	Namespace string // Empty string for cluster-scoped resources
	Name      string // Resource name
}

ResourceIdentifier encapsulates all information needed to uniquely identify a Kubernetes resource. Its Key() is the fully-qualified REST-style identity ({group}/{version}/{resource}/{namespace}/{name}); its ToGitPath() is the versionless, namespace-first Git storage path (see that method).

func NewResourceIdentifier

func NewResourceIdentifier(group, version, resource, namespace, name string) ResourceIdentifier

NewResourceIdentifier creates a ResourceIdentifier from explicit parts. Useful for watch-based ingestion where we know group/version/resource.

func (ResourceIdentifier) IsClusterScoped

func (r ResourceIdentifier) IsClusterScoped() bool

IsClusterScoped returns true if the resource is cluster-scoped.

func (ResourceIdentifier) Key

func (r ResourceIdentifier) Key() string

Key returns a stable, fully-qualified identifier suitable for map keys and deduplication.

The exact string is a public contract. Tools built around GitOps Reverser key their own rows on this identity and join them against ours, so a consumer that cannot import this package (it lives under internal/) reimplements the format from this comment. Changing any byte of it is a breaking change rather than a refactor, and TestResourceIdentifier_Key_GoldenFormat is the gate that turns such a change into a decision instead of a silent split.

namespaced:      "{group}/{version}/{resource}/{namespace}/{name}"
cluster-scoped:  "{group}/{version}/{resource}/{name}"

Two rules a reimplementation has to get right, and they pull in opposite directions:

  • A cluster-scoped resource DROPS the namespace segment; it does not emit an empty one. Always joining five parts yields "…/clusterroles//admin", which never joins.
  • A core-group resource has an EMPTY group segment, which it does emit, so the key leads with "/".

The four shapes, which are the four cases of the golden test:

apps/v1/deployments/prod/api                        namespaced, grouped
rbac.authorization.k8s.io/v1/clusterroles/admin     cluster-scoped, grouped
/v1/secrets/prod/db                                 namespaced, core group
/v1/nodes/node-1                                    cluster-scoped, core group

Key versus ToGitPath: which one is "the same resource"

Key includes Version and ResourceIdentifier.ToGitPath deliberately excludes it, so the two disagree about whether a preferred-version bump is the same object. The decision, recorded at both methods: Key is the API-side identity — correct for in-process map keys, deduplication and logs, where every participant observes one version at a time — and the versionless, namespace-first path is the DURABLE identity of the object, which is why a storage-version bump moves no file in Git.

A join that must survive a storage-version bump is therefore keyed on the versionless identity, not on Key. Consumers holding rows across releases should drop the version segment (the second) rather than treat "apps/v1/deployments/prod/api" and "apps/v2/deployments/prod/api" as two resources.

Example

ExampleResourceIdentifier_Key shows the four shapes of the key format, including the two empty-segment rules that pull in opposite directions.

namespaced := ResourceIdentifier{
	Group: "apps", Version: "v1", Resource: "deployments", Namespace: "prod", Name: "api",
}
clusterScoped := ResourceIdentifier{
	Group: "rbac.authorization.k8s.io", Version: "v1", Resource: "clusterroles", Name: "admin",
}
coreNamespaced := ResourceIdentifier{
	Version: "v1", Resource: "secrets", Namespace: "prod", Name: "db",
}
coreClusterScoped := ResourceIdentifier{
	Version: "v1", Resource: "nodes", Name: "node-1",
}

fmt.Println(namespaced.Key())
fmt.Println(clusterScoped.Key())     // no empty namespace segment
fmt.Println(coreNamespaced.Key())    // empty group: a leading "/"
fmt.Println(coreClusterScoped.Key()) // both rules at once
Output:
apps/v1/deployments/prod/api
rbac.authorization.k8s.io/v1/clusterroles/admin
/v1/secrets/prod/db
/v1/nodes/node-1

func (ResourceIdentifier) String

func (r ResourceIdentifier) String() string

String returns a human-readable representation.

func (ResourceIdentifier) ToGitPath

func (r ResourceIdentifier) ToGitPath() string

ToGitPath generates the canonical Git file path for a new resource: {namespace-or-cluster}/{group}/{resource}/{name}.yaml. The scope segment leads (a real namespace, or the literal "_cluster" for a cluster-scoped resource) so a repository reads namespace-first, the way a human browses it; the API group is omitted for core resources, and the API version is deliberately left out — the operator writes one version per object, so a version segment adds noise and would churn the path on a preferred-version bump. This is only the cold-start fallback: once any layout exists in the target, sibling inference follows it, and an existing document is always edited in place at its current location (match-first), so changing this shape never moves a file that is already in Git. See docs/spec/gittarget-new-file-placement-rules.md.

That omitted version is the other half of the decision recorded at ResourceIdentifier.Key: this versionless identity is the durable one — the object stays the same object across a preferred-version bump — while Key is the API-side identity and splits on that bump. Neither is wrong; they answer different questions, and a caller joining data that outlives a release wants this one.

Example

ExampleResourceIdentifier_ToGitPath contrasts the two identity functions on one object: the key carries the API version, the path deliberately does not.

deployment := ResourceIdentifier{
	Group: "apps", Version: "v1", Resource: "deployments", Namespace: "prod", Name: "api",
}
node := ResourceIdentifier{Version: "v1", Resource: "nodes", Name: "node-1"}

fmt.Println(deployment.Key())
fmt.Println(deployment.ToGitPath())
fmt.Println(node.Key())
fmt.Println(node.ToGitPath()) // cluster-scoped resources live under "_cluster"
Output:
apps/v1/deployments/prod/api
prod/apps/deployments/api.yaml
/v1/nodes/node-1
_cluster/nodes/node-1.yaml

type ResourceReference

type ResourceReference struct {
	Name      string
	Namespace string
	UID       string
}

ResourceReference references a Kubernetes resource by name and namespace. Provides a clean, reusable type for referencing GitDestinations and other resources.

UID, when set, identifies the specific object generation. It is deliberately excluded from String/Key/Equal so in-memory bookkeeping stays keyed by namespace/name; it scopes durable Redis keys (e.g. watch cursors) so a recreated GitTarget never inherits a deleted predecessor's state.

func NewResourceReference

func NewResourceReference(name, namespace string) ResourceReference

NewResourceReference creates a new resource reference.

func (ResourceReference) Equal

func (r ResourceReference) Equal(other ResourceReference) bool

Equal checks if two references are equal.

func (ResourceReference) IsZero

func (r ResourceReference) IsZero() bool

IsZero returns true if this is an empty reference.

func (ResourceReference) Key

func (r ResourceReference) Key() string

Key returns a string key suitable for map lookups: "namespace/name".

Not to be confused with ResourceIdentifier.Key, which is the fully-qualified "{group}/{version}/{resource}/{namespace}/{name}" identity of a watched object. This one names a GitTarget-like object by reference and carries no group, version or resource.

func (ResourceReference) String

func (r ResourceReference) String() string

String returns "namespace/name" format.

func (ResourceReference) WithUID

WithUID returns a copy of the reference carrying the given object UID.

type SensitiveResourcePolicy

type SensitiveResourcePolicy struct {
	// contains filtered or unexported fields
}

SensitiveResourcePolicy classifies resource types that must use the encrypted Git write path. Core Kubernetes Secrets are always sensitive.

func ParseSensitiveResourcePolicy

func ParseSensitiveResourcePolicy(additional string) (SensitiveResourcePolicy, error)

ParseSensitiveResourcePolicy builds a policy from comma-separated additional entries in resource or group/resource form.

func (SensitiveResourcePolicy) Entries

func (p SensitiveResourcePolicy) Entries() []string

Entries returns the built-in and additional sensitive resource types in flag form.

func (SensitiveResourcePolicy) IsSensitive

func (p SensitiveResourcePolicy) IsSensitive(group, resource string) bool

IsSensitive reports whether group/resource must use the encrypted Git write path.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL