From e76285e1ebee4b484779ae4d9a531b4c3d3f6873 Mon Sep 17 00:00:00 2001 From: Tom Wieczorek Date: Mon, 23 Sep 2024 17:21:26 +0200 Subject: [PATCH] Replace kubectl apply usage in inttests This removes SSH and "shelling out" from the equation, making the tests a bit more direct and hopefully improving error messages when things go south. Signed-off-by: Tom Wieczorek --- inttest/ap-airgap/airgap_test.go | 15 ++++---- .../controllerworker_test.go | 22 +++++------ .../ap-platformselect/platformselect_test.go | 18 ++++----- inttest/ap-quorum/quorum_test.go | 17 +++++---- inttest/ap-quorumsafety/quorumsafety_test.go | 27 +++++++------ inttest/ap-removedapis/removedapis_test.go | 16 ++++---- inttest/ap-selector/selector_test.go | 25 ++++++------ inttest/ap-single/single_test.go | 18 ++++----- inttest/ap-updater-periodic/updater_test.go | 25 +++++------- inttest/ap-updater/updater_test.go | 26 +++++-------- inttest/common/util.go | 38 ++++++++++++++++++- .../kubeletcertrotate_test.go | 21 +++++----- 12 files changed, 145 insertions(+), 123 deletions(-) diff --git a/inttest/ap-airgap/airgap_test.go b/inttest/ap-airgap/airgap_test.go index cc852d8d99ba..5fc8513aab3a 100644 --- a/inttest/ap-airgap/airgap_test.go +++ b/inttest/ap-airgap/airgap_test.go @@ -24,6 +24,7 @@ import ( "github.com/k0sproject/k0s/pkg/apis/k0s/v1beta1" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" "github.com/k0sproject/k0s/pkg/constant" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -142,20 +143,18 @@ spec: ) s.Require().NoError(err) - client, err := s.AutopilotClient(s.ControllerNode(0)) + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) - manifestFile := "/tmp/happy.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) + s.Require().NoError(err) + s.T().Logf("Plan created") updateStart := time.Now() - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) - s.Require().NoError(err) - // The plan has enough information to perform a successful update of k0s, so wait for it. + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) _, err = aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) diff --git a/inttest/ap-controllerworker/controllerworker_test.go b/inttest/ap-controllerworker/controllerworker_test.go index 555dd30510d4..7fa1e07b32ca 100644 --- a/inttest/ap-controllerworker/controllerworker_test.go +++ b/inttest/ap-controllerworker/controllerworker_test.go @@ -22,15 +22,15 @@ import ( "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" - apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" "github.com/k0sproject/k0s/pkg/constant" "github.com/k0sproject/k0s/pkg/kubernetes/watch" - "github.com/stretchr/testify/suite" - corev1 "k8s.io/api/core/v1" + + "github.com/stretchr/testify/suite" ) type controllerworkerSuite struct { @@ -114,9 +114,10 @@ func (s *controllerworkerSuite) SetupTest() { // TestApply applies a well-formed `plan` yaml, and asserts that // all of the correct values across different objects + controllers are correct. func (s *controllerworkerSuite) TestApply() { - client, err := s.AutopilotClient(s.ControllerNode(0)) + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 @@ -144,16 +145,15 @@ spec: - controller2 - controller0 ` - ctx := s.Context() - manifestFile := "/tmp/happy.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) s.Require().NoError(err) + s.T().Logf("Plan created") // The plan has enough information to perform a successful update of k0s, so wait for it. - plan, err := aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + plan, err := aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) s.Equal(1, len(plan.Status.Commands)) diff --git a/inttest/ap-platformselect/platformselect_test.go b/inttest/ap-platformselect/platformselect_test.go index a74a3243e7ac..0f9c5eb9693f 100644 --- a/inttest/ap-platformselect/platformselect_test.go +++ b/inttest/ap-platformselect/platformselect_test.go @@ -15,12 +15,12 @@ package platformselect import ( - "fmt" "testing" "time" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" @@ -51,9 +51,10 @@ func (s *platformSelectSuite) SetupTest() { // TestApply applies a well-formed `plan` yaml that includes multiple // platform definitions, and asserts that the proper binary is downloaded. func (s *platformSelectSuite) TestApply() { - client, err := s.AutopilotClient(s.ControllerNode(0)) + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 @@ -82,18 +83,17 @@ spec: - controller0 ` - manifestFile := "/tmp/happy.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) - - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) s.Require().NoError(err) + s.T().Logf("Plan created") // Its expected that if the wrong platform were to be downloaded, the update wouldn't be successful, // as the binary would fail to run. // The plan has enough information to perform a successful update of k0s, so wait for it. - plan, err := aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + plan, err := aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) s.Equal(1, len(plan.Status.Commands)) diff --git a/inttest/ap-quorum/quorum_test.go b/inttest/ap-quorum/quorum_test.go index 796858a76729..fec18789ab1b 100644 --- a/inttest/ap-quorum/quorum_test.go +++ b/inttest/ap-quorum/quorum_test.go @@ -21,6 +21,7 @@ import ( apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" @@ -77,9 +78,10 @@ func (s *quorumSuite) SetupTest() { // TestApply applies a well-formed `plan` yaml, and asserts that // all of the correct values across different objects + controllers are correct. func (s *quorumSuite) TestApply() { - client, err := s.AutopilotClient(s.ControllerNode(0)) + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 @@ -106,15 +108,14 @@ spec: - controller2 ` - manifestFile := "/tmp/happy.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) - - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) s.Require().NoError(err) + s.T().Logf("Plan created") // The plan has enough information to perform a successful update of k0s, so wait for it. - plan, err := aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + plan, err := aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) s.Equal(1, len(plan.Status.Commands)) diff --git a/inttest/ap-quorumsafety/quorumsafety_test.go b/inttest/ap-quorumsafety/quorumsafety_test.go index 0763e8b6f73a..81c36b9e2697 100644 --- a/inttest/ap-quorumsafety/quorumsafety_test.go +++ b/inttest/ap-quorumsafety/quorumsafety_test.go @@ -21,6 +21,7 @@ import ( apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" @@ -77,6 +78,10 @@ func (s *quorumSafetySuite) SetupTest() { // TestApply applies a well-formed `plan` yaml, and asserts that // all of the correct values across different objects + controllers are correct. func (s *quorumSafetySuite) TestApply() { + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) + s.Require().NoError(err) // Create a third node by way of a new `ControlNode` entry that doesen't map to a host. // This will allow autopilot to get past the node tests in newplan (IncompleteTargets) @@ -91,18 +96,13 @@ metadata: kubernetes.io/hostname: controller2 kubernetes.io/os: linux ` - controller2Filename := "/tmp/controller2.yaml" - s.PutFile(s.ControllerNode(0), controller2Filename, controller2Def) - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", controller2Filename)) - s.T().Logf("kubectl apply output (controller2): '%s'", out) + + _, err = common.Create(ctx, restConfig, []byte(controller2Def)) s.Require().NoError(err) + s.T().Logf("Second ControlNode created") // Create + populate the plan - client, err := s.AutopilotClient(s.ControllerNode(0)) - s.Require().NoError(err) - s.NotEmpty(client) - planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 kind: Plan @@ -128,16 +128,15 @@ spec: - controller2 ` - manifestFile := "/tmp/happy.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) - - out, err = s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output (plan): '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) s.Require().NoError(err) + s.T().Logf("Plan created") // The plan should fail with "InconsistentTargets" due to autopilot detecting that `controller2` // despite existing as a `ControlNode`, does not resolve. - _, err = aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanInconsistentTargets) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + _, err = aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanInconsistentTargets) s.Require().NoError(err) } diff --git a/inttest/ap-removedapis/removedapis_test.go b/inttest/ap-removedapis/removedapis_test.go index d4e448f7f1a9..73676e8e7ac1 100644 --- a/inttest/ap-removedapis/removedapis_test.go +++ b/inttest/ap-removedapis/removedapis_test.go @@ -15,11 +15,11 @@ package removedapis import ( - "fmt" "testing" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" apiextensionsv1client "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/typed/apiextensions/v1" @@ -79,20 +79,18 @@ func (s *plansRemovedAPIsSuite) SetupTest() { // TestApply applies a well-formed `plan` yaml, and asserts that all of the correct values // across different objects are correct. func (s *plansRemovedAPIsSuite) TestApply() { - client, err := s.AutopilotClient(s.ControllerNode(0)) - s.Require().NoError(err) - s.NotEmpty(client) - ctx := s.Context() - manifestFile := "/tmp/plan.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) + s.Require().NoError(err) - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) s.Require().NoError(err) + s.T().Logf("Plan created") // The plan has enough information to perform a successful update of k0s, so wait for it. + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) plan, err := aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanWarning) if s.NoError(err) && s.Len(plan.Status.Commands, 1) { s.Equal(appc.PlanWarning, plan.Status.Commands[0].State) diff --git a/inttest/ap-selector/selector_test.go b/inttest/ap-selector/selector_test.go index 7a9026c034dc..743c8c91cece 100644 --- a/inttest/ap-selector/selector_test.go +++ b/inttest/ap-selector/selector_test.go @@ -22,6 +22,7 @@ import ( apv1beta2 "github.com/k0sproject/k0s/pkg/apis/autopilot/v1beta2" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" @@ -92,6 +93,11 @@ func (s *selectorSuite) SetupTest() { // TestSelectors applies a well-formed `plan` yaml that wants to only update a controller statically, and // a worker via field/label selector definitions. func (s *selectorSuite) TestSelectors() { + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) + s.Require().NoError(err) + planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 kind: Plan @@ -120,26 +126,21 @@ spec: fields: metadata.name=worker1 ` // Add 'foo=bar' to both 'controller0' and 'worker1' - _, err := s.RunCommandController(0, "/usr/local/bin/k0s kubectl label controlnodes controller0 foo=bar") + _, err = s.RunCommandController(0, "/usr/local/bin/k0s kubectl label controlnodes controller0 foo=bar") s.Require().NoError(err) _, err = s.RunCommandController(0, "/usr/local/bin/k0s kubectl label nodes worker1 foo=bar") s.Require().NoError(err) - // Save + apply the plan + // Create the plan - apc, err := s.AutopilotClient(s.ControllerNode(0)) - s.Require().NoError(err) - s.NotEmpty(apc) - - manifestFile := "/tmp/plan.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) - - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) s.Require().NoError(err) + s.T().Logf("Plan created") // The plan has enough information to perform a successful update of k0s, so wait for it. - plan, err := aptest.WaitForPlanState(s.Context(), apc, apconst.AutopilotName, appc.PlanCompleted) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + plan, err := aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) s.Equal(1, len(plan.Status.Commands)) diff --git a/inttest/ap-single/single_test.go b/inttest/ap-single/single_test.go index 27a78cee5e6c..2a63c39b81db 100644 --- a/inttest/ap-single/single_test.go +++ b/inttest/ap-single/single_test.go @@ -15,11 +15,11 @@ package single import ( - "fmt" "testing" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" @@ -61,9 +61,10 @@ func (s *plansSingleControllerSuite) SetupTest() { // TestApply applies a well-formed `plan` yaml, and asserts that all of the correct values // across different objects are correct. func (s *plansSingleControllerSuite) TestApply() { - client, err := s.AutopilotClient(s.ControllerNode(0)) + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 @@ -88,15 +89,14 @@ spec: - controller0 ` - manifestFile := "/tmp/happy.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) - - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) s.Require().NoError(err) + s.T().Logf("Plan created") // The plan has enough information to perform a successful update of k0s, so wait for it. - plan, err := aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + plan, err := aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err, "While waiting for plan to complete") s.Equal(1, len(plan.Status.Commands)) diff --git a/inttest/ap-updater-periodic/updater_test.go b/inttest/ap-updater-periodic/updater_test.go index 9b918333bbe3..65888a24b0cb 100644 --- a/inttest/ap-updater-periodic/updater_test.go +++ b/inttest/ap-updater-periodic/updater_test.go @@ -21,6 +21,7 @@ import ( "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" @@ -105,9 +106,10 @@ func (s *plansSingleControllerSuite) getClusterID(kc kubernetes.Interface) strin // TestApply applies a well-formed `plan` yaml, and asserts that all of the correct values // across different objects are correct. func (s *plansSingleControllerSuite) TestApply() { - client, err := s.AutopilotClient(s.ControllerNode(0)) + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) updaterConfig := ` apiVersion: autopilot.k0sproject.io/v1beta2 @@ -116,7 +118,7 @@ metadata: name: autopilot spec: channel: latest - updateServer: {{.Address}} + updateServer: http://` + s.GetUpdateServerIPAddress() + ` upgradeStrategy: type: periodic periodic: @@ -136,21 +138,14 @@ spec: selector: {} ` - vars := struct { - Address string - }{ - Address: fmt.Sprintf("http://%s", s.GetUpdateServerIPAddress()), - } - - manifestFile := "/tmp/updateconfig.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, updaterConfig, vars) - - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(updaterConfig)) s.Require().NoError(err) + s.T().Logf("Plan created") // The plan has enough information to perform a successful update of k0s, so wait for it. - _, err = aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + _, err = aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) kc, err := s.KubeClient(s.ControllerNode(0)) diff --git a/inttest/ap-updater/updater_test.go b/inttest/ap-updater/updater_test.go index bd0664df27cd..b6e21858722b 100644 --- a/inttest/ap-updater/updater_test.go +++ b/inttest/ap-updater/updater_test.go @@ -15,12 +15,12 @@ package updater import ( - "fmt" "testing" "time" "github.com/k0sproject/k0s/inttest/common" aptest "github.com/k0sproject/k0s/inttest/common/autopilot" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" @@ -56,9 +56,10 @@ func (s *plansSingleControllerSuite) SetupTest() { // TestApply applies a well-formed `plan` yaml, and asserts that all of the correct values // across different objects are correct. func (s *plansSingleControllerSuite) TestApply() { - client, err := s.AutopilotClient(s.ControllerNode(0)) + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) updaterConfig := ` apiVersion: autopilot.k0sproject.io/v1beta2 @@ -67,7 +68,7 @@ metadata: name: autopilot spec: channel: stable - updateServer: {{.Address}} + updateServer: http://` + s.GetUpdateServerIPAddress() + ` upgradeStrategy: type: cron cron: "* * * * * *" @@ -81,21 +82,14 @@ spec: selector: {} ` - vars := struct { - Address string - }{ - Address: fmt.Sprintf("http://%s", s.GetUpdateServerIPAddress()), - } - - manifestFile := "/tmp/updateconfig.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, updaterConfig, vars) - - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(updaterConfig)) s.Require().NoError(err) + s.T().Logf("UpdateConfig created") // The plan has enough information to perform a successful update of k0s, so wait for it. - _, err = aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + _, err = aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) } diff --git a/inttest/common/util.go b/inttest/common/util.go index 6d3e618b1702..d8b367908ea9 100644 --- a/inttest/common/util.go +++ b/inttest/common/util.go @@ -38,20 +38,56 @@ import ( corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "k8s.io/apimachinery/pkg/fields" "k8s.io/apimachinery/pkg/util/wait" + "k8s.io/client-go/discovery" + "k8s.io/client-go/dynamic" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" + "k8s.io/client-go/restmapper" apiregistrationv1 "k8s.io/kube-aggregator/pkg/apis/apiregistration/v1" aggregatorclient "k8s.io/kube-aggregator/pkg/client/clientset_generated/clientset" "github.com/sirupsen/logrus" + "sigs.k8s.io/yaml" ) // LogfFn will be used whenever something needs to be logged. type LogfFn func(format string, args ...any) -// Poll tries a condition func until it returns true, an error or the specified +// Creates the resource described by the given manifest. +func Create(ctx context.Context, restConfig *rest.Config, manifest []byte) (*unstructured.Unstructured, error) { + var u unstructured.Unstructured + if err := yaml.Unmarshal(manifest, &u); err != nil { + return nil, err + } + + disco, err := discovery.NewDiscoveryClientForConfig(restConfig) + if err != nil { + return nil, err + } + + resources, err := restmapper.GetAPIGroupResources(disco) + if err != nil { + return nil, err + } + + gvk := u.GroupVersionKind() + mapper := restmapper.NewDiscoveryRESTMapper(resources) + mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version) + if err != nil { + return nil, err + } + + dyn, err := dynamic.NewForConfig(restConfig) + if err != nil { + return nil, err + } + + return dyn.Resource(mapping.Resource).Namespace(u.GetNamespace()).Create(ctx, &u, metav1.CreateOptions{}) +} + // context is canceled or expired. func Poll(ctx context.Context, condition wait.ConditionWithContextFunc) error { return wait.PollUntilContextCancel(ctx, 100*time.Millisecond, true, condition) diff --git a/inttest/kubeletcertrotate/kubeletcertrotate_test.go b/inttest/kubeletcertrotate/kubeletcertrotate_test.go index d9576cd37017..418283b992f0 100644 --- a/inttest/kubeletcertrotate/kubeletcertrotate_test.go +++ b/inttest/kubeletcertrotate/kubeletcertrotate_test.go @@ -23,6 +23,7 @@ import ( apv1beta2 "github.com/k0sproject/k0s/pkg/apis/autopilot/v1beta2" apconst "github.com/k0sproject/k0s/pkg/autopilot/constant" appc "github.com/k0sproject/k0s/pkg/autopilot/controller/plans/core" + k0sclientset "github.com/k0sproject/k0s/pkg/client/clientset" "github.com/k0sproject/k0s/pkg/component/status" "github.com/k0sproject/k0s/inttest/common" @@ -84,15 +85,14 @@ func (s *kubeletCertRotateSuite) SetupTest() { } func (s *kubeletCertRotateSuite) applyPlan(id string) { - client, err := s.AutopilotClient(s.ControllerNode(0)) + ctx := s.Context() + + restConfig, err := s.GetKubeConfig(s.ControllerNode(0)) s.Require().NoError(err) - s.NotEmpty(client) // Ensure that a plan and yaml do not exist (safely) _, err = s.RunCommandController(0, "/usr/local/bin/k0s kubectl delete plan autopilot | true") s.Require().NoError(err) - _, err = s.RunCommandController(0, "rm -f /tmp/happy.yaml") - s.Require().NoError(err) planTemplate := ` apiVersion: autopilot.k0sproject.io/v1beta2 @@ -124,17 +124,16 @@ spec: - worker0 ` - // Apply the plan + // Create the plan - manifestFile := "/tmp/happy.yaml" - s.PutFileTemplate(s.ControllerNode(0), manifestFile, planTemplate, nil) - - out, err := s.RunCommandController(0, fmt.Sprintf("/usr/local/bin/k0s kubectl apply -f %s", manifestFile)) - s.T().Logf("kubectl apply output: '%s'", out) + _, err = common.Create(ctx, restConfig, []byte(planTemplate)) s.Require().NoError(err) + s.T().Logf("Plan created") // The plan has enough information to perform a successful update of k0s, so wait for it. - plan, err := aptest.WaitForPlanState(s.Context(), client, apconst.AutopilotName, appc.PlanCompleted) + client, err := k0sclientset.NewForConfig(restConfig) + s.Require().NoError(err) + plan, err := aptest.WaitForPlanState(ctx, client, apconst.AutopilotName, appc.PlanCompleted) s.Require().NoError(err) // Ensure all state/status are completed