Skip to content

Commit

Permalink
Introduce bindings for ExternalWorkload resources
Browse files Browse the repository at this point in the history
We introduced an ExternalWorkload CRD for mesh expansion. This change
follows up by adding bindings for Rust and Go code.

For Go code:
* We add a new schema and ExternalWorkload types
* We also update the code-gen script to generate informers
* We add a new informer type to our abstractions built on-top of
  client-go, including a function to check if a client has access to the
  resource.

For Rust code:
* We add ExternalWorkload bindings to the policy controller.

Signed-off-by: Matei David <[email protected]>
  • Loading branch information
mateiidavid committed Jan 5, 2024
1 parent 31e1334 commit 9a1e046
Show file tree
Hide file tree
Showing 30 changed files with 1,405 additions and 7 deletions.
2 changes: 1 addition & 1 deletion bin/update-codegen.sh
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ CODEGEN_PKG=${GOPATH}/pkg/mod/k8s.io/code-generator@${GEN_VER}
rm -rf "${SCRIPT_ROOT}/controller/gen/client/clientset/*"
rm -rf "${SCRIPT_ROOT}/controller/gen/client/listeners/*"
rm -rf "${SCRIPT_ROOT}/controller/gen/client/informers/*"
crds=(serviceprofile:v1alpha2 server:v1beta1 serverauthorization:v1beta1 link:v1alpha1 policy:v1alpha1 policy:v1beta3)
crds=(serviceprofile:v1alpha2 server:v1beta1 serverauthorization:v1beta1 link:v1alpha1 policy:v1alpha1 policy:v1beta3 externalworkload:v1alpha1)
for crd in "${crds[@]}"
do
crd_path=$(tr : / <<< "$crd")
Expand Down
4 changes: 4 additions & 0 deletions controller/gen/apis/externalworkload/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
package externalworkload

// GroupName identifies the API Group name for an ExternalWorkload
const GroupName = "workload.linkerd.io"
3 changes: 3 additions & 0 deletions controller/gen/apis/externalworkload/v1alpha1/doc.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
// +k8s:deepcopy-gen=package

package v1alpha1
49 changes: 49 additions & 0 deletions controller/gen/apis/externalworkload/v1alpha1/register.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package v1alpha1

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"

"github.com/linkerd/linkerd2/controller/gen/apis/externalworkload"
)

var (
// SchemeGroupVersion is the identifier for the API which includes the name
// of the group and the version of the API.
SchemeGroupVersion = schema.GroupVersion{
Group: externalworkload.GroupName,
Version: "v1alpha1",
}

// SchemeBuilder collects functions that add things to a scheme. It's to
// allow code to compile without explicitly referencing generated types.
// You should declare one in each package that will have generated deep
// copy or conversion functions.
SchemeBuilder = runtime.NewSchemeBuilder(addKnownTypes)

// AddToScheme applies all the stored functions to the scheme. A non-nil error
// indicates that one function failed and the attempt was abandoned.
AddToScheme = SchemeBuilder.AddToScheme
)

// Kind takes an unqualified kind and returns back a Group qualified GroupKind
func Kind(kind string) schema.GroupKind {
return SchemeGroupVersion.WithKind(kind).GroupKind()
}

// Resource takes an unqualified resource and returns a Group qualified
// GroupResource
func Resource(resource string) schema.GroupResource {
return SchemeGroupVersion.WithResource(resource).GroupResource()
}

// Adds the list of known types to Scheme.
func addKnownTypes(scheme *runtime.Scheme) error {
scheme.AddKnownTypes(SchemeGroupVersion,
&ExternalWorkload{},
&ExternalWorkloadList{},
)
metav1.AddToGroupVersion(scheme, SchemeGroupVersion)
return nil
}
136 changes: 136 additions & 0 deletions controller/gen/apis/externalworkload/v1alpha1/types.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,136 @@
package v1alpha1

import (
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

// +genclient
// +genclient:noStatus
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
// +groupName=workload.linkerd.io

// ExternalWorkload describes a single workload (i.e. a deployable unit,
// conceptually similar to a Kubernetes Pod) that is running outside of a
// Kubernetes cluster. An ExternalWorkload should be enrolled in the mesh and
// typically represents a virtual machine.
type ExternalWorkload struct {
// TypeMeta is the metadata for the resource, like kind and apiversion
metav1.TypeMeta `json:",inline"`
// ObjectMeta contains the metadata for the particular object, including
// things like...
// - name
// - namespace
// - self link
// - labels
// - ... etc ...
metav1.ObjectMeta `json:"metadata,omitempty"`

// Spec defines the desired state of an external workload instance
Spec ExternalWorkloadSpec `json:"spec"`

// Status defines the current state of an external workload instance
Status ExternalWorkloadStatus `json:"status,omitempty"`
}

// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object

// ExternalWorkloadList contains a list of ExternalWorkload resources.
type ExternalWorkloadList struct {
metav1.TypeMeta `json:",inline"`
metav1.ListMeta `json:"metadata"`

Items []ExternalWorkload `json:"items"`
}

// ExternalWorkloadSpec represents the desired state of an external workload
type ExternalWorkloadSpec struct {
// MeshTls describes TLS settings associated with an external workload
//
// +optional
MeshTls MeshTls `json:"meshTls,omitempty"`
// Ports describes a set of ports exposed by the workload
Ports []PortSpec `json:"ports"`
// List of IP addresses that can be used to send traffic to an external
// workload
WorkloadIPs []WorkloadIP `json:"workloadIPs"`
}

// MeshTls describes TLS settings associated with an external workload
type MeshTls struct {
// Identity associated with the workload. Used by peers to perform
// verification in the mTLS handshake
Identity string `json:"identity,omitempty"`
// ServerName is the DNS formatted name associated with the workload. Used
// to terminate TLS using the SNI extension.
ServerName string `json:"serverName,omitempty"`
}

// PortSpec represents a network port in a single workload.
type PortSpec struct {
// If specified, must be an IANA_SVC_NAME and unique within the exposed
// ports set. Each named port must have a unique name. The name may be
// referred to by services
// +optional
Name string `json:"name,omitempty"`
// Number of port exposed on the workload's IP address.
// Must be a valid port number, i.e. 0 < x < 65536.
Port int32 `json:"port"`
// Protocol defines network protocols supported. One of UDP, TCP, or SCTP.
// Should coincide with Service selecting the workload.
// Defaults to "TCP" if unspecified.
// +optional
// +default="TCP"
Protocol v1.Protocol `json:"protocol,omitempty"`
}

// WorkloadIPs contains a list of IP addresses exposed by an ExternalWorkload
type WorkloadIP struct {
Ip string `json:"ip"`
}

// WorkloadStatus holds information about the status of an external workload.
// The status describes the state of the workload.
type ExternalWorkloadStatus struct {
// Current service state of an ExternalWorkload
// +optional
Conditions []WorkloadCondition `json:"conditions,omitempty"`
}

// WorkloadCondition represents the service state of an ExternalWorkload
type WorkloadCondition struct {
// Type of the condition
// see: https://kubernetes.io/docs/concepts/workloads/pods/pod-lifecycle#pod-conditions
Type WorkloadConditionType `json:"type"`
// Status of the condition.
// Can be True, False, Unknown
Status WorkloadConditionStatus `json:"status"`
// Last time an ExternalWorkload was probed for a condition.
// +optional
LastProbeTime metav1.Time `json:"lastProbeTime,omitempty"`
// Last time a condition transitioned from one status to another.
LastTransitionTime metav1.Time `json:"lastTransitionTime"`
// Unique one word reason in CamelCase that describes the reason for a
// transition.
Reason string `json:"reason"`
// Human readable message that describes details about last transition.
Message string `json:"message"`
}

// WorkloadConditionType is a value for the type of a condition in an
// ExternalWorkload's status
type WorkloadConditionType string

const (
// Ready to serve traffic
WorkloadReady WorkloadConditionType = "Ready"
)

// WorkloadConditionStatus
type WorkloadConditionStatus string

const (
ConditionTrue WorkloadConditionStatus = "True"
ConditionFalse WorkloadConditionStatus = "False"
ConditionUnknown WorkloadConditionStatus = "Unknown"
)
Loading

0 comments on commit 9a1e046

Please sign in to comment.