cmd/k8s-operator: include peer relay CRD in generation (#20593)
This commit modifies the generation command for the kubernetes operator to include the CRD for peer relays in the helm chart and static manifests Updates: #fixup Signed-off-by: David Bond <davidsbond93@gmail.com>
This commit is contained in:
@@ -10,3 +10,4 @@
|
|||||||
/recorder.yaml
|
/recorder.yaml
|
||||||
/tailnet.yaml
|
/tailnet.yaml
|
||||||
/proxygrouppolicy.yaml
|
/proxygrouppolicy.yaml
|
||||||
|
/peerrelay.yaml
|
||||||
|
|||||||
@@ -1463,6 +1463,271 @@ spec:
|
|||||||
---
|
---
|
||||||
apiVersion: apiextensions.k8s.io/v1
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
kind: CustomResourceDefinition
|
kind: CustomResourceDefinition
|
||||||
|
metadata:
|
||||||
|
annotations:
|
||||||
|
controller-gen.kubebuilder.io/version: v0.17.0
|
||||||
|
name: peerrelays.tailscale.com
|
||||||
|
spec:
|
||||||
|
group: tailscale.com
|
||||||
|
names:
|
||||||
|
kind: PeerRelay
|
||||||
|
listKind: PeerRelayList
|
||||||
|
plural: peerrelays
|
||||||
|
shortNames:
|
||||||
|
- pr
|
||||||
|
singular: peerrelay
|
||||||
|
scope: Cluster
|
||||||
|
versions:
|
||||||
|
- additionalPrinterColumns:
|
||||||
|
- jsonPath: .metadata.creationTimestamp
|
||||||
|
name: Age
|
||||||
|
type: date
|
||||||
|
- description: Status of the deployed PeerRelay resources.
|
||||||
|
jsonPath: .status.conditions[?(@.type == "PeerRelayReady")].reason
|
||||||
|
name: Status
|
||||||
|
type: string
|
||||||
|
- description: Public addresses the peer relay replicas are reachable on.
|
||||||
|
jsonPath: .status.endpoints[*].address
|
||||||
|
name: Endpoints
|
||||||
|
type: string
|
||||||
|
name: v1alpha1
|
||||||
|
schema:
|
||||||
|
openAPIV3Schema:
|
||||||
|
properties:
|
||||||
|
apiVersion:
|
||||||
|
description: |-
|
||||||
|
APIVersion defines the versioned schema of this representation of an object.
|
||||||
|
Servers should convert recognized schemas to the latest internal value, and
|
||||||
|
may reject unrecognized values.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources
|
||||||
|
type: string
|
||||||
|
kind:
|
||||||
|
description: |-
|
||||||
|
Kind is a string value representing the REST resource this object represents.
|
||||||
|
Servers may infer this from the endpoint the client submits requests to.
|
||||||
|
Cannot be updated.
|
||||||
|
In CamelCase.
|
||||||
|
More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds
|
||||||
|
type: string
|
||||||
|
metadata:
|
||||||
|
type: object
|
||||||
|
spec:
|
||||||
|
description: |-
|
||||||
|
Spec describes the desired state of the PeerRelay.
|
||||||
|
More info:
|
||||||
|
https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#spec-and-status
|
||||||
|
properties:
|
||||||
|
aws:
|
||||||
|
description: |-
|
||||||
|
AWS contains configuration for pinning each replica to a specific AWS Elastic IP and subnet. Only meaningful
|
||||||
|
when running on EKS with the AWS Load Balancer Controller. When set, the per-replica values override any
|
||||||
|
aws-load-balancer-eip-allocations or aws-load-balancer-subnets values supplied via spec.service.annotations.
|
||||||
|
properties:
|
||||||
|
elasticIPs:
|
||||||
|
description: |-
|
||||||
|
ElasticIPs pins each replica to a specific AWS EIP allocation and subnet. Only meaningful when Network Load
|
||||||
|
Balancers are provisioned by the AWS Load Balancer Controller. ElasticIPs supplies one allocation-subnet pair
|
||||||
|
per replica: replica N uses ElasticIPs[N]. The list must be at least as long as spec.replicas so every replica
|
||||||
|
has a distinct EIP; extra entries are permitted so that scale-up doesn't immediately trip validation.
|
||||||
|
|
||||||
|
When set, the reconciler stamps
|
||||||
|
service.beta.kubernetes.io/aws-load-balancer-eip-allocations and
|
||||||
|
service.beta.kubernetes.io/aws-load-balancer-subnets on each per-replica Service, overriding any values in
|
||||||
|
spec.service.annotations.
|
||||||
|
items:
|
||||||
|
description: PeerRelayAWSElasticIP pairs an EIP allocation with the subnet in the same AZ.
|
||||||
|
properties:
|
||||||
|
allocationID:
|
||||||
|
description: |-
|
||||||
|
AllocationID is the AWS EIP allocation ID (e.g. eipalloc-0123abcd) whose public IP this replica is reachable
|
||||||
|
on. Stamped as service.beta.kubernetes.io/aws-load-balancer-eip-allocations on the replica's Service.
|
||||||
|
pattern: ^eipalloc-[0-9a-f]+$
|
||||||
|
type: string
|
||||||
|
subnetID:
|
||||||
|
description: |-
|
||||||
|
SubnetID is the AWS subnet in the same availability zone as AllocationID (e.g. subnet-0123abcd). Stamped as
|
||||||
|
service.beta.kubernetes.io/aws-load-balancer-subnets on the replica's Service so the NLB is provisioned in
|
||||||
|
the same AZ as the EIP.
|
||||||
|
pattern: ^subnet-[0-9a-f]+$
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- allocationID
|
||||||
|
- subnetID
|
||||||
|
type: object
|
||||||
|
minItems: 1
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-type: atomic
|
||||||
|
required:
|
||||||
|
- elasticIPs
|
||||||
|
type: object
|
||||||
|
hostnamePrefix:
|
||||||
|
description: |-
|
||||||
|
HostnamePrefix specifies the hostname prefix for each
|
||||||
|
replica. Each device will have the integer number
|
||||||
|
from its StatefulSet pod appended to this prefix to form the full hostname.
|
||||||
|
HostnamePrefix can contain lower case letters, numbers and dashes, it
|
||||||
|
must not start with a dash and must be between 1 and 62 characters long.
|
||||||
|
pattern: ^[a-z0-9][a-z0-9-]{0,61}$
|
||||||
|
type: string
|
||||||
|
proxyClass:
|
||||||
|
description: |-
|
||||||
|
ProxyClass is the name of the ProxyClass custom resource that
|
||||||
|
contains configuration options that should be applied to the
|
||||||
|
resources created for this PeerRelay. If unset, the operator will
|
||||||
|
create resources with the default configuration.
|
||||||
|
type: string
|
||||||
|
replicas:
|
||||||
|
default: 1
|
||||||
|
description: |-
|
||||||
|
Replicas specifies how many devices to create. Set this to enable
|
||||||
|
high availability for peer relays.
|
||||||
|
https://tailscale.com/kb/1115/high-availability. Defaults to 1.
|
||||||
|
format: int32
|
||||||
|
minimum: 0
|
||||||
|
type: integer
|
||||||
|
service:
|
||||||
|
description: Service contains configuration values to modify the LoadBalancer service used to expose the peer relay.
|
||||||
|
properties:
|
||||||
|
annotations:
|
||||||
|
additionalProperties:
|
||||||
|
type: string
|
||||||
|
description: |-
|
||||||
|
Annotations to apply to the LoadBalancer service. Any annotations that conflict with those used by known
|
||||||
|
cloud providers to ensure IP addresses rather than DNS names are ignored.
|
||||||
|
type: object
|
||||||
|
type: object
|
||||||
|
tags:
|
||||||
|
description: |-
|
||||||
|
Tags that the Tailscale node will be tagged with.
|
||||||
|
Defaults to [tag:k8s].
|
||||||
|
To autoapprove the device defined by a PeerRelay,
|
||||||
|
you can configure Tailscale ACLs to give these tags the necessary
|
||||||
|
permissions.
|
||||||
|
See https://tailscale.com/kb/1337/acl-syntax#autoapprovers.
|
||||||
|
If you specify custom tags here, you must also make the operator an owner of these tags.
|
||||||
|
See https://tailscale.com/kb/1236/kubernetes-operator/#setting-up-the-kubernetes-operator.
|
||||||
|
Tags cannot be changed once a PeerRelay node has been created.
|
||||||
|
Tag values must be in form ^tag:[a-zA-Z][a-zA-Z0-9-]*$.
|
||||||
|
items:
|
||||||
|
pattern: ^tag:[a-zA-Z][a-zA-Z0-9-]*$
|
||||||
|
type: string
|
||||||
|
type: array
|
||||||
|
tailnet:
|
||||||
|
description: |-
|
||||||
|
Tailnet specifies the tailnet this PeerRelay should join. If blank, the default tailnet is used. When set, this
|
||||||
|
name must match that of a valid Tailnet resource. This field is immutable and cannot be changed once set.
|
||||||
|
type: string
|
||||||
|
x-kubernetes-validations:
|
||||||
|
- message: PeerRelay tailnet is immutable
|
||||||
|
rule: self == oldSelf
|
||||||
|
type: object
|
||||||
|
x-kubernetes-validations:
|
||||||
|
- message: spec.aws.elasticIPs must contain at least one entry per replica
|
||||||
|
rule: '!has(self.aws) || !has(self.aws.elasticIPs) || self.aws.elasticIPs.size() >= self.replicas'
|
||||||
|
status:
|
||||||
|
description: |-
|
||||||
|
Status describes the status of the PeerRelay. This is set
|
||||||
|
and managed by the Tailscale operator.
|
||||||
|
properties:
|
||||||
|
conditions:
|
||||||
|
items:
|
||||||
|
description: Condition contains details for one aspect of the current state of this API Resource.
|
||||||
|
properties:
|
||||||
|
lastTransitionTime:
|
||||||
|
description: |-
|
||||||
|
lastTransitionTime is the last time the condition transitioned from one status to another.
|
||||||
|
This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable.
|
||||||
|
format: date-time
|
||||||
|
type: string
|
||||||
|
message:
|
||||||
|
description: |-
|
||||||
|
message is a human readable message indicating details about the transition.
|
||||||
|
This may be an empty string.
|
||||||
|
maxLength: 32768
|
||||||
|
type: string
|
||||||
|
observedGeneration:
|
||||||
|
description: |-
|
||||||
|
observedGeneration represents the .metadata.generation that the condition was set based upon.
|
||||||
|
For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date
|
||||||
|
with respect to the current state of the instance.
|
||||||
|
format: int64
|
||||||
|
minimum: 0
|
||||||
|
type: integer
|
||||||
|
reason:
|
||||||
|
description: |-
|
||||||
|
reason contains a programmatic identifier indicating the reason for the condition's last transition.
|
||||||
|
Producers of specific condition types may define expected values and meanings for this field,
|
||||||
|
and whether the values are considered a guaranteed API.
|
||||||
|
The value should be a CamelCase string.
|
||||||
|
This field may not be empty.
|
||||||
|
maxLength: 1024
|
||||||
|
minLength: 1
|
||||||
|
pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$
|
||||||
|
type: string
|
||||||
|
status:
|
||||||
|
description: status of the condition, one of True, False, Unknown.
|
||||||
|
enum:
|
||||||
|
- "True"
|
||||||
|
- "False"
|
||||||
|
- Unknown
|
||||||
|
type: string
|
||||||
|
type:
|
||||||
|
description: type of condition in CamelCase or in foo.example.com/CamelCase.
|
||||||
|
maxLength: 316
|
||||||
|
pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$
|
||||||
|
type: string
|
||||||
|
required:
|
||||||
|
- lastTransitionTime
|
||||||
|
- message
|
||||||
|
- reason
|
||||||
|
- status
|
||||||
|
- type
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- type
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
endpoints:
|
||||||
|
description: |-
|
||||||
|
Endpoints lists the public address:port pairs each peer relay replica is reachable on. There is one entry
|
||||||
|
per replica whose LoadBalancer Service has been assigned a public address; entries appear as the underlying
|
||||||
|
cloud provisions each Service.
|
||||||
|
items:
|
||||||
|
properties:
|
||||||
|
address:
|
||||||
|
description: |-
|
||||||
|
Address is the public IP or hostname the cloud has allocated for this replica's LoadBalancer Service.
|
||||||
|
Peers reach this relay by connecting to Address:Port over UDP.
|
||||||
|
type: string
|
||||||
|
port:
|
||||||
|
description: Port is the UDP port the peer relay listens on.
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
replica:
|
||||||
|
description: Replica is the zero-based index of the peer relay replica this endpoint targets.
|
||||||
|
format: int32
|
||||||
|
type: integer
|
||||||
|
required:
|
||||||
|
- address
|
||||||
|
- port
|
||||||
|
- replica
|
||||||
|
type: object
|
||||||
|
type: array
|
||||||
|
x-kubernetes-list-map-keys:
|
||||||
|
- replica
|
||||||
|
x-kubernetes-list-type: map
|
||||||
|
type: object
|
||||||
|
required:
|
||||||
|
- metadata
|
||||||
|
- spec
|
||||||
|
type: object
|
||||||
|
served: true
|
||||||
|
storage: true
|
||||||
|
subresources:
|
||||||
|
status: {}
|
||||||
|
---
|
||||||
|
apiVersion: apiextensions.k8s.io/v1
|
||||||
|
kind: CustomResourceDefinition
|
||||||
metadata:
|
metadata:
|
||||||
annotations:
|
annotations:
|
||||||
controller-gen.kubebuilder.io/version: v0.17.0
|
controller-gen.kubebuilder.io/version: v0.17.0
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ const (
|
|||||||
proxyGroupCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_proxygroups.yaml"
|
proxyGroupCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_proxygroups.yaml"
|
||||||
tailnetCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_tailnets.yaml"
|
tailnetCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_tailnets.yaml"
|
||||||
proxyGroupPolicyCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_proxygrouppolicies.yaml"
|
proxyGroupPolicyCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_proxygrouppolicies.yaml"
|
||||||
|
peerRelayCRDPath = operatorDeploymentFilesPath + "/crds/tailscale.com_peerrelays.yaml"
|
||||||
helmTemplatesPath = operatorDeploymentFilesPath + "/chart/templates"
|
helmTemplatesPath = operatorDeploymentFilesPath + "/chart/templates"
|
||||||
connectorCRDHelmTemplatePath = helmTemplatesPath + "/connector.yaml"
|
connectorCRDHelmTemplatePath = helmTemplatesPath + "/connector.yaml"
|
||||||
proxyClassCRDHelmTemplatePath = helmTemplatesPath + "/proxyclass.yaml"
|
proxyClassCRDHelmTemplatePath = helmTemplatesPath + "/proxyclass.yaml"
|
||||||
@@ -36,6 +37,7 @@ const (
|
|||||||
proxyGroupCRDHelmTemplatePath = helmTemplatesPath + "/proxygroup.yaml"
|
proxyGroupCRDHelmTemplatePath = helmTemplatesPath + "/proxygroup.yaml"
|
||||||
tailnetCRDHelmTemplatePath = helmTemplatesPath + "/tailnet.yaml"
|
tailnetCRDHelmTemplatePath = helmTemplatesPath + "/tailnet.yaml"
|
||||||
proxyGroupPolicyCRDHelmTemplatePath = helmTemplatesPath + "/proxygrouppolicy.yaml"
|
proxyGroupPolicyCRDHelmTemplatePath = helmTemplatesPath + "/proxygrouppolicy.yaml"
|
||||||
|
peerRelayCRDHelmTemplatePath = helmTemplatesPath + "/peerrelay.yaml"
|
||||||
|
|
||||||
helmConditionalStart = "{{ if .Values.installCRDs -}}\n"
|
helmConditionalStart = "{{ if .Values.installCRDs -}}\n"
|
||||||
helmConditionalEnd = "{{- end -}}"
|
helmConditionalEnd = "{{- end -}}"
|
||||||
@@ -160,6 +162,7 @@ func generate(baseDir string) error {
|
|||||||
{proxyGroupCRDPath, proxyGroupCRDHelmTemplatePath},
|
{proxyGroupCRDPath, proxyGroupCRDHelmTemplatePath},
|
||||||
{tailnetCRDPath, tailnetCRDHelmTemplatePath},
|
{tailnetCRDPath, tailnetCRDHelmTemplatePath},
|
||||||
{proxyGroupPolicyCRDPath, proxyGroupPolicyCRDHelmTemplatePath},
|
{proxyGroupPolicyCRDPath, proxyGroupPolicyCRDHelmTemplatePath},
|
||||||
|
{peerRelayCRDPath, peerRelayCRDHelmTemplatePath},
|
||||||
} {
|
} {
|
||||||
if err := addCRDToHelm(crd.crdPath, crd.templatePath); err != nil {
|
if err := addCRDToHelm(crd.crdPath, crd.templatePath); err != nil {
|
||||||
return fmt.Errorf("error adding %s CRD to Helm templates: %w", crd.crdPath, err)
|
return fmt.Errorf("error adding %s CRD to Helm templates: %w", crd.crdPath, err)
|
||||||
@@ -178,6 +181,7 @@ func cleanup(baseDir string) error {
|
|||||||
proxyGroupCRDHelmTemplatePath,
|
proxyGroupCRDHelmTemplatePath,
|
||||||
tailnetCRDHelmTemplatePath,
|
tailnetCRDHelmTemplatePath,
|
||||||
proxyGroupPolicyCRDHelmTemplatePath,
|
proxyGroupPolicyCRDHelmTemplatePath,
|
||||||
|
peerRelayCRDHelmTemplatePath,
|
||||||
} {
|
} {
|
||||||
if err := os.Remove(filepath.Join(baseDir, path)); err != nil && !os.IsNotExist(err) {
|
if err := os.Remove(filepath.Join(baseDir, path)); err != nil && !os.IsNotExist(err) {
|
||||||
return fmt.Errorf("error cleaning up %s: %w", path, err)
|
return fmt.Errorf("error cleaning up %s: %w", path, err)
|
||||||
|
|||||||
Reference in New Issue
Block a user