From 3efcd0bd5c20c97b001b5d372dff55e417e60f24 Mon Sep 17 00:00:00 2001 From: rick Date: Fri, 20 Dec 2019 15:51:58 +0800 Subject: [PATCH] Add support to create a jnlp agent --- app/cmd/common.go | 5 ++ app/cmd/computer_create.go | 47 +++++++++++++++++++ app/cmd/computer_create_test.go | 68 +++++++++++++++++++++++++++ app/cmd/computer_delete.go | 43 +++++++++++++++++ app/cmd/computer_delete_test.go | 68 +++++++++++++++++++++++++++ app/cmd/computer_launch.go | 82 +++++++++++++++++++++++++++++---- app/cmd/computer_launch_test.go | 56 ++++++++++++++++------ app/cmd/credential_delete.go | 2 +- app/cmd/job_delete.go | 9 ++-- app/cmd/user_delete.go | 9 ++-- client/computer.go | 69 +++++++++++++++++++++++++++ client/computer_test.go | 29 ++++++++++-- client/computer_test_common.go | 32 +++++++++++++ 13 files changed, 485 insertions(+), 34 deletions(-) create mode 100644 app/cmd/computer_create.go create mode 100644 app/cmd/computer_create_test.go create mode 100644 app/cmd/computer_delete.go create mode 100644 app/cmd/computer_delete_test.go diff --git a/app/cmd/common.go b/app/cmd/common.go index 0652457..756e219 100644 --- a/app/cmd/common.go +++ b/app/cmd/common.go @@ -266,3 +266,8 @@ func getCurrentJenkinsAndClient(jClient *client.JenkinsCore) (jenkins *JenkinsSe } return } + +// GetAliasesDel returns the aliases for delete command +func GetAliasesDel() []string { + return []string{"remove", "del"} +} diff --git a/app/cmd/computer_create.go b/app/cmd/computer_create.go new file mode 100644 index 0000000..a48098f --- /dev/null +++ b/app/cmd/computer_create.go @@ -0,0 +1,47 @@ +package cmd + +import ( + "net/http" + + "github.com/jenkins-zh/jenkins-cli/client" + + "github.com/jenkins-zh/jenkins-cli/app/i18n" + + "github.com/spf13/cobra" +) + +// ComputerCreateOption option for config list command +type ComputerCreateOption struct { + OutputOption + + RoundTripper http.RoundTripper +} + +var computerCreateOption ComputerCreateOption + +func init() { + computerCmd.AddCommand(computerCreateCmd) +} + +var computerCreateCmd = &cobra.Command{ + Use: "create", + Short: i18n.T("Create an Jenkins agent"), + Long: i18n.T(`Create an Jenkins agent +It can only create a JNLP agent.`), + Example: `jcli agent create agent-name`, + Args: cobra.MinimumNArgs(1), + RunE: func(cmd *cobra.Command, args []string) (err error) { + jClient := &client.ComputerClient{ + JenkinsCore: client.JenkinsCore{ + RoundTripper: computerCreateOption.RoundTripper, + }, + } + getCurrentJenkinsAndClient(&(jClient.JenkinsCore)) + + err = jClient.Create(args[0]) + return + }, + Annotations: map[string]string{ + since: "v0.0.24", + }, +} diff --git a/app/cmd/computer_create_test.go b/app/cmd/computer_create_test.go new file mode 100644 index 0000000..72da4f1 --- /dev/null +++ b/app/cmd/computer_create_test.go @@ -0,0 +1,68 @@ +package cmd + +import ( + "bytes" + "io" + "io/ioutil" + "os" + + "github.com/jenkins-zh/jenkins-cli/client" + + "github.com/golang/mock/gomock" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/jenkins-zh/jenkins-cli/mock/mhttp" +) + +var _ = Describe("create list command", func() { + var ( + ctrl *gomock.Controller + roundTripper *mhttp.MockRoundTripper + buf io.Writer + ) + + BeforeEach(func() { + ctrl = gomock.NewController(GinkgoT()) + roundTripper = mhttp.NewMockRoundTripper(ctrl) + rootCmd.SetArgs([]string{}) + buf = new(bytes.Buffer) + rootCmd.SetOutput(buf) + rootOptions.Jenkins = "" + rootOptions.ConfigFile = "test.yaml" + + computerCreateOption.RoundTripper = roundTripper + }) + + AfterEach(func() { + rootCmd.SetArgs([]string{}) + os.Remove(rootOptions.ConfigFile) + rootOptions.ConfigFile = "" + ctrl.Finish() + }) + + Context("basic cases", func() { + var ( + err error + ) + + BeforeEach(func() { + var data []byte + data, err = generateSampleConfig() + Expect(err).To(BeNil()) + err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664) + Expect(err).To(BeNil()) + }) + + It("should success", func() { + name := "fake-name" + + client.PrepareForComputerCreateRequest(roundTripper, "http://localhost:8080/jenkins", + "admin", "111e3a2f0231198855dceaff96f20540a9", name) + + rootCmd.SetArgs([]string{"computer", "create", name}) + _, err = rootCmd.ExecuteC() + Expect(err).NotTo(HaveOccurred()) + }) + }) +}) diff --git a/app/cmd/computer_delete.go b/app/cmd/computer_delete.go new file mode 100644 index 0000000..5d7a82a --- /dev/null +++ b/app/cmd/computer_delete.go @@ -0,0 +1,43 @@ +package cmd + +import ( + "github.com/jenkins-zh/jenkins-cli/client" + + "github.com/jenkins-zh/jenkins-cli/app/i18n" + + "github.com/spf13/cobra" +) + +// ComputerDeleteOption option for agent delete command +type ComputerDeleteOption struct { + CommonOption +} + +var computerDeleteOption ComputerDeleteOption + +func init() { + computerCmd.AddCommand(computerDeleteCmd) +} + +var computerDeleteCmd = &cobra.Command{ + Use: "delete", + Aliases: GetAliasesDel(), + Short: i18n.T("Delete an agent from Jenkins"), + Long: i18n.T("Delete an agent from Jenkins"), + Args: cobra.MinimumNArgs(1), + Example: `jcli agent delete agent-name`, + RunE: func(cmd *cobra.Command, args []string) (err error) { + jClient := &client.ComputerClient{ + JenkinsCore: client.JenkinsCore{ + RoundTripper: computerDeleteOption.RoundTripper, + }, + } + getCurrentJenkinsAndClient(&(jClient.JenkinsCore)) + + err = jClient.Delete(args[0]) + return + }, + Annotations: map[string]string{ + since: "v0.0.24", + }, +} diff --git a/app/cmd/computer_delete_test.go b/app/cmd/computer_delete_test.go new file mode 100644 index 0000000..d57ffbc --- /dev/null +++ b/app/cmd/computer_delete_test.go @@ -0,0 +1,68 @@ +package cmd + +import ( + "bytes" + "io" + "io/ioutil" + "os" + + "github.com/jenkins-zh/jenkins-cli/client" + + "github.com/golang/mock/gomock" + . "github.com/onsi/ginkgo" + . "github.com/onsi/gomega" + + "github.com/jenkins-zh/jenkins-cli/mock/mhttp" +) + +var _ = Describe("create delete command", func() { + var ( + ctrl *gomock.Controller + roundTripper *mhttp.MockRoundTripper + buf io.Writer + ) + + BeforeEach(func() { + ctrl = gomock.NewController(GinkgoT()) + roundTripper = mhttp.NewMockRoundTripper(ctrl) + rootCmd.SetArgs([]string{}) + buf = new(bytes.Buffer) + rootCmd.SetOutput(buf) + rootOptions.Jenkins = "" + rootOptions.ConfigFile = "test.yaml" + + computerDeleteOption.RoundTripper = roundTripper + }) + + AfterEach(func() { + rootCmd.SetArgs([]string{}) + os.Remove(rootOptions.ConfigFile) + rootOptions.ConfigFile = "" + ctrl.Finish() + }) + + Context("basic cases", func() { + var ( + err error + ) + + BeforeEach(func() { + var data []byte + data, err = generateSampleConfig() + Expect(err).To(BeNil()) + err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664) + Expect(err).To(BeNil()) + }) + + It("should success", func() { + name := "fake-name" + + client.PrepareForComputerDeleteRequest(roundTripper, "http://localhost:8080/jenkins", + "admin", "111e3a2f0231198855dceaff96f20540a9", name) + + rootCmd.SetArgs([]string{"computer", "delete", name}) + _, err = rootCmd.ExecuteC() + Expect(err).NotTo(HaveOccurred()) + }) + }) +}) diff --git a/app/cmd/computer_launch.go b/app/cmd/computer_launch.go index f9f370d..11f9da5 100644 --- a/app/cmd/computer_launch.go +++ b/app/cmd/computer_launch.go @@ -1,7 +1,12 @@ package cmd import ( + "fmt" "github.com/jenkins-zh/jenkins-cli/client" + "github.com/jenkins-zh/jenkins-cli/util" + "go.uber.org/zap" + "io/ioutil" + "os" "github.com/jenkins-zh/jenkins-cli/app/i18n" @@ -11,34 +16,95 @@ import ( // ComputerLaunchOption option for config list command type ComputerLaunchOption struct { CommonOption + + Type string + ShowProgress bool + + /** share info between inner functions */ + ComputerClient *client.ComputerClient + CurrentJenkins *JenkinsServer + Output string } var computerLaunchOption ComputerLaunchOption func init() { computerCmd.AddCommand(computerLaunchCmd) + computerLaunchCmd.Flags().StringVarP(&computerLaunchOption.Type, "type", "", "", + i18n.T("The type of agent, include jnlp")) + computerLaunchCmd.Flags().BoolVarP(&computerLaunchOption.ShowProgress, "show-progress", "", true, + i18n.T("Show the progress of downloading agent.jar")) } var computerLaunchCmd = &cobra.Command{ - Use: "launch ", + Use: "launch", Aliases: []string{"start"}, Short: i18n.T("Launch the agent of your Jenkins"), Long: i18n.T("Launch the agent of your Jenkins"), Args: cobra.MinimumNArgs(1), + Example: `jcli agent launch agent-name +jcli agent launch agent-name --type jnlp`, + PreRunE: func(_ *cobra.Command, args []string) (err error) { + if computerLaunchOption.Type != "jnlp" { + return + } + + var f *os.File + if f, err = ioutil.TempFile("/tmp", "agent.jar"); err == nil { + computerLaunchOption.Output = f.Name() + downloader := util.HTTPDownloader{ + RoundTripper: computerLaunchOption.RoundTripper, + TargetFilePath: computerLaunchOption.Output, + URL: fmt.Sprintf("%s/jnlpJars/agent.jar", computerLaunchOption.ComputerClient.URL), + ShowProgress: computerLaunchOption.ShowProgress, + } + err = downloader.DownloadFile() + } + return + }, RunE: func(_ *cobra.Command, args []string) (err error) { + name := args[0] + jClient := &client.ComputerClient{ JenkinsCore: client.JenkinsCore{ RoundTripper: computerLaunchOption.RoundTripper, }, } - getCurrentJenkinsAndClient(&(jClient.JenkinsCore)) + computerLaunchOption.ComputerClient = jClient + computerLaunchOption.CurrentJenkins = getCurrentJenkinsAndClient(&(jClient.JenkinsCore)) - err = jClient.Launch(args[0]) + switch computerLaunchOption.Type { + case "": + err = computerLaunchOption.Launch(name) + case "jnlp": + err = computerLaunchOption.LaunchJnlp(name) + } return - // /computer/nginx/toggleOffline - // json: {"offlineMessage": "sdd", "Jenkins-Crumb": "c1482407700d5edfeca3d78315fe7ca33ba89caaaf55ae6b3c6f351fcc2f5470"} - - // /computer/nginx/changeOfflineCause - //json: {"offlineMessage": "被 jenkins : sdd断开连接", "Jenkins-Crumb": "c1482407700d5edfeca3d78315fe7ca33ba89caaaf55ae6b3c6f351fcc2f5470"} }, } + +// Launch start a normal agent +func (o *ComputerLaunchOption) Launch(name string) (err error) { + err = o.ComputerClient.Launch(name) + return +} + +// LaunchJnlp start a JNLP agent +func (o *ComputerLaunchOption) LaunchJnlp(name string) (err error) { + var secret string + if secret, err = o.ComputerClient.GetSecret(name); err == nil { + var binary string + binary, err = util.LookPath("java", centerStartOption.LookPathContext) + if err == nil { + env := os.Environ() + agentArgs := []string{"java", "-jar", computerLaunchOption.Output, + "-jnlpUrl", fmt.Sprintf("%s/computer/%s/slave-agent.jnlp", o.ComputerClient.URL, name), + "-secret", secret, "-workDir", "/tmp"} + + logger.Debug("start a jnlp agent", zap.Any("command", agentArgs)) + + err = util.Exec(binary, agentArgs, env, o.SystemCallExec) + } + } + return +} diff --git a/app/cmd/computer_launch_test.go b/app/cmd/computer_launch_test.go index 4e27151..13daba6 100644 --- a/app/cmd/computer_launch_test.go +++ b/app/cmd/computer_launch_test.go @@ -2,8 +2,10 @@ package cmd import ( "bytes" + "github.com/jenkins-zh/jenkins-cli/util" "io" "io/ioutil" + "net/http" "os" "github.com/jenkins-zh/jenkins-cli/client" @@ -20,6 +22,8 @@ var _ = Describe("computer launch command", func() { ctrl *gomock.Controller roundTripper *mhttp.MockRoundTripper buf io.Writer + err error + name string ) BeforeEach(func() { @@ -32,6 +36,13 @@ var _ = Describe("computer launch command", func() { rootOptions.ConfigFile = "test.yaml" computerLaunchOption.RoundTripper = roundTripper + name = "fake" + + var data []byte + data, err = generateSampleConfig() + Expect(err).To(BeNil()) + err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664) + Expect(err).To(BeNil()) }) AfterEach(func() { @@ -41,21 +52,8 @@ var _ = Describe("computer launch command", func() { ctrl.Finish() }) - Context("basic cases", func() { - var ( - err error - ) - - BeforeEach(func() { - var data []byte - data, err = generateSampleConfig() - Expect(err).To(BeNil()) - err = ioutil.WriteFile(rootOptions.ConfigFile, data, 0664) - Expect(err).To(BeNil()) - }) - + Context("launch a default type of agent", func() { It("should success", func() { - name := "fake" client.PrepareForLaunchComputer(roundTripper, "http://localhost:8080/jenkins", "admin", "111e3a2f0231198855dceaff96f20540a9", name) @@ -65,4 +63,34 @@ var _ = Describe("computer launch command", func() { Expect(err).To(BeNil()) }) }) + + Context("launch a jnlp agent", func() { + var ( + fakeJar string + ) + BeforeEach(func() { + fakeJar = "fake-jar-content" + computerLaunchOption.SystemCallExec = util.FakeSystemCallExecSuccess + computerLaunchOption.LookPathContext = util.FakeLookPath + + request, _ := http.NewRequest("GET", "http://localhost:8080/jenkins/jnlpJars/agent.jar", nil) + response := &http.Response{ + StatusCode: 200, + Request: request, + Body: ioutil.NopCloser(bytes.NewBufferString(fakeJar)), + } + roundTripper.EXPECT(). + RoundTrip(request).Return(response, nil) + + secret := "fake-secret" + client.PrepareForComputerAgentSecretRequest(roundTripper, + "http://localhost:8080/jenkins", "admin", "111e3a2f0231198855dceaff96f20540a9", name, secret) + }) + + It("should success", func() { + rootCmd.SetArgs([]string{"computer", "launch", name, "--type", "jnlp", "--show-progress=false"}) + _, err = rootCmd.ExecuteC() + Expect(err).NotTo(HaveOccurred()) + }) + }) }) diff --git a/app/cmd/credential_delete.go b/app/cmd/credential_delete.go index 6291ec5..ac1ffda 100644 --- a/app/cmd/credential_delete.go +++ b/app/cmd/credential_delete.go @@ -32,7 +32,7 @@ func init() { var credentialDeleteCmd = &cobra.Command{ Use: "delete [store] [id]", - Aliases: []string{"remove", "del"}, + Aliases: GetAliasesDel(), Short: i18n.T("Delete a credential from Jenkins"), Long: i18n.T("Delete a credential from Jenkins"), PreRunE: func(cmd *cobra.Command, args []string) (err error) { diff --git a/app/cmd/job_delete.go b/app/cmd/job_delete.go index a2c6511..019da01 100644 --- a/app/cmd/job_delete.go +++ b/app/cmd/job_delete.go @@ -26,10 +26,11 @@ func init() { } var jobDeleteCmd = &cobra.Command{ - Use: "delete ", - Short: i18n.T("Delete a job in your Jenkins"), - Long: i18n.T("Delete a job in your Jenkins"), - Args: cobra.MinimumNArgs(1), + Use: "delete ", + Aliases: GetAliasesDel(), + Short: i18n.T("Delete a job in your Jenkins"), + Long: i18n.T("Delete a job in your Jenkins"), + Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { jobName := args[0] if !jobDeleteOption.Confirm(fmt.Sprintf("Are you sure to delete job %s ?", jobName)) { diff --git a/app/cmd/user_delete.go b/app/cmd/user_delete.go index 26efe88..ec85664 100644 --- a/app/cmd/user_delete.go +++ b/app/cmd/user_delete.go @@ -24,10 +24,11 @@ func init() { } var userDeleteCmd = &cobra.Command{ - Use: "delete ", - Short: "Delete a user for your Jenkins", - Long: `Delete a user for your Jenkins`, - Args: cobra.MinimumNArgs(1), + Use: "delete ", + Aliases: GetAliasesDel(), + Short: "Delete a user for your Jenkins", + Long: `Delete a user for your Jenkins`, + Args: cobra.MinimumNArgs(1), Run: func(cmd *cobra.Command, args []string) { username := args[0] diff --git a/client/computer.go b/client/computer.go index e5976c2..873bfba 100644 --- a/client/computer.go +++ b/client/computer.go @@ -2,8 +2,11 @@ package client import ( "fmt" + "github.com/jenkins-zh/jenkins-cli/util" "io/ioutil" "net/http" + "net/url" + "strings" ) // ComputerClient is client for operate computers @@ -25,6 +28,26 @@ func (c *ComputerClient) Launch(name string) (err error) { return } +// Delete removes a agent from Jenkins +func (c *ComputerClient) Delete(name string) (err error) { + api := fmt.Sprintf("/computer/%s/doDelete", name) + _, err = c.RequestWithoutData("POST", api, nil, nil, 200) + return +} + +// GetSecret returns the secret of an agent +func (c *ComputerClient) GetSecret(name string) (secret string, err error) { + api := fmt.Sprintf("/instance/agentSecret?name=%s", name) + var response *http.Response + if response, err = c.RequestWithResponse("POST", api, nil, nil); err == nil { + var data []byte + if data, err = ioutil.ReadAll(response.Body); err == nil { + secret = string(data) + } + } + return +} + // GetLog fetch the log a computer func (c *ComputerClient) GetLog(name string) (log string, err error) { var response *http.Response @@ -44,6 +67,52 @@ func (c *ComputerClient) GetLog(name string) (log string, err error) { return } +// Create creates a computer by name +func (c *ComputerClient) Create(name string) (err error) { + formData := url.Values{ + "name": {name}, + "mode": {"hudson.slaves.DumbSlave"}, + } + payload := strings.NewReader(formData.Encode()) + if _, err = c.RequestWithoutData("POST", "/computer/createItem", + map[string]string{util.ContentType: util.ApplicationForm}, payload, 200); err == nil { + payload = GetPayloadForCreateAgent(name) + _, err = c.RequestWithoutData("POST", "/computer/doCreateItem", + map[string]string{util.ContentType: util.ApplicationForm}, payload, 200) + } + return +} + +// GetPayloadForCreateAgent returns a payload for creating an agent +func GetPayloadForCreateAgent(name string) *strings.Reader { + palyLoad := fmt.Sprintf(`{ + "name": "%s", + "nodeDescription": "", + "numExecutors": "1", + "remoteFS": "/abc", + "labelString": "", + "mode": "NORMAL", + "launcher": { + "$class": "hudson.slaves.JNLPLauncher", + "workDirSettings": { + "disabled": false, + "workDirPath": "", + "internalDir": "remoting", + "failIfWorkDirIsMissing": false + }, + "tunnel": "", + "vmargs": "" + }, + "type": "hudson.slaves.DumbSlave" +}`, name) + formData := url.Values{ + "name": {name}, + "type": {"hudson.slaves.DumbSlave"}, + "json": {palyLoad}, + } + return strings.NewReader(formData.Encode()) +} + // Computer is the agent of Jenkins type Computer struct { AssignedLabels []ComputerLabel diff --git a/client/computer_test.go b/client/computer_test.go index 6d7be39..4456731 100644 --- a/client/computer_test.go +++ b/client/computer_test.go @@ -13,6 +13,7 @@ var _ = Describe("computer test", func() { ctrl *gomock.Controller computerClient client.ComputerClient roundTripper *mhttp.MockRoundTripper + name string ) BeforeEach(func() { @@ -22,6 +23,7 @@ var _ = Describe("computer test", func() { computerClient = client.ComputerClient{} computerClient.RoundTripper = roundTripper computerClient.URL = "http://localhost" + name = "fake-name" }) AfterEach(func() { @@ -38,7 +40,6 @@ var _ = Describe("computer test", func() { }) It("Launch", func() { - name := "fake-name" client.PrepareForLaunchComputer(roundTripper, computerClient.URL, "", "", name) err := computerClient.Launch(name) @@ -46,7 +47,6 @@ var _ = Describe("computer test", func() { }) It("GetLog", func() { - name := "fake-name" client.PrepareForComputerLogRequest(roundTripper, computerClient.URL, "", "", name) log, err := computerClient.GetLog(name) @@ -55,10 +55,33 @@ var _ = Describe("computer test", func() { }) It("GetLog with 500", func() { - name := "fake-name" client.PrepareForComputerLogRequestWithCode(roundTripper, computerClient.URL, "", "", name, 500) _, err := computerClient.GetLog(name) Expect(err).To(HaveOccurred()) }) + + It("Delete an agent", func() { + client.PrepareForComputerDeleteRequest(roundTripper, computerClient.URL, "", "", name) + + err := computerClient.Delete(name) + Expect(err).NotTo(HaveOccurred()) + }) + + It("GetSecret of an agent", func() { + secret := "fake-secret" + client.PrepareForComputerAgentSecretRequest(roundTripper, + computerClient.URL, "", "", name, secret) + + result, err := computerClient.GetSecret(name) + Expect(err).NotTo(HaveOccurred()) + Expect(result).To(Equal(secret)) + }) + + It("Create an agent", func() { + client.PrepareForComputerCreateRequest(roundTripper, computerClient.URL, "", "", name) + + err := computerClient.Create(name) + Expect(err).NotTo(HaveOccurred()) + }) }) diff --git a/client/computer_test_common.go b/client/computer_test_common.go index e9256a6..b7a7128 100644 --- a/client/computer_test_common.go +++ b/client/computer_test_common.go @@ -3,8 +3,11 @@ package client import ( "bytes" "fmt" + "github.com/jenkins-zh/jenkins-cli/util" "io/ioutil" "net/http" + "net/url" + "strings" "github.com/jenkins-zh/jenkins-cli/mock/mhttp" ) @@ -51,6 +54,35 @@ func PrepareForComputerLogRequestWithCode(roundTripper *mhttp.MockRoundTripper, } } +// PrepareForComputerDeleteRequest only for test +func PrepareForComputerDeleteRequest(roundTripper *mhttp.MockRoundTripper, rootURL, user, password, name string) { + request, _ := http.NewRequest("POST", fmt.Sprintf("%s/computer/%s/doDelete", rootURL, name), nil) + PrepareCommonPost(request, "", roundTripper, user, password, rootURL) +} + +// PrepareForComputerAgentSecretRequest only for test +func PrepareForComputerAgentSecretRequest(roundTripper *mhttp.MockRoundTripper, rootURL, user, password, name, secret string) { + request, _ := http.NewRequest("POST", fmt.Sprintf("%s/instance/agentSecret?name=%s", rootURL, name), nil) + PrepareCommonPost(request, secret, roundTripper, user, password, rootURL) +} + +// PrepareForComputerCreateRequest only for test +func PrepareForComputerCreateRequest(roundTripper *mhttp.MockRoundTripper, rootURL, user, password, name string) { + formData := url.Values{ + "name": {name}, + "mode": {"hudson.slaves.DumbSlave"}, + } + payload := strings.NewReader(formData.Encode()) + request, _ := http.NewRequest("POST", fmt.Sprintf("%s/computer/createItem", rootURL), payload) + request.Header.Add(util.ContentType, util.ApplicationForm) + PrepareCommonPost(request, "", roundTripper, user, password, rootURL) + + payload = GetPayloadForCreateAgent(name) + request, _ = http.NewRequest("POST", fmt.Sprintf("%s/computer/doCreateItem", rootURL), payload) + request.Header.Add(util.ContentType, util.ApplicationForm) + PrepareCommonPost(request, "", roundTripper, user, password, rootURL) +} + // PrepareForComputerList only for test func PrepareForComputerList() string { return ` -- GitLab