|
| 1 | +// NOTE(chandler): This is my illuminated manuscript for PR 13007, which is |
| 2 | +// much better than the way that kgateway 2.1.0 specifies many Kubernetes |
| 3 | +// fields, but never the one you need, in its GatewayParameters. |
| 4 | + |
| 5 | +package agentgateway |
| 6 | + |
| 7 | +import ( |
| 8 | + corev1 "k8s.io/api/core/v1" |
| 9 | + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" |
| 10 | + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" |
| 11 | +) |
| 12 | + |
| 13 | +// +kubebuilder:rbac:groups=agentgateway.dev,resources=agentgatewayparameters,verbs=get;list;watch |
| 14 | +// +kubebuilder:rbac:groups=agentgateway.dev,resources=agentgatewayparameters/status,verbs=get;update;patch |
| 15 | + |
| 16 | +// +kubebuilder:printcolumn:name="Accepted",type=string,JSONPath=".status.ancestors[*].conditions[?(@.type=='Accepted')].status",description="Agentgateway policy acceptance status" |
| 17 | +// +kubebuilder:printcolumn:name="Attached",type=string,JSONPath=".status.ancestors[*].conditions[?(@.type=='Attached')].status",description="Agentgateway policy attachment status" |
| 18 | +// +kubebuilder:printcolumn:name="Age",type=date,JSONPath=`.metadata.creationTimestamp` |
| 19 | + |
| 20 | +// +genclient |
| 21 | +// +kubebuilder:object:root=true |
| 22 | +// +kubebuilder:metadata:labels={app=kgateway,app.kubernetes.io/name=kgateway} |
| 23 | +// +kubebuilder:resource:categories=kgateway,shortName=agpar,path=agentgatewayparameters |
| 24 | +// +kubebuilder:subresource:status |
| 25 | +// +kubebuilder:metadata:labels="gateway.networking.k8s.io/policy=Direct" |
| 26 | +type AgentgatewayParameters struct { |
| 27 | + metav1.TypeMeta `json:",inline"` |
| 28 | + // metadata for the object |
| 29 | + // More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#metadata |
| 30 | + // +optional |
| 31 | + metav1.ObjectMeta `json:"metadata"` |
| 32 | + |
| 33 | + // spec defines the desired state of AgentgatewayParameters. |
| 34 | + // +required |
| 35 | + Spec AgentgatewayParametersSpec `json:"spec"` |
| 36 | + |
| 37 | + // status defines the current state of AgentgatewayParameters. |
| 38 | + // +optional |
| 39 | + Status AgentgatewayParametersStatus `json:"status"` |
| 40 | +} |
| 41 | + |
| 42 | +// The current conditions of the GatewayParameters. This is not currently implemented. |
| 43 | +type AgentgatewayParametersStatus struct{} |
| 44 | + |
| 45 | +// +kubebuilder:object:root=true |
| 46 | +type AgentgatewayParametersList struct { |
| 47 | + metav1.TypeMeta `json:",inline"` |
| 48 | + metav1.ListMeta `json:"metadata"` |
| 49 | + Items []AgentgatewayParameters `json:"items"` |
| 50 | +} |
| 51 | + |
| 52 | +type AgentgatewayParametersSpec struct { |
| 53 | + AgentgatewayParametersConfigs `json:",inline"` |
| 54 | + AgentgatewayParametersOverlays `json:",inline"` |
| 55 | +} |
| 56 | + |
| 57 | +// +kubebuilder:validation:Enum=Json;Plain |
| 58 | +type AgentgatewayParametersLoggingFormat string |
| 59 | + |
| 60 | +const ( |
| 61 | + AgentgatewayParametersLoggingJson AgentgatewayParametersLoggingFormat = "Json" |
| 62 | + AgentgatewayParametersLoggingPlain AgentgatewayParametersLoggingFormat = "Plain" |
| 63 | +) |
| 64 | + |
| 65 | +// +kubebuilder:validation:AtMostOneOf=level;levels |
| 66 | +type AgentgatewayParametersLogging struct { |
| 67 | + // +optional |
| 68 | + Level string `json:"level,omitempty"` |
| 69 | + // +optional |
| 70 | + Levels []string `json:"levels,omitempty"` |
| 71 | + // +optional |
| 72 | + Format AgentgatewayParametersLoggingFormat `json:"format,omitempty"` |
| 73 | +} |
| 74 | + |
| 75 | +type AgentgatewayParametersConfigs struct { |
| 76 | + // Common set of labels to apply to all generated resources. |
| 77 | + // +optional |
| 78 | + Labels map[string]string `json:"labels,omitempty"` |
| 79 | + |
| 80 | + // Common set of annotations to apply to all generated resources. |
| 81 | + // +optional |
| 82 | + Annotations map[string]string `json:"annotations,omitempty"` |
| 83 | + |
| 84 | + // logging configuration for Agentgateway. By default, all logs are set to "info" level. |
| 85 | + // +optional |
| 86 | + Logging *AgentgatewayParametersLogging `json:"logging,omitempty"` |
| 87 | + |
| 88 | + // The agentgateway container image. See |
| 89 | + // https://kubernetes.io/docs/concepts/containers/images |
| 90 | + // for details. |
| 91 | + // |
| 92 | + // Default values, which may be overridden individually: |
| 93 | + // |
| 94 | + // registry: ghcr.io/agentgateway |
| 95 | + // repository: agentgateway |
| 96 | + // tag: <agentgateway version> |
| 97 | + // pullPolicy: <omitted, relying on Kubernetes defaults which depend on the tag> |
| 98 | + // |
| 99 | + // +optional |
| 100 | + Image *Image `json:"image,omitempty"` |
| 101 | + |
| 102 | + // The container environment variables. These override any existing |
| 103 | + // values. If you want to delete an environment variable entirely, use |
| 104 | + // `$patch: delete` with AgentgatewayParametersOverlays instead. Note that |
| 105 | + // [variable |
| 106 | + // expansion](https://kubernetes.io/docs/tasks/inject-data-application/define-interdependent-environment-variables/) |
| 107 | + // does apply, but is highly discouraged -- to set dependent environment |
| 108 | + // variables, you can use $(VAR_NAME), but it's highly |
| 109 | + // discouraged. `$$(VAR_NAME)` avoids expansion and results in a literal |
| 110 | + // `$(VAR_NAME)`. |
| 111 | + // |
| 112 | + // +optional |
| 113 | + Env []corev1.EnvVar `json:"env,omitempty"` |
| 114 | + |
| 115 | + // The compute resources required by this container. See |
| 116 | + // https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/ |
| 117 | + // for details. |
| 118 | + // |
| 119 | + // +optional |
| 120 | + Resources *corev1.ResourceRequirements `json:"resources,omitempty"` |
| 121 | + |
| 122 | + // Shutdown delay configuration. How graceful planned or unplanned data |
| 123 | + // plane changes happen is in tension with how quickly rollouts of the data |
| 124 | + // plane complete. How long a data plane pod must wait for shutdown to be |
| 125 | + // perfectly graceful depends on how you have configured your Gateways. |
| 126 | + // |
| 127 | + // +optional |
| 128 | + Shutdown *ShutdownSpec `json:"shutdown,omitempty"` |
| 129 | +} |
| 130 | + |
| 131 | +// +kubebuilder:validation:XValidation:rule="self.minSeconds <= self.maxSeconds",message="The 'minSeconds' value must be less than or equal to the 'maxSeconds' value." |
| 132 | +type ShutdownSpec struct { |
| 133 | + // Minimum time (in seconds) to wait before allowing Agentgateway to |
| 134 | + // terminate. Refer to the CONNECTION_MIN_TERMINATION_DEADLINE environment |
| 135 | + // variable for details. |
| 136 | + // |
| 137 | + // +optional |
| 138 | + // +kubebuilder:validation:Minimum=0 |
| 139 | + // +kubebuilder:validation:Maximum=31536000 |
| 140 | + MinSeconds *int64 `json:"minSeconds,omitempty"` |
| 141 | + |
| 142 | + // Maximum time (in seconds) to wait before allowing Agentgateway to |
| 143 | + // terminate. Refer to the TERMINATION_GRACE_PERIOD_SECONDS environment |
| 144 | + // variable for details. |
| 145 | + // |
| 146 | + // +optional |
| 147 | + // +kubebuilder:validation:Minimum=0 |
| 148 | + // +kubebuilder:validation:Maximum=31536000 |
| 149 | + MaxSeconds *int64 `json:"maxSeconds,omitempty"` |
| 150 | +} |
| 151 | + |
| 152 | +type AgentgatewayParametersOverlays struct { |
| 153 | + // deployment allows specifying overrides for the generated Deployment resource. |
| 154 | + // +optional |
| 155 | + Deployment *KubernetesResourceOverlay `json:"deployment,omitempty"` |
| 156 | + |
| 157 | + // service allows specifying overrides for the generated Service resource. |
| 158 | + // +optional |
| 159 | + Service *KubernetesResourceOverlay `json:"service,omitempty"` |
| 160 | + |
| 161 | + // serviceAccount allows specifying overrides for the generated ServiceAccount resource. |
| 162 | + // +optional |
| 163 | + ServiceAccount *KubernetesResourceOverlay `json:"serviceAccount,omitempty"` |
| 164 | +} |
| 165 | + |
| 166 | +type AgentgatewayParametersObjectMetadata struct { |
| 167 | + // Map of string keys and values that can be used to organize and categorize |
| 168 | + // (scope and select) objects. May match selectors of replication controllers |
| 169 | + // and services. |
| 170 | + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/labels |
| 171 | + // +optional |
| 172 | + Labels map[string]string `json:"labels,omitempty"` |
| 173 | + |
| 174 | + // Annotations is an unstructured key value map stored with a resource that may be |
| 175 | + // set by external tools to store and retrieve arbitrary metadata. They are not |
| 176 | + // queryable and should be preserved when modifying objects. |
| 177 | + // More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/annotations |
| 178 | + // +optional |
| 179 | + Annotations map[string]string `json:"annotations,omitempty"` |
| 180 | +} |
| 181 | + |
| 182 | +// KubernetesResourceOverlay provides a mechanism to customize generated |
| 183 | +// Kubernetes resources using [Strategic Merge |
| 184 | +// Patch](https://github.com/kubernetes/community/blob/master/contributors/devel/sig-api-machinery/strategic-merge-patch.md) |
| 185 | +// semantics. |
| 186 | +type KubernetesResourceOverlay struct { |
| 187 | + // metadata defines a subset of object metadata to be customized. |
| 188 | + // +optional |
| 189 | + Metadata AgentgatewayParametersObjectMetadata `json:"metadata"` |
| 190 | + |
| 191 | + // Spec provides an opaque mechanism to configure the resource Spec. |
| 192 | + // This field accepts a complete or partial Kubernetes resource spec (e.g., PodSpec, ServiceSpec) |
| 193 | + // and will be merged with the generated configuration using **Strategic Merge Patch** semantics. |
| 194 | + // The patch is applied after all other fields are applied. |
| 195 | + // |
| 196 | + // # Strategic Merge Patch & Deletion Guide |
| 197 | + // |
| 198 | + // This merge strategy allows you to override individual fields, merge lists, or delete items |
| 199 | + // without needing to provide the entire resource definition. |
| 200 | + // |
| 201 | + // **1. Replacing Values (Scalars):** |
| 202 | + // Simple fields (strings, integers, booleans) in your config will overwrite the generated defaults. |
| 203 | + // |
| 204 | + // **2. Merging Lists (Append/Merge):** |
| 205 | + // Lists with "merge keys" (like `containers` which merges on `name`, or `tolerations` which merges on `key`) |
| 206 | + // will append your items to the generated list, or update existing items if keys match. |
| 207 | + // |
| 208 | + // **3. Deleting List Items ($patch: delete):** |
| 209 | + // To remove an item from a generated list (e.g., removing a default sidecar), you must use |
| 210 | + // the special `$patch: delete` directive. |
| 211 | + // |
| 212 | + // spec: |
| 213 | + // template: |
| 214 | + // spec: |
| 215 | + // containers: |
| 216 | + // - name: unwanted-sidecar |
| 217 | + // $patch: delete |
| 218 | + // |
| 219 | + // **4. Deleting/Clearing Map Fields (null):** |
| 220 | + // To remove a map field or a scalar entirely, set its value to `null`. |
| 221 | + // |
| 222 | + // spec: |
| 223 | + // template: |
| 224 | + // spec: |
| 225 | + // nodeSelector: null # Removes default nodeSelector |
| 226 | + // |
| 227 | + // **5. Replacing Lists Entirely ($patch: replace):** |
| 228 | + // If you want to strictly define a list and ignore all generated defaults, use `$patch: replace`. |
| 229 | + // |
| 230 | + // spec: |
| 231 | + // template: |
| 232 | + // spec: |
| 233 | + // containers: |
| 234 | + // - name: my-only-container |
| 235 | + // image: alpine |
| 236 | + // $patch: replace |
| 237 | + // |
| 238 | + // +optional |
| 239 | + // +kubebuilder:validation:Type=object |
| 240 | + // +kubebuilder:pruning:PreserveUnknownFields |
| 241 | + Spec *apiextensionsv1.JSON `json:"spec,omitempty"` |
| 242 | +} |
| 243 | + |
| 244 | +// A container image. See https://kubernetes.io/docs/concepts/containers/images |
| 245 | +// for details. |
| 246 | +type Image struct { |
| 247 | + // The image registry. |
| 248 | + // |
| 249 | + // +optional |
| 250 | + Registry *string `json:"registry,omitempty"` |
| 251 | + |
| 252 | + // The image repository (name). |
| 253 | + // |
| 254 | + // +optional |
| 255 | + Repository *string `json:"repository,omitempty"` |
| 256 | + |
| 257 | + // The image tag. |
| 258 | + // |
| 259 | + // +optional |
| 260 | + Tag *string `json:"tag,omitempty"` |
| 261 | + |
| 262 | + // The hash digest of the image, e.g. `sha256:12345...` |
| 263 | + // |
| 264 | + // +optional |
| 265 | + Digest *string `json:"digest,omitempty"` |
| 266 | + |
| 267 | + // The image pull policy for the container. See |
| 268 | + // https://kubernetes.io/docs/concepts/containers/images/#image-pull-policy |
| 269 | + // for details. |
| 270 | + // |
| 271 | + // +optional |
| 272 | + PullPolicy *corev1.PullPolicy `json:"pullPolicy,omitempty"` |
| 273 | +} |
0 commit comments