mirror of
https://github.com/kubesphere/kubekey.git
synced 2025-12-26 01:22:51 +00:00
feat: run gather_facts by module (#2588)
Signed-off-by: joyceliu <joyceliu@yunify.com>
This commit is contained in:
parent
de5cc690e2
commit
202700fb43
|
|
@ -4,7 +4,6 @@ import (
|
|||
"context"
|
||||
"encoding/json"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
"github.com/cockroachdb/errors"
|
||||
kkcorev1 "github.com/kubesphere/kubekey/api/core/v1"
|
||||
|
|
@ -182,5 +181,5 @@ func (e blockExecutor) dealTask(ctx context.Context, hosts []string, when []stri
|
|||
return errors.Wrapf(err, "failed to set playbook %q ownerReferences to %q", ctrlclient.ObjectKeyFromObject(e.playbook), block.Name)
|
||||
}
|
||||
|
||||
return (&taskExecutor{option: e.option, task: task, taskRunTimeout: 60 * time.Minute}).Exec(ctx)
|
||||
return (&taskExecutor{option: e.option, task: task}).Exec(ctx)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,11 +22,12 @@ import (
|
|||
|
||||
"github.com/cockroachdb/errors"
|
||||
kkcorev1 "github.com/kubesphere/kubekey/api/core/v1"
|
||||
kkcorev1alpha1 "github.com/kubesphere/kubekey/api/core/v1alpha1"
|
||||
kkprojectv1 "github.com/kubesphere/kubekey/api/project/v1"
|
||||
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||||
"k8s.io/klog/v2"
|
||||
ctrlclient "sigs.k8s.io/controller-runtime/pkg/client"
|
||||
|
||||
"github.com/kubesphere/kubekey/v4/pkg/connector"
|
||||
"github.com/kubesphere/kubekey/v4/pkg/converter"
|
||||
"github.com/kubesphere/kubekey/v4/pkg/project"
|
||||
"github.com/kubesphere/kubekey/v4/pkg/variable"
|
||||
|
|
@ -199,36 +200,21 @@ func (e playbookExecutor) dealGatherFacts(ctx context.Context, gatherFacts bool,
|
|||
// skip
|
||||
return nil
|
||||
}
|
||||
dealGatherFactsInHost := func(hostname string) error {
|
||||
// get host connector
|
||||
conn, err := connector.NewConnector(hostname, e.variable)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := conn.Init(ctx); err != nil {
|
||||
return err
|
||||
}
|
||||
defer conn.Close(ctx)
|
||||
// run as option
|
||||
|
||||
if gf, ok := conn.(connector.GatherFacts); ok {
|
||||
remoteInfo, err := gf.HostInfo(ctx)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if err := e.variable.Merge(variable.MergeRemoteVariable(remoteInfo, hostname)); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
for _, hostname := range hosts {
|
||||
if err := dealGatherFactsInHost(hostname); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
return (&taskExecutor{option: e.option, task: &kkcorev1alpha1.Task{
|
||||
ObjectMeta: metav1.ObjectMeta{
|
||||
GenerateName: e.playbook.Name + "-",
|
||||
Namespace: e.playbook.Namespace,
|
||||
},
|
||||
Spec: kkcorev1alpha1.TaskSpec{
|
||||
Name: "gather_facts",
|
||||
Hosts: hosts,
|
||||
Module: kkcorev1alpha1.Module{
|
||||
Name: "setup",
|
||||
},
|
||||
},
|
||||
}}).Exec(ctx)
|
||||
}
|
||||
|
||||
// dealSerial "serial" argument in playbook.
|
||||
|
|
|
|||
|
|
@ -39,6 +39,9 @@ type taskExecutor struct {
|
|||
// Exec creates and executes a task, updating its status and the parent playbook's status.
|
||||
// It returns an error if the task creation or execution fails.
|
||||
func (e *taskExecutor) Exec(ctx context.Context) error {
|
||||
if e.taskRunTimeout == time.Duration(0) {
|
||||
e.taskRunTimeout = 60 * time.Minute
|
||||
}
|
||||
// create task
|
||||
if err := e.client.Create(ctx, e.task); err != nil {
|
||||
return errors.Wrapf(err, "failed to create task %q", e.task.Spec.Name)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,54 @@
|
|||
package modules
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
|
||||
utilruntime "k8s.io/apimachinery/pkg/util/runtime"
|
||||
|
||||
"github.com/kubesphere/kubekey/v4/pkg/connector"
|
||||
"github.com/kubesphere/kubekey/v4/pkg/variable"
|
||||
)
|
||||
|
||||
/*
|
||||
Module Setup
|
||||
|
||||
This module is used to set up the connection to a remote host and gather facts about it.
|
||||
It performs the following operations:
|
||||
1. Establishes a connection to the specified host using the appropriate connector
|
||||
2. If the connector supports fact gathering (implements GatherFacts interface):
|
||||
- Retrieves host information
|
||||
- Merges the remote host information into the variables map
|
||||
3. Returns success if all operations complete successfully
|
||||
|
||||
Usage:
|
||||
- host: The target host to connect to
|
||||
- variable: Map of variables to be used for connection and fact gathering
|
||||
*/
|
||||
|
||||
// ModuleSetup establishes a connection to a remote host and gathers facts about it.
|
||||
// It returns StdoutSuccess if successful, or an error message if any step fails.
|
||||
func ModuleSetup(ctx context.Context, options ExecOptions) (string, string) {
|
||||
// get connector
|
||||
conn, err := getConnector(ctx, options.Host, options.Variable)
|
||||
if err != nil {
|
||||
return "", fmt.Sprintf("failed to connector of %q error: %v", options.Host, err)
|
||||
}
|
||||
defer conn.Close(ctx)
|
||||
|
||||
if gf, ok := conn.(connector.GatherFacts); ok {
|
||||
remoteInfo, err := gf.HostInfo(ctx)
|
||||
if err != nil {
|
||||
return "", err.Error()
|
||||
}
|
||||
if err := options.Variable.Merge(variable.MergeRemoteVariable(remoteInfo, options.Host)); err != nil {
|
||||
return "", err.Error()
|
||||
}
|
||||
}
|
||||
|
||||
return StdoutSuccess, ""
|
||||
}
|
||||
|
||||
func init() {
|
||||
utilruntime.Must(RegisterModule("setup", ModuleSetup))
|
||||
}
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
package modules
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestModuleSetup(t *testing.T) {
|
||||
testcases := []struct {
|
||||
name string
|
||||
opt ExecOptions
|
||||
ctxFunc func() context.Context
|
||||
exceptStdout string
|
||||
exceptStderr string
|
||||
}{
|
||||
{
|
||||
name: "successful setup with fact gathering",
|
||||
opt: ExecOptions{
|
||||
Host: "test-host",
|
||||
Variable: &testVariable{},
|
||||
},
|
||||
ctxFunc: func() context.Context {
|
||||
return context.WithValue(context.Background(), ConnKey, successConnector)
|
||||
},
|
||||
exceptStdout: StdoutSuccess,
|
||||
exceptStderr: "",
|
||||
},
|
||||
{
|
||||
name: "failed connector setup",
|
||||
opt: ExecOptions{
|
||||
Host: "invalid-host",
|
||||
Variable: &testVariable{},
|
||||
},
|
||||
ctxFunc: context.Background,
|
||||
exceptStdout: "",
|
||||
exceptStderr: "failed to connector of \"invalid-host\" error:",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tc := range testcases {
|
||||
t.Run(tc.name, func(t *testing.T) {
|
||||
ctx, cancel := context.WithTimeout(tc.ctxFunc(), time.Second*5)
|
||||
defer cancel()
|
||||
|
||||
stdout, stderr := ModuleSetup(ctx, tc.opt)
|
||||
assert.Contains(t, stdout, tc.exceptStdout)
|
||||
if tc.exceptStderr != "" {
|
||||
assert.Contains(t, stderr, tc.exceptStderr)
|
||||
} else {
|
||||
assert.Empty(t, stderr)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue