diff --git a/.github/workflows/pr.yaml b/.github/workflows/pr.yaml index efa55b14..e3ddf418 100644 --- a/.github/workflows/pr.yaml +++ b/.github/workflows/pr.yaml @@ -33,7 +33,7 @@ jobs: - name: Install dependencies run: go mod download - name: Run Tests - run: go test -cover `go list ./... | grep -v 'pkg/client'` + run: go test -cover `go list ./...` test-swagger: name: Test Swagger diff --git a/Makefile b/Makefile index 93aaeab8..5a904b61 100644 --- a/Makefile +++ b/Makefile @@ -74,7 +74,7 @@ ifndef HAS_SWAGGER go install github.com/go-swagger/go-swagger/cmd/swagger@v0.30.5 endif ifndef HAS_GOLANGCI_LINT - go install github.com/golangci/golangci-lint/cmd/golangci-lint@v1.55.2 + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(go env GOPATH)/bin v1.55.2 endif ifndef HAS_MOCKGEN go install github.com/golang/mock/mockgen@v1.6.0 diff --git a/api/alerting/alerting_controller.go b/api/alerting/alerting_controller.go index 098b87a4..e1753244 100644 --- a/api/alerting/alerting_controller.go +++ b/api/alerting/alerting_controller.go @@ -6,7 +6,6 @@ import ( alertingModels "github.com/equinor/radix-api/api/alerting/models" "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" crdutils "github.com/equinor/radix-operator/pkg/apis/utils" "github.com/gorilla/mux" v1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -30,42 +29,42 @@ func (ec *alertingController) GetRoutes() models.Routes { models.Route{ Path: envPath + "/alerting", Method: "PUT", - HandlerFunc: EnvironmentRouteAccessCheck(UpdateEnvironmentAlertingConfig), + HandlerFunc: ec.EnvironmentRouteAccessCheck(ec.UpdateEnvironmentAlertingConfig), }, models.Route{ Path: envPath + "/alerting", Method: http.MethodGet, - HandlerFunc: EnvironmentRouteAccessCheck(GetEnvironmentAlertingConfig), + HandlerFunc: ec.EnvironmentRouteAccessCheck(ec.GetEnvironmentAlertingConfig), }, models.Route{ Path: envPath + "/alerting/enable", Method: http.MethodPost, - HandlerFunc: EnvironmentRouteAccessCheck(EnableEnvironmentAlerting), + HandlerFunc: ec.EnvironmentRouteAccessCheck(ec.EnableEnvironmentAlerting), }, models.Route{ Path: envPath + "/alerting/disable", Method: http.MethodPost, - HandlerFunc: EnvironmentRouteAccessCheck(DisableEnvironmentAlerting), + HandlerFunc: ec.EnvironmentRouteAccessCheck(ec.DisableEnvironmentAlerting), }, models.Route{ Path: appPath + "/alerting", Method: "PUT", - HandlerFunc: UpdateApplicationAlertingConfig, + HandlerFunc: ec.UpdateApplicationAlertingConfig, }, models.Route{ Path: appPath + "/alerting", Method: http.MethodGet, - HandlerFunc: GetApplicationAlertingConfig, + HandlerFunc: ec.GetApplicationAlertingConfig, }, models.Route{ Path: appPath + "/alerting/enable", Method: http.MethodPost, - HandlerFunc: EnableApplicationAlerting, + HandlerFunc: ec.EnableApplicationAlerting, }, models.Route{ Path: appPath + "/alerting/disable", Method: http.MethodPost, - HandlerFunc: DisableApplicationAlerting, + HandlerFunc: ec.DisableApplicationAlerting, }, } @@ -74,14 +73,14 @@ func (ec *alertingController) GetRoutes() models.Routes { // EnvironmentRouteAccessCheck gets appName and envName from route and verifies that environment exists // Returns 404 NotFound if environment is not defined, otherwise calls handler -func EnvironmentRouteAccessCheck(handler models.RadixHandlerFunc) models.RadixHandlerFunc { +func (ec *alertingController) EnvironmentRouteAccessCheck(handler models.RadixHandlerFunc) models.RadixHandlerFunc { return func(a models.Accounts, rw http.ResponseWriter, r *http.Request) { appName := mux.Vars(r)["appName"] envName := mux.Vars(r)["envName"] envNamespace := crdutils.GetEnvironmentNamespace(appName, envName) if _, err := a.ServiceAccount.RadixClient.RadixV1().RadixEnvironments().Get(r.Context(), envNamespace, v1.GetOptions{}); err != nil { - radixhttp.ErrorResponse(rw, r, err) + ec.ErrorResponse(rw, r, err) return } @@ -90,7 +89,7 @@ func EnvironmentRouteAccessCheck(handler models.RadixHandlerFunc) models.RadixHa } // UpdateEnvironmentAlertingConfig Configures alert settings -func UpdateEnvironmentAlertingConfig(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (ec *alertingController) UpdateEnvironmentAlertingConfig(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation PUT /applications/{appName}/environments/{envName}/alerting environment updateEnvironmentAlertingConfig // --- // summary: Update alerts configuration for an environment @@ -142,7 +141,7 @@ func UpdateEnvironmentAlertingConfig(accounts models.Accounts, w http.ResponseWr var updateAlertingConfig alertingModels.UpdateAlertingConfig if err := json.NewDecoder(r.Body).Decode(&updateAlertingConfig); err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } @@ -150,15 +149,15 @@ func UpdateEnvironmentAlertingConfig(accounts models.Accounts, w http.ResponseWr alertsConfig, err := alertHandler.UpdateAlertingConfig(r.Context(), updateAlertingConfig) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, alertsConfig) + ec.JSONResponse(w, r, alertsConfig) } // GetEnvironmentAlertingConfig returns alerts configuration -func GetEnvironmentAlertingConfig(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (ec *alertingController) GetEnvironmentAlertingConfig(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/environments/{envName}/alerting environment getEnvironmentAlertingConfig // --- // summary: Get alerts configuration for an environment @@ -203,15 +202,15 @@ func GetEnvironmentAlertingConfig(accounts models.Accounts, w http.ResponseWrite alertsConfig, err := alertHandler.GetAlertingConfig(r.Context()) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, alertsConfig) + ec.JSONResponse(w, r, alertsConfig) } // EnableEnvironmentAlerting enables alerting for application environment -func EnableEnvironmentAlerting(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (ec *alertingController) EnableEnvironmentAlerting(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation POST /applications/{appName}/environments/{envName}/alerting/enable environment enableEnvironmentAlerting // --- // summary: Enable alerting for an environment @@ -258,15 +257,15 @@ func EnableEnvironmentAlerting(accounts models.Accounts, w http.ResponseWriter, alertsConfig, err := alertHandler.EnableAlerting(r.Context()) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, alertsConfig) + ec.JSONResponse(w, r, alertsConfig) } // DisableEnvironmentAlerting disables alerting for application environment -func DisableEnvironmentAlerting(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (ec *alertingController) DisableEnvironmentAlerting(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation POST /applications/{appName}/environments/{envName}/alerting/disable environment disableEnvironmentAlerting // --- // summary: Disable alerting for an environment @@ -312,15 +311,15 @@ func DisableEnvironmentAlerting(accounts models.Accounts, w http.ResponseWriter, alertHandler := NewEnvironmentHandler(accounts, appName, envName) alertsConfig, err := alertHandler.DisableAlerting(r.Context()) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, alertsConfig) + ec.JSONResponse(w, r, alertsConfig) } // UpdateApplicationAlertingConfig Configures alert settings -func UpdateApplicationAlertingConfig(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func(ec *alertingController) UpdateApplicationAlertingConfig(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation PUT /applications/{appName}/alerting application updateApplicationAlertingConfig // --- // summary: Update alerts configuration for application namespace @@ -366,7 +365,7 @@ func UpdateApplicationAlertingConfig(accounts models.Accounts, w http.ResponseWr var updateAlertingConfig alertingModels.UpdateAlertingConfig if err := json.NewDecoder(r.Body).Decode(&updateAlertingConfig); err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } @@ -374,15 +373,15 @@ func UpdateApplicationAlertingConfig(accounts models.Accounts, w http.ResponseWr alertsConfig, err := alertHandler.UpdateAlertingConfig(r.Context(), updateAlertingConfig) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, alertsConfig) + ec.JSONResponse(w, r, alertsConfig) } // GetApplicationAlertingConfig returns alerts configuration -func GetApplicationAlertingConfig(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func(ec *alertingController) GetApplicationAlertingConfig(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/alerting application getApplicationAlertingConfig // --- // summary: Get alerts configuration for application namespace @@ -421,15 +420,15 @@ func GetApplicationAlertingConfig(accounts models.Accounts, w http.ResponseWrite alertsConfig, err := alertHandler.GetAlertingConfig(r.Context()) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, alertsConfig) + ec.JSONResponse(w, r, alertsConfig) } // EnableApplicationAlerting enables alerting for application -func EnableApplicationAlerting(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func(ec *alertingController) EnableApplicationAlerting(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation POST /applications/{appName}/alerting/enable application enableApplicationAlerting // --- // summary: Enable alerting for application namespace @@ -470,15 +469,15 @@ func EnableApplicationAlerting(accounts models.Accounts, w http.ResponseWriter, alertsConfig, err := alertHandler.EnableAlerting(r.Context()) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, alertsConfig) + ec.JSONResponse(w, r, alertsConfig) } // DisableApplicationAlerting disables alerting for application -func DisableApplicationAlerting(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func(ec *alertingController) DisableApplicationAlerting(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation POST /applications/{appName}/alerting/disable application disableApplicationAlerting // --- // summary: Disable alerting for application namespace @@ -518,9 +517,9 @@ func DisableApplicationAlerting(accounts models.Accounts, w http.ResponseWriter, alertHandler := NewApplicationHandler(accounts, appName) alertsConfig, err := alertHandler.DisableAlerting(r.Context()) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ec.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, alertsConfig) + ec.JSONResponse(w, r, alertsConfig) } diff --git a/api/applications/applications_controller.go b/api/applications/applications_controller.go index 1fefb2bd..329fac93 100644 --- a/api/applications/applications_controller.go +++ b/api/applications/applications_controller.go @@ -8,7 +8,6 @@ import ( applicationModels "github.com/equinor/radix-api/api/applications/models" "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" "github.com/gorilla/mux" ) @@ -183,12 +182,11 @@ func (ac *applicationController) ShowApplications(accounts models.Accounts, w ht appRegistrations, err := handler.GetApplications(r.Context(), matcher, ac.hasAccessToRR, GetApplicationsOptions{}) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, appRegistrations) -} + ac.JSONResponse(w, r, appRegistrations)} // SearchApplications Gets applications by list of application names func (ac *applicationController) SearchApplications(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { @@ -292,7 +290,7 @@ func (ac *applicationController) SearchApplications(accounts models.Accounts, w } case http.MethodPost: if err := json.NewDecoder(r.Body).Decode(&appNamesRequest); err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } default: @@ -302,7 +300,7 @@ func (ac *applicationController) SearchApplications(accounts models.Accounts, w // No need to perform search if names in request is empty. Just return empty list if len(appNamesRequest.Names) == 0 { - radixhttp.JSONResponse(w, r, []interface{}{}) + ac.JSONResponse(w, r, []interface{}{}) return } @@ -319,11 +317,11 @@ func (ac *applicationController) SearchApplications(accounts models.Accounts, w }, ) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, appRegistrations) + ac.JSONResponse(w, r, appRegistrations) } // GetApplication Gets application by application name @@ -370,11 +368,11 @@ func (ac *applicationController) GetApplication(accounts models.Accounts, w http application, err := handler.GetApplication(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &application) + ac.JSONResponse(w, r, &application) } // IsDeployKeyValidHandler validates deploy key for radix application found for application name @@ -416,11 +414,11 @@ func (ac *applicationController) IsDeployKeyValidHandler(accounts models.Account isDeployKeyValid, err := IsDeployKeyValid(r.Context(), accounts.UserAccount, appName) if isDeployKeyValid { - radixhttp.JSONResponse(w, r, &isDeployKeyValid) + ac.JSONResponse(w, r, &isDeployKeyValid) return } - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) } // RegenerateDeployKeyHandler Regenerates deploy key and secret and returns the new key @@ -463,13 +461,13 @@ func (ac *applicationController) RegenerateDeployKeyHandler(accounts models.Acco handler := ac.applicationHandlerFactory.Create(accounts) var sharedSecretAndPrivateKey applicationModels.RegenerateDeployKeyAndSecretData if err := json.NewDecoder(r.Body).Decode(&sharedSecretAndPrivateKey); err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } err := handler.RegenerateDeployKey(r.Context(), appName, sharedSecretAndPrivateKey) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } @@ -510,11 +508,11 @@ func (ac *applicationController) GetDeployKeyAndSecret(accounts models.Accounts, deployKeyAndSecret, err := handler.GetDeployKeyAndSecret(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &deployKeyAndSecret) + ac.JSONResponse(w, r, &deployKeyAndSecret) } @@ -553,7 +551,7 @@ func (ac *applicationController) RegisterApplication(accounts models.Accounts, w // description: "Conflict" var applicationRegistrationRequest applicationModels.ApplicationRegistrationRequest if err := json.NewDecoder(r.Body).Decode(&applicationRegistrationRequest); err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } @@ -561,11 +559,11 @@ func (ac *applicationController) RegisterApplication(accounts models.Accounts, w handler := ac.applicationHandlerFactory.Create(accounts) appRegistrationUpsertResponse, err := handler.RegisterApplication(r.Context(), applicationRegistrationRequest) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &appRegistrationUpsertResponse) + ac.JSONResponse(w, r, &appRegistrationUpsertResponse) } // ChangeRegistrationDetails Updates application registration @@ -612,7 +610,7 @@ func (ac *applicationController) ChangeRegistrationDetails(accounts models.Accou var applicationRegistrationRequest applicationModels.ApplicationRegistrationRequest if err := json.NewDecoder(r.Body).Decode(&applicationRegistrationRequest); err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } @@ -620,11 +618,11 @@ func (ac *applicationController) ChangeRegistrationDetails(accounts models.Accou handler := ac.applicationHandlerFactory.Create(accounts) appRegistrationUpsertResponse, err := handler.ChangeRegistrationDetails(r.Context(), appName, applicationRegistrationRequest) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &appRegistrationUpsertResponse) + ac.JSONResponse(w, r, &appRegistrationUpsertResponse) } // ModifyRegistrationDetails Updates specific field(s) of an application registration @@ -671,7 +669,7 @@ func (ac *applicationController) ModifyRegistrationDetails(accounts models.Accou var applicationRegistrationPatchRequest applicationModels.ApplicationRegistrationPatchRequest if err := json.NewDecoder(r.Body).Decode(&applicationRegistrationPatchRequest); err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } @@ -679,11 +677,11 @@ func (ac *applicationController) ModifyRegistrationDetails(accounts models.Accou handler := ac.applicationHandlerFactory.Create(accounts) appRegistrationUpsertResponse, err := handler.ModifyRegistrationDetails(r.Context(), appName, applicationRegistrationPatchRequest) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &appRegistrationUpsertResponse) + ac.JSONResponse(w, r, &appRegistrationUpsertResponse) } // DeleteApplication Deletes application @@ -722,7 +720,7 @@ func (ac *applicationController) DeleteApplication(accounts models.Accounts, w h err := handler.DeleteApplication(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } @@ -751,7 +749,7 @@ func (ac *applicationController) ListPipelines(accounts models.Accounts, w http. // It was suggested to keep this under /applications/{appName} endpoint, but for now this will be the same for all applications handler := ac.applicationHandlerFactory.Create(accounts) supportedPipelines := handler.GetSupportedPipelines() - radixhttp.JSONResponse(w, r, supportedPipelines) + ac.JSONResponse(w, r, supportedPipelines) } // TriggerPipelineBuild creates a build pipeline job for the application @@ -795,11 +793,11 @@ func (ac *applicationController) TriggerPipelineBuild(accounts models.Accounts, jobSummary, err := handler.TriggerPipelineBuild(r.Context(), appName, r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &jobSummary) + ac.JSONResponse(w, r, &jobSummary) } // TriggerPipelineBuildDeploy creates a build-deploy pipeline job for the application @@ -844,11 +842,11 @@ func (ac *applicationController) TriggerPipelineBuildDeploy(accounts models.Acco jobSummary, err := handler.TriggerPipelineBuildDeploy(r.Context(), appName, r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &jobSummary) + ac.JSONResponse(w, r, &jobSummary) } // TriggerPipelineDeploy creates a deploy pipeline job for the application @@ -893,11 +891,11 @@ func (ac *applicationController) TriggerPipelineDeploy(accounts models.Accounts, jobSummary, err := handler.TriggerPipelineDeploy(r.Context(), appName, r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &jobSummary) + ac.JSONResponse(w, r, &jobSummary) } // TriggerPipelinePromote creates a promote pipeline job for the application @@ -940,9 +938,9 @@ func (ac *applicationController) TriggerPipelinePromote(accounts models.Accounts jobSummary, err := handler.TriggerPipelinePromote(r.Context(), appName, r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + ac.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, &jobSummary) + ac.JSONResponse(w, r, &jobSummary) } diff --git a/api/buildsecrets/buildsecrets_controller.go b/api/buildsecrets/buildsecrets_controller.go index ab617811..6ff7c86c 100644 --- a/api/buildsecrets/buildsecrets_controller.go +++ b/api/buildsecrets/buildsecrets_controller.go @@ -5,9 +5,7 @@ import ( "net/http" environmentModels "github.com/equinor/radix-api/api/secrets/models" - "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" "github.com/gorilla/mux" ) @@ -28,12 +26,12 @@ func (dc *buildSecretsController) GetRoutes() models.Routes { models.Route{ Path: rootPath + "/buildsecrets", Method: "GET", - HandlerFunc: GetBuildSecrets, + HandlerFunc: dc.GetBuildSecrets, }, models.Route{ Path: rootPath + "/buildsecrets/{secretName}", Method: "PUT", - HandlerFunc: ChangeBuildSecret, + HandlerFunc: dc.ChangeBuildSecret, }, } @@ -41,7 +39,7 @@ func (dc *buildSecretsController) GetRoutes() models.Routes { } // GetBuildSecrets Lists build secrets -func GetBuildSecrets(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (dc *buildSecretsController) GetBuildSecrets(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/buildsecrets application getBuildSecrets // --- // summary: Lists the application build secrets @@ -78,15 +76,15 @@ func GetBuildSecrets(accounts models.Accounts, w http.ResponseWriter, r *http.Re buildSecrets, err := buildSecretsHandler.GetBuildSecrets(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, buildSecrets) + dc.JSONResponse(w, r, buildSecrets) } // ChangeBuildSecret Modifies an application build secret -func ChangeBuildSecret(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (dc *buildSecretsController) ChangeBuildSecret(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation PUT /applications/{appName}/buildsecrets/{secretName} application updateBuildSecretsSecretValue // --- // summary: Update an application build secret @@ -135,7 +133,7 @@ func ChangeBuildSecret(accounts models.Accounts, w http.ResponseWriter, r *http. var secretParameters environmentModels.SecretParameters if err := json.NewDecoder(r.Body).Decode(&secretParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } @@ -143,9 +141,9 @@ func ChangeBuildSecret(accounts models.Accounts, w http.ResponseWriter, r *http. err := buildSecretsHandler.ChangeBuildSecret(r.Context(), appName, secretName, secretParameters.SecretValue) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + dc.JSONResponse(w, r, "Success") } diff --git a/api/buildstatus/buildstatus_controller.go b/api/buildstatus/buildstatus_controller.go index f4f31fbd..31136fc1 100644 --- a/api/buildstatus/buildstatus_controller.go +++ b/api/buildstatus/buildstatus_controller.go @@ -7,7 +7,6 @@ import ( buildmodels "github.com/equinor/radix-api/api/buildstatus/models" "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" radixv1 "github.com/equinor/radix-operator/pkg/apis/radix/v1" "github.com/gorilla/mux" ) @@ -83,7 +82,7 @@ func (bsc *buildStatusController) GetBuildStatus(accounts models.Accounts, w htt } disableClientCaching(w) - radixhttp.ByteArrayResponse(w, r, "image/svg+xml; charset=utf-8", buildStatus) + bsc.ByteArrayResponse(w, r, "image/svg+xml; charset=utf-8", buildStatus) } func disableClientCaching(w http.ResponseWriter) { diff --git a/api/deployments/deployment_controller.go b/api/deployments/deployment_controller.go index b6fa0237..80196036 100644 --- a/api/deployments/deployment_controller.go +++ b/api/deployments/deployment_controller.go @@ -9,7 +9,6 @@ import ( "github.com/equinor/radix-api/api/utils/logs" "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" "github.com/gorilla/mux" ) @@ -30,22 +29,22 @@ func (dc *deploymentController) GetRoutes() models.Routes { models.Route{ Path: rootPath + "/deployments", Method: "GET", - HandlerFunc: GetDeployments, + HandlerFunc: dc.GetDeployments, }, models.Route{ Path: rootPath + "/deployments/{deploymentName}", Method: "GET", - HandlerFunc: GetDeployment, + HandlerFunc: dc.GetDeployment, }, models.Route{ Path: rootPath + "/deployments/{deploymentName}/components/{componentName}/replicas/{podName}/logs", Method: "GET", - HandlerFunc: GetPodLog, + HandlerFunc: dc.GetPodLog, }, models.Route{ Path: rootPath + "/deployments/{deploymentName}/components", Method: "GET", - HandlerFunc: GetComponents, + HandlerFunc: dc.GetComponents, }, } @@ -53,7 +52,7 @@ func (dc *deploymentController) GetRoutes() models.Routes { } // GetDeployments Lists deployments -func GetDeployments(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (dc *deploymentController) GetDeployments(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/deployments application getDeployments // --- // summary: Lists the application deployments @@ -103,7 +102,7 @@ func GetDeployments(accounts models.Accounts, w http.ResponseWriter, r *http.Req if strings.TrimSpace(latest) != "" { useLatest, err = strconv.ParseBool(r.FormValue("latest")) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } } @@ -112,15 +111,15 @@ func GetDeployments(accounts models.Accounts, w http.ResponseWriter, r *http.Req appDeployments, err := deployHandler.GetDeploymentsForApplicationEnvironment(r.Context(), appName, environment, useLatest) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, appDeployments) + dc.JSONResponse(w, r, appDeployments) } // GetDeployment Get deployment details -func GetDeployment(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (dc *deploymentController) GetDeployment(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/deployments/{deploymentName} deployment getDeployment // --- // summary: Get deployment details @@ -161,15 +160,15 @@ func GetDeployment(accounts models.Accounts, w http.ResponseWriter, r *http.Requ appDeployment, err := deployHandler.GetDeploymentWithName(r.Context(), appName, deploymentName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, appDeployment) + dc.JSONResponse(w, r, appDeployment) } // GetComponents for a deployment -func GetComponents(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (dc *deploymentController) GetComponents(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/deployments/{deploymentName}/components component components // --- // summary: Get components for a deployment @@ -209,15 +208,15 @@ func GetComponents(accounts models.Accounts, w http.ResponseWriter, r *http.Requ deployHandler := Init(accounts) components, err := deployHandler.GetComponentsForDeploymentName(r.Context(), appName, deploymentName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, components) + dc.JSONResponse(w, r, components) } // GetPodLog Get logs of a single pod -func GetPodLog(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (dc *deploymentController) GetPodLog(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/deployments/{deploymentName}/components/{componentName}/replicas/{podName}/logs component log // --- // summary: Get logs from a deployed pod @@ -288,22 +287,22 @@ func GetPodLog(accounts models.Accounts, w http.ResponseWriter, r *http.Request) since, asFile, logLines, err, previousLog := logs.GetLogParams(r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } deployHandler := Init(accounts) - log, err := deployHandler.GetLogs(r.Context(), appName, podName, &since, logLines, previousLog) + logs, err := deployHandler.GetLogs(r.Context(), appName, podName, &since, logLines, previousLog) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } - defer log.Close() + defer func() {_ = logs.Close()}() if asFile { fileName := fmt.Sprintf("%s.log", time.Now().Format("20060102150405")) - radixhttp.ReaderFileResponse(w, log, fileName, "text/plain; charset=utf-8") + dc.ReaderFileResponse(w, r, logs, fileName, "text/plain; charset=utf-8") } else { - radixhttp.ReaderResponse(w, log, "text/plain; charset=utf-8") + dc.ReaderResponse(w, r, logs, "text/plain; charset=utf-8") } } diff --git a/api/environments/environment_controller.go b/api/environments/environment_controller.go index 4873ef2f..083b9f69 100644 --- a/api/environments/environment_controller.go +++ b/api/environments/environment_controller.go @@ -12,7 +12,6 @@ import ( environmentsModels "github.com/equinor/radix-api/api/environments/models" "github.com/equinor/radix-api/api/utils/logs" "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" "github.com/equinor/radix-operator/pkg/apis/defaults" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" @@ -261,7 +260,7 @@ func (c *environmentController) GetApplicationEnvironmentDeployments(accounts mo if strings.TrimSpace(latest) != "" { useLatest, err = strconv.ParseBool(r.FormValue("latest")) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } } @@ -270,11 +269,10 @@ func (c *environmentController) GetApplicationEnvironmentDeployments(accounts mo appEnvironmentDeployments, err := deploymentHandler.GetDeploymentsForApplicationEnvironment(r.Context(), appName, envName, useLatest) if err != nil { - radixhttp.ErrorResponse(w, r, err) - return + c.ErrorResponse(w, r, err) } - radixhttp.JSONResponse(w, r, appEnvironmentDeployments) + c.JSONResponse(w,r, appEnvironmentDeployments) } // CreateEnvironment Creates a new environment @@ -317,7 +315,7 @@ func (c *environmentController) CreateEnvironment(accounts models.Accounts, w ht _, err := environmentHandler.CreateEnvironment(r.Context(), appName, envName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } @@ -367,11 +365,11 @@ func (c *environmentController) GetEnvironment(accounts models.Accounts, w http. appEnvironment, err := environmentHandler.GetEnvironment(r.Context(), appName, envName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, appEnvironment) + c.JSONResponse(w, r, appEnvironment) } @@ -416,7 +414,7 @@ func (c *environmentController) DeleteEnvironment(accounts models.Accounts, w ht err := environmentHandler.DeleteEnvironment(r.Context(), appName, envName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } @@ -461,11 +459,11 @@ func (c *environmentController) GetEnvironmentSummary(accounts models.Accounts, appEnvironments, err := environmentHandler.GetEnvironmentSummary(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, appEnvironments) + c.JSONResponse(w, r, appEnvironments) } // GetEnvironmentEvents Get events for an application environment @@ -513,11 +511,11 @@ func (c *environmentController) GetEnvironmentEvents(accounts models.Accounts, w events, err := environmentHandler.GetEnvironmentEvents(r.Context(), appName, envName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, events) + c.JSONResponse(w, r, events) } @@ -567,11 +565,11 @@ func (c *environmentController) StopComponent(accounts models.Accounts, w http.R err := environmentHandler.StopComponent(r.Context(), appName, envName, componentName, false) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // StartComponent Starts job @@ -620,11 +618,11 @@ func (c *environmentController) StartComponent(accounts models.Accounts, w http. err := environmentHandler.StartComponent(r.Context(), appName, envName, componentName, false) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // RestartComponent Restarts job @@ -677,11 +675,11 @@ func (c *environmentController) RestartComponent(accounts models.Accounts, w htt err := environmentHandler.RestartComponent(r.Context(), appName, envName, componentName, false) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // StopEnvironment all components in the environment @@ -724,11 +722,11 @@ func (c *environmentController) StopEnvironment(accounts models.Accounts, w http err := environmentHandler.StopEnvironment(r.Context(), appName, envName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // StartEnvironment Starts all components in the environment @@ -771,11 +769,11 @@ func (c *environmentController) StartEnvironment(accounts models.Accounts, w htt err := environmentHandler.StartEnvironment(r.Context(), appName, envName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // RestartEnvironment Restarts all components in the environment @@ -824,11 +822,11 @@ func (c *environmentController) RestartEnvironment(accounts models.Accounts, w h err := environmentHandler.RestartEnvironment(r.Context(), appName, envName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // StopApplication all components in all environments of the application @@ -865,11 +863,11 @@ func (c *environmentController) StopApplication(accounts models.Accounts, w http err := environmentHandler.StopApplication(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // StartApplication Starts all components in all environments of the application @@ -906,11 +904,11 @@ func (c *environmentController) StartApplication(accounts models.Accounts, w htt err := environmentHandler.StartApplication(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // RestartApplication Restarts all components in all environments of the application @@ -951,11 +949,11 @@ func (c *environmentController) RestartApplication(accounts models.Accounts, w h err := environmentHandler.RestartApplication(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // RestartOAuthAuxiliaryResource Restarts oauth auxiliary resource for a component @@ -1010,11 +1008,11 @@ func (c *environmentController) RestartOAuthAuxiliaryResource(accounts models.Ac err := environmentHandler.RestartComponentAuxiliaryResource(r.Context(), appName, envName, componentName, defaults.OAuthProxyAuxiliaryComponentType) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // GetPodLog Get logs of a single pod @@ -1090,23 +1088,25 @@ func (c *environmentController) GetPodLog(accounts models.Accounts, w http.Respo since, asFile, logLines, err, previousLog := logs.GetLogParams(r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } eh := c.environmentHandlerFactory(accounts) - log, err := eh.GetLogs(r.Context(), appName, envName, podName, &since, logLines, previousLog) + logs, err := eh.GetLogs(r.Context(), appName, envName, podName, &since, logLines, previousLog) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - defer log.Close() + defer func() { + _ = logs.Close() + }() if asFile { fileName := fmt.Sprintf("%s.log", time.Now().Format("20060102150405")) - radixhttp.ReaderFileResponse(w, log, fileName, "text/plain; charset=utf-8") + c.ReaderFileResponse(w, r, logs, fileName, "text/plain; charset=utf-8") } else { - radixhttp.ReaderResponse(w, log, "text/plain; charset=utf-8") + c.ReaderResponse(w, r, logs, "text/plain; charset=utf-8") } } @@ -1177,23 +1177,24 @@ func (c *environmentController) GetScheduledJobLog(accounts models.Accounts, w h since, asFile, logLines, err, _ := logs.GetLogParams(r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } eh := c.environmentHandlerFactory(accounts) - log, err := eh.GetScheduledJobLogs(r.Context(), appName, envName, scheduledJobName, &since, logLines) + logs, err := eh.GetScheduledJobLogs(r.Context(), appName, envName, scheduledJobName, &since, logLines) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - defer log.Close() + defer func() {_ = logs.Close()}() if asFile { fileName := fmt.Sprintf("%s.log", time.Now().Format("20060102150405")) - radixhttp.ReaderFileResponse(w, log, fileName, "text/plain; charset=utf-8") + c.ReaderFileResponse(w, r, logs, fileName, "text/plain; charset=utf-8") + } else { - radixhttp.ReaderResponse(w, log, "text/plain; charset=utf-8") + c.ReaderResponse(w, r, logs, "text/plain; charset=utf-8") } } @@ -1245,11 +1246,11 @@ func (c *environmentController) GetJobComponentDeployments(accounts models.Accou jobComponentDeployments, err := eh.deployHandler.GetJobComponentDeployments(r.Context(), appName, envName, jobComponentName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, jobComponentDeployments) + c.JSONResponse(w, r, jobComponentDeployments) } // GetJobs Get list of scheduled jobs @@ -1300,11 +1301,11 @@ func (c *environmentController) GetJobs(accounts models.Accounts, w http.Respons jobSummaries, err := eh.GetJobs(r.Context(), appName, envName, jobComponentName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, jobSummaries) + c.JSONResponse(w, r, jobSummaries) } // GetJob Get a scheduled job @@ -1359,11 +1360,11 @@ func (c *environmentController) GetJob(accounts models.Accounts, w http.Response jobSummary, err := eh.GetJob(r.Context(), appName, envName, jobComponentName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, jobSummary) + c.JSONResponse(w, r, jobSummary) } // StopJob Stop a scheduled job @@ -1422,7 +1423,7 @@ func (c *environmentController) StopJob(accounts models.Accounts, w http.Respons eh := c.environmentHandlerFactory(accounts) err := eh.StopJob(r.Context(), appName, envName, jobComponentName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } @@ -1485,7 +1486,7 @@ func (c *environmentController) RestartJob(accounts models.Accounts, w http.Resp eh := c.environmentHandlerFactory(accounts) err := eh.RestartJob(r.Context(), appName, envName, jobComponentName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } @@ -1548,7 +1549,7 @@ func (c *environmentController) DeleteJob(accounts models.Accounts, w http.Respo eh := c.environmentHandlerFactory(accounts) err := eh.DeleteJob(r.Context(), appName, envName, jobComponentName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } @@ -1603,11 +1604,11 @@ func (c *environmentController) GetBatches(accounts models.Accounts, w http.Resp batchSummaries, err := eh.GetBatches(r.Context(), appName, envName, jobComponentName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, batchSummaries) + c.JSONResponse(w, r, batchSummaries) } // GetBatch Get a scheduled batch @@ -1662,11 +1663,11 @@ func (c *environmentController) GetBatch(accounts models.Accounts, w http.Respon batchSummary, err := eh.GetBatch(r.Context(), appName, envName, jobComponentName, batchName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, batchSummary) + c.JSONResponse(w, r, batchSummary) } // StopBatch Stop a scheduled batch @@ -1725,7 +1726,7 @@ func (c *environmentController) StopBatch(accounts models.Accounts, w http.Respo eh := c.environmentHandlerFactory(accounts) err := eh.StopBatch(r.Context(), appName, envName, jobComponentName, batchName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } @@ -1788,7 +1789,7 @@ func (c *environmentController) RestartBatch(accounts models.Accounts, w http.Re eh := c.environmentHandlerFactory(accounts) err := eh.RestartBatch(r.Context(), appName, envName, jobComponentName, batchName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } @@ -1857,18 +1858,18 @@ func (c *environmentController) CopyBatch(accounts models.Accounts, w http.Respo batchName := mux.Vars(r)["batchName"] var scheduledBatchRequest environmentsModels.ScheduledBatchRequest if err := json.NewDecoder(r.Body).Decode(&scheduledBatchRequest); err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } eh := c.environmentHandlerFactory(accounts) batchSummary, err := eh.CopyBatch(r.Context(), appName, envName, jobComponentName, batchName, scheduledBatchRequest) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, batchSummary) + c.JSONResponse(w, r, batchSummary) } // CopyJob Create a copy of existing scheduled job with optional changes @@ -1933,18 +1934,18 @@ func (c *environmentController) CopyJob(accounts models.Accounts, w http.Respons jobName := mux.Vars(r)["jobName"] var scheduledJobRequest environmentsModels.ScheduledJobRequest if err := json.NewDecoder(r.Body).Decode(&scheduledJobRequest); err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } eh := c.environmentHandlerFactory(accounts) jobSummary, err := eh.CopyJob(r.Context(), appName, envName, jobComponentName, jobName, scheduledJobRequest) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, jobSummary) + c.JSONResponse(w, r, jobSummary) } // DeleteBatch Delete a batch @@ -2003,7 +2004,7 @@ func (c *environmentController) DeleteBatch(accounts models.Accounts, w http.Res eh := c.environmentHandlerFactory(accounts) err := eh.DeleteBatch(r.Context(), appName, envName, jobComponentName, batchName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } @@ -2084,23 +2085,23 @@ func (c *environmentController) GetOAuthAuxiliaryResourcePodLog(accounts models. since, asFile, logLines, err, _ := logs.GetLogParams(r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } eh := c.environmentHandlerFactory(accounts) - log, err := eh.GetAuxiliaryResourcePodLog(r.Context(), appName, envName, componentName, defaults.OAuthProxyAuxiliaryComponentType, podName, &since, logLines) + logs, err := eh.GetAuxiliaryResourcePodLog(r.Context(), appName, envName, componentName, defaults.OAuthProxyAuxiliaryComponentType, podName, &since, logLines) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - defer log.Close() + defer func() {_ = logs.Close()}() if asFile { fileName := fmt.Sprintf("%s.log", time.Now().Format("20060102150405")) - radixhttp.ReaderFileResponse(w, log, fileName, "text/plain; charset=utf-8") + c.ReaderFileResponse(w, r, logs, fileName, "text/plain; charset=utf-8") } else { - radixhttp.ReaderResponse(w, log, "text/plain; charset=utf-8") + c.ReaderResponse(w, r, logs, "text/plain; charset=utf-8") } } @@ -2156,12 +2157,11 @@ func (c *environmentController) GetJobPayload(accounts models.Accounts, w http.R payload, err := eh.GetJobPayload(r.Context(), appName, envName, jobComponentName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.ReaderResponse(w, payload, "text/plain; charset=utf-8") -} + c.ReaderResponse(w, r, payload, "text/plain; charset=utf-8")} // ScaleComponent Scale component replicas func (c *environmentController) ScaleComponent(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { @@ -2217,14 +2217,14 @@ func (c *environmentController) ScaleComponent(accounts models.Accounts, w http. replicas, err := strconv.Atoi(mux.Vars(r)["replicas"]) if err != nil { log.Error(err) - radixhttp.ErrorResponse(w, r, fmt.Errorf("invalid new desired number of replicas argument")) + c.ErrorResponse(w, r, fmt.Errorf("invalid new desired number of replicas argument")) return } eh := c.environmentHandlerFactory(accounts) err = eh.ScaleComponent(r.Context(), appName, envName, componentName, replicas) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } diff --git a/api/environments/environment_controller_secrets_test.go b/api/environments/environment_controller_secrets_test.go index 5764a535..05d5187b 100644 --- a/api/environments/environment_controller_secrets_test.go +++ b/api/environments/environment_controller_secrets_test.go @@ -863,7 +863,6 @@ func (s *secretHandlerTestSuite) createPodForRadixComponent(kubeClient kubernete kube.RadixComponentLabel: componentName, } if isJobComponent { - labels[k8sJobNameLabel] = componentName labels[kube.RadixJobTypeLabel] = kube.RadixJobTypeJobSchedule } _, _ = kubeClient.CoreV1().Pods(envNamespace).Create(context.Background(), &corev1.Pod{ diff --git a/api/environments/job_handler.go b/api/environments/job_handler.go index 6913ed14..36909e45 100644 --- a/api/environments/job_handler.go +++ b/api/environments/job_handler.go @@ -35,15 +35,6 @@ func (eh EnvironmentHandler) GetJobs(ctx context.Context, appName, envName, jobC return nil, err } - // Backward compatibility: Get list of jobs not handled by RadixBatch - // TODO: Remove when there are no legacy jobs left - jh := legacyJobHandler{accounts: eh.accounts} - legacyJobs, err := jh.GetJobs(ctx, appName, envName, jobComponentName) - if err != nil { - return nil, err - } - jobs = append(jobs, legacyJobs...) - sort.SliceStable(jobs, func(i, j int) bool { return utils.IsBefore(&jobs[j], &jobs[i]) }) @@ -62,16 +53,7 @@ func (eh EnvironmentHandler) getJobs(ctx context.Context, appName, envName, jobC // GetJob Gets job by name func (eh EnvironmentHandler) GetJob(ctx context.Context, appName, envName, jobComponentName, jobName string) (*deploymentModels.ScheduledJobSummary, error) { - if jobSummary, err := eh.getJob(ctx, appName, envName, jobComponentName, jobName); err == nil { - return jobSummary, nil - } - - // TODO: Return error from getJob when legacy handler is removed - // TODO: Remove when there are no legacy jobs left - - // Backward compatibility: Get job not handled by RadixBatch - jh := legacyJobHandler{accounts: eh.accounts} - return jh.GetJob(ctx, appName, envName, jobComponentName, jobName) + return eh.getJob(ctx, appName, envName, jobComponentName, jobName) } // StopJob Stop job by name @@ -178,15 +160,6 @@ func (eh EnvironmentHandler) GetBatches(ctx context.Context, appName, envName, j return nil, err } - // Backward compatibility: Get list of batches not handled by RadixBatch - // TODO: Remove when there are no legacy jobs left - jh := legacyJobHandler{accounts: eh.accounts} - legacyBatches, err := jh.GetBatches(ctx, appName, envName, jobComponentName) - if err != nil { - return nil, err - } - summaries = append(summaries, legacyBatches...) - sort.SliceStable(summaries, func(i, j int) bool { return utils.IsBefore(&summaries[j], &summaries[i]) }) @@ -265,16 +238,7 @@ func (eh EnvironmentHandler) CopyJob(ctx context.Context, appName, envName, jobC // GetBatch Gets batch by name func (eh EnvironmentHandler) GetBatch(ctx context.Context, appName, envName, jobComponentName, batchName string) (*deploymentModels.ScheduledBatchSummary, error) { - if batchSummary, err := eh.getBatch(ctx, appName, envName, jobComponentName, batchName); err == nil { - return batchSummary, nil - } - - // TODO: Return error from getBatch when legacy handler is removed - // TODO: Remove legacy handler when there are no legacy jobs left - - // Backward compatibility: Get batch not handled by RadixBatch - jh := legacyJobHandler{accounts: eh.accounts} - return jh.GetBatch(ctx, appName, envName, jobComponentName, batchName) + return eh.getBatch(ctx, appName, envName, jobComponentName, batchName) } func (eh EnvironmentHandler) getBatch(ctx context.Context, appName, envName, jobComponentName, batchName string) (*deploymentModels.ScheduledBatchSummary, error) { @@ -295,14 +259,7 @@ func (eh EnvironmentHandler) getBatch(ctx context.Context, appName, envName, job // GetJobPayload Gets job payload func (eh EnvironmentHandler) GetJobPayload(ctx context.Context, appName, envName, jobComponentName, jobName string) (io.ReadCloser, error) { - if payload, err := eh.getJobPayload(ctx, appName, envName, jobComponentName, jobName); err == nil { - return payload, nil - } - - // Backward compatibility: Get batch not handled by RadixBatch - // TODO: Remove when there are no legacy jobs left - jh := legacyJobHandler{accounts: eh.accounts} - return jh.GetJobPayload(appName, envName, jobComponentName, jobName) + return eh.getJobPayload(ctx, appName, envName, jobComponentName, jobName) } func (eh EnvironmentHandler) getJobPayload(ctx context.Context, appName, envName, jobComponentName, jobName string) (io.ReadCloser, error) { diff --git a/api/environments/legacy_job_handler.go b/api/environments/legacy_job_handler.go deleted file mode 100644 index 436c4ba4..00000000 --- a/api/environments/legacy_job_handler.go +++ /dev/null @@ -1,348 +0,0 @@ -package environments - -import ( - "bytes" - "context" - "fmt" - "io" - "sort" - "strconv" - "strings" - - deploymentModels "github.com/equinor/radix-api/api/deployments/models" - environmentModels "github.com/equinor/radix-api/api/environments/models" - jobModels "github.com/equinor/radix-api/api/jobs/models" - "github.com/equinor/radix-api/api/utils" - apiModels "github.com/equinor/radix-api/models" - radixutils "github.com/equinor/radix-common/utils" - - // batchSchedulerApi "github.com/equinor/radix-job-scheduler/api/batches" - // jobSchedulerApi "github.com/equinor/radix-job-scheduler/api/jobs" - - "github.com/equinor/radix-operator/pkg/apis/kube" - operatorUtils "github.com/equinor/radix-operator/pkg/apis/utils" - log "github.com/sirupsen/logrus" - batchv1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/apimachinery/pkg/selection" -) - -const ( - legacyRadixBatchJobCountAnnotation = "radix.equinor.com/batch-job-count" - legacyJobPayloadPropertyName = "payload" - k8sJobNameLabel = "job-name" // A label that k8s automatically adds to a Pod created by a Job -) - -type legacyJobHandler struct { - accounts apiModels.Accounts -} - -// GetJobs Get jobs -func (h legacyJobHandler) GetJobs(ctx context.Context, appName, envName, jobComponentName string) ([]deploymentModels. - ScheduledJobSummary, error) { - namespace := operatorUtils.GetEnvironmentNamespace(appName, envName) - jobs, err := h.getSingleJobs(ctx, namespace, jobComponentName) - if err != nil { - return nil, err - } - jobPodLabelSelector := labels.Set{ - kube.RadixJobTypeLabel: kube.RadixJobTypeJobSchedule, - } - podList, err := h.getPodsForSelector(ctx, namespace, labels.SelectorFromSet(jobPodLabelSelector)) - if err != nil { - return nil, err - } - jobPodMap, err := h.getJobPodsMap(podList) - if err != nil { - return nil, err - } - jobSummaryList := h.getScheduledJobSummaryList(jobs, jobPodMap) - return jobSummaryList, nil -} - -func (h legacyJobHandler) GetJob(ctx context.Context, appName, envName, jobComponentName, jobName string) (*deploymentModels. - ScheduledJobSummary, error) { - namespace := operatorUtils.GetEnvironmentNamespace(appName, envName) - job, err := h.getJob(ctx, namespace, jobComponentName, jobName, kube.RadixJobTypeJobSchedule) - if err != nil { - return nil, err - } - jobPodLabelSelector := labels.Set{ - k8sJobNameLabel: jobName, - kube.RadixJobTypeLabel: kube.RadixJobTypeJobSchedule, - } - podList, err := h.getPodsForSelector(ctx, namespace, labels.SelectorFromSet(jobPodLabelSelector)) - if err != nil { - return nil, err - } - jobPodMap, err := h.getJobPodsMap(podList) - if err != nil { - return nil, err - } - jobSummary := h.getScheduledJobSummary(job, jobPodMap) - return jobSummary, nil -} - -// GetBatches Get batches -func (h legacyJobHandler) GetBatches(ctx context.Context, appName, envName, jobComponentName string) ([]deploymentModels. - ScheduledBatchSummary, error) { - namespace := operatorUtils.GetEnvironmentNamespace(appName, envName) - batches, err := h.getBatches(ctx, namespace, jobComponentName) - if err != nil { - return nil, err - } - return h.getScheduledBatchSummaryList(batches) -} - -func (h legacyJobHandler) getScheduledJobSummaryList(jobs []batchv1.Job, - jobPodsMap map[string][]corev1.Pod) []deploymentModels.ScheduledJobSummary { - summaries := make([]deploymentModels.ScheduledJobSummary, 0) // return an array - not null - for _, job := range jobs { - summary := h.getScheduledJobSummary(&job, jobPodsMap) - summaries = append(summaries, *summary) - } - - // Sort job-summaries descending - sort.Slice(summaries, func(i, j int) bool { - return utils.IsBefore(&summaries[j], &summaries[i]) - }) - return summaries -} - -func (h legacyJobHandler) GetBatch(ctx context.Context, appName, envName, jobComponentName, batchName string) (*deploymentModels. - ScheduledBatchSummary, error) { - namespace := operatorUtils.GetEnvironmentNamespace(appName, envName) - batch, err := h.getJob(ctx, namespace, jobComponentName, batchName, kube.RadixJobTypeBatchSchedule) - if err != nil { - return nil, err - } - summary, err := h.getScheduledBatchSummary(batch) - if err != nil { - return nil, err - } - kubeClient := h.accounts.UserAccount.Client - jobPodLabelSelector := labels.Set{ - kube.RadixBatchNameLabel: batchName, - } - batchPods, err := h.getPodsForSelector(ctx, namespace, labels.SelectorFromSet(jobPodLabelSelector)) - if err != nil { - return nil, err - } - batchStatus, err := GetBatchStatusFromJob(kubeClient, batch, batchPods) - if err != nil { - return nil, err - } - summary.Status = batchStatus.Status - //nolint:staticcheck - //lint:ignore SA1019 support old batch scheduler - summary.Message = batchStatus.Message - - jobPodsMap, err := h.getJobPodsMap(batchPods) - if err != nil { - return nil, err - } - if batchPod, ok := jobPodsMap[batchName]; ok && len(batchPod) > 0 { - batchPodSummary := deploymentModels.GetReplicaSummary(batchPod[0]) - //nolint:staticcheck - //lint:ignore SA1019 support old batch scheduler - summary.Replica = &batchPodSummary - } - batchJobSummaryList, err := h.getBatchJobSummaryList(ctx, namespace, jobComponentName, batchName, jobPodsMap) - if err != nil { - return nil, err - } - summary.JobList = batchJobSummaryList - return summary, nil -} - -// GetJobPayload Gets job payload -func (h legacyJobHandler) GetJobPayload(appName, envName, jobComponentName, jobName string) (io.ReadCloser, error) { - namespace := operatorUtils.GetEnvironmentNamespace(appName, envName) - kubeUtil, err := kube.New(h.accounts.ServiceAccount.Client, h.accounts.UserAccount.RadixClient, nil) - if err != nil { - return nil, err - } - payloadSecrets, err := kubeUtil.ListSecretsWithSelector(namespace, h.getJobsSchedulerPayloadSecretSelector(appName, jobComponentName, jobName)) - if err != nil { - return nil, err - } - if len(payloadSecrets) == 0 { - return nil, environmentModels.ScheduledJobPayloadNotFoundError(appName, jobName) - } - if len(payloadSecrets) > 1 { - return nil, environmentModels.ScheduledJobPayloadUnexpectedError(appName, jobName, "unexpected multiple payloads found") - } - payload := payloadSecrets[0].Data[legacyJobPayloadPropertyName] - return io.NopCloser(bytes.NewReader(payload)), nil -} - -func (h legacyJobHandler) getJobsSchedulerPayloadSecretSelector(appName, jobComponentName, jobName string) string { - return labels.SelectorFromSet(map[string]string{ - kube.RadixAppLabel: appName, - kube.RadixComponentLabel: jobComponentName, - kube.RadixJobTypeLabel: kube.RadixJobTypeJobSchedule, - kube.RadixJobNameLabel: jobName, - }).String() -} - -func (h legacyJobHandler) getScheduledJobSummary(job *batchv1.Job, - jobPodsMap map[string][]corev1.Pod) *deploymentModels.ScheduledJobSummary { - creationTimestamp := job.GetCreationTimestamp() - batchName := job.ObjectMeta.Labels[kube.RadixBatchNameLabel] - summary := deploymentModels.ScheduledJobSummary{ - Name: job.Name, - Created: radixutils.FormatTimestamp(creationTimestamp.Time), - Started: radixutils.FormatTime(job.Status.StartTime), - BatchName: batchName, - JobId: job.ObjectMeta.Labels["radix-job-id"], - } - summary.TimeLimitSeconds = job.Spec.Template.Spec.ActiveDeadlineSeconds - jobPods := jobPodsMap[job.Name] - if len(jobPods) > 0 { - summary.ReplicaList = getReplicaSummariesForPods(jobPods) - } - summary.Resources = h.getJobResourceRequirements(job, jobPods) - summary.BackoffLimit = h.getJobBackoffLimit(job) - jobStatus := GetJobStatusFromJob(h.accounts.UserAccount.Client, job, jobPodsMap[job.Name]) - summary.Status = jobStatus.Status - summary.Message = jobStatus.Message - summary.Ended = jobStatus.Ended - return &summary -} - -func (h legacyJobHandler) getScheduledBatchSummaryList(batches []batchv1.Job) ([]deploymentModels.ScheduledBatchSummary, error) { - summaries := make([]deploymentModels.ScheduledBatchSummary, 0) // return an array - not null - for _, batch := range batches { - summary, err := h.getScheduledBatchSummary(&batch) - if err != nil { - return nil, err - } - summary.Status = jobModels.Succeeded.String() // TODO should be real status? - summaries = append(summaries, *summary) - } - - return summaries, nil -} - -func (h legacyJobHandler) getScheduledBatchSummary(batch *batchv1.Job) (*deploymentModels.ScheduledBatchSummary, error) { - creationTimestamp := batch.GetCreationTimestamp() - summary := deploymentModels.ScheduledBatchSummary{ - Name: batch.Name, - Created: radixutils.FormatTimestamp(creationTimestamp.Time), - Started: radixutils.FormatTime(batch.Status.StartTime), - Ended: radixutils.FormatTime(batch.Status.CompletionTime), - } - if jobCount, ok := batch.ObjectMeta.Annotations[legacyRadixBatchJobCountAnnotation]; ok { - if count, err := strconv.Atoi(jobCount); err == nil { - summary.TotalJobCount = count - } else { - log.Warnf("failed to get job count for the annotation %s", - legacyRadixBatchJobCountAnnotation) - } - } - - return &summary, nil -} - -func (h legacyJobHandler) getBatchJobSummaryList(ctx context.Context, namespace string, jobComponentName string, batchName string, jobPodsMap map[string][]corev1.Pod) ([]deploymentModels.ScheduledJobSummary, error) { - summaries := make([]deploymentModels.ScheduledJobSummary, 0) // return an array - not null - batchJobs, err := h.getBatchJobs(ctx, namespace, jobComponentName, batchName) - if err != nil { - return nil, err - } - for _, job := range batchJobs { - summaries = append(summaries, *h.getScheduledJobSummary(&job, jobPodsMap)) - } - return summaries, nil -} - -func (h legacyJobHandler) getJobBackoffLimit(job *batchv1.Job) int32 { - if job.Spec.BackoffLimit == nil { - return 0 - } - return *job.Spec.BackoffLimit -} - -func (h legacyJobHandler) getJobResourceRequirements(job *batchv1.Job, jobPods []corev1.Pod) deploymentModels.ResourceRequirements { - if len(jobPods) > 0 && len(jobPods[0].Spec.Containers) > 0 { - return deploymentModels.ConvertResourceRequirements(jobPods[0].Spec.Containers[0].Resources) - } else if len(job.Spec.Template.Spec.Containers) > 0 { - return deploymentModels.ConvertResourceRequirements(job.Spec.Template.Spec.Containers[0].Resources) - } - return deploymentModels.ResourceRequirements{} -} - -func (h legacyJobHandler) getJobPodsMap(podList []corev1.Pod) (map[string][]corev1.Pod, error) { - jobPodMap := make(map[string][]corev1.Pod) - for _, pod := range podList { - pod := pod - if jobName, ok := pod.GetLabels()[k8sJobNameLabel]; ok { - jobPodList := jobPodMap[jobName] - jobPodMap[jobName] = append(jobPodList, pod) - } - } - return jobPodMap, nil -} - -func (h legacyJobHandler) getPodsForSelector(ctx context.Context, namespace string, selector labels.Selector) ([]corev1.Pod, error) { - podList, err := h.accounts.UserAccount.Client.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ - LabelSelector: selector.String(), - }) - if err != nil { - return nil, err - } - return podList.Items, err -} - -func (h legacyJobHandler) getSingleJobs(ctx context.Context, namespace, componentName string) ([]batchv1.Job, error) { - batchNameNotExistsRequirement, err := labels.NewRequirement(kube.RadixBatchNameLabel, selection.DoesNotExist, nil) - if err != nil { - return nil, err - } - selector := labels.SelectorFromSet(map[string]string{ - kube.RadixComponentLabel: componentName, - kube.RadixJobTypeLabel: kube.RadixJobTypeJobSchedule, - }).Add(*batchNameNotExistsRequirement) - return h.getJobsForLabelSelector(ctx, namespace, selector) -} - -func (h legacyJobHandler) getBatches(ctx context.Context, namespace, componentName string) ([]batchv1.Job, error) { - jobLabelSelector := map[string]string{ - kube.RadixComponentLabel: componentName, - kube.RadixJobTypeLabel: kube.RadixJobTypeBatchSchedule, - } - return h.getJobsForLabelSelector(ctx, namespace, labels.SelectorFromSet(jobLabelSelector)) -} - -func (h legacyJobHandler) getBatchJobs(ctx context.Context, namespace, componentName, batchName string) ([]batchv1.Job, error) { - labelSelector := map[string]string{ - kube.RadixComponentLabel: componentName, - kube.RadixJobTypeLabel: kube.RadixJobTypeJobSchedule, - kube.RadixBatchNameLabel: batchName, - } - return h.getJobsForLabelSelector(ctx, namespace, labels.SelectorFromSet(labelSelector)) -} - -func (h legacyJobHandler) getJobsForLabelSelector(ctx context.Context, namespace string, labelSelector labels.Selector) ([]batchv1.Job, error) { - jobList, err := h.accounts.UserAccount.Client.BatchV1().Jobs(namespace).List(ctx, metav1.ListOptions{ - LabelSelector: labelSelector.String(), - }) - if err != nil { - return nil, fmt.Errorf("error getting jobs: %w", err) - } - return jobList.Items, err -} - -func (h legacyJobHandler) getJob(ctx context.Context, namespace, componentName, name, jobType string) (*batchv1.Job, error) { - job, err := h.accounts.UserAccount.Client.BatchV1().Jobs(namespace).Get(ctx, name, metav1.GetOptions{}) - if err != nil { - return nil, err - } - if strings.EqualFold(job.Labels[kube.RadixComponentLabel], componentName) && - strings.EqualFold(job.Labels[kube.RadixJobTypeLabel], jobType) { - return job, nil - } - return nil, jobNotFoundError(name) -} diff --git a/api/environments/legacy_job_status.go b/api/environments/legacy_job_status.go deleted file mode 100644 index 79d269f4..00000000 --- a/api/environments/legacy_job_status.go +++ /dev/null @@ -1,167 +0,0 @@ -package environments - -import ( - "context" - "fmt" - "sort" - "strings" - - jobSchedulerCommonModels "github.com/equinor/radix-job-scheduler/models/common" - jobSchedulerV1Models "github.com/equinor/radix-job-scheduler/models/v1" - "github.com/equinor/radix-operator/pkg/apis/kube" - - "github.com/equinor/radix-common/utils" - v1 "k8s.io/api/batch/v1" - corev1 "k8s.io/api/core/v1" - metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/client-go/kubernetes" -) - -// TODO: Remove this when all legacy jobs are gone - -var imageErrors = map[string]bool{"ImagePullBackOff": true, "ImageInspectError": true, "ErrImagePull": true, - "ErrImageNeverPull": true, "RegistryUnavailable": true, "InvalidImageName": true} - -// GetBatchStatusFromJob Gets job from a k8s jobs for the batch -func GetBatchStatusFromJob(kubeClient kubernetes.Interface, job *v1.Job, jobPods []corev1.Pod) (*jobSchedulerV1Models.BatchStatus, error) { - batchJobStatus := GetJobStatusFromJob(kubeClient, job, jobPods) - batchJobStatus.BatchName = job.GetName() - batchStatus := jobSchedulerV1Models.BatchStatus{ - JobStatus: *batchJobStatus, - } - return &batchStatus, nil -} - -// GetJobStatusFromJob Gets job from a k8s job -func GetJobStatusFromJob(kubeClient kubernetes.Interface, job *v1.Job, jobPods []corev1.Pod) *jobSchedulerV1Models.JobStatus { - jobStatus := jobSchedulerV1Models.JobStatus{ - Name: job.GetName(), - Created: utils.FormatTime(&job.ObjectMeta.CreationTimestamp), - Started: utils.FormatTime(job.Status.StartTime), - Ended: getJobEndTimestamp(job), - } - status := jobSchedulerCommonModels.GetStatusFromJobStatus(job.Status) - - jobStatus.Status = status.String() - jobStatus.JobId = job.ObjectMeta.Labels["radix-job-id"] // Not empty, if JobId exists - jobStatus.BatchName = job.ObjectMeta.Labels[kube.RadixBatchNameLabel] // Not empty, if BatchName exists - if status != jobSchedulerCommonModels.Running { - // if the job is not in state 'Running', we check that job's pod status reason - for _, pod := range jobPods { - if pod.Status.Reason == "DeadlineExceeded" { - // if the pod's status reason is 'DeadlineExceeded', the entire job also gets that status - jobStatus.Status = jobSchedulerCommonModels.DeadlineExceeded.String() - jobStatus.Message = pod.Status.Message - return &jobStatus - } - } - return &jobStatus - } - for _, pod := range jobPods { - if len(pod.Status.ContainerStatuses) > 0 { - cs := pod.Status.ContainerStatuses[0] - if cs.Ready { - continue - } - switch { - case cs.State.Terminated != nil: - // job with one or more 'terminated' containers gets status 'Stopped' - jobStatus.Status = jobSchedulerCommonModels.Stopped.String() - jobStatus.Message = cs.State.Terminated.Message - - return &jobStatus - case cs.State.Waiting != nil: - if _, ok := imageErrors[cs.State.Waiting.Reason]; ok { - // if container waits because of inaccessible image, the job is 'Failed' - jobStatus.Status = jobSchedulerCommonModels.Failed.String() - } else { - // if container waits for any other reason, job is 'Waiting' - jobStatus.Status = jobSchedulerCommonModels.Waiting.String() - } - jobStatus.Started = "" - message := cs.State.Waiting.Message - if len(message) > 0 { - jobStatus.Message = message - return &jobStatus - } - jobStatus.Message = getLastEventMessageForPod(kubeClient, pod) - if len(jobStatus.Message) == 0 { - jobStatus.Message = "Job has not been started. If it takes long time to start, please check an events list for a reason." - } - return &jobStatus - } - continue - } - if len(pod.Status.Conditions) > 0 { - - lastCondition := sortPodStatusConditionsDesc(pod.Status.Conditions)[0] - if lastCondition.Status == corev1.ConditionTrue { - continue - } - jobStatus.Status = jobSchedulerCommonModels.Waiting.String() - jobStatus.Message = fmt.Sprintf("%s %s", lastCondition.Reason, lastCondition.Message) - } - } - return &jobStatus -} - -func getJobEndTimestamp(job *v1.Job) string { - if job.Status.CompletionTime != nil { - // if the k8s job succeeds, we simply return the CompletionTime - return utils.FormatTime(job.Status.CompletionTime) - } - // if a k8s job fails, there is no timestamp for the failure. We set the job's failure time to be - // the timestamp for the job's last status condition. - if job.Status.Conditions != nil { - lastCondition := sortJobStatusConditionsDesc(job.Status.Conditions)[0].LastTransitionTime - return utils.FormatTime(&lastCondition) - } - return "" -} - -func getLastEventMessageForPod(kubeClient kubernetes.Interface, pod corev1.Pod) string { - eventsList, err := kubeClient.CoreV1().Events(pod.Namespace).List(context.Background(), metav1.ListOptions{}) - if err != nil { - return "" - } - events := sortEventsDesc(eventsList.Items) - for _, event := range events { - if event.InvolvedObject.Name == pod.Name { - if strings.Contains(event.Message, "container init was OOM-killed (memory limit too low?)") { - return fmt.Sprintf("Memory limit is probably too low. Error: %s", event.Message) - } - return event.Message - } - } - return "" -} - -func sortEventsDesc(events []corev1.Event) []corev1.Event { - sort.Slice(events, func(i, j int) bool { - if events[i].CreationTimestamp.IsZero() || events[j].CreationTimestamp.IsZero() { - return false - } - return events[j].CreationTimestamp.Before(&events[i].CreationTimestamp) - }) - return events -} - -func sortPodStatusConditionsDesc(podConditions []corev1.PodCondition) []corev1.PodCondition { - sort.Slice(podConditions, func(i, j int) bool { - if podConditions[i].LastTransitionTime.IsZero() || podConditions[j].LastTransitionTime.IsZero() { - return false - } - return podConditions[j].LastTransitionTime.Before(&podConditions[i].LastTransitionTime) - }) - return podConditions -} - -func sortJobStatusConditionsDesc(jobConditions []v1.JobCondition) []v1.JobCondition { - sort.Slice(jobConditions, func(i, j int) bool { - if jobConditions[i].LastTransitionTime.IsZero() || jobConditions[j].LastTransitionTime.IsZero() { - return false - } - return jobConditions[j].LastTransitionTime.Before(&jobConditions[i].LastTransitionTime) - }) - return jobConditions -} diff --git a/api/environmentvariables/env_vars_controller.go b/api/environmentvariables/env_vars_controller.go index 8d203895..26724564 100644 --- a/api/environmentvariables/env_vars_controller.go +++ b/api/environmentvariables/env_vars_controller.go @@ -6,7 +6,6 @@ import ( envvarsmodels "github.com/equinor/radix-api/api/environmentvariables/models" "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" "github.com/gorilla/mux" log "github.com/sirupsen/logrus" ) @@ -94,11 +93,11 @@ func (controller *envVarsController) GetComponentEnvVars(accounts models.Account envVars, err := eh.GetComponentEnvVars(appName, envName, componentName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + controller.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, envVars) + controller.JSONResponse(w, r, envVars) } // ChangeEnvVar Modifies an environment variable @@ -159,7 +158,7 @@ func (controller *envVarsController) ChangeEnvVar(accounts models.Accounts, w ht appName, envName, componentName := mux.Vars(r)["appName"], mux.Vars(r)["envName"], mux.Vars(r)["componentName"] var envVarParameters []envvarsmodels.EnvVarParameter if err := json.NewDecoder(r.Body).Decode(&envVarParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + controller.ErrorResponse(w, r, err) return } @@ -169,9 +168,9 @@ func (controller *envVarsController) ChangeEnvVar(accounts models.Accounts, w ht err := envVarsHandler.ChangeEnvVar(appName, envName, componentName, envVarParameters) if err != nil { - radixhttp.ErrorResponse(w, r, err) + controller.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + controller.JSONResponse(w, r, "Success") } diff --git a/api/jobs/job_controller.go b/api/jobs/job_controller.go index 93aa736c..48c1cabd 100644 --- a/api/jobs/job_controller.go +++ b/api/jobs/job_controller.go @@ -8,7 +8,6 @@ import ( "github.com/equinor/radix-api/api/deployments" "github.com/equinor/radix-api/api/utils/logs" "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" "github.com/gorilla/mux" ) @@ -29,57 +28,57 @@ func (jc *jobController) GetRoutes() models.Routes { models.Route{ Path: rootPath + "/jobs", Method: "GET", - HandlerFunc: GetApplicationJobs, + HandlerFunc: jc.GetApplicationJobs, }, models.Route{ Path: rootPath + "/jobs/{jobName}", Method: "GET", - HandlerFunc: GetApplicationJob, + HandlerFunc: jc.GetApplicationJob, }, models.Route{ Path: rootPath + "/jobs/{jobName}/stop", Method: "POST", - HandlerFunc: StopApplicationJob, + HandlerFunc: jc.StopApplicationJob, }, models.Route{ Path: rootPath + "/jobs/{jobName}/rerun", Method: "POST", - HandlerFunc: RerunApplicationJob, + HandlerFunc: jc.RerunApplicationJob, }, models.Route{ Path: rootPath + "/jobs/{jobName}/pipelineruns", Method: "GET", - HandlerFunc: GetTektonPipelineRuns, + HandlerFunc: jc.GetTektonPipelineRuns, }, models.Route{ Path: rootPath + "/jobs/{jobName}/pipelineruns/{pipelineRunName}", Method: "GET", - HandlerFunc: GetTektonPipelineRun, + HandlerFunc: jc.GetTektonPipelineRun, }, models.Route{ Path: rootPath + "/jobs/{jobName}/pipelineruns/{pipelineRunName}/tasks", Method: "GET", - HandlerFunc: GetTektonPipelineRunTasks, + HandlerFunc: jc.GetTektonPipelineRunTasks, }, models.Route{ Path: rootPath + "/jobs/{jobName}/pipelineruns/{pipelineRunName}/tasks/{taskName}", Method: "GET", - HandlerFunc: GetTektonPipelineRunTask, + HandlerFunc: jc.GetTektonPipelineRunTask, }, models.Route{ Path: rootPath + "/jobs/{jobName}/pipelineruns/{pipelineRunName}/tasks/{taskName}/steps", Method: "GET", - HandlerFunc: GetTektonPipelineRunTaskSteps, + HandlerFunc: jc.GetTektonPipelineRunTaskSteps, }, models.Route{ Path: rootPath + "/jobs/{jobName}/pipelineruns/{pipelineRunName}/tasks/{taskName}/logs/{stepName}", Method: "GET", - HandlerFunc: GetTektonPipelineRunTaskStepLogs, + HandlerFunc: jc.GetTektonPipelineRunTaskStepLogs, }, models.Route{ Path: rootPath + "/jobs/{jobName}/logs/{stepName}", Method: "GET", - HandlerFunc: GetPipelineJobStepLogs, + HandlerFunc: jc.GetPipelineJobStepLogs, }, } @@ -87,7 +86,7 @@ func (jc *jobController) GetRoutes() models.Routes { } // GetApplicationJobs gets pipeline-job summaries -func GetApplicationJobs(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetApplicationJobs(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs pipeline-job getApplicationJobs // --- // summary: Gets the summary of jobs for a given application @@ -124,15 +123,15 @@ func GetApplicationJobs(accounts models.Accounts, w http.ResponseWriter, r *http jobSummaries, err := handler.GetApplicationJobs(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, jobSummaries) + jc.JSONResponse(w, r, jobSummaries) } // GetApplicationJob gets specific pipeline-job details -func GetApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs/{jobName} pipeline-job getApplicationJob // --- // summary: Gets the detail of a given pipeline-job for a given application @@ -173,15 +172,15 @@ func GetApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http. jobDetail, err := handler.GetApplicationJob(r.Context(), appName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, jobDetail) + jc.JSONResponse(w, r, jobDetail) } // StopApplicationJob Stops job -func StopApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) StopApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation POST /applications/{appName}/jobs/{jobName}/stop pipeline-job stopApplicationJob // --- // summary: Stops job @@ -220,7 +219,7 @@ func StopApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http err := handler.StopJob(r.Context(), appName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } @@ -228,7 +227,7 @@ func StopApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http } // RerunApplicationJob Reruns the pipeline job -func RerunApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) RerunApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation POST /applications/{appName}/jobs/{jobName}/rerun pipeline-job rerunApplicationJob // --- // summary: Reruns the pipeline job @@ -266,7 +265,7 @@ func RerunApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *htt err := handler.RerunJob(r.Context(), appName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } @@ -274,7 +273,7 @@ func RerunApplicationJob(accounts models.Accounts, w http.ResponseWriter, r *htt } // GetTektonPipelineRuns Get the Tekton pipeline runs overview -func GetTektonPipelineRuns(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetTektonPipelineRuns(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs/{jobName}/pipelineruns pipeline-job getTektonPipelineRuns // --- // summary: Gets list of pipeline runs for a pipeline-job @@ -317,15 +316,15 @@ func GetTektonPipelineRuns(accounts models.Accounts, w http.ResponseWriter, r *h tektonPipelineRuns, err := handler.GetTektonPipelineRuns(r.Context(), appName, jobName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, tektonPipelineRuns) + jc.JSONResponse(w, r, tektonPipelineRuns) } // GetTektonPipelineRun Get the Tekton pipeline run overview -func GetTektonPipelineRun(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetTektonPipelineRun(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs/{jobName}/pipelineruns/{pipelineRunName} pipeline-job getTektonPipelineRun // --- // summary: Gets a pipeline run for a pipeline-job @@ -372,15 +371,15 @@ func GetTektonPipelineRun(accounts models.Accounts, w http.ResponseWriter, r *ht tektonPipelineRun, err := handler.GetTektonPipelineRun(r.Context(), appName, jobName, pipelineRunName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, tektonPipelineRun) + jc.JSONResponse(w, r, tektonPipelineRun) } // GetTektonPipelineRunTasks Get the Tekton task list of a pipeline run -func GetTektonPipelineRunTasks(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetTektonPipelineRunTasks(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs/{jobName}/pipelineruns/{pipelineRunName}/tasks pipeline-job getTektonPipelineRunTasks // --- // summary: Gets list of pipeline run tasks of a pipeline-job @@ -429,15 +428,15 @@ func GetTektonPipelineRunTasks(accounts models.Accounts, w http.ResponseWriter, tektonTasks, err := handler.GetTektonPipelineRunTasks(r.Context(), appName, jobName, pipelineRunName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, tektonTasks) + jc.JSONResponse(w, r, tektonTasks) } // GetTektonPipelineRunTask Get the Tekton task of a pipeline run -func GetTektonPipelineRunTask(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetTektonPipelineRunTask(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs/{jobName}/pipelineruns/{pipelineRunName}/tasks/{taskName} pipeline-job getTektonPipelineRunTask // --- // summary: Gets list of pipeline run task of a pipeline-job @@ -490,15 +489,15 @@ func GetTektonPipelineRunTask(accounts models.Accounts, w http.ResponseWriter, r tektonTasks, err := handler.GetTektonPipelineRunTask(r.Context(), appName, jobName, pipelineRunName, taskName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, tektonTasks) + jc.JSONResponse(w, r, tektonTasks) } // GetTektonPipelineRunTaskSteps Get the Tekton task step list of a pipeline run -func GetTektonPipelineRunTaskSteps(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetTektonPipelineRunTaskSteps(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs/{jobName}/pipelineruns/{pipelineRunName}/tasks/{taskName}/steps pipeline-job getTektonPipelineRunTaskSteps // --- // summary: Gets list of steps for a pipeline run task of a pipeline-job @@ -553,15 +552,15 @@ func GetTektonPipelineRunTaskSteps(accounts models.Accounts, w http.ResponseWrit tektonTaskSteps, err := handler.GetTektonPipelineRunTaskSteps(r.Context(), appName, jobName, pipelineRunName, taskName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, tektonTaskSteps) + jc.JSONResponse(w, r, tektonTaskSteps) } // GetTektonPipelineRunTaskStepLogs Get step logs of a pipeline run task for a pipeline job -func GetTektonPipelineRunTaskStepLogs(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetTektonPipelineRunTaskStepLogs(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs/{jobName}/pipelineruns/{pipelineRunName}/tasks/{taskName}/logs/{stepName} pipeline-job getTektonPipelineRunTaskStepLogs // --- // summary: Gets logs of pipeline runs for a pipeline-job @@ -635,28 +634,28 @@ func GetTektonPipelineRunTaskStepLogs(accounts models.Accounts, w http.ResponseW stepName := mux.Vars(r)["stepName"] since, asFile, logLines, err, _ := logs.GetLogParams(r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } handler := Init(accounts, deployments.Init(accounts)) log, err := handler.GetTektonPipelineRunTaskStepLogs(r.Context(), appName, jobName, pipelineRunName, taskName, stepName, &since, logLines) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - defer log.Close() + defer func() {_ = log.Close()}() if asFile { fileName := fmt.Sprintf("%s.log", time.Now().Format("20060102150405")) - radixhttp.ReaderFileResponse(w, log, fileName, "text/plain; charset=utf-8") + jc.ReaderFileResponse(w, r, log, fileName, "text/plain; charset=utf-8") } else { - radixhttp.ReaderResponse(w, log, "text/plain; charset=utf-8") + jc.ReaderResponse(w, r, log, "text/plain; charset=utf-8") } } // GetPipelineJobStepLogs Get log of a pipeline job step -func GetPipelineJobStepLogs(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { +func (jc *jobController) GetPipelineJobStepLogs(accounts models.Accounts, w http.ResponseWriter, r *http.Request) { // swagger:operation GET /applications/{appName}/jobs/{jobName}/logs/{stepName} pipeline-job getPipelineJobStepLogs // --- // summary: Gets logs of a pipeline job step @@ -718,22 +717,22 @@ func GetPipelineJobStepLogs(accounts models.Accounts, w http.ResponseWriter, r * stepName := mux.Vars(r)["stepName"] since, asFile, logLines, err, _ := logs.GetLogParams(r) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } handler := Init(accounts, deployments.Init(accounts)) log, err := handler.GetPipelineJobStepLogs(r.Context(), appName, jobName, stepName, &since, logLines) if err != nil { - radixhttp.ErrorResponse(w, r, err) + jc.ErrorResponse(w, r, err) return } - defer log.Close() + defer func() {_ = log.Close()}() if asFile { fileName := fmt.Sprintf("%s.log", time.Now().Format("20060102150405")) - radixhttp.ReaderFileResponse(w, log, fileName, "text/plain; charset=utf-8") + jc.ReaderFileResponse(w, r, log, fileName, "text/plain; charset=utf-8") } else { - radixhttp.ReaderResponse(w, log, "text/plain; charset=utf-8") + jc.ReaderResponse(w, r, log, "text/plain; charset=utf-8") } } diff --git a/api/jobs/job_handler_test.go b/api/jobs/job_handler_test.go index 69ed9ab0..b3bed268 100644 --- a/api/jobs/job_handler_test.go +++ b/api/jobs/job_handler_test.go @@ -185,7 +185,7 @@ func (s *JobHandlerTestSuite) Test_GetApplicationJob() { //lint:ignore SA1019 we want to make sure that Components is populated for backward compatibility (at least for a while) s.ElementsMatch(slice.PointersOf(expectedComponents), actualJob.Components) expectedSteps := []jobModels.Step{ - {Name: step1Name, PodName: step1Pod, Status: string(step1Condition), Started: radixutils.FormatTime(&step1Started), Ended: radixutils.FormatTime(&step1Ended), Components: step1Components}, + {Name: step1Name, PodName: step1Pod, Status: string(step1Condition), Started: &step1Started.Time, Ended: &step1Ended.Time, Components: step1Components}, {Name: step2Name}, } s.ElementsMatch(expectedSteps, actualJob.Steps) diff --git a/api/jobs/models/job.go b/api/jobs/models/job.go index 5f5b4343..31209f94 100644 --- a/api/jobs/models/job.go +++ b/api/jobs/models/job.go @@ -179,15 +179,16 @@ func GetJobFromRadixJob(job *radixv1.RadixJob, jobDeployments []*deploymentModel // GetJobStepsFromRadixJob Gets the steps from a Radix job func GetJobStepsFromRadixJob(job *radixv1.RadixJob) []Step { var steps []Step + for _, jobStep := range job.Status.Steps { step := Step{ Name: jobStep.Name, Status: string(jobStep.Condition), - Started: radixutils.FormatTime(jobStep.Started), - Ended: radixutils.FormatTime(jobStep.Ended), PodName: jobStep.PodName, Components: jobStep.Components, } + if jobStep.Started != nil {step.Started = &jobStep.Started.Time} + if jobStep.Ended != nil {step.Ended = &jobStep.Ended.Time} steps = append(steps, step) } diff --git a/api/jobs/models/step.go b/api/jobs/models/step.go index 05d11703..1545246c 100644 --- a/api/jobs/models/step.go +++ b/api/jobs/models/step.go @@ -1,5 +1,7 @@ package models +import "time" + // Step holds general information about job step // swagger:model Step type Step struct { @@ -19,14 +21,16 @@ type Step struct { // Started timestamp // // required: false + // swagger:strfmt date-time // example: 2006-01-02T15:04:05Z - Started string `json:"started"` + Started *time.Time `json:"started"` // Ended timestamp // // required: false + // swagger:strfmt date-time // example: 2006-01-02T15:04:05Z - Ended string `json:"ended"` + Ended *time.Time `json:"ended"` // Pod name // diff --git a/api/privateimagehubs/privateimagehubs_controller.go b/api/privateimagehubs/privateimagehubs_controller.go index d3142356..61cb4d90 100644 --- a/api/privateimagehubs/privateimagehubs_controller.go +++ b/api/privateimagehubs/privateimagehubs_controller.go @@ -5,9 +5,7 @@ import ( "net/http" environmentModels "github.com/equinor/radix-api/api/secrets/models" - "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" "github.com/gorilla/mux" ) @@ -78,11 +76,11 @@ func (dc *privateImageHubController) GetPrivateImageHubs(accounts models.Account imageHubSecrets, err := privateImageHubHandler.GetPrivateImageHubs(r.Context(), appName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, imageHubSecrets) + dc.JSONResponse(w, r, imageHubSecrets) } // ChangePrivateImageHubSecret Modifies an application private image hub secret @@ -135,7 +133,7 @@ func (dc *privateImageHubController) ChangePrivateImageHubSecret(accounts models var secretParameters environmentModels.SecretParameters if err := json.NewDecoder(r.Body).Decode(&secretParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } @@ -143,9 +141,9 @@ func (dc *privateImageHubController) ChangePrivateImageHubSecret(accounts models err := privateImageHubHandler.UpdatePrivateImageHubValue(appName, serverName, secretParameters.SecretValue) if err != nil { - radixhttp.ErrorResponse(w, r, err) + dc.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + dc.JSONResponse(w, r, "Success") } diff --git a/api/secrets/secret_controller.go b/api/secrets/secret_controller.go index 69b1f34d..2c0dfe6c 100644 --- a/api/secrets/secret_controller.go +++ b/api/secrets/secret_controller.go @@ -6,7 +6,6 @@ import ( secretModels "github.com/equinor/radix-api/api/secrets/models" "github.com/equinor/radix-api/models" - radixhttp "github.com/equinor/radix-common/net/http" "github.com/gorilla/mux" ) @@ -119,18 +118,18 @@ func (c *secretController) ChangeComponentSecret(accounts models.Accounts, w htt var secretParameters secretModels.SecretParameters if err := json.NewDecoder(r.Body).Decode(&secretParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } handler := Init(WithAccounts(accounts)) if err := handler.ChangeComponentSecret(r.Context(), appName, envName, componentName, secretName, secretParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // GetAzureKeyVaultSecretVersions Get Azure Key vault secret versions for a component @@ -204,11 +203,11 @@ func (c *secretController) GetAzureKeyVaultSecretVersions(accounts models.Accoun secretStatuses, err := handler.GetAzureKeyVaultSecretVersions(appName, envName, componentName, azureKeyVaultName, secretName) if err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, secretStatuses) + c.JSONResponse(w, r, secretStatuses) } // SetComponentExternalDNSTLSKey Set external DNS TLS key for a component @@ -276,18 +275,18 @@ func (c *secretController) SetComponentExternalDNSTLSKey(accounts models.Account var secretParameters secretModels.SecretParameters if err := json.NewDecoder(r.Body).Decode(&secretParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } handler := Init(WithAccounts(accounts)) if err := handler.ChangeComponentExternalDNSTLSKey(r.Context(), appName, envName, componentName, fqdn, secretParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } // SetComponentExternalDNSTLSCertificate Set external DNS TLS certificate for a component @@ -355,16 +354,16 @@ func (c *secretController) SetComponentExternalDNSTLSCertificate(accounts models var secretParameters secretModels.SecretParameters if err := json.NewDecoder(r.Body).Decode(&secretParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } handler := Init(WithAccounts(accounts)) if err := handler.ChangeComponentExternalDNSTLSCertificate(r.Context(), appName, envName, componentName, fqdn, secretParameters); err != nil { - radixhttp.ErrorResponse(w, r, err) + c.ErrorResponse(w, r, err) return } - radixhttp.JSONResponse(w, r, "Success") + c.JSONResponse(w, r, "Success") } diff --git a/api/utils/radix_middleware.go b/api/utils/radix_middleware.go index 47dafbdb..180f729d 100644 --- a/api/utils/radix_middleware.go +++ b/api/utils/radix_middleware.go @@ -8,6 +8,7 @@ import ( "github.com/equinor/radix-api/models" radixhttp "github.com/equinor/radix-common/net/http" "github.com/gorilla/mux" + log "github.com/sirupsen/logrus" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -59,13 +60,17 @@ func (handler *RadixMiddleware) handleAuthorization(w http.ResponseWriter, r *ht token, err := getBearerTokenFromHeader(r, useOutClusterClient) if err != nil { - radixhttp.ErrorResponse(w, r, err) + if err = radixhttp.ErrorResponse(w, r, err); err != nil { + log.Errorf("handleAuthorization: failed to write error response: %v", err) + } return } impersonation, err := radixhttp.GetImpersonationFromHeader(r) if err != nil { - radixhttp.ErrorResponse(w, r, radixhttp.UnexpectedError("Problems impersonating", err)) + if err = radixhttp.ErrorResponse(w, r, radixhttp.UnexpectedError("Problems impersonating", err)); err != nil { + log.Errorf("handleAuthorization: failed to write error response: %v", err) + } return } @@ -88,7 +93,9 @@ func (handler *RadixMiddleware) handleAuthorization(w http.ResponseWriter, r *ht // Check if registration of application exists for application-specific requests if appName, exists := mux.Vars(r)["appName"]; exists { if _, err := accounts.UserAccount.RadixClient.RadixV1().RadixRegistrations().Get(r.Context(), appName, metav1.GetOptions{}); err != nil { - radixhttp.ErrorResponse(w, r, err) + if err = radixhttp.ErrorResponse(w, r, err); err != nil { + log.Errorf("handleAuthorization: failed to write error response: %v", err) + } return } } diff --git a/go.mod b/go.mod index aec1cd43..63491c9c 100644 --- a/go.mod +++ b/go.mod @@ -4,36 +4,36 @@ go 1.21 require ( github.com/equinor/radix-common v1.7.1 - github.com/equinor/radix-job-scheduler v1.8.4 + github.com/equinor/radix-job-scheduler v1.8.5 github.com/equinor/radix-operator v1.47.6-0.20240102073852-648f9e23dec0 - github.com/evanphx/json-patch/v5 v5.6.0 + github.com/evanphx/json-patch/v5 v5.7.0 github.com/go-swagger/go-swagger v0.30.5 github.com/golang-jwt/jwt/v4 v4.5.0 github.com/golang/mock v1.6.0 - github.com/gorilla/handlers v1.5.1 - github.com/gorilla/mux v1.8.0 + github.com/gorilla/handlers v1.5.2 + github.com/gorilla/mux v1.8.1 github.com/marstr/guid v1.1.0 github.com/mitchellh/mapstructure v1.5.0 github.com/prometheus-operator/prometheus-operator/pkg/client v0.70.0 github.com/prometheus/client_golang v1.18.0 - github.com/rs/cors v1.8.3 + github.com/rs/cors v1.10.1 github.com/sirupsen/logrus v1.9.3 github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.18.2 github.com/stretchr/testify v1.8.4 - github.com/tektoncd/pipeline v0.53.0 + github.com/tektoncd/pipeline v0.55.0 github.com/urfave/negroni/v3 v3.0.0 golang.org/x/sync v0.5.0 k8s.io/api v0.29.0 k8s.io/apimachinery v0.29.0 k8s.io/client-go v0.29.0 - knative.dev/pkg v0.0.0-20231011193800-bd99f2f98be7 + knative.dev/pkg v0.0.0-20231219072704-d513e487961e sigs.k8s.io/secrets-store-csi-driver v1.4.0 ) require ( contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect - contrib.go.opencensus.io/exporter/prometheus v0.4.0 // indirect + contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect dario.cat/mergo v1.0.0 // indirect github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df // indirect github.com/beorn7/perks v1.0.1 // indirect @@ -43,7 +43,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect github.com/emicklei/go-restful/v3 v3.11.0 // indirect github.com/evanphx/json-patch v5.7.0+incompatible // indirect - github.com/felixge/httpsnoop v1.0.3 // indirect + github.com/felixge/httpsnoop v1.0.4 // indirect github.com/fsnotify/fsnotify v1.7.0 // indirect github.com/go-kit/log v0.2.1 // indirect github.com/go-logfmt/logfmt v0.5.1 // indirect @@ -54,7 +54,7 @@ require ( github.com/gogo/protobuf v1.3.2 // indirect github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect github.com/golang/protobuf v1.5.3 // indirect - github.com/google/cel-go v0.17.7 // indirect + github.com/google/cel-go v0.18.1 // indirect github.com/google/gnostic-models v0.6.8 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/go-containerregistry v0.16.1 // indirect @@ -81,7 +81,7 @@ require ( github.com/prometheus/client_model v0.5.0 // indirect github.com/prometheus/common v0.45.0 // indirect github.com/prometheus/procfs v0.12.0 // indirect - github.com/prometheus/statsd_exporter v0.21.0 // indirect + github.com/prometheus/statsd_exporter v0.22.7 // indirect github.com/sagikazarmark/locafero v0.4.0 // indirect github.com/sagikazarmark/slog-shim v0.1.0 // indirect github.com/sourcegraph/conc v0.3.0 // indirect @@ -90,7 +90,6 @@ require ( github.com/stoewer/go-strcase v1.2.0 // indirect github.com/subosito/gotenv v1.6.0 // indirect go.opencensus.io v0.24.0 // indirect - go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect go.uber.org/zap v1.26.0 // indirect golang.org/x/crypto v0.17.0 // indirect @@ -102,11 +101,11 @@ require ( golang.org/x/text v0.14.0 // indirect golang.org/x/time v0.5.0 // indirect gomodules.xyz/jsonpatch/v2 v2.4.0 // indirect - google.golang.org/api v0.153.0 // indirect + google.golang.org/api v0.154.0 // indirect google.golang.org/appengine v1.6.8 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 // indirect - google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f // indirect - google.golang.org/grpc v1.59.0 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f // indirect + google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 // indirect + google.golang.org/grpc v1.60.1 // indirect google.golang.org/protobuf v1.31.0 // indirect gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/ini.v1 v1.67.0 // indirect diff --git a/go.sum b/go.sum index 693b4bd5..ea670fc5 100644 --- a/go.sum +++ b/go.sum @@ -32,8 +32,8 @@ cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RX cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0= contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d h1:LblfooH1lKOpp1hIhukktmSAxFkqMPFk9KR6iZ0MJNI= contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d/go.mod h1:IshRmMJBhDfFj5Y67nVhMYTTIze91RUeT73ipWKs/GY= -contrib.go.opencensus.io/exporter/prometheus v0.4.0 h1:0QfIkj9z/iVZgK31D9H9ohjjIDApI2GOPScCKwxedbs= -contrib.go.opencensus.io/exporter/prometheus v0.4.0/go.mod h1:o7cosnyfuPVK0tB8q0QmaQNhGnptITnPQB+z1+qeFB0= +contrib.go.opencensus.io/exporter/prometheus v0.4.2 h1:sqfsYl5GIY/L570iT+l93ehxaWJs2/OwXtiWwew3oAg= +contrib.go.opencensus.io/exporter/prometheus v0.4.2/go.mod h1:dvEHbiKmgvbr5pjaF9fpw1KeYcjrnC1J8B+JKjsZyRQ= dario.cat/mergo v1.0.0 h1:AGCNq9Evsj31mOgNPcLyXc+4PNABt905YmuqPYYpBWk= dario.cat/mergo v1.0.0/go.mod h1:uNxQE+84aUszobStD9th8a29P2fMDhsBdgRYvZOxGmk= dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= @@ -44,6 +44,7 @@ github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuy github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= +github.com/alecthomas/units v0.0.0-20211218093645-b94a6e3cc137/go.mod h1:OMCwj8VM1Kc9e19TLln2VL61YJF0x1XFtfdL4JdbSyE= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df h1:7RFfzj4SSt6nnvCPbCqijJi1nWCd+TqAT3bYCStRC18= github.com/antlr/antlr4/runtime/Go/antlr/v4 v4.0.0-20230305170008-8188dc5388df/go.mod h1:pSwJ0fSY5KhvocuWSx4fz3BA8OrA1bQn+K1Eli3BRwM= @@ -57,6 +58,7 @@ github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA github.com/census-instrumentation/opencensus-proto v0.4.1 h1:iKLQ0xPNFxR/2hzXZMrBo8f1j86j5WHzznCCQxV/b8g= github.com/census-instrumentation/opencensus-proto v0.4.1/go.mod h1:4T9NM4+4Vw91VeyqjLS6ao50K5bOcLKN6Q42XnYaRYw= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= +github.com/cespare/xxhash/v2 v2.1.2/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= github.com/cespare/xxhash/v2 v2.2.0/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/chzyer/logex v1.1.10/go.mod h1:+Ywpsq7O8HXn0nuIou7OrIPyXbp3wmkHB+jjWRnGsAI= @@ -79,17 +81,16 @@ github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1m github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/equinor/radix-common v1.7.1 h1:kl7Tuo2VEo2WHGm/vkvktrZ9t9S3Nht7Mob3CSIzcJI= github.com/equinor/radix-common v1.7.1/go.mod h1:M6mhgHtFQ3rnjJnyOuECXiZOh7XQ5xVeHMyCAU+YPzQ= -github.com/equinor/radix-job-scheduler v1.8.4 h1:vqhP/xmOiU8UoaVhOoPjIQRSScmxSt9jMmYhEAzjIao= -github.com/equinor/radix-job-scheduler v1.8.4/go.mod h1:r71td0yDeDixdiMtq5TuCpCICD3lMHR8d1o5rSgTrTo= +github.com/equinor/radix-job-scheduler v1.8.5 h1:ahw6FkFpPV167B1/w7/aQKpVMmU5Vc7UBO8411ZtYck= +github.com/equinor/radix-job-scheduler v1.8.5/go.mod h1:rNIQU1eCInLV8Yl+5SRITOUU52QwYioYrIGQcsDc3kg= github.com/equinor/radix-operator v1.47.6-0.20240102073852-648f9e23dec0 h1:GbGRsmGmDwwoZre8cF55pid4NgC9DJECENHAlDsYyrE= github.com/equinor/radix-operator v1.47.6-0.20240102073852-648f9e23dec0/go.mod h1:i8A6V/g1OM+Zk2lAASZaoX+lHdJIZYYZHA586SHB2p8= github.com/evanphx/json-patch v5.7.0+incompatible h1:vgGkfT/9f8zE6tvSCe74nfpAVDQ2tG6yudJd8LBksgI= github.com/evanphx/json-patch v5.7.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk= -github.com/evanphx/json-patch/v5 v5.6.0 h1:b91NhWfaz02IuVxO9faSllyAtNXHMPkC5J8sJCLunww= -github.com/evanphx/json-patch/v5 v5.6.0/go.mod h1:G79N1coSVB93tBe7j6PhzjmR3/2VvlbKOFpnXhI9Bw4= -github.com/felixge/httpsnoop v1.0.1/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= -github.com/felixge/httpsnoop v1.0.3 h1:s/nj+GCswXYzN5v2DpNMuMQYe+0DDwt5WVCU6CWBdXk= -github.com/felixge/httpsnoop v1.0.3/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= +github.com/evanphx/json-patch/v5 v5.7.0 h1:nJqP7uwL84RJInrohHfW0Fx3awjbm8qZeFv0nW9SYGc= +github.com/evanphx/json-patch/v5 v5.7.0/go.mod h1:VNkHZ/282BpEyt/tObQO8s5CMPmYYq14uClGH4abBuQ= +github.com/felixge/httpsnoop v1.0.4 h1:NFTV2Zj1bL4mc9sqWACXbQFVBBg2W3GPvqp8/ESS2Wg= +github.com/felixge/httpsnoop v1.0.4/go.mod h1:m8KPJKqk1gH5J9DgRY2ASl2lWCfGKXixSwevea8zH2U= github.com/frankban/quicktest v1.14.6 h1:7Xjx+VpznH+oBnejlPUj8oUpdxnVs4f8XU8WnHkI4W8= github.com/frankban/quicktest v1.14.6/go.mod h1:4ptaffx2x8+WTWXmUCuVU6aPUX1/Mz7zb5vbUoiM6w0= github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA= @@ -101,6 +102,7 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2 github.com/go-kit/kit v0.8.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/kit v0.9.0/go.mod h1:xBxKIO96dXMWWy0MnWVtmwkA9/13aqxPnvrjFYMA2as= github.com/go-kit/log v0.1.0/go.mod h1:zbhenjAZHb184qTLMA9ZjW7ThYL0H2mk7Q6pNt4vbaY= +github.com/go-kit/log v0.2.0/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-kit/log v0.2.1 h1:MRVx0/zhvdseW+Gza6N9rVzU/IVzaeE1SFI4raAhmBU= github.com/go-kit/log v0.2.1/go.mod h1:NwTd00d/i8cPZ3xOwwiv2PO5MOcx78fFErGNcVmBjv0= github.com/go-logfmt/logfmt v0.3.0/go.mod h1:Qt1PoO58o5twSAckw1HlFXLmHsOX5/0LbT9GBnD5lWE= @@ -165,8 +167,8 @@ github.com/golang/protobuf v1.5.3 h1:KhyjKVUg7Usr/dYsdSqoFveMYd5ko72D+zANwlG1mmg github.com/golang/protobuf v1.5.3/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= -github.com/google/cel-go v0.17.7 h1:6ebJFzu1xO2n7TLtN+UBqShGBhlD85bhvglh5DpcfqQ= -github.com/google/cel-go v0.17.7/go.mod h1:HXZKzB0LXqer5lHHgfWAnlYwJaQBDKMjxjulNQzhwhY= +github.com/google/cel-go v0.18.1 h1:V/lAXKq4C3BYLDy/ARzMtpkEEYfHQpZzVyzy69nEUjs= +github.com/google/cel-go v0.18.1/go.mod h1:PVAybmSnWkNMUZR/tEWFUiJ1Np4Hz0MHsZJcgC4zln4= github.com/google/gnostic-models v0.6.8 h1:yo/ABAfM5IMRsS1VnXjTBvUb61tFIHozhlYvRgGre9I= github.com/google/gnostic-models v0.6.8/go.mod h1:5n7qKqH0f5wFt+aWF8CW6pZLLNOfYuF5OpfBSENuI8U= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= @@ -179,6 +181,7 @@ github.com/google/go-cmp v0.5.1/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.3/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-cmp v0.5.8/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= @@ -204,10 +207,10 @@ github.com/google/uuid v1.5.0 h1:1p67kYwdtXjb0gL0BPiP1Av9wiZPo5A8z2cWkTZ+eyU= github.com/google/uuid v1.5.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+vpHVxEJEs9eg= github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk= -github.com/gorilla/handlers v1.5.1 h1:9lRY6j8DEeeBT10CvO9hGW0gmky0BprnvDI5vfhUHH4= -github.com/gorilla/handlers v1.5.1/go.mod h1:t8XrUpc4KVXb7HGyJ4/cEnwQiaxrX/hz1Zv/4g96P1Q= -github.com/gorilla/mux v1.8.0 h1:i40aqfkR1h2SlN9hojwV5ZA91wcXFOvkdNIeFDP5koI= -github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= +github.com/gorilla/handlers v1.5.2 h1:cLTUSsNkgcwhgRqvCNmdbRWG0A3N4F+M2nWKdScwyEE= +github.com/gorilla/handlers v1.5.2/go.mod h1:dX+xVpaxdSw+q0Qek8SSsl3dfMk3jNddUkMzo0GtH0w= +github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= +github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ= github.com/grpc-ecosystem/grpc-gateway v1.14.6/go.mod h1:zdiPV4Yse/1gnckTHtghG4GkDEdKCRJduHpTxT3/jcw= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0 h1:YBftPWNWd4WwGqtY2yeZL2ef8rHAxPBD8KFhJpmcqms= github.com/grpc-ecosystem/grpc-gateway/v2 v2.16.0/go.mod h1:YN5jB8ie0yfIUg6VvR9Kz84aCaG7AsGZnLjhHbUqwPg= @@ -225,7 +228,6 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc= github.com/imdario/mergo v0.3.13 h1:lFzP57bqS/wsqKssCGmtLAb8A0wKjLGrve2q3PPVcBk= github.com/imdario/mergo v0.3.13/go.mod h1:4lJ1jqUDcsbIECGy0RUJAXNIhg+6ocWgb1ALK2O4oXg= -github.com/jessevdk/go-flags v1.4.0/go.mod h1:4FA24M0QyGHXBuZZK/XkWh8h0e1EYbRYJSGM75WSRxI= github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY= github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= @@ -299,6 +301,9 @@ github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXP github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= +github.com/prometheus/client_golang v1.12.1/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.12.2/go.mod h1:3Z9XVyYiZYEO+YQWt3RD2R3jrbd179Rt297l4aS6nDY= +github.com/prometheus/client_golang v1.13.0/go.mod h1:vTeo+zgvILHsnnj/39Ou/1fPN5nJFOEMgftOUOmlvYQ= github.com/prometheus/client_golang v1.18.0 h1:HzFfmkOzH5Q8L8G+kSJKUx5dtG87sewO+FoDDqP5Tbk= github.com/prometheus/client_golang v1.18.0/go.mod h1:T+GXkCk5wSJyOqMIzVgvvjFDlkOQntgjkJWKrN5txjA= github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910/go.mod h1:MbSGuTsp3dbXC40dX6PRTWyKYBIrTGTE9sqQNg2J8bo= @@ -310,25 +315,27 @@ github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= -github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.32.1/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+M/gUGO4Hls= +github.com/prometheus/common v0.35.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= +github.com/prometheus/common v0.37.0/go.mod h1:phzohg0JFMnBEFGxTDbfu3QyL5GI8gTQJFhYO5B3mfA= github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.7.3/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= +github.com/prometheus/procfs v0.8.0/go.mod h1:z7EfXMXOkbkqb9IINtpCn86r/to3BnA0uaxHdg830/4= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= -github.com/prometheus/statsd_exporter v0.21.0 h1:hA05Q5RFeIjgwKIYEdFd59xu5Wwaznf33yKI+pyX6T8= -github.com/prometheus/statsd_exporter v0.21.0/go.mod h1:rbT83sZq2V+p73lHhPZfMc3MLCHmSHelCh9hSGYNLTQ= -github.com/rakyll/statik v0.1.7 h1:OF3QCZUuyPxuGEP7B4ypUa7sB/iHtqOTDYZXGM8KOdQ= -github.com/rakyll/statik v0.1.7/go.mod h1:AlZONWzMtEnMs7W4e/1LURLiI49pIMmp6V9Unghqrcc= +github.com/prometheus/statsd_exporter v0.22.7 h1:7Pji/i2GuhK6Lu7DHrtTkFmNBCudCPT1pX2CziuyQR0= +github.com/prometheus/statsd_exporter v0.22.7/go.mod h1:N/TevpjkIh9ccs6nuzY3jQn9dFqnUakOjnEuMPJJJnI= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= github.com/rogpeppe/go-internal v1.10.0/go.mod h1:UQnix2H7Ngw/k4C5ijL5+65zddjncjaFoBhdsK/akog= -github.com/rs/cors v1.8.3 h1:O+qNyWn7Z+F9M0ILBHgMVPuB1xTOucVd5gtaYyXBpRo= -github.com/rs/cors v1.8.3/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= +github.com/rs/cors v1.10.1 h1:L0uuZVXIKlI1SShY2nhFfo44TYvDPQ1w4oFkUJNfhyo= +github.com/rs/cors v1.10.1/go.mod h1:XyqrcTp5zjWr1wsJ8PIRZssZ8b/WMcMf71DJnit4EMU= github.com/sagikazarmark/locafero v0.4.0 h1:HApY1R9zGo4DBgr7dqsTH/JJxLTTsOt7u6keLGt6kNQ= github.com/sagikazarmark/locafero v0.4.0/go.mod h1:Pe1W6UlPYUk/+wc/6KFhbORCfqzgYEpgQ3O5fPuL3H4= github.com/sagikazarmark/slog-shim v0.1.0 h1:diDBnUNK9N/354PgrxMywXnAwEr1QZcOr6gto+ugjYE= @@ -366,10 +373,11 @@ github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO github.com/stretchr/testify v1.8.1/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stvp/go-udp-testing v0.0.0-20201019212854-469649b16807/go.mod h1:7jxmlfBCDBXRzr0eAQJ48XC1hBu1np4CS5+cHEYfwpc= github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8= github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU= -github.com/tektoncd/pipeline v0.53.0 h1:PRgIrOKelWKyj6JZ+/ftGKJZ9lyGeq5+y0UR7runCG0= -github.com/tektoncd/pipeline v0.53.0/go.mod h1:tO7iI+L4+kO+CrAYiM9FlXQYveyjyMDCYmy+7VLiwjk= +github.com/tektoncd/pipeline v0.55.0 h1:RUfqSC/J1dMrdfu1ThJreHojwGXcWc8P131el/c+c1c= +github.com/tektoncd/pipeline v0.55.0/go.mod h1:fFbFAhyNwsPQpitrwhi+Wp0Xse2EkIE1LtGKC08rVqo= github.com/urfave/negroni/v3 v3.0.0 h1:Vo8CeZfu1lFR9gW8GnAb6dOGCJyijfil9j/jKKc/JhU= github.com/urfave/negroni/v3 v3.0.0/go.mod h1:jWvnX03kcSjDBl/ShB0iHvx5uOs7mAzZXW+JvJ5XYAs= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= @@ -387,8 +395,6 @@ go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opencensus.io v0.24.0 h1:y73uSU6J157QMP2kn2r30vwW1A2W2WFwSCGnAVxeaD0= go.opencensus.io v0.24.0/go.mod h1:vNK8G9p7aAivkbmorf4v+7Hgx+Zs0yY+0fOtgBfjQKo= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= -go.uber.org/atomic v1.10.0 h1:9qC72Qh0+3MqyJbAn8YU5xVq1frD8bn3JtD2oXtafVQ= -go.uber.org/atomic v1.10.0/go.mod h1:LUxbIzbOniOlMKjJjyPfpl4v+PKK2cNJn91OQbhoJI0= go.uber.org/goleak v1.2.1 h1:NBol2c7O1ZokfZ0LEU9K6Whx/KnwvepVetCUhtKja4A= go.uber.org/goleak v1.2.1/go.mod h1:qlT2yGI9QafXHhZZLxlSuNsMw3FFLxBr+tBRlmO1xH4= go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= @@ -440,8 +446,8 @@ golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= -golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= -golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/mod v0.14.0 h1:dGoOF9QVLYng8IHTm7BAyWqCqSheQ5pYWGhzW00YJr0= +golang.org/x/mod v0.14.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= @@ -476,6 +482,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210525063256-abc453219eb5/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= +golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c= golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U= @@ -485,6 +493,7 @@ golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4Iltr golang.org/x/oauth2 v0.0.0-20191202225959-858c2ad4c8b6/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A= +golang.org/x/oauth2 v0.0.0-20220223155221-ee480838109b/go.mod h1:DAh4E804XQdzx2j+YRIaUnCqCV2RuMz24cGBJ5QYIrc= golang.org/x/oauth2 v0.15.0 h1:s8pnnxNVzjWyrvYdFUQq5llS1PX2zhPXmccZv99h7uQ= golang.org/x/oauth2 v0.15.0/go.mod h1:q48ptWNTY5XWf+JNten23lcvHpLJ0ZSxF5ttTHKVCAM= golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= @@ -498,6 +507,7 @@ golang.org/x/sync v0.0.0-20200625203802-6e8e738ad208/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220601150217-0de741cfad7f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= @@ -540,7 +550,10 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20211216021012-1d35b9e2eb4e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220114195835-da31bd327af9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220708085239-5a0f0661e09d/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc= @@ -608,8 +621,8 @@ golang.org/x/tools v0.0.0-20200825202427-b303f430e36d/go.mod h1:njjCfa9FT2d7l9Bc golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.1.1/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= -golang.org/x/tools v0.13.0 h1:Iey4qkscZuv0VvIt8E0neZjtPVQFSc870HQ448QgEmQ= -golang.org/x/tools v0.13.0/go.mod h1:HvlwmtVNQAhOuCjW7xxvovg8wbNq7LwfXh/k7wXUl58= +golang.org/x/tools v0.16.1 h1:TLyB3WofjdOEepBHAU20JdNC1Zbg87elYofWYAY5oZA= +golang.org/x/tools v0.16.1/go.mod h1:kYVVN6I1mBNoB1OX+noeBjbRk4IUEPa7JJ+TJMEooJ0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -633,8 +646,8 @@ google.golang.org/api v0.25.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0M google.golang.org/api v0.28.0/go.mod h1:lIXQywCXRcnZPGlsd8NbLnOjtAoL6em04bJ9+z0MncE= google.golang.org/api v0.29.0/go.mod h1:Lcubydp8VUV7KeIHD9z2Bys/sm/vGKnG1UHuDBSrHWM= google.golang.org/api v0.30.0/go.mod h1:QGmEvQ87FHZNiUVJkT14jQNYJ4ZJjdRF23ZXz5138Fc= -google.golang.org/api v0.153.0 h1:N1AwGhielyKFaUqH07/ZSIQR3uNPcV7NVw0vj+j4iR4= -google.golang.org/api v0.153.0/go.mod h1:3qNJX5eOmhiWYc67jRA/3GsDw97UFb5ivv7Y2PrriAY= +google.golang.org/api v0.154.0 h1:X7QkVKZBskztmpPKWQXgjJRPA2dJYrL6r+sYPRLj050= +google.golang.org/api v0.154.0/go.mod h1:qhSMkM85hgqiokIYsrRyKxrjfBeIhgl4Z2JmeRkYylc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= @@ -674,12 +687,12 @@ google.golang.org/genproto v0.0.0-20200618031413-b414f8b61790/go.mod h1:jDfRM7Fc google.golang.org/genproto v0.0.0-20200729003335-053ba62fc06f/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17 h1:wpZ8pe2x1Q3f2KyT5f8oP/fa9rHAKgFPr/HZdNuS+PQ= -google.golang.org/genproto v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:J7XzRzVy1+IPwWHZUzoD0IccYZIrXILAQpc+Qy9CMhY= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17 h1:JpwMPBpFN3uKhdaekDpiNlImDdkUAyiJ6ez/uxGaUSo= -google.golang.org/genproto/googleapis/api v0.0.0-20231106174013-bbf56f31fb17/go.mod h1:0xJLfVdJqpAPl8tDg1ujOCGzx6LFLttXT5NhllGOXY4= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f h1:ultW7fxlIvee4HYrtnaRPon9HpEgFk5zYpmfMgtKB5I= -google.golang.org/genproto/googleapis/rpc v0.0.0-20231120223509-83a465c0220f/go.mod h1:L9KNLi232K1/xB6f7AlSX692koaRnKaWSR0stBki0Yc= +google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f h1:Vn+VyHU5guc9KjB5KrjI2q0wCOWEOIh0OEsleqakHJg= +google.golang.org/genproto v0.0.0-20231120223509-83a465c0220f/go.mod h1:nWSwAFPb+qfNJXsoeO3Io7zf4tMSfN8EA8RlDA04GhY= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f h1:2yNACc1O40tTnrsbk9Cv6oxiW8pxI/pXj0wRtdlYmgY= +google.golang.org/genproto/googleapis/api v0.0.0-20231120223509-83a465c0220f/go.mod h1:Uy9bTZJqmfrw2rIBxgGLnamc78euZULUBrLZ9XTITKI= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4 h1:DC7wcm+i+P1rN3Ff07vL+OndGg5OhNddHyTA+ocPqYE= +google.golang.org/genproto/googleapis/rpc v0.0.0-20231127180814-3a041ad873d4/go.mod h1:eJVxU6o+4G1PSczBr85xmyvSNYAKvAYgkub40YGomFM= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.21.1/go.mod h1:oYelfM1adQP15Ek0mdvEgi9Df8B9CZIaU1084ijfRaM= @@ -693,8 +706,8 @@ google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3Iji google.golang.org/grpc v1.30.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.31.0/go.mod h1:N36X2cJ7JwdamYAgDz+s+rVMFjt3numwzf/HckM8pak= google.golang.org/grpc v1.33.2/go.mod h1:JMHMWHQWaTccqQQlmk3MJZS+GWXOdAesneDmEnv2fbc= -google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk= -google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98= +google.golang.org/grpc v1.60.1 h1:26+wFr+cNqSGFcOXcabYC0lUVJVRa2Sb2ortSK7VrEU= +google.golang.org/grpc v1.60.1/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= google.golang.org/protobuf v0.0.0-20200228230310-ab0ca4ff8a60/go.mod h1:cfTl7dwQJ+fmap5saPgwCLgHXTUD7jkjRqWcaiX5VyM= @@ -707,6 +720,8 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c= google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw= google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= +google.golang.org/protobuf v1.28.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= +google.golang.org/protobuf v1.28.1/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8= google.golang.org/protobuf v1.31.0/go.mod h1:HV8QOd/L58Z+nl8r43ehVNZIU/HEI6OcFqwMG9pJV4I= gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw= @@ -754,8 +769,8 @@ k8s.io/kube-openapi v0.0.0-20231129212854-f0671cc7e66a h1:ZeIPbyHHqahGIbeyLJJjAU k8s.io/kube-openapi v0.0.0-20231129212854-f0671cc7e66a/go.mod h1:AsvuZPBlUDVuCdzJ87iajxtXuR9oktsTctW/R9wwouA= k8s.io/utils v0.0.0-20231127182322-b307cd553661 h1:FepOBzJ0GXm8t0su67ln2wAZjbQ6RxQGZDnzuLcrUTI= k8s.io/utils v0.0.0-20231127182322-b307cd553661/go.mod h1:OLgZIPagt7ERELqWJFomSt595RzquPNLL48iOWgYOg0= -knative.dev/pkg v0.0.0-20231011193800-bd99f2f98be7 h1:y3qbfYX1SuSr/1ysXvKfpV8q/kCwWLWieCUgAhBUHmQ= -knative.dev/pkg v0.0.0-20231011193800-bd99f2f98be7/go.mod h1:g+UCgSKQ2f15kHYu/V3CPtoKo5F1x/2Y1ot0NSK7gA0= +knative.dev/pkg v0.0.0-20231219072704-d513e487961e h1:br9VUyN8M4ZUaWsmKifLg5lIAy6JmNw2MdeHd6wgp9g= +knative.dev/pkg v0.0.0-20231219072704-d513e487961e/go.mod h1:YWJGsIxySXQehfkslagVEpJJwHgSScUc21+KpEgBXcY= rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= diff --git a/models/controller.go b/models/controller.go index 5ffbf460..1d061343 100644 --- a/models/controller.go +++ b/models/controller.go @@ -1,7 +1,11 @@ package models import ( + "io" "net/http" + + radixhttp "github.com/equinor/radix-common/net/http" + log "github.com/sirupsen/logrus" ) // RadixHandlerFunc Pattern for handler functions @@ -15,3 +19,45 @@ type Controller interface { // DefaultController Default implementation type DefaultController struct { } + +// ErrorResponse Marshals error for user requester +func (c *DefaultController) ErrorResponse(w http.ResponseWriter, r *http.Request, err error) { + err = radixhttp.ErrorResponse(w, r, err) + if err != nil { + log.Errorf("%s %s: failed to write response: %v", r.Method, r.URL.Path, err) + } +} + +// JSONResponse Marshals response with header +func (c *DefaultController) JSONResponse(w http.ResponseWriter, r *http.Request, result interface{}) { + err := radixhttp.JSONResponse(w, r, result) + if err != nil { + log.Errorf("%s %s: failed to write response: %v",r.Method, r.URL.Path, err) + } +} + + +// ReaderFileResponse writes the content from the reader to the response, +// and sets Content-Disposition=attachment; filename= +func (c *DefaultController) ReaderFileResponse(w http.ResponseWriter, r *http.Request, reader io.Reader, fileName, contentType string) { + err := radixhttp.ReaderFileResponse(w, reader, fileName, contentType) + if err != nil { + log.Errorf("%s %s: failed to write response: %v", r.Method, r.URL.Path, err) + } +} +// ReaderResponse writes the content from the reader to the response, +func (c *DefaultController) ReaderResponse(w http.ResponseWriter, r *http.Request, reader io.Reader, contentType string) { + err := radixhttp.ReaderResponse(w, reader, contentType) + if err != nil { + log.Errorf("%s %s: failed to write reader to response: %v", r.Method, r.URL.Path, err) + } + +} + +// ByteArrayResponse Used for response data. I.e. image +func (c *DefaultController) ByteArrayResponse(w http.ResponseWriter, r *http.Request, contentType string, result []byte) { + err := radixhttp.ByteArrayResponse(w, r, contentType, result) + if err != nil { + log.Errorf("%s %s: failed to write ByteArray response: %v", r.Method, r.URL.Path, err) + } +} diff --git a/swaggerui/html/swagger.json b/swaggerui/html/swagger.json index 699bf830..cf56e1ab 100644 --- a/swaggerui/html/swagger.json +++ b/swaggerui/html/swagger.json @@ -7330,8 +7330,8 @@ "ended": { "description": "Ended timestamp", "type": "string", - "x-go-name": "Ended", - "example": "2006-01-02T15:04:05Z" + "format": "date-time", + "x-go-name": "Ended" }, "name": { "description": "Name of the step", @@ -7342,8 +7342,8 @@ "started": { "description": "Started timestamp", "type": "string", - "x-go-name": "Started", - "example": "2006-01-02T15:04:05Z" + "format": "date-time", + "x-go-name": "Started" }, "status": { "description": "Status of the step",