From 9d12e547d43d0e2034749d01be6259dc2c6ff7bc Mon Sep 17 00:00:00 2001 From: Ansh Garhewal Date: Sun, 21 Jul 2024 16:12:28 +0530 Subject: [PATCH] fix: refactored to support context API - Context API support is added to the Jenkins API interface. --- pkg/client/jenkins.go | 75 +++++++++++---------- pkg/client/job.go | 5 +- pkg/client/mockgen.go | 17 ++--- pkg/client/script.go | 5 +- pkg/client/token.go | 3 +- pkg/configuration/user/seedjobs/seedjobs.go | 4 +- test/e2e/jenkins_pod_restart_test.go | 2 +- test/e2e/restorebackup_test.go | 6 +- test/e2e/seedjobs_test.go | 12 ++-- test/e2e/wait.go | 2 +- 10 files changed, 68 insertions(+), 63 deletions(-) diff --git a/pkg/client/jenkins.go b/pkg/client/jenkins.go index e84809d2..3216b5be 100644 --- a/pkg/client/jenkins.go +++ b/pkg/client/jenkins.go @@ -2,6 +2,7 @@ package client import ( "bytes" + "context" "fmt" "io" "net/http" @@ -20,41 +21,41 @@ var ( // Jenkins defines Jenkins API. type Jenkins interface { GenerateToken(userName, tokenName string) (*UserToken, error) - Info() (*gojenkins.ExecutorResponse, error) - SafeRestart() error - CreateNode(name string, numExecutors int, description string, remoteFS string, label string, options ...interface{}) (*gojenkins.Node, error) - DeleteNode(name string) (bool, error) - CreateFolder(name string, parents ...string) (*gojenkins.Folder, error) - CreateJobInFolder(config string, jobName string, parentIDs ...string) (*gojenkins.Job, error) - CreateJob(config string, options ...interface{}) (*gojenkins.Job, error) + Info(ctx context.Context) (*gojenkins.ExecutorResponse, error) + SafeRestart(ctx context.Context) error + CreateNode(ctx context.Context, name string, numExecutors int, description string, remoteFS string, label string, options ...interface{}) (*gojenkins.Node, error) + DeleteNode(ctx context.Context, name string) (bool, error) + CreateFolder(ctx context.Context, name string, parents ...string) (*gojenkins.Folder, error) + CreateJobInFolder(ctx context.Context, config string, jobName string, parentIDs ...string) (*gojenkins.Job, error) + CreateJob(ctx context.Context, config string, options ...interface{}) (*gojenkins.Job, error) CreateOrUpdateJob(config, jobName string) (*gojenkins.Job, bool, error) - RenameJob(job string, name string) *gojenkins.Job - CopyJob(copyFrom string, newName string) (*gojenkins.Job, error) - DeleteJob(name string) (bool, error) - BuildJob(name string, options ...interface{}) (int64, error) - GetNode(name string) (*gojenkins.Node, error) - GetLabel(name string) (*gojenkins.Label, error) + RenameJob(ctx context.Context, job string, name string) *gojenkins.Job + CopyJob(ctx context.Context, copyFrom string, newName string) (*gojenkins.Job, error) + CreateView(ctx context.Context, name string, viewType string) (*gojenkins.View, error) + DeleteJob(ctx context.Context, name string) (bool, error) + BuildJob(ctx context.Context, name string, options map[string]string) (int64, error) + GetNode(ctx context.Context, name string) (*gojenkins.Node, error) + GetLabel(ctx context.Context, name string) (*gojenkins.Label, error) GetBuild(jobName string, number int64) (*gojenkins.Build, error) - GetJob(id string, parentIDs ...string) (*gojenkins.Job, error) - GetSubJob(parentID string, childID string) (*gojenkins.Job, error) - GetFolder(id string, parents ...string) (*gojenkins.Folder, error) - GetAllNodes() ([]*gojenkins.Node, error) - GetAllBuildIds(job string) ([]gojenkins.JobBuild, error) - GetAllJobNames() ([]gojenkins.InnerJob, error) - GetAllJobs() ([]*gojenkins.Job, error) - GetQueue() (*gojenkins.Queue, error) + GetJob(ctx context.Context, id string, parentIDs ...string) (*gojenkins.Job, error) + GetSubJob(ctx context.Context, parentID string, childID string) (*gojenkins.Job, error) + GetFolder(ctx context.Context, id string, parents ...string) (*gojenkins.Folder, error) + GetAllNodes(ctx context.Context) ([]*gojenkins.Node, error) + GetAllBuildIds(ctx context.Context, job string) ([]gojenkins.JobBuild, error) + GetAllJobNames(context.Context) ([]gojenkins.InnerJob, error) + GetAllJobs(context.Context) ([]*gojenkins.Job, error) + GetQueue(context.Context) (*gojenkins.Queue, error) GetQueueUrl() string - GetQueueItem(id int64) (*gojenkins.Task, error) - GetArtifactData(id string) (*gojenkins.FingerPrintResponse, error) + GetQueueItem(ctx context.Context, id int64) (*gojenkins.Task, error) + GetArtifactData(ctx context.Context, id string) (*gojenkins.FingerPrintResponse, error) GetPlugins(depth int) (*gojenkins.Plugins, error) - UninstallPlugin(name string) error - HasPlugin(name string) (*gojenkins.Plugin, error) - InstallPlugin(name string, version string) error - ValidateFingerPrint(id string) (bool, error) - GetView(name string) (*gojenkins.View, error) - GetAllViews() ([]*gojenkins.View, error) - CreateView(name string, viewType string) (*gojenkins.View, error) - Poll() (int, error) + UninstallPlugin(ctx context.Context, name string) error + HasPlugin(ctx context.Context, name string) (*gojenkins.Plugin, error) + InstallPlugin(ctx context.Context, name string, version string) error + ValidateFingerPrint(ctx context.Context, id string) (bool, error) + GetView(ctx context.Context, name string) (*gojenkins.View, error) + GetAllViews(context.Context) ([]*gojenkins.View, error) + Poll(ctx context.Context) (int, error) ExecuteScript(groovyScript string) (logs string, err error) GetNodeSecret(name string) (string, error) } @@ -90,15 +91,15 @@ func (t *setBearerToken) RoundTrip(r *http.Request) (*http.Response, error) { // CreateOrUpdateJob creates or updates a job from config. func (jenkins *jenkins) CreateOrUpdateJob(config, jobName string) (job *gojenkins.Job, created bool, err error) { // create or update - job, err = jenkins.GetJob(jobName) + job, err = jenkins.GetJob(context.TODO(), jobName) if isNotFoundError(err) { - job, err = jenkins.CreateJob(config, jobName) + job, err = jenkins.CreateJob(context.TODO(), config, jobName) return job, true, errors.WithStack(err) } else if err != nil { return job, false, errors.WithStack(err) } - err = job.UpdateConfig(config) + err = job.UpdateConfig(context.TODO(), config) return job, false, errors.WithStack(err) } @@ -173,11 +174,11 @@ func newClient(url, userName, passwordOrToken string) (Jenkins, error) { Client: httpClient, BasicAuth: basicAuth, } - if _, err := jenkinsClient.Init(); err != nil { + if _, err := jenkinsClient.Init(context.TODO()); err != nil { return nil, errors.Wrap(err, "couldn't init Jenkins API client") } - status, err := jenkinsClient.Poll() + status, err := jenkinsClient.Poll(context.TODO()) if err != nil { return nil, errors.Wrap(err, "couldn't poll data from Jenkins API") } @@ -234,7 +235,7 @@ func (jenkins *jenkins) GetNodeSecret(name string) (string, error) { // You can supply depth parameter, to limit how much data is returned. func (jenkins *jenkins) GetPlugins(depth int) (*gojenkins.Plugins, error) { p := gojenkins.Plugins{Jenkins: &jenkins.Jenkins, Raw: new(gojenkins.PluginResponse), Base: "/pluginManager", Depth: depth} - statusCode, err := p.Poll() + statusCode, err := p.Poll(context.TODO()) if err != nil { return nil, err } diff --git a/pkg/client/job.go b/pkg/client/job.go index 5c00ee5c..a15c6075 100644 --- a/pkg/client/job.go +++ b/pkg/client/job.go @@ -1,13 +1,14 @@ package client import ( + "context" "net/url" "github.com/bndr/gojenkins" ) func (jenkins *jenkins) GetBuild(jobName string, number int64) (*gojenkins.Build, error) { - job, err := jenkins.GetJob(jobName) + job, err := jenkins.GetJob(context.TODO(), jobName) if err != nil { return nil, err } @@ -21,7 +22,7 @@ func (jenkins *jenkins) GetBuild(jobName string, number int64) (*gojenkins.Build job.Raw.URL = jobURL.RequestURI() // workaround end - build, err := job.GetBuild(number) + build, err := job.GetBuild(context.TODO(), number) if err != nil { return nil, err diff --git a/pkg/client/mockgen.go b/pkg/client/mockgen.go index fca9c5c0..da81d04e 100644 --- a/pkg/client/mockgen.go +++ b/pkg/client/mockgen.go @@ -5,6 +5,7 @@ package client import ( + "context" "reflect" "github.com/bndr/gojenkins" @@ -63,7 +64,7 @@ func (mr *MockJenkinsMockRecorder) GenerateToken(userName, tokenName interface{} } // Info mocks base method -func (m *MockJenkins) Info() (*gojenkins.ExecutorResponse, error) { +func (m *MockJenkins) Info(context.Context) (*gojenkins.ExecutorResponse, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "Info") ret0, _ := ret[0].(*gojenkins.ExecutorResponse) @@ -78,7 +79,7 @@ func (mr *MockJenkinsMockRecorder) Info() *gomock.Call { } // SafeRestart mocks base method -func (m *MockJenkins) SafeRestart() error { +func (m *MockJenkins) SafeRestart(context.Context) error { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "SafeRestart") ret0, _ := ret[0].(error) @@ -92,7 +93,7 @@ func (mr *MockJenkinsMockRecorder) SafeRestart() *gomock.Call { } // CreateNode mocks base method -func (m *MockJenkins) CreateNode(name string, numExecutors int, description, remoteFS, label string, options ...interface{}) (*gojenkins.Node, error) { +func (m *MockJenkins) CreateNode(ctx context.Context,name string, numExecutors int, description, remoteFS, label string, options ...interface{}) (*gojenkins.Node, error) { m.ctrl.T.Helper() varargs := []interface{}{name, numExecutors, description, remoteFS, label} for _, a := range options { @@ -112,7 +113,7 @@ func (mr *MockJenkinsMockRecorder) CreateNode(name, numExecutors, description, r } // DeleteNode mocks base method -func (m *MockJenkins) DeleteNode(name string) (bool, error) { +func (m *MockJenkins) DeleteNode(ctx context.Context,name string) (bool, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "DeleteNode", name) ret0, _ := ret[0].(bool) @@ -127,7 +128,7 @@ func (mr *MockJenkinsMockRecorder) DeleteNode(name interface{}) *gomock.Call { } // CreateFolder mocks base method -func (m *MockJenkins) CreateFolder(name string, parents ...string) (*gojenkins.Folder, error) { +func (m *MockJenkins) CreateFolder(ctx context.Context,name string, parents ...string) (*gojenkins.Folder, error) { m.ctrl.T.Helper() varargs := []interface{}{name} for _, a := range parents { @@ -147,7 +148,7 @@ func (mr *MockJenkinsMockRecorder) CreateFolder(name interface{}, parents ...int } // CreateJobInFolder mocks base method -func (m *MockJenkins) CreateJobInFolder(config, jobName string, parentIDs ...string) (*gojenkins.Job, error) { +func (m *MockJenkins) CreateJobInFolder(ctx context.Context,config, jobName string, parentIDs ...string) (*gojenkins.Job, error) { m.ctrl.T.Helper() varargs := []interface{}{config, jobName} for _, a := range parentIDs { @@ -160,14 +161,14 @@ func (m *MockJenkins) CreateJobInFolder(config, jobName string, parentIDs ...str } // CreateJobInFolder indicates an expected call of CreateJobInFolder -func (mr *MockJenkinsMockRecorder) CreateJobInFolder(config, jobName interface{}, parentIDs ...interface{}) *gomock.Call { +func (mr *MockJenkinsMockRecorder) CreateJobInFolder(ctx context.Context,config, jobName interface{}, parentIDs ...interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() varargs := append([]interface{}{config, jobName}, parentIDs...) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "CreateJobInFolder", reflect.TypeOf((*MockJenkins)(nil).CreateJobInFolder), varargs...) } // CreateJob mocks base method -func (m *MockJenkins) CreateJob(config string, options ...interface{}) (*gojenkins.Job, error) { +func (m *MockJenkins) CreateJob(ctx context.Context,config string, options ...interface{}) (*gojenkins.Job, error) { m.ctrl.T.Helper() varargs := []interface{}{config} for _, a := range options { diff --git a/pkg/client/script.go b/pkg/client/script.go index c9a2f6ad..108cf783 100644 --- a/pkg/client/script.go +++ b/pkg/client/script.go @@ -2,6 +2,7 @@ package client import ( "bytes" + "context" "fmt" "net/http" "net/url" @@ -38,13 +39,13 @@ func (jenkins *jenkins) executeScript(script string, verifier string) (string, e data.Set("script", fullScript) ar := gojenkins.NewAPIRequest("POST", "/scriptText", bytes.NewBufferString(data.Encode())) - if err := jenkins.Requester.SetCrumb(ar); err != nil { + if err := jenkins.Requester.SetCrumb(context.TODO(), ar); err != nil { return output, err } ar.SetHeader("Content-Type", "application/x-www-form-urlencoded") ar.Suffix = "" - r, err := jenkins.Requester.Do(ar, &output, nil) + r, err := jenkins.Requester.Do(context.TODO(), ar, &output, nil) if err != nil { return "", errors.Wrapf(err, "couldn't execute groovy script, logs '%s'", output) } diff --git a/pkg/client/token.go b/pkg/client/token.go index 6cca2e3b..5cb401fb 100644 --- a/pkg/client/token.go +++ b/pkg/client/token.go @@ -1,6 +1,7 @@ package client import ( + "context" "fmt" "net/http" @@ -34,7 +35,7 @@ func (jenkins *jenkins) GenerateToken(userName, tokenName string) (*UserToken, e base: fmt.Sprintf("/user/%s/descriptorByName/jenkins.security.ApiTokenProperty/generateNewToken", userName)} endpoint := token.base data := map[string]string{"newTokenName": tokenName} - r, err := jenkins.Requester.Post(endpoint, nil, token.raw, data) + r, err := jenkins.Requester.Post(context.TODO(), endpoint, nil, token.raw, data) if err != nil { return nil, errors.Wrap(err, "couldn't generate API token") } diff --git a/pkg/configuration/user/seedjobs/seedjobs.go b/pkg/configuration/user/seedjobs/seedjobs.go index 8aa12486..5d3a10a0 100644 --- a/pkg/configuration/user/seedjobs/seedjobs.go +++ b/pkg/configuration/user/seedjobs/seedjobs.go @@ -369,11 +369,11 @@ func (s *seedJobs) isRecreatePodNeeded(jenkins v1alpha2.Jenkins) bool { // createAgent deploys Jenkins agent to Kubernetes cluster func (s *seedJobs) createAgent(jenkinsClient jenkinsclient.Jenkins, k8sClient client.Client, jenkinsManifest *v1alpha2.Jenkins, namespace string, agentName string) error { - _, err := jenkinsClient.GetNode(agentName) + _, err := jenkinsClient.GetNode(context.TODO(), agentName) // Create node if not exists if err != nil && err.Error() == "No node found" { - _, err = jenkinsClient.CreateNode(agentName, 5, "The jenkins-operator generated agent", "/home/jenkins", agentName) + _, err = jenkinsClient.CreateNode(context.TODO(), agentName, 5, "The jenkins-operator generated agent", "/home/jenkins", agentName) if err != nil { return stackerr.WithStack(err) } diff --git a/test/e2e/jenkins_pod_restart_test.go b/test/e2e/jenkins_pod_restart_test.go index 4d474329..1888c639 100644 --- a/test/e2e/jenkins_pod_restart_test.go +++ b/test/e2e/jenkins_pod_restart_test.go @@ -103,7 +103,7 @@ var _ = Describe("Jenkins controller", func() { jenkinsClient, cleanUpFunc := verifyJenkinsAPIConnection(jenkins, namespace.Name) defer cleanUpFunc() checkIfAuthorizationStrategyUnsecuredIsSet(jenkinsClient) - err := jenkinsClient.SafeRestart() + err := jenkinsClient.SafeRestart(context.TODO()) Expect(err).NotTo(HaveOccurred()) waitForJenkinsSafeRestart(jenkinsClient) checkIfAuthorizationStrategyUnsecuredIsSet(jenkinsClient) diff --git a/test/e2e/restorebackup_test.go b/test/e2e/restorebackup_test.go index 3b195af0..8477b64b 100644 --- a/test/e2e/restorebackup_test.go +++ b/test/e2e/restorebackup_test.go @@ -25,7 +25,7 @@ func waitForJobCreation(jenkinsClient client.Jenkins, jobID string) { var err error Eventually(func() (bool, error) { - _, err = jenkinsClient.GetJob(jobID) + _, err = jenkinsClient.GetJob(context.TODO(), jobID) if err != nil { return false, err } @@ -38,9 +38,9 @@ func waitForJobCreation(jenkinsClient client.Jenkins, jobID string) { func verifyJobBuildsAfterRestoreBackup(jenkinsClient client.Jenkins, jobID string) { By("checking if job builds after restoring backup") - job, err := jenkinsClient.GetJob(jobID) + job, err := jenkinsClient.GetJob(context.TODO(), jobID) Expect(err).NotTo(HaveOccurred()) - build, err := job.GetLastBuild() + build, err := job.GetLastBuild(context.TODO()) Expect(err).NotTo(HaveOccurred()) Expect(build.GetBuildNumber()).To(Equal(int64(1))) diff --git a/test/e2e/seedjobs_test.go b/test/e2e/seedjobs_test.go index dad98c2d..97d58dbd 100644 --- a/test/e2e/seedjobs_test.go +++ b/test/e2e/seedjobs_test.go @@ -68,7 +68,7 @@ func verifyJenkinsSeedJobs(jenkinsClient jenkinsclient.Jenkins, seedJobs []seedJ for _, requireJobName := range seedJob.JobNames { err = try.Until(func() (end bool, err error) { - _, err = jenkinsClient.GetJob(requireJobName) + _, err = jenkinsClient.GetJob(context.TODO(), requireJobName) return err == nil, err }, time.Second*2, time.Minute*2) Expect(err).NotTo(HaveOccurred(), fmt.Sprintf("Jenkins job '%s' not created by seed job ID '%s'\n", requireJobName, seedJob.ID)) @@ -244,11 +244,11 @@ for (BuildStep step : jobRef.getBuildersList()) { func verifyJobCanBeRun(jenkinsClient jenkinsclient.Jenkins, jobID string) { By("retrieving created Jenkins job") - job, err := jenkinsClient.GetJob(jobID) + job, err := jenkinsClient.GetJob(context.TODO(), jobID) Expect(err).To(BeNil()) By("running Jenkins job") - _, err = job.InvokeSimple(map[string]string{}) + _, err = job.InvokeSimple(context.TODO(), map[string]string{}) Expect(err).To(BeNil()) // FIXME: waitForJobToFinish use @@ -265,12 +265,12 @@ func verifyJobHasBeenRunCorrectly(jenkinsClient jenkinsclient.Jenkins, jobID str ) Eventually(func() (bool, error) { - job, err = jenkinsClient.GetJob(jobID) + job, err = jenkinsClient.GetJob(context.TODO(), jobID) Expect(err).To(BeNil()) - build, err = job.GetLastBuild() + build, err = job.GetLastBuild(context.TODO()) Expect(err).To(BeNil()) By("evaluating correctness of the outcome") - return build.IsGood(), err + return build.IsGood(context.TODO()), err }, time.Duration(110)*retryInterval, retryInterval).Should(BeTrue()) } diff --git a/test/e2e/wait.go b/test/e2e/wait.go index 4d4b97a0..ec934f1b 100644 --- a/test/e2e/wait.go +++ b/test/e2e/wait.go @@ -87,7 +87,7 @@ func waitForJenkinsSafeRestart(jenkinsClient jenkinsclient.Jenkins) { ginkgo.By("waiting for Jenkins safe restart") gomega.Eventually(func() (bool, error) { - status, err := jenkinsClient.Poll() + status, err := jenkinsClient.Poll(context.TODO()) _, _ = fmt.Fprintf(ginkgo.GinkgoWriter, "Safe restart status: %+v, err: %s\n", status, err) if err != nil { return false, err