Skip to content

Commit

Permalink
feat: populate addresses and hostname in ServerBindings
Browse files Browse the repository at this point in the history
Get addresses from the events coming into events sink container.

Add v1beta1 support.
Update `metalmachine_controller` to set providerID earlier and add
ProviderSet condition to be set after the cluster nodes actually get
patched with the provider ID as well.

The condition is required to trigger reconcile on CAPI `machines`,
otherwise it never picks `Node` ready condition.

Signed-off-by: Artem Chernyshev <artem.chernyshev@talos-systems.com>
  • Loading branch information
Unix4ever committed Dec 27, 2021
1 parent d69264f commit 6454dee
Show file tree
Hide file tree
Showing 39 changed files with 772 additions and 403 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ package v1alpha3

import (
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
capiv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
)

const (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
// This Source Code Form is subject to the terms of the Mozilla Public
// License, v. 2.0. If a copy of the MPL was not distributed with this
// file, You can obtain one at http://mozilla.org/MPL/2.0/.

// +kubebuilder:object:generate=true
// +groupName=controlplane.cluster.x-k8s.io
package v1alpha3

import clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"

// Conditions and condition Reasons for the TalosControlPlane object

const (
// ProviderSetCondition reports when the nodes have .spec.Provider ID field set.
ProviderSetCondition clusterv1.ConditionType = "ProviderSet"

// ProviderUpdateFailedReason (Severity=Warning) documents that controller failed
// to set ProviderID labels on all nodes.
ProviderUpdateFailedReason = "ProviderUpdateFailed"
)
21 changes: 20 additions & 1 deletion app/caps-controller-manager/api/v1alpha3/metalmachine_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ package v1alpha3
import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
"sigs.k8s.io/cluster-api/errors"
)

Expand All @@ -29,7 +30,11 @@ type MetalMachineSpec struct {

// MetalMachineStatus defines the observed state of MetalMachine.
type MetalMachineStatus struct {
Ready bool `json:"ready"`
// +optional
Ready bool `json:"ready,omitempty"`

// Addresses contains the Metal machine associated addresses.
Addresses []clusterv1.MachineAddress `json:"addresses,omitempty"`

// FailureReason will be set in the event that there is a terminal problem
// reconciling the Machine and will contain a succinct value suitable
Expand Down Expand Up @@ -68,6 +73,10 @@ type MetalMachineStatus struct {
// controller's output.
// +optional
FailureMessage *string `json:"failureMessage,omitempty"`

// Conditions defines current state of the MetalMachine.
// +optional
Conditions clusterv1.Conditions `json:"conditions,omitempty"`
}

// +kubebuilder:object:root=true
Expand All @@ -89,6 +98,16 @@ type MetalMachine struct {
Status MetalMachineStatus `json:"status,omitempty"`
}

// GetConditions returns the set of conditions for this object.
func (in *MetalMachine) GetConditions() clusterv1.Conditions {
return in.Status.Conditions
}

// SetConditions sets the conditions on this object.
func (in *MetalMachine) SetConditions(conditions clusterv1.Conditions) {
in.Status.Conditions = conditions
}

// +kubebuilder:object:root=true

// MetalMachineList contains a list of MetalMachine.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ type ServerBindingSpec struct {
// SideroLink describes state of the SideroLink tunnel.
// +optional
SideroLink SideroLinkSpec `json:"siderolink,omitempty"`

// Addresses describes node addresses for the server.
// +optional
Addresses []string `json:"addresses,omitempty"`

// Hostname describes node hostname for the server.
// +optional
Hostname string `json:"hostname,omitempty"`
}

// SideroLinkSpec defines the state of SideroLink connection.
Expand Down
18 changes: 18 additions & 0 deletions app/caps-controller-manager/api/v1alpha3/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -315,6 +315,69 @@ spec:
status:
description: MetalMachineStatus defines the observed state of MetalMachine.
properties:
addresses:
description: Addresses contains the Metal machine associated addresses.
items:
description: MachineAddress contains information for the node's
address.
properties:
address:
description: The machine address.
type: string
type:
description: Machine address type, one of Hostname, ExternalIP
or InternalIP.
type: string
required:
- address
- type
type: object
type: array
conditions:
description: Conditions defines current state of the MetalMachine.
items:
description: Condition defines an observation of a Cluster API resource
operational state.
properties:
lastTransitionTime:
description: 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: A human readable message indicating details about
the transition. This field may be empty.
type: string
reason:
description: The reason for the condition's last transition
in CamelCase. The specific API may choose whether or not this
field is considered a guaranteed API. This field may not be
empty.
type: string
severity:
description: Severity provides an explicit classification of
Reason code, so the users or machines can immediately understand
the current situation and act accordingly. The Severity field
MUST be set only when Status=False.
type: string
status:
description: Status of the condition, one of True, False, Unknown.
type: string
type:
description: Type of condition in CamelCase or in foo.example.com/CamelCase.
Many .condition.type values are consistent across resources
like Available, but because arbitrary conditions can be useful
(see .node.status.conditions), the ability to deconflict is
important.
type: string
required:
- lastTransitionTime
- status
- type
type: object
type: array
failureMessage:
description: "FailureMessage will be set in the event that there is
a terminal problem reconciling the Machine and will contain a more
Expand Down Expand Up @@ -347,8 +410,6 @@ spec:
type: string
ready:
type: boolean
required:
- ready
type: object
type: object
served: true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,14 @@ spec:
spec:
description: ServerBindingSpec defines the spec of the ServerBinding object.
properties:
addresses:
description: Addresses describes node addresses for the server.
items:
type: string
type: array
hostname:
description: Hostname describes node hostname for the server.
type: string
metalMachineRef:
description: 'ObjectReference contains enough information to let you
inspect or modify the referred object. --- New uses of this type
Expand Down
64 changes: 61 additions & 3 deletions app/caps-controller-manager/controllers/metalmachine_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,13 +21,17 @@ import (
"k8s.io/client-go/tools/record"
"k8s.io/client-go/tools/reference"
"k8s.io/utils/pointer"
capiv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
"sigs.k8s.io/cluster-api/util"
"sigs.k8s.io/cluster-api/util/conditions"
"sigs.k8s.io/cluster-api/util/patch"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"sigs.k8s.io/controller-runtime/pkg/handler"
"sigs.k8s.io/controller-runtime/pkg/reconcile"
"sigs.k8s.io/controller-runtime/pkg/source"

infrav1 "github.com/talos-systems/sidero/app/caps-controller-manager/api/v1alpha3"
"github.com/talos-systems/sidero/app/caps-controller-manager/pkg/constants"
Expand Down Expand Up @@ -98,7 +102,7 @@ func (r *MetalMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request
}

if machine.Spec.Bootstrap.DataSecretName == nil {
logger.Info(" Bootstrap secret is not available yet")
logger.Info("Bootstrap secret is not available yet")

return ctrl.Result{RequeueAfter: constants.DefaultRequeueAfter}, nil
}
Expand Down Expand Up @@ -154,14 +158,47 @@ func (r *MetalMachineReconciler) Reconcile(ctx context.Context, req ctrl.Request
// Set the providerID, as its required in upstream capi for machine lifecycle
metalMachine.Spec.ProviderID = pointer.StringPtr(fmt.Sprintf("%s://%s", constants.ProviderID, metalMachine.Spec.ServerRef.Name))

if metalMachine.Spec.ServerRef != nil {
var serverBinding infrav1.ServerBinding

err = r.Get(ctx, types.NamespacedName{Namespace: metalMachine.Spec.ServerRef.Namespace, Name: metalMachine.Spec.ServerRef.Name}, &serverBinding)
if err != nil {
if apierrors.IsNotFound(err) {
return ctrl.Result{RequeueAfter: constants.DefaultRequeueAfter}, nil
}

return ctrl.Result{}, err
}

addresses := make([]capiv1.MachineAddress, 0, len(serverBinding.Spec.Addresses))
for _, addr := range serverBinding.Spec.Addresses {
addresses = append(addresses, capiv1.MachineAddress{
Type: capiv1.MachineInternalIP,
Address: addr,
})
}

if serverBinding.Spec.Hostname != "" {
addresses = append(addresses, capiv1.MachineAddress{
Type: capiv1.MachineHostName,
Address: serverBinding.Spec.Hostname,
})
}

metalMachine.Status.Addresses = addresses
metalMachine.Status.Ready = true
}

err = r.patchProviderID(ctx, cluster, metalMachine)
if err != nil {
logger.Info("Failed to set provider ID", "error", err)

conditions.MarkFalse(metalMachine, infrav1.ProviderSetCondition, infrav1.ProviderUpdateFailedReason, capiv1.ConditionSeverityWarning, err.Error())

return ctrl.Result{RequeueAfter: constants.DefaultRequeueAfter}, nil
}

metalMachine.Status.Ready = true
conditions.MarkTrue(metalMachine, infrav1.ProviderSetCondition)

return ctrl.Result{}, nil
}
Expand Down Expand Up @@ -196,9 +233,30 @@ func (r *MetalMachineReconciler) SetupWithManager(ctx context.Context, mgr ctrl.
return err
}

mapRequests := func(a client.Object) []reconcile.Request {
serverBinding := &infrav1.ServerBinding{}

if err := r.Get(context.Background(), types.NamespacedName{Namespace: a.GetNamespace(), Name: a.GetName()}, serverBinding); err != nil {
return nil
}

return []reconcile.Request{
{
NamespacedName: types.NamespacedName{
Name: serverBinding.Spec.MetalMachineRef.Name,
Namespace: serverBinding.Spec.MetalMachineRef.Namespace,
},
},
}
}

return ctrl.NewControllerManagedBy(mgr).
WithOptions(options).
For(&infrav1.MetalMachine{}).
Watches(
&source.Kind{Type: &infrav1.ServerBinding{}},
handler.EnqueueRequestsFromMapFunc(mapRequests),
).
Complete(r)
}

Expand Down
2 changes: 1 addition & 1 deletion app/caps-controller-manager/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import (
clientgoscheme "k8s.io/client-go/kubernetes/scheme"
typedcorev1 "k8s.io/client-go/kubernetes/typed/core/v1"
cgrecord "k8s.io/client-go/tools/record"
capiv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
capiv1 "sigs.k8s.io/cluster-api/api/v1beta1"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/controller"
"sigs.k8s.io/controller-runtime/pkg/log/zap"
Expand Down
2 changes: 1 addition & 1 deletion app/sidero-controller-manager/api/v1alpha1/server_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ import (
corev1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
clusterv1 "sigs.k8s.io/cluster-api/api/v1alpha4"
clusterv1 "sigs.k8s.io/cluster-api/api/v1beta1"
"sigs.k8s.io/controller-runtime/pkg/client"
)

Expand Down

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 6454dee

Please sign in to comment.