github.com/zppinho/prow@v0.0.0-20240510014325-1738badeb017/cmd/deck/abort.go (about) 1 /* 2 Copyright 2022 The Kubernetes Authors. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package main 18 19 import ( 20 "context" 21 "encoding/json" 22 "fmt" 23 "net/http" 24 25 "github.com/sirupsen/logrus" 26 kerrors "k8s.io/apimachinery/pkg/api/errors" 27 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" 28 ktypes "k8s.io/apimachinery/pkg/types" 29 prowapi "sigs.k8s.io/prow/pkg/apis/prowjobs/v1" 30 prowv1 "sigs.k8s.io/prow/pkg/client/clientset/versioned/typed/prowjobs/v1" 31 "sigs.k8s.io/prow/pkg/githuboauth" 32 "sigs.k8s.io/prow/pkg/plugins" 33 ) 34 35 func handleAbort(prowJobClient prowv1.ProwJobInterface, cfg authCfgGetter, goa *githuboauth.Agent, ghc githuboauth.AuthenticatedUserIdentifier, cli deckGitHubClient, pluginAgent *plugins.ConfigAgent, log *logrus.Entry) http.HandlerFunc { 36 return func(w http.ResponseWriter, r *http.Request) { 37 ctx := context.TODO() 38 name := r.URL.Query().Get("prowjob") 39 l := log.WithField("prowjob", name) 40 if name == "" { 41 http.Error(w, "Request did not provide the 'prowjob' query parameter.", http.StatusBadRequest) 42 return 43 } 44 pj, err := prowJobClient.Get(ctx, name, metav1.GetOptions{}) 45 if err != nil { 46 http.Error(w, fmt.Sprintf("ProwJob not found: %v.", err), http.StatusNotFound) 47 if !kerrors.IsNotFound(err) { 48 // admins only care about errors other than not found 49 l.WithError(err).Warning("ProwJob not found.") 50 } 51 return 52 } 53 switch r.Method { 54 case http.MethodPost: 55 if pj.Status.State != prowapi.TriggeredState && pj.Status.State != prowapi.PendingState { 56 http.Error(w, fmt.Sprintf("Cannot abort job with state: %q.", pj.Status.State), http.StatusBadRequest) 57 l.Debug("Cannot abort job with state.") 58 return 59 } 60 // Using same permission validation as rerun, could be future work to add validation 61 // unique to Abort 62 allowed, user, err, code := isAllowedToRerun(r, cfg, goa, ghc, *pj, cli, pluginAgent, l) 63 if err != nil { 64 http.Error(w, fmt.Sprintf("Could not verify if allowed to abort: %v.", err), code) 65 l.WithError(err).Debug("Could not verify if allowed to abort.") 66 return 67 } 68 l = l.WithField("allowed", allowed) 69 l.Info("Attempted abort") 70 if !allowed { 71 http.Error(w, "You don't have permission to abort this job.", http.StatusUnauthorized) 72 l.Debug("You don't have permission to abort this job.") 73 return 74 } 75 var abortDescription string 76 if len(user) > 0 { 77 abortDescription = fmt.Sprintf("%v successfully aborted %v.", user, name) 78 } else { 79 abortDescription = fmt.Sprintf("Successfully aborted %v.", name) 80 } 81 pj.Status.State = prowapi.AbortedState 82 pj.Status.Description = abortDescription 83 jsonPJ, err := json.Marshal(pj) 84 if err != nil { 85 http.Error(w, fmt.Sprintf("Error marshal source job: %v.", err), http.StatusInternalServerError) 86 l.WithError(err).Errorf("Error marshal source job.") 87 return 88 } 89 pj, err := prowJobClient.Patch(ctx, pj.Name, ktypes.MergePatchType, jsonPJ, metav1.PatchOptions{}) 90 if err != nil { 91 http.Error(w, fmt.Sprintf("Could not patch aborted job: %v.", err), http.StatusInternalServerError) 92 l.WithError(err).Errorf("Could not patch aborted job.") 93 return 94 } 95 l.Info(abortDescription) 96 if _, err = w.Write([]byte("Job successfully aborted.")); err != nil { 97 l.WithError(err).Debug(fmt.Sprintf("Error writing to abort response for %v.", pj.Name)) 98 } 99 return 100 default: 101 http.Error(w, fmt.Sprintf("bad verb %v", r.Method), http.StatusMethodNotAllowed) 102 return 103 } 104 } 105 }