Scaffold kea-operator: CRDs, controllers, config rendering, REST API, CI
Replace the ISC dhcpd PXE-boot VM with a Kea DHCP Kubernetes operator, modelled on bind-operator. The operator renders kea-dhcp4 config from CRs and runs an HA pair of kea-dhcp4 + kea-ctrl-agent servers behind an anycast Service. - add KeaCluster/KeaSubnet/KeaClientClass/KeaAPI CRDs (group kea.unkin.net) - render deterministic kea-dhcp4.conf + kea-ctrl-agent.conf into a ConfigMap and roll the StatefulSet via a config-hash annotation; best-effort hot-reload via the kea-ctrl-agent REST channel - run HA hot-standby (memfile leases) with stable per-peer DNS identity from a StatefulSet; expose an anycast LoadBalancer Service for PureLB - represent the full legacy dhcpd config: 198.18.13-17.0/24 pools, pool-less 198.18.25.0/24, and the Legacy/UEFI-64 PXE arch classes (option 93) - add the KeaAPI-spawned REST service: Terraform-friendly CRUD over subnet and client-class CRs (stable IDs, PUT upsert, 404 drift, bearer-token auth) - add Makefile (patch/minor/major tag targets), distroless operator/api images, an AlmaLinux+EPEL kea workload image, and woodpecker CI with k8s resources + serviceAccountName on every step - unit tests for config rendering, controller reconcile/config-hash, and the API Claude-Session: https://claude.ai/code/session_01JUoARVdmhxKQHyyyp1pxeT
This commit is contained in:
@@ -0,0 +1,3 @@
|
||||
// +kubebuilder:object:generate=true
|
||||
// +groupName=kea.unkin.net
|
||||
package v1alpha1
|
||||
@@ -0,0 +1,18 @@
|
||||
// Package v1alpha1 contains the kea.unkin.net API types.
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/apimachinery/pkg/runtime/schema"
|
||||
"sigs.k8s.io/controller-runtime/pkg/scheme"
|
||||
)
|
||||
|
||||
var (
|
||||
// GroupVersion is the group/version used to register these objects.
|
||||
GroupVersion = schema.GroupVersion{Group: "kea.unkin.net", Version: "v1alpha1"}
|
||||
|
||||
// SchemeBuilder registers the kea.unkin.net types with a scheme.
|
||||
SchemeBuilder = &scheme.Builder{GroupVersion: GroupVersion}
|
||||
|
||||
// AddToScheme adds the kea.unkin.net types to a scheme.
|
||||
AddToScheme = SchemeBuilder.AddToScheme
|
||||
)
|
||||
@@ -0,0 +1,99 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// KeaAPISpec defines the REST API service that manages KeaSubnet and
|
||||
// KeaClientClass CRs (a Terraform-friendly alternative to argocd-managed CRs).
|
||||
type KeaAPISpec struct {
|
||||
// Replicas of the API server.
|
||||
// +kubebuilder:default=1
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +optional
|
||||
Replicas *int32 `json:"replicas,omitempty"`
|
||||
|
||||
// Image is the kea-api container image.
|
||||
// +optional
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
// TokenSecretName is a Secret holding the bearer token under key "token".
|
||||
// If the Secret does not exist the operator creates one with a random
|
||||
// token (so it may instead be pre-seeded, e.g. by a Vault static secret).
|
||||
// +optional
|
||||
TokenSecretName string `json:"tokenSecretName,omitempty"`
|
||||
|
||||
// Service configures how the API is exposed.
|
||||
// +optional
|
||||
Service KeaAPIServiceSpec `json:"service,omitempty"`
|
||||
|
||||
// Resources for the API container.
|
||||
// +optional
|
||||
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
|
||||
|
||||
// +optional
|
||||
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
|
||||
// +optional
|
||||
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
|
||||
// +optional
|
||||
Affinity *corev1.Affinity `json:"affinity,omitempty"`
|
||||
}
|
||||
|
||||
// KeaAPIServiceSpec configures the API Service.
|
||||
type KeaAPIServiceSpec struct {
|
||||
// +kubebuilder:default=ClusterIP
|
||||
// +optional
|
||||
Type corev1.ServiceType `json:"type,omitempty"`
|
||||
// +kubebuilder:default=8080
|
||||
// +optional
|
||||
Port int32 `json:"port,omitempty"`
|
||||
// +optional
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// KeaAPIStatus captures observed state.
|
||||
type KeaAPIStatus struct {
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
// Endpoint is the in-cluster base URL of the API.
|
||||
// +optional
|
||||
Endpoint string `json:"endpoint,omitempty"`
|
||||
// +optional
|
||||
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
// +optional
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:shortName=kapi
|
||||
// +kubebuilder:printcolumn:name="Endpoint",type=string,JSONPath=`.status.endpoint`
|
||||
// +kubebuilder:printcolumn:name="Ready",type=integer,JSONPath=`.status.readyReplicas`
|
||||
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
|
||||
|
||||
// KeaAPI spawns the REST API service Deployment.
|
||||
type KeaAPI struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KeaAPISpec `json:"spec,omitempty"`
|
||||
Status KeaAPIStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// KeaAPIList contains a list of KeaAPI.
|
||||
type KeaAPIList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KeaAPI `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KeaAPI{}, &KeaAPIList{})
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// KeaClientClassSpec defines a PXE boot client-class, typically matching the
|
||||
// DHCP client architecture option (code 93).
|
||||
type KeaClientClassSpec struct {
|
||||
// ClusterRef selects the owning KeaCluster by name. Empty means every
|
||||
// KeaCluster in the namespace.
|
||||
// +optional
|
||||
ClusterRef string `json:"clusterRef,omitempty"`
|
||||
|
||||
// Test is a raw Kea class-match expression. When empty it is generated
|
||||
// from ArchHex.
|
||||
// +optional
|
||||
Test string `json:"test,omitempty"`
|
||||
|
||||
// ArchHex is a convenience list of client-architecture values (option 93),
|
||||
// e.g. ["0x0000"] or ["0x0007","0x0009"]. Rendered into a Test expression
|
||||
// of the form: option[93].hex == 0x0007 or option[93].hex == 0x0009.
|
||||
// +optional
|
||||
ArchHex []string `json:"archHex,omitempty"`
|
||||
|
||||
// BootFileName handed to matching clients (option 67 / boot-file-name).
|
||||
// +optional
|
||||
BootFileName string `json:"bootFileName,omitempty"`
|
||||
|
||||
// NextServer overrides siaddr for matching clients.
|
||||
// +optional
|
||||
NextServer string `json:"nextServer,omitempty"`
|
||||
|
||||
// ServerHostname (sname) for matching clients.
|
||||
// +optional
|
||||
ServerHostname string `json:"serverHostname,omitempty"`
|
||||
|
||||
// OptionData carries additional options set for matching clients.
|
||||
// +optional
|
||||
OptionData []OptionData `json:"optionData,omitempty"`
|
||||
}
|
||||
|
||||
// KeaClientClassStatus captures observed state.
|
||||
type KeaClientClassStatus struct {
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
// +optional
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:shortName=kcc
|
||||
// +kubebuilder:printcolumn:name="Cluster",type=string,JSONPath=`.spec.clusterRef`
|
||||
// +kubebuilder:printcolumn:name="BootFile",type=string,JSONPath=`.spec.bootFileName`
|
||||
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
|
||||
|
||||
// KeaClientClass is a PXE boot class matched on the client architecture.
|
||||
type KeaClientClass struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KeaClientClassSpec `json:"spec,omitempty"`
|
||||
Status KeaClientClassStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// KeaClientClassList contains a list of KeaClientClass.
|
||||
type KeaClientClassList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KeaClientClass `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KeaClientClass{}, &KeaClientClassList{})
|
||||
}
|
||||
@@ -0,0 +1,209 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
corev1 "k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// HAMode selects the Kea High Availability hook operating mode.
|
||||
// +kubebuilder:validation:Enum=hot-standby;load-balancing
|
||||
type HAMode string
|
||||
|
||||
const (
|
||||
// HAHotStandby runs one active (primary) server; the standby only serves
|
||||
// when the primary is detected down. Preferred for PXE-only, low-volume,
|
||||
// ephemeral leases where split-pool double allocation must be avoided.
|
||||
HAHotStandby HAMode = "hot-standby"
|
||||
// HALoadBalancing splits clients across both peers by a hash.
|
||||
HALoadBalancing HAMode = "load-balancing"
|
||||
)
|
||||
|
||||
// HASpec configures the libdhcp_ha hook shared between the cluster replicas.
|
||||
type HASpec struct {
|
||||
// Mode is the HA operating mode.
|
||||
// +kubebuilder:default=hot-standby
|
||||
// +optional
|
||||
Mode HAMode `json:"mode,omitempty"`
|
||||
|
||||
// HeartbeatDelay is the interval (ms) between HA heartbeats.
|
||||
// +kubebuilder:default=10000
|
||||
// +kubebuilder:validation:Minimum=1000
|
||||
// +optional
|
||||
HeartbeatDelay int `json:"heartbeatDelay,omitempty"`
|
||||
|
||||
// MaxResponseDelay (ms) before a peer is considered unresponsive.
|
||||
// +kubebuilder:default=60000
|
||||
// +kubebuilder:validation:Minimum=1000
|
||||
// +optional
|
||||
MaxResponseDelay int `json:"maxResponseDelay,omitempty"`
|
||||
|
||||
// MaxAckDelay (ms) a client may wait before HA considers it unacked.
|
||||
// +kubebuilder:default=5000
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
// +optional
|
||||
MaxAckDelay int `json:"maxAckDelay,omitempty"`
|
||||
|
||||
// MaxUnackedClients before a partner is declared to be in a failure state.
|
||||
// +kubebuilder:default=5
|
||||
// +kubebuilder:validation:Minimum=0
|
||||
// +optional
|
||||
MaxUnackedClients int `json:"maxUnackedClients,omitempty"`
|
||||
}
|
||||
|
||||
// OptionDef is a custom DHCPv4 option definition (e.g. the PXE client
|
||||
// architecture option, code 93).
|
||||
type OptionDef struct {
|
||||
Name string `json:"name"`
|
||||
Code int `json:"code"`
|
||||
// Type is a Kea option data type, e.g. "uint16", "string", "ipv4-address".
|
||||
Type string `json:"type"`
|
||||
// Space defaults to "dhcp4".
|
||||
// +kubebuilder:default=dhcp4
|
||||
// +optional
|
||||
Space string `json:"space,omitempty"`
|
||||
// Array marks the option as an array of Type.
|
||||
// +optional
|
||||
Array bool `json:"array,omitempty"`
|
||||
// RecordTypes is a comma-separated list for record-type options.
|
||||
// +optional
|
||||
RecordTypes string `json:"recordTypes,omitempty"`
|
||||
// Encapsulate names an option space this option encapsulates.
|
||||
// +optional
|
||||
Encapsulate string `json:"encapsulate,omitempty"`
|
||||
}
|
||||
|
||||
// ClusterServiceSpec configures the anycast LoadBalancer Service that fronts
|
||||
// the DHCP replicas. DHCP traffic arrives unicast via router relays to the
|
||||
// anycast address (typically a PureLB-assigned IP), so no host networking is
|
||||
// required.
|
||||
type ClusterServiceSpec struct {
|
||||
// Type of the DHCP Service. Defaults to LoadBalancer for anycast exposure.
|
||||
// +kubebuilder:default=LoadBalancer
|
||||
// +optional
|
||||
Type corev1.ServiceType `json:"type,omitempty"`
|
||||
|
||||
// LoadBalancerIP requests a specific (anycast) address.
|
||||
// +optional
|
||||
LoadBalancerIP string `json:"loadBalancerIP,omitempty"`
|
||||
|
||||
// LoadBalancerClass selects the LB implementation (e.g. purelb.io/purelb).
|
||||
// +optional
|
||||
LoadBalancerClass *string `json:"loadBalancerClass,omitempty"`
|
||||
|
||||
// IPAddressPool is a convenience for the PureLB service-group annotation.
|
||||
// +optional
|
||||
IPAddressPool string `json:"ipAddressPool,omitempty"`
|
||||
|
||||
// Annotations are merged onto the Service (e.g. PureLB pool selection).
|
||||
// +optional
|
||||
Annotations map[string]string `json:"annotations,omitempty"`
|
||||
}
|
||||
|
||||
// KeaClusterSpec defines the desired state of a KeaCluster.
|
||||
type KeaClusterSpec struct {
|
||||
// Replicas is the number of kea-dhcp4 servers. HA is designed around 2.
|
||||
// +kubebuilder:default=2
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +optional
|
||||
Replicas *int32 `json:"replicas,omitempty"`
|
||||
|
||||
// Image is the kea-dhcp4 + kea-ctrl-agent container image.
|
||||
// +optional
|
||||
Image string `json:"image,omitempty"`
|
||||
|
||||
// DomainName is the global domain-name option handed to clients.
|
||||
// +optional
|
||||
DomainName string `json:"domainName,omitempty"`
|
||||
|
||||
// DefaultLeaseTime in seconds (valid-lifetime).
|
||||
// +kubebuilder:default=1200
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +optional
|
||||
DefaultLeaseTime int `json:"defaultLeaseTime,omitempty"`
|
||||
|
||||
// MaxLeaseTime in seconds (max-valid-lifetime).
|
||||
// +kubebuilder:default=86400
|
||||
// +kubebuilder:validation:Minimum=1
|
||||
// +optional
|
||||
MaxLeaseTime int `json:"maxLeaseTime,omitempty"`
|
||||
|
||||
// NTPServers are handed to clients as the ntp-servers option.
|
||||
// +optional
|
||||
NTPServers []string `json:"ntpServers,omitempty"`
|
||||
|
||||
// OptionDefs are custom option definitions (e.g. PXE client-arch, code 93).
|
||||
// +optional
|
||||
OptionDefs []OptionDef `json:"optionDefs,omitempty"`
|
||||
|
||||
// HA configures the libdhcp_ha hook between replicas.
|
||||
// +optional
|
||||
HA HASpec `json:"ha,omitempty"`
|
||||
|
||||
// Service configures the anycast LoadBalancer fronting the replicas.
|
||||
// +optional
|
||||
Service ClusterServiceSpec `json:"service,omitempty"`
|
||||
|
||||
// Resources for the kea containers.
|
||||
// +optional
|
||||
Resources corev1.ResourceRequirements `json:"resources,omitempty"`
|
||||
|
||||
// +optional
|
||||
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
|
||||
// +optional
|
||||
Tolerations []corev1.Toleration `json:"tolerations,omitempty"`
|
||||
// +optional
|
||||
Affinity *corev1.Affinity `json:"affinity,omitempty"`
|
||||
}
|
||||
|
||||
// KeaClusterStatus captures the observed state of a KeaCluster.
|
||||
type KeaClusterStatus struct {
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
// +optional
|
||||
Replicas int32 `json:"replicas,omitempty"`
|
||||
// +optional
|
||||
ReadyReplicas int32 `json:"readyReplicas,omitempty"`
|
||||
// ActivePeer is the pod currently acting as the HA primary.
|
||||
// +optional
|
||||
ActivePeer string `json:"activePeer,omitempty"`
|
||||
// ServiceIP is the anycast address assigned to the DHCP Service.
|
||||
// +optional
|
||||
ServiceIP string `json:"serviceIP,omitempty"`
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
// +optional
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:shortName=kc
|
||||
// +kubebuilder:printcolumn:name="Mode",type=string,JSONPath=`.spec.ha.mode`
|
||||
// +kubebuilder:printcolumn:name="Ready",type=integer,JSONPath=`.status.readyReplicas`
|
||||
// +kubebuilder:printcolumn:name="ServiceIP",type=string,JSONPath=`.status.serviceIP`
|
||||
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
|
||||
|
||||
// KeaCluster spawns a StatefulSet of kea-dhcp4 servers with an HA control
|
||||
// channel and an anycast DHCP Service.
|
||||
type KeaCluster struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KeaClusterSpec `json:"spec,omitempty"`
|
||||
Status KeaClusterStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// KeaClusterList contains a list of KeaCluster.
|
||||
type KeaClusterList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KeaCluster `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KeaCluster{}, &KeaClusterList{})
|
||||
}
|
||||
@@ -0,0 +1,121 @@
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
)
|
||||
|
||||
// OptionData is a rendered DHCPv4 option value (subnet- or class-scoped).
|
||||
type OptionData struct {
|
||||
// Name of the option, e.g. "routers", "domain-name-servers".
|
||||
// +optional
|
||||
Name string `json:"name,omitempty"`
|
||||
// Code of the option (alternative to Name).
|
||||
// +optional
|
||||
Code int `json:"code,omitempty"`
|
||||
// Data is the option value(s), comma-separated per Kea convention.
|
||||
Data string `json:"data"`
|
||||
// Space defaults to "dhcp4".
|
||||
// +optional
|
||||
Space string `json:"space,omitempty"`
|
||||
// CSVFormat controls whether Data is parsed as CSV (default true in Kea).
|
||||
// +optional
|
||||
CSVFormat *bool `json:"csvFormat,omitempty"`
|
||||
}
|
||||
|
||||
// KeaSubnetSpec defines a single DHCPv4 subnet served by a KeaCluster.
|
||||
type KeaSubnetSpec struct {
|
||||
// ClusterRef selects the owning KeaCluster by name. Empty means every
|
||||
// KeaCluster in the namespace.
|
||||
// +optional
|
||||
ClusterRef string `json:"clusterRef,omitempty"`
|
||||
|
||||
// Subnet is the CIDR, e.g. "198.18.13.0/24".
|
||||
Subnet string `json:"subnet"`
|
||||
|
||||
// ID is the stable Kea subnet id. When zero the operator assigns one
|
||||
// deterministically from the sorted set of subnets.
|
||||
// +optional
|
||||
ID int `json:"id,omitempty"`
|
||||
|
||||
// Pools are dynamic ranges, e.g. "198.18.13.200 - 198.18.13.220". A subnet
|
||||
// with no pool is still declared so relayed requests on that network are
|
||||
// serviced (matching, option delivery) without dynamic allocation.
|
||||
// +optional
|
||||
Pools []string `json:"pools,omitempty"`
|
||||
|
||||
// Routers is the default-gateway list (routers option).
|
||||
// +optional
|
||||
Routers []string `json:"routers,omitempty"`
|
||||
|
||||
// DNSServers is the domain-name-servers option.
|
||||
// +optional
|
||||
DNSServers []string `json:"dnsServers,omitempty"`
|
||||
|
||||
// DomainName is the per-subnet domain-name option.
|
||||
// +optional
|
||||
DomainName string `json:"domainName,omitempty"`
|
||||
|
||||
// NextServer is the TFTP server address for PXE (siaddr / next-server).
|
||||
// +optional
|
||||
NextServer string `json:"nextServer,omitempty"`
|
||||
|
||||
// BootFileName sets the PXE boot file for this subnet (overridden by class).
|
||||
// +optional
|
||||
BootFileName string `json:"bootFileName,omitempty"`
|
||||
|
||||
// ClientClasses restricts the subnet to the listed client classes.
|
||||
// +optional
|
||||
ClientClasses []string `json:"clientClasses,omitempty"`
|
||||
|
||||
// ValidLifetime overrides the cluster default lease time for this subnet.
|
||||
// +optional
|
||||
ValidLifetime int `json:"validLifetime,omitempty"`
|
||||
|
||||
// OptionData carries any additional option values for the subnet.
|
||||
// +optional
|
||||
OptionData []OptionData `json:"optionData,omitempty"`
|
||||
}
|
||||
|
||||
// KeaSubnetStatus captures observed state.
|
||||
type KeaSubnetStatus struct {
|
||||
// +optional
|
||||
Phase string `json:"phase,omitempty"`
|
||||
// AssignedID is the subnet id that was rendered into kea config.
|
||||
// +optional
|
||||
AssignedID int `json:"assignedID,omitempty"`
|
||||
// +optional
|
||||
ObservedGeneration int64 `json:"observedGeneration,omitempty"`
|
||||
// +listType=map
|
||||
// +listMapKey=type
|
||||
// +optional
|
||||
Conditions []metav1.Condition `json:"conditions,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
// +kubebuilder:subresource:status
|
||||
// +kubebuilder:resource:shortName=ksn
|
||||
// +kubebuilder:printcolumn:name="Cluster",type=string,JSONPath=`.spec.clusterRef`
|
||||
// +kubebuilder:printcolumn:name="Subnet",type=string,JSONPath=`.spec.subnet`
|
||||
// +kubebuilder:printcolumn:name="Phase",type=string,JSONPath=`.status.phase`
|
||||
|
||||
// KeaSubnet is one DHCPv4 subnet declaration referenced to a KeaCluster.
|
||||
type KeaSubnet struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ObjectMeta `json:"metadata,omitempty"`
|
||||
|
||||
Spec KeaSubnetSpec `json:"spec,omitempty"`
|
||||
Status KeaSubnetStatus `json:"status,omitempty"`
|
||||
}
|
||||
|
||||
// +kubebuilder:object:root=true
|
||||
|
||||
// KeaSubnetList contains a list of KeaSubnet.
|
||||
type KeaSubnetList struct {
|
||||
metav1.TypeMeta `json:",inline"`
|
||||
metav1.ListMeta `json:"metadata,omitempty"`
|
||||
Items []KeaSubnet `json:"items"`
|
||||
}
|
||||
|
||||
func init() {
|
||||
SchemeBuilder.Register(&KeaSubnet{}, &KeaSubnetList{})
|
||||
}
|
||||
@@ -0,0 +1,596 @@
|
||||
//go:build !ignore_autogenerated
|
||||
|
||||
// Code generated by controller-gen. DO NOT EDIT.
|
||||
|
||||
package v1alpha1
|
||||
|
||||
import (
|
||||
"k8s.io/api/core/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
runtime "k8s.io/apimachinery/pkg/runtime"
|
||||
)
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *ClusterServiceSpec) DeepCopyInto(out *ClusterServiceSpec) {
|
||||
*out = *in
|
||||
if in.LoadBalancerClass != nil {
|
||||
in, out := &in.LoadBalancerClass, &out.LoadBalancerClass
|
||||
*out = new(string)
|
||||
**out = **in
|
||||
}
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ClusterServiceSpec.
|
||||
func (in *ClusterServiceSpec) DeepCopy() *ClusterServiceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(ClusterServiceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *HASpec) DeepCopyInto(out *HASpec) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new HASpec.
|
||||
func (in *HASpec) DeepCopy() *HASpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(HASpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaAPI) DeepCopyInto(out *KeaAPI) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaAPI.
|
||||
func (in *KeaAPI) DeepCopy() *KeaAPI {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaAPI)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KeaAPI) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaAPIList) DeepCopyInto(out *KeaAPIList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KeaAPI, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaAPIList.
|
||||
func (in *KeaAPIList) DeepCopy() *KeaAPIList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaAPIList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KeaAPIList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaAPIServiceSpec) DeepCopyInto(out *KeaAPIServiceSpec) {
|
||||
*out = *in
|
||||
if in.Annotations != nil {
|
||||
in, out := &in.Annotations, &out.Annotations
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaAPIServiceSpec.
|
||||
func (in *KeaAPIServiceSpec) DeepCopy() *KeaAPIServiceSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaAPIServiceSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaAPISpec) DeepCopyInto(out *KeaAPISpec) {
|
||||
*out = *in
|
||||
if in.Replicas != nil {
|
||||
in, out := &in.Replicas, &out.Replicas
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
in.Service.DeepCopyInto(&out.Service)
|
||||
in.Resources.DeepCopyInto(&out.Resources)
|
||||
if in.NodeSelector != nil {
|
||||
in, out := &in.NodeSelector, &out.NodeSelector
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Tolerations != nil {
|
||||
in, out := &in.Tolerations, &out.Tolerations
|
||||
*out = make([]v1.Toleration, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Affinity != nil {
|
||||
in, out := &in.Affinity, &out.Affinity
|
||||
*out = new(v1.Affinity)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaAPISpec.
|
||||
func (in *KeaAPISpec) DeepCopy() *KeaAPISpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaAPISpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaAPIStatus) DeepCopyInto(out *KeaAPIStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]metav1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaAPIStatus.
|
||||
func (in *KeaAPIStatus) DeepCopy() *KeaAPIStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaAPIStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaClientClass) DeepCopyInto(out *KeaClientClass) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaClientClass.
|
||||
func (in *KeaClientClass) DeepCopy() *KeaClientClass {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaClientClass)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KeaClientClass) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaClientClassList) DeepCopyInto(out *KeaClientClassList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KeaClientClass, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaClientClassList.
|
||||
func (in *KeaClientClassList) DeepCopy() *KeaClientClassList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaClientClassList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KeaClientClassList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaClientClassSpec) DeepCopyInto(out *KeaClientClassSpec) {
|
||||
*out = *in
|
||||
if in.ArchHex != nil {
|
||||
in, out := &in.ArchHex, &out.ArchHex
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.OptionData != nil {
|
||||
in, out := &in.OptionData, &out.OptionData
|
||||
*out = make([]OptionData, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaClientClassSpec.
|
||||
func (in *KeaClientClassSpec) DeepCopy() *KeaClientClassSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaClientClassSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaClientClassStatus) DeepCopyInto(out *KeaClientClassStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]metav1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaClientClassStatus.
|
||||
func (in *KeaClientClassStatus) DeepCopy() *KeaClientClassStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaClientClassStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaCluster) DeepCopyInto(out *KeaCluster) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaCluster.
|
||||
func (in *KeaCluster) DeepCopy() *KeaCluster {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaCluster)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KeaCluster) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaClusterList) DeepCopyInto(out *KeaClusterList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KeaCluster, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaClusterList.
|
||||
func (in *KeaClusterList) DeepCopy() *KeaClusterList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaClusterList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KeaClusterList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaClusterSpec) DeepCopyInto(out *KeaClusterSpec) {
|
||||
*out = *in
|
||||
if in.Replicas != nil {
|
||||
in, out := &in.Replicas, &out.Replicas
|
||||
*out = new(int32)
|
||||
**out = **in
|
||||
}
|
||||
if in.NTPServers != nil {
|
||||
in, out := &in.NTPServers, &out.NTPServers
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.OptionDefs != nil {
|
||||
in, out := &in.OptionDefs, &out.OptionDefs
|
||||
*out = make([]OptionDef, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
out.HA = in.HA
|
||||
in.Service.DeepCopyInto(&out.Service)
|
||||
in.Resources.DeepCopyInto(&out.Resources)
|
||||
if in.NodeSelector != nil {
|
||||
in, out := &in.NodeSelector, &out.NodeSelector
|
||||
*out = make(map[string]string, len(*in))
|
||||
for key, val := range *in {
|
||||
(*out)[key] = val
|
||||
}
|
||||
}
|
||||
if in.Tolerations != nil {
|
||||
in, out := &in.Tolerations, &out.Tolerations
|
||||
*out = make([]v1.Toleration, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
if in.Affinity != nil {
|
||||
in, out := &in.Affinity, &out.Affinity
|
||||
*out = new(v1.Affinity)
|
||||
(*in).DeepCopyInto(*out)
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaClusterSpec.
|
||||
func (in *KeaClusterSpec) DeepCopy() *KeaClusterSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaClusterSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaClusterStatus) DeepCopyInto(out *KeaClusterStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]metav1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaClusterStatus.
|
||||
func (in *KeaClusterStatus) DeepCopy() *KeaClusterStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaClusterStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaSubnet) DeepCopyInto(out *KeaSubnet) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ObjectMeta.DeepCopyInto(&out.ObjectMeta)
|
||||
in.Spec.DeepCopyInto(&out.Spec)
|
||||
in.Status.DeepCopyInto(&out.Status)
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaSubnet.
|
||||
func (in *KeaSubnet) DeepCopy() *KeaSubnet {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaSubnet)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KeaSubnet) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaSubnetList) DeepCopyInto(out *KeaSubnetList) {
|
||||
*out = *in
|
||||
out.TypeMeta = in.TypeMeta
|
||||
in.ListMeta.DeepCopyInto(&out.ListMeta)
|
||||
if in.Items != nil {
|
||||
in, out := &in.Items, &out.Items
|
||||
*out = make([]KeaSubnet, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaSubnetList.
|
||||
func (in *KeaSubnetList) DeepCopy() *KeaSubnetList {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaSubnetList)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object.
|
||||
func (in *KeaSubnetList) DeepCopyObject() runtime.Object {
|
||||
if c := in.DeepCopy(); c != nil {
|
||||
return c
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaSubnetSpec) DeepCopyInto(out *KeaSubnetSpec) {
|
||||
*out = *in
|
||||
if in.Pools != nil {
|
||||
in, out := &in.Pools, &out.Pools
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.Routers != nil {
|
||||
in, out := &in.Routers, &out.Routers
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.DNSServers != nil {
|
||||
in, out := &in.DNSServers, &out.DNSServers
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.ClientClasses != nil {
|
||||
in, out := &in.ClientClasses, &out.ClientClasses
|
||||
*out = make([]string, len(*in))
|
||||
copy(*out, *in)
|
||||
}
|
||||
if in.OptionData != nil {
|
||||
in, out := &in.OptionData, &out.OptionData
|
||||
*out = make([]OptionData, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaSubnetSpec.
|
||||
func (in *KeaSubnetSpec) DeepCopy() *KeaSubnetSpec {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaSubnetSpec)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *KeaSubnetStatus) DeepCopyInto(out *KeaSubnetStatus) {
|
||||
*out = *in
|
||||
if in.Conditions != nil {
|
||||
in, out := &in.Conditions, &out.Conditions
|
||||
*out = make([]metav1.Condition, len(*in))
|
||||
for i := range *in {
|
||||
(*in)[i].DeepCopyInto(&(*out)[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new KeaSubnetStatus.
|
||||
func (in *KeaSubnetStatus) DeepCopy() *KeaSubnetStatus {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(KeaSubnetStatus)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OptionData) DeepCopyInto(out *OptionData) {
|
||||
*out = *in
|
||||
if in.CSVFormat != nil {
|
||||
in, out := &in.CSVFormat, &out.CSVFormat
|
||||
*out = new(bool)
|
||||
**out = **in
|
||||
}
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OptionData.
|
||||
func (in *OptionData) DeepCopy() *OptionData {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OptionData)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
|
||||
// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil.
|
||||
func (in *OptionDef) DeepCopyInto(out *OptionDef) {
|
||||
*out = *in
|
||||
}
|
||||
|
||||
// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new OptionDef.
|
||||
func (in *OptionDef) DeepCopy() *OptionDef {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := new(OptionDef)
|
||||
in.DeepCopyInto(out)
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user