Skip to content

Commit 703cb26

Browse files
Merge pull request openshift#8650 from andfasano/agent-day2-use-secure-port
AGENT-925: retrieve ignition endpoint to add a new node
2 parents 0115fda + adc56ce commit 703cb26

File tree

4 files changed

+104
-1
lines changed

4 files changed

+104
-1
lines changed

data/data/agent/systemd/units/agent-import-cluster.service.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ EnvironmentFile=/usr/local/share/assisted-service/assisted-service.env
1616
EnvironmentFile=/etc/assisted/add-nodes.env
1717
ExecStartPre=/bin/rm -f %t/%n.ctr-id
1818
ExecStartPre=/usr/local/bin/wait-for-assisted-service.sh
19-
ExecStart=podman run --net host --cidfile=%t/%n.ctr-id --cgroups=no-conmon --log-driver=journald --rm --pod-id-file=%t/assisted-service-pod.pod-id --replace --name=agent-import-cluster -v /etc/assisted/manifests:/manifests -v /etc/assisted/extra-manifests:/extra-manifests {{ if .HaveMirrorConfig }}-v /etc/containers:/etc/containers{{ end }} {{.CaBundleMount}} --env SERVICE_BASE_URL --env OPENSHIFT_INSTALL_RELEASE_IMAGE_MIRROR --env CLUSTER_ID --env CLUSTER_NAME --env CLUSTER_API_VIP_DNS_NAME $SERVICE_IMAGE /usr/local/bin/agent-installer-client importCluster
19+
ExecStart=podman run --net host --cidfile=%t/%n.ctr-id --cgroups=no-conmon --log-driver=journald --rm --pod-id-file=%t/assisted-service-pod.pod-id --replace --name=agent-import-cluster -v /etc/assisted/clusterconfig:/clusterconfig -v /etc/assisted/manifests:/manifests -v /etc/assisted/extra-manifests:/extra-manifests {{ if .HaveMirrorConfig }}-v /etc/containers:/etc/containers{{ end }} {{.CaBundleMount}} --env SERVICE_BASE_URL --env OPENSHIFT_INSTALL_RELEASE_IMAGE_MIRROR --env CLUSTER_ID --env CLUSTER_NAME --env CLUSTER_API_VIP_DNS_NAME $SERVICE_IMAGE /usr/local/bin/agent-installer-client importCluster
2020
ExecStop=/usr/bin/podman stop --ignore --cidfile=%t/%n.ctr-id
2121
ExecStopPost=/usr/bin/podman rm -f --ignore --cidfile=%t/%n.ctr-id
2222

pkg/asset/agent/image/ignition.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package image
22

33
import (
44
"context"
5+
"encoding/json"
56
"fmt"
67
"net"
78
"net/url"
@@ -46,6 +47,7 @@ const nmConnectionsPath = "/etc/assisted/network"
4647
const extraManifestPath = "/etc/assisted/extra-manifests"
4748
const registriesConfPath = "/etc/containers/registries.conf"
4849
const registryCABundlePath = "/etc/pki/ca-trust/source/anchors/domain.crt"
50+
const clusterConfigPath = "/etc/assisted/clusterconfig"
4951

5052
// Ignition is an asset that generates the agent installer ignition file.
5153
type Ignition struct {
@@ -194,6 +196,10 @@ func (a *Ignition) Generate(_ context.Context, dependencies asset.Parents) error
194196
streamGetter = func(ctx context.Context) (*stream.Stream, error) {
195197
return clusterInfo.OSImage, nil
196198
}
199+
// If defined, add the ignition endpoints
200+
if err := addDay2IgnitionEndpoints(&config, *clusterInfo); err != nil {
201+
return err
202+
}
197203

198204
default:
199205
return fmt.Errorf("AgentWorkflowType value not supported: %s", agentWorkflow.Workflow)
@@ -528,6 +534,35 @@ func addHostConfig(config *igntypes.Config, agentHosts *agentconfig.AgentHosts)
528534
return nil
529535
}
530536

537+
func addDay2IgnitionEndpoints(config *igntypes.Config, clusterInfo joiner.ClusterInfo) error {
538+
if clusterInfo.IgnitionEndpointWorker == nil {
539+
return nil
540+
}
541+
542+
user := "root"
543+
mode := 0644
544+
config.Storage.Directories = append(config.Storage.Directories, igntypes.Directory{
545+
Node: igntypes.Node{
546+
Path: clusterConfigPath,
547+
User: igntypes.NodeUser{
548+
Name: &user,
549+
},
550+
Overwrite: util.BoolToPtr(true),
551+
},
552+
DirectoryEmbedded1: igntypes.DirectoryEmbedded1{
553+
Mode: &mode,
554+
},
555+
})
556+
557+
workerIgnitionBytes, err := json.Marshal(clusterInfo.IgnitionEndpointWorker)
558+
if err != nil {
559+
return err
560+
}
561+
workerIgnitionFile := ignition.FileFromBytes(path.Join(clusterConfigPath, "worker-ignition-endpoint.json"), user, mode, workerIgnitionBytes)
562+
config.Storage.Files = append(config.Storage.Files, workerIgnitionFile)
563+
return nil
564+
}
565+
531566
func addExtraManifests(config *igntypes.Config, extraManifests *manifests.ExtraManifests) error {
532567

533568
user := "root"

pkg/asset/agent/joiner/clusterinfo.go

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ import (
44
"context"
55
"encoding/json"
66
"fmt"
7+
"strings"
78

9+
igntypes "github.com/coreos/ignition/v2/config/v3_2/types"
810
"github.com/coreos/stream-metadata-go/arch"
911
"github.com/coreos/stream-metadata-go/stream"
1012
"k8s.io/apimachinery/pkg/api/errors"
@@ -15,6 +17,7 @@ import (
1517
"sigs.k8s.io/yaml"
1618

1719
hiveext "github.com/openshift/assisted-service/api/hiveextension/v1beta1"
20+
"github.com/openshift/assisted-service/models"
1821
configclient "github.com/openshift/client-go/config/clientset/versioned"
1922
"github.com/openshift/installer/pkg/asset"
2023
"github.com/openshift/installer/pkg/asset/agent"
@@ -45,6 +48,7 @@ type ClusterInfo struct {
4548
SSHKey string
4649
OSImage *stream.Stream
4750
OSImageLocation string
51+
IgnitionEndpointWorker *models.IgnitionEndpoint
4852
}
4953

5054
var _ asset.WritableAsset = (*ClusterInfo)(nil)
@@ -106,6 +110,10 @@ func (ci *ClusterInfo) Generate(_ context.Context, dependencies asset.Parents) e
106110
if err != nil {
107111
return err
108112
}
113+
err = ci.retrieveIgnitionEndpointWorker()
114+
if err != nil {
115+
return err
116+
}
109117

110118
ci.Namespace = "cluster0"
111119

@@ -269,6 +277,48 @@ func (ci *ClusterInfo) retrieveOsImage() error {
269277
return nil
270278
}
271279

280+
// This method retrieves, if present, the secured ignition endpoint - along with its ca certificate.
281+
// These information will be used to configure subsequently the imported Assisted Service cluster,
282+
// so that the secure port (22623) could be used by the nodes to fetch the worker ignition.
283+
func (ci *ClusterInfo) retrieveIgnitionEndpointWorker() error {
284+
workerUserDataManaged, err := ci.Client.CoreV1().Secrets("openshift-machine-api").Get(context.Background(), "worker-user-data-managed", metav1.GetOptions{})
285+
if err != nil {
286+
if errors.IsNotFound(err) {
287+
return nil
288+
}
289+
return err
290+
}
291+
userData := workerUserDataManaged.Data["userData"]
292+
293+
config := &igntypes.Config{}
294+
err = json.Unmarshal(userData, config)
295+
if err != nil {
296+
return err
297+
}
298+
299+
// Check if there is at least a CA certificate in the ignition
300+
if len(config.Ignition.Security.TLS.CertificateAuthorities) == 0 {
301+
return nil
302+
}
303+
304+
// Get the first source and ca certificate (and strip the base64 data header)
305+
ignEndpointURL := config.Ignition.Config.Merge[0].Source
306+
caCertSource := *config.Ignition.Security.TLS.CertificateAuthorities[0].Source
307+
308+
hdrIndex := strings.Index(caCertSource, ",")
309+
if hdrIndex == -1 {
310+
return fmt.Errorf("error while parsing ignition endpoints ca certificate, invalid data url format")
311+
}
312+
caCert := caCertSource[hdrIndex+1:]
313+
314+
ci.IgnitionEndpointWorker = &models.IgnitionEndpoint{
315+
URL: ignEndpointURL,
316+
CaCertificate: &caCert,
317+
}
318+
319+
return nil
320+
}
321+
272322
// Files returns the files generated by the asset.
273323
func (*ClusterInfo) Files() []*asset.File {
274324
return []*asset.File{}

pkg/asset/agent/joiner/clusterinfo_test.go

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ import (
1111
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
1212
"k8s.io/apimachinery/pkg/runtime"
1313
"k8s.io/client-go/kubernetes/fake"
14+
"k8s.io/utils/ptr"
1415
"sigs.k8s.io/yaml"
1516

1617
configv1 "github.com/openshift/api/config/v1"
1718
"github.com/openshift/assisted-service/api/hiveextension/v1beta1"
19+
"github.com/openshift/assisted-service/models"
1820
fakeclientconfig "github.com/openshift/client-go/config/clientset/versioned/fake"
1921
"github.com/openshift/installer/pkg/asset"
2022
"github.com/openshift/installer/pkg/asset/agent/workflow"
@@ -115,6 +117,17 @@ func TestClusterInfo_Generate(t *testing.T) {
115117
"stream": makeCoreOsBootImages(t, buildStreamData()),
116118
},
117119
},
120+
&corev1.Secret{
121+
ObjectMeta: v1.ObjectMeta{
122+
Name: "worker-user-data-managed",
123+
Namespace: "openshift-machine-api",
124+
},
125+
Data: map[string][]byte{
126+
"userData": []byte(`{"ignition":{"config":{"merge":[{"source":"https://192.168.111.5:22623/config/worker","verification":{}}],
127+
"replace":{"verification":{}}},"proxy":{},"security":{"tls":{"certificateAuthorities":[{"source":"data:text/plain;charset=utf-8;base64,LS0tL_FakeCertificate_LS0tCg==",
128+
"verification":{}}]}},"timeouts":{},"version":"3.4.0"},"kernelArguments":{},"passwd":{},"storage":{},"systemd":{}}`),
129+
},
130+
},
118131
},
119132
expectedClusterInfo: ClusterInfo{
120133
ClusterID: "1b5ba46b-7e56-47b1-a326-a9eebddfb38c",
@@ -143,6 +156,10 @@ func TestClusterInfo_Generate(t *testing.T) {
143156
SSHKey: "my-ssh-key",
144157
OSImage: buildStreamData(),
145158
OSImageLocation: "http://my-coreosimage-url/416.94.202402130130-0",
159+
IgnitionEndpointWorker: &models.IgnitionEndpoint{
160+
URL: ptr.To("https://192.168.111.5:22623/config/worker"),
161+
CaCertificate: ptr.To("LS0tL_FakeCertificate_LS0tCg=="),
162+
},
146163
},
147164
},
148165
}
@@ -180,6 +197,7 @@ func TestClusterInfo_Generate(t *testing.T) {
180197
assert.Equal(t, tc.expectedClusterInfo.SSHKey, clusterInfo.SSHKey)
181198
assert.Equal(t, tc.expectedClusterInfo.OSImageLocation, clusterInfo.OSImageLocation)
182199
assert.Equal(t, tc.expectedClusterInfo.OSImage, clusterInfo.OSImage)
200+
assert.Equal(t, tc.expectedClusterInfo.IgnitionEndpointWorker, clusterInfo.IgnitionEndpointWorker)
183201
})
184202
}
185203
}

0 commit comments

Comments
 (0)