Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion class/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ parameters:

clusterName: ${cluster:name}

talosVersion: '1.13'
talosVersion: '1.13.10'
# NOTE(sg): this is the well-known default schematic UUID
talosSchematicUUID: 376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba
kubernetesVersion: 'v1.36.4'
Expand Down
1 change: 1 addition & 0 deletions class/talos-capi-cluster-cloudscale.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ parameters:
output_path: .
- input_paths:
- ${_base_directory}/component/main.jsonnet
- ${_base_directory}/component/tuppr-talosupgrade.jsonnet
input_type: jsonnet
output_path: talos-capi-cluster-cloudscale/
51 changes: 32 additions & 19 deletions component/main.jsonnet
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ local capi = import 'lib/capi-core.libsonnet';
local capcs = import 'lib/capi-provider-cloudscale.libsonnet';
local capi_talos = import 'lib/capi-provider-talos.libsonnet';

local utils = import 'utils.libsonnet';

local inv = kap.inventory();
local params = inv.parameters.talos_capi_cluster_cloudscale;

Expand All @@ -16,20 +18,6 @@ assert
: '\n\nComponent talos-capi-cluster-cloudscale requires components '
+ 'capi-core, capi-provider-cloudscale, and capi-provider-talos';


local validateTalosVersion(tver) =
local parts = std.split(tver, '.');
assert std.length(parts) == 2 : 'Expected Talos version to contain exacty 1 dot';
local major = std.parseJson(parts[0]);
local minor = std.parseJson(parts[1]);
if !std.isInteger(major) || !std.isInteger(minor) then
error "Expected Talos version to be '<major>.<minor>', got '%s'" % tver
else
{
major: major,
minor: minor,
};

local cloudscaleImageSlug = 'custom:%s' % params.cloudscale.customImageSlug;

local resourceSetLabelKey = 'talos-capi-cluster-cloudscale.syn.tools/bootstrap';
Expand Down Expand Up @@ -109,11 +97,13 @@ local talosStrategicPatch = {
install: {
disk: '/dev/sda',
wipe: true,
// NOTE(sg): image is required by Tuppr in order to compute the update
// NOTE(sg): image is required by Tuppr in order to compute the update.
// We don't use the user-supplied patch version here, so that pure patch
// upgrades (without new Talos base image) don't create new machines.
image: 'factory.talos.dev/openstack-installer/%(schematic_uuid)s:v%(version)s' % {
schematic_uuid: params.talosSchematicUUID,
version:
'%(major)s.%(minor)s.0' % validateTalosVersion(params.talosVersion),
'%(major)s.%(minor)s.0' % utils.validateTalosVersion(params.talosVersion),
},
},
kubelet: {
Expand Down Expand Up @@ -208,6 +198,27 @@ local authenticationPatch =
}),
] else [];

// NOTE(sg): kubernetesTalosAPIAccess can only be configured on control plane
// nodes, worker provisioning fails with the following error if
// kubernetesTalosAPIAccess is present in the machine configuration:
//
// failed to validate config acquired via platform openstack: 1 error occurred:
// * v1alpha1.Config: 1 error occurred:
// * feature Kubernetes Talos API Access can only be enabled on control plane machines
local tupprAccessPatch = {
machine: {
features: {
kubernetesTalosAPIAccess: {
enabled: true,
allowedKubernetesNamespaces: [
'syn-tuppr',
],
allowedRoles: [ 'os:admin' ],
},
},
},
};

// NOTE(sg): We sort user-provided control plane patches by their names in
// asciibetical order.
local controlPlaneStrategicPatches = [
Expand All @@ -217,7 +228,9 @@ local controlPlaneStrategicPatches = [
for p in std.sort(std.objectFields(
params.talosControlPlane.strategicPatches
))
] + authenticationPatch;
] + authenticationPatch + [
std.manifestJsonMinified(tupprAccessPatch),
];

local capiTalosControlPlane = capi_talos.TalosControlPlane(params.clusterName) {
metadata+: filteredMetadata(std.get(params.talosControlPlane, 'metadata', {})),
Expand All @@ -236,7 +249,7 @@ local capiTalosControlPlane = capi_talos.TalosControlPlane(params.clusterName) {
controlPlaneConfig+: {
controlplane+: {
generateType: 'controlplane',
talosVersion: '%(major)s.%(minor)s' % validateTalosVersion(params.talosVersion),
talosVersion: '%(major)s.%(minor)s' % utils.validateTalosVersion(params.talosVersion),
hostname: {
// we want to use the VM name defined by the cloudscale CAPI
// provider.
Expand All @@ -257,7 +270,7 @@ local capiWorkerGroup(name) =
template: {
spec: {
generateType: 'join',
talosVersion: '%(major)s.%(minor)s' % validateTalosVersion(params.talosVersion),
talosVersion: '%(major)s.%(minor)s' % utils.validateTalosVersion(params.talosVersion),
hostname: {
source: 'InfrastructureName',
},
Expand Down
72 changes: 72 additions & 0 deletions component/tuppr-talosupgrade.jsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
local kap = import 'lib/kapitan.libjsonnet';
local tuppr = import 'lib/tuppr.libsonnet';

local capi = import 'lib/capi-core.libsonnet';
local capi_talos = import 'lib/capi-provider-talos.libsonnet';

local utils = import 'utils.libsonnet';

local inv = kap.inventory();
local params = inv.parameters.talos_capi_cluster_cloudscale;

local tcp = capi_talos.TalosControlPlane('');
local md = capi.MachineDeployment('');

local talosUpgrade = tuppr.TalosUpgrade('cluster') {
metadata+: {
annotations+: {
// Ensure this is applied after the CAPI resources. This should ensure
// that Tuppr never tries to start a Talos patch or minor upgrade when
// we also replace machines (e.g. K8s upgrade or similar).
'argocd.argoproj.io/sync-wave': '10',
},
},
spec+: {
drain: {
enabled: true,
},
talos: {
version:
'v%(major)s.%(minor)s.%(patch)s' %
utils.validateTalosVersion(params.talosVersion),
},
healthChecks: [
// NOTE(sg): This should wait for control plane health before doing Talos
// upgrades.
{
apiVersion: tcp.apiVersion,
kind: tcp.kind,
namespace: params.namespace,
// TODO(sg): figure out good timeout for this.
timeout: '30m',
expr: |||
status.conditions.exists(
c, c.type == "EtcdClusterHealthyCondition" && c.status == "True"
) && status.conditions.exists(
c, c.type == "ControlPlaneComponentsHealthy" && c.status == "True"
)
|||,
},
// NOTE(sg): This should wait for node creations & replacements to
// complete before doing Talos upgrades.
{
apiVersion: md.apiVersion,
kind: md.kind,
namespace: params.namespace,
// TODO(sg): figure out good timeout for this.
timeout: '30m',
expr: |||
status.phase == "Running"
&& status.conditions.exists(c, c.type == "Available" && c.status == "True")
|||,
},
],
},
};

if std.member(inv.applications, 'tuppr') then {
tuppr_talosupgrade: talosUpgrade,
} else std.trace(
'Not rendering Tuppr TalosUpgrade because component-tuppr is missing.',
{}
)
17 changes: 17 additions & 0 deletions component/utils.libsonnet
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
{
validateTalosVersion(tver):
local parts = std.split(tver, '.');
assert std.length(parts) == 3
: "Expected Talos version to contain exacty 2 dots, got '%s'" % tver;
local major = std.parseJson(parts[0]);
local minor = std.parseJson(parts[1]);
local patch = std.parseJson(parts[2]);
if !std.isInteger(major) || !std.isInteger(minor) || !std.isInteger(patch) then
error "Expected Talos version to be '<major>.<minor>.<patch>', got '%s'" % tver
else
{
major: major,
minor: minor,
patch: patch,
},
}
15 changes: 15 additions & 0 deletions docs/modules/ROOT/pages/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,18 @@ The component expects that the following Cluster API components are available on
* https://hub.syn.tools/capi-provider-talos[component-capi-provider-talos]

See the xref:references/parameters.adoc[parameters] reference for further details.

== Talos upgrades with Tuppr

The component optionally renders a Tuppr `TalosUpgrade` for the cluster if https://hub.syn.tools/tuppr[component-tuppr] is available on the target cluster.

[WARNING]
====
We recommend that users don't perform Talos minor upgrades via Tuppr.

Instead, please see the https://kb.vshn.ch/talos/how-tos/minor-upgrade.html[VSHN Managed Talos Minor Upgrade how-to] for a supported minor upgrade process which works with this component.
====

== Talos API access

The component configures Talos API access for Tuppr by applying an appropriate `MachineConfiguration` patch to the Talos control plane nodes.
8 changes: 7 additions & 1 deletion docs/modules/ROOT/pages/references/parameters.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,13 @@ default:: https://github.com/projectsyn/component-talos-capi-cluster-cloudscale/

The Talos version to use when provisioning the cluster.

NOTE: The Talos CAPI provider uses the value of this parameter only to decide how to render the Talos `MachineConfiguration`.
[NOTE]
====
The Talos CAPI provider uses the value of this parameter only to decide how to render the Talos `MachineConfiguration`.
This decision is made solely based on the Talos major and minor version provided in this parameter.
====

NOTE: The component uses the full Talos version when rendering the Tuppr `TalosUpgrade`.

== `talosSchematicUUID`

Expand Down
4 changes: 4 additions & 0 deletions tests/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ applications:
- capi-core
- capi-provider-cloudscale
- capi-provider-talos
- tuppr

parameters:
kapitan:
Expand All @@ -16,6 +17,9 @@ parameters:
- type: https
source: https://raw.githubusercontent.com/projectsyn/component-capi-provider-talos/master/lib/capi-provider-talos.libsonnet
output_path: vendor/lib/capi-provider-talos.libsonnet
- type: https
source: https://raw.githubusercontent.com/projectsyn/component-tuppr/master/lib/tuppr.libsonnet
output_path: vendor/lib/tuppr.libsonnet

cilium:
cilium_helm_values:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ spec:
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: CloudscaleMachineTemplate
metadata:
name: c-green-test-1234-control-plane-1a05392e618ad8f5
name: c-green-test-1234-control-plane-60a7e556a402d267
spec:
template:
spec:
flavor: plus-16-4
image: custom:talos-v1.13-37656798
image: custom:talos-v1.13.10-37656798
interfaces:
- network: privnet-c-green-test-1234
rootVolumeSize: 50
Expand All @@ -61,12 +61,13 @@ spec:
source: InfrastructureName
strategicPatches:
- '{"cluster":{"externalCloudProvider":{"enabled":true},"network":{"cni":{"name":"none"}},"proxy":{"disabled":true}},"machine":{"install":{"disk":"/dev/sda","image":"factory.talos.dev/openstack-installer/376567988ad370138ad8b2698212367b8edcb69b5fd68c80be1f2ec7d603b4ba:v1.13.0","wipe":true},"kubelet":{"extraArgs":{"rotate-server-certificates":true}},"network":{"interfaces":[{"deviceSelector":{"physical":true},"dhcp":true}]}}}'
- '{"machine":{"features":{"kubernetesTalosAPIAccess":{"allowedKubernetesNamespaces":["syn-tuppr"],"allowedRoles":["os:admin"],"enabled":true}}}}'
talosVersion: '1.13'
machineTemplate:
spec:
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: CloudscaleMachineTemplate
name: c-green-test-1234-control-plane-1a05392e618ad8f5
name: c-green-test-1234-control-plane-60a7e556a402d267
replicas: 1
version: v1.36.4
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
apiVersion: tuppr.home-operations.com/v1alpha1
kind: TalosUpgrade
metadata:
annotations:
argocd.argoproj.io/sync-wave: '10'
name: cluster
spec:
drain:
enabled: true
healthChecks:
- apiVersion: controlplane.cluster.x-k8s.io/v1beta1
expr: |
status.conditions.exists(
c, c.type == "EtcdClusterHealthyCondition" && c.status == "True"
) && status.conditions.exists(
c, c.type == "ControlPlaneComponentsHealthy" && c.status == "True"
)
kind: TalosControlPlane
namespace: syn-cluster-api
timeout: 30m
- apiVersion: cluster.x-k8s.io/v1beta2
expr: |
status.phase == "Running"
&& status.conditions.exists(c, c.type == "Available" && c.status == "True")
kind: MachineDeployment
namespace: syn-cluster-api
timeout: 30m
talos:
version: v1.13.10
Original file line number Diff line number Diff line change
Expand Up @@ -21,18 +21,18 @@ spec:
infrastructureRef:
apiGroup: infrastructure.cluster.x-k8s.io
kind: CloudscaleMachineTemplate
name: worker-140736b57cf90932
name: worker-51894217089d35c8
version: v1.36.4
---
apiVersion: infrastructure.cluster.x-k8s.io/v1beta2
kind: CloudscaleMachineTemplate
metadata:
name: worker-140736b57cf90932
name: worker-51894217089d35c8
spec:
template:
spec:
flavor: plus-16-4
image: custom:talos-v1.13-37656798
image: custom:talos-v1.13.10-37656798
interfaces:
- network: privnet-c-green-test-1234
rootVolumeSize: 50
Expand Down
Loading