diff --git a/Dockerfile b/Dockerfile index 37df5c28c6..fc5dbe1dce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -17,7 +17,8 @@ RUN apt clean autoclean RUN apt autoremove -y && rm -rf /var/lib/apt/lists/* COPY --from=build-env /go/src/github.com/devtron-labs/devtron/devtron . COPY --from=build-env /go/src/github.com/devtron-labs/devtron/auth_model.conf . -COPY --from=build-env /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets/ /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets +#COPY --from=build-env /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets/ /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets +COPY --from=build-env /go/src/github.com/devtron-labs/devtron/argocd-assets/ /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets COPY --from=build-env /go/src/github.com/devtron-labs/devtron/scripts/devtron-reference-helm-charts scripts/devtron-reference-helm-charts COPY --from=build-env /go/src/github.com/devtron-labs/devtron/scripts/sql scripts/sql COPY --from=build-env /go/src/github.com/devtron-labs/devtron/scripts/casbin scripts/casbin diff --git a/DockerfileEA b/DockerfileEA index b142d25dad..72b8e31849 100644 --- a/DockerfileEA +++ b/DockerfileEA @@ -17,7 +17,8 @@ RUN apt autoremove -y && rm -rf /var/lib/apt/lists/* COPY --from=build-env /go/src/github.com/devtron-labs/devtron/auth_model.conf . COPY --from=build-env /go/src/github.com/devtron-labs/devtron/cmd/external-app/devtron-ea . -COPY --from=build-env /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets/ /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets +#COPY --from=build-env /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets/ /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets +COPY --from=build-env /go/src/github.com/devtron-labs/devtron/argocd-assets/ /go/src/github.com/devtron-labs/devtron/vendor/github.com/argoproj/argo-cd/assets COPY --from=build-env /go/src/github.com/devtron-labs/devtron/scripts/devtron-reference-helm-charts scripts/devtron-reference-helm-charts COPY --from=build-env /go/src/github.com/devtron-labs/devtron/scripts/sql scripts/sql COPY --from=build-env /go/src/github.com/devtron-labs/devtron/scripts/casbin scripts/casbin diff --git a/api/argoApplication/ArgoApplicationRestHandler.go b/api/argoApplication/ArgoApplicationRestHandler.go index 5478f62e47..a48812d329 100644 --- a/api/argoApplication/ArgoApplicationRestHandler.go +++ b/api/argoApplication/ArgoApplicationRestHandler.go @@ -20,6 +20,7 @@ import ( "errors" "github.com/devtron-labs/devtron/api/restHandler/common" "github.com/devtron-labs/devtron/pkg/argoApplication" + "github.com/devtron-labs/devtron/pkg/argoApplication/read" "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin" "go.uber.org/zap" "net/http" @@ -34,14 +35,16 @@ type ArgoApplicationRestHandler interface { type ArgoApplicationRestHandlerImpl struct { argoApplicationService argoApplication.ArgoApplicationService + readService read.ArgoApplicationReadService logger *zap.SugaredLogger enforcer casbin.Enforcer } func NewArgoApplicationRestHandlerImpl(argoApplicationService argoApplication.ArgoApplicationService, - logger *zap.SugaredLogger, enforcer casbin.Enforcer) *ArgoApplicationRestHandlerImpl { + readService read.ArgoApplicationReadService, logger *zap.SugaredLogger, enforcer casbin.Enforcer) *ArgoApplicationRestHandlerImpl { return &ArgoApplicationRestHandlerImpl{ argoApplicationService: argoApplicationService, + readService: readService, logger: logger, enforcer: enforcer, } @@ -101,9 +104,9 @@ func (handler *ArgoApplicationRestHandlerImpl) GetApplicationDetail(w http.Respo return } } - resp, err := handler.argoApplicationService.GetAppDetail(resourceName, namespace, clusterId) + resp, err := handler.readService.GetAppDetail(resourceName, namespace, clusterId) if err != nil { - handler.logger.Errorw("error in listing all argo applications", "err", err, "resourceName", resourceName, "clusterId", clusterId) + handler.logger.Errorw("error in getting argo application app detail", "err", err, "resourceName", resourceName, "clusterId", clusterId) common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) return } diff --git a/api/argoApplication/wire_argoApplication.go b/api/argoApplication/wire_argoApplication.go index a65ac47028..d70cfd3082 100644 --- a/api/argoApplication/wire_argoApplication.go +++ b/api/argoApplication/wire_argoApplication.go @@ -18,10 +18,14 @@ package argoApplication import ( "github.com/devtron-labs/devtron/pkg/argoApplication" + "github.com/devtron-labs/devtron/pkg/argoApplication/read" "github.com/google/wire" ) var ArgoApplicationWireSet = wire.NewSet( + read.NewArgoApplicationReadServiceImpl, + wire.Bind(new(read.ArgoApplicationReadService), new(*read.ArgoApplicationReadServiceImpl)), + argoApplication.NewArgoApplicationServiceImpl, wire.Bind(new(argoApplication.ArgoApplicationService), new(*argoApplication.ArgoApplicationServiceImpl)), diff --git a/api/helm-app/HelmAppRestHandler.go b/api/helm-app/HelmAppRestHandler.go index 059ce2ad9d..3762a10990 100644 --- a/api/helm-app/HelmAppRestHandler.go +++ b/api/helm-app/HelmAppRestHandler.go @@ -25,9 +25,11 @@ import ( "github.com/devtron-labs/devtron/pkg/appStore/installedApp/service" "github.com/devtron-labs/devtron/pkg/appStore/installedApp/service/EAMode" "github.com/devtron-labs/devtron/pkg/argoApplication" + "github.com/devtron-labs/devtron/pkg/argoApplication/helper" clientErrors "github.com/devtron-labs/devtron/pkg/errors" "github.com/devtron-labs/devtron/pkg/fluxApplication" bean2 "github.com/devtron-labs/devtron/pkg/k8s/application/bean" + "github.com/devtron-labs/devtron/pkg/pipeline" "net/http" "strconv" "strings" @@ -144,6 +146,11 @@ func (handler *HelmAppRestHandlerImpl) GetApplicationDetail(w http.ResponseWrite //RBAC enforcer Ends appdetail, err := handler.helmAppService.GetApplicationDetail(context.Background(), appIdentifier) if err != nil { + + if pipeline.CheckAppReleaseNotExist(err) { + common.WriteJsonResp(w, err, nil, http.StatusNotFound) + return + } apiError := clientErrors.ConvertToApiError(err) if apiError != nil { err = apiError @@ -226,7 +233,7 @@ func (handler *HelmAppRestHandlerImpl) handleFluxApplicationHibernate(r *http.Re return handler.fluxApplication.HibernateFluxApplication(r.Context(), appIdentifier, hibernateRequest) } func (handler *HelmAppRestHandlerImpl) handleArgoApplicationHibernate(r *http.Request, token string, hibernateRequest *openapi.HibernateRequest) ([]*openapi.HibernateStatus, error) { - appIdentifier, err := argoApplication.DecodeExternalArgoAppId(*hibernateRequest.AppId) + appIdentifier, err := helper.DecodeExternalArgoAppId(*hibernateRequest.AppId) if err != nil { return nil, err } @@ -310,7 +317,7 @@ func (handler *HelmAppRestHandlerImpl) handleFluxApplicationUnHibernate(r *http. return handler.fluxApplication.UnHibernateFluxApplication(r.Context(), appIdentifier, hibernateRequest) } func (handler *HelmAppRestHandlerImpl) handleArgoApplicationUnHibernate(r *http.Request, token string, hibernateRequest *openapi.HibernateRequest) ([]*openapi.HibernateStatus, error) { - appIdentifier, err := argoApplication.DecodeExternalArgoAppId(*hibernateRequest.AppId) + appIdentifier, err := helper.DecodeExternalArgoAppId(*hibernateRequest.AppId) if err != nil { return nil, err } diff --git a/api/k8s/application/k8sApplicationRestHandler.go b/api/k8s/application/k8sApplicationRestHandler.go index d153d84c98..8f5e7ee968 100644 --- a/api/k8s/application/k8sApplicationRestHandler.go +++ b/api/k8s/application/k8sApplicationRestHandler.go @@ -33,7 +33,8 @@ import ( client "github.com/devtron-labs/devtron/api/helm-app/service" "github.com/devtron-labs/devtron/api/restHandler/common" util2 "github.com/devtron-labs/devtron/internal/util" - "github.com/devtron-labs/devtron/pkg/argoApplication" + "github.com/devtron-labs/devtron/pkg/argoApplication/helper" + "github.com/devtron-labs/devtron/pkg/argoApplication/read" "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin" "github.com/devtron-labs/devtron/pkg/auth/user" "github.com/devtron-labs/devtron/pkg/cluster" @@ -81,39 +82,39 @@ type K8sApplicationRestHandler interface { } type K8sApplicationRestHandlerImpl struct { - logger *zap.SugaredLogger - k8sApplicationService application2.K8sApplicationService - pump connector.Pump - terminalSessionHandler terminal.TerminalSessionHandler - enforcer casbin.Enforcer - validator *validator.Validate - enforcerUtil rbac.EnforcerUtil - enforcerUtilHelm rbac.EnforcerUtilHelm - helmAppService client.HelmAppService - userService user.UserService - k8sCommonService k8s.K8sCommonService - terminalEnvVariables *util.TerminalEnvVariables - fluxAppService fluxApplication.FluxApplicationService - argoApplication argoApplication.ArgoApplicationService + logger *zap.SugaredLogger + k8sApplicationService application2.K8sApplicationService + pump connector.Pump + terminalSessionHandler terminal.TerminalSessionHandler + enforcer casbin.Enforcer + validator *validator.Validate + enforcerUtil rbac.EnforcerUtil + enforcerUtilHelm rbac.EnforcerUtilHelm + helmAppService client.HelmAppService + userService user.UserService + k8sCommonService k8s.K8sCommonService + terminalEnvVariables *util.TerminalEnvVariables + fluxAppService fluxApplication.FluxApplicationService + argoApplicationReadService read.ArgoApplicationReadService } -func NewK8sApplicationRestHandlerImpl(logger *zap.SugaredLogger, k8sApplicationService application2.K8sApplicationService, pump connector.Pump, terminalSessionHandler terminal.TerminalSessionHandler, enforcer casbin.Enforcer, enforcerUtilHelm rbac.EnforcerUtilHelm, enforcerUtil rbac.EnforcerUtil, helmAppService client.HelmAppService, userService user.UserService, k8sCommonService k8s.K8sCommonService, validator *validator.Validate, envVariables *util.EnvironmentVariables, fluxAppService fluxApplication.FluxApplicationService, argoApplication argoApplication.ArgoApplicationService, +func NewK8sApplicationRestHandlerImpl(logger *zap.SugaredLogger, k8sApplicationService application2.K8sApplicationService, pump connector.Pump, terminalSessionHandler terminal.TerminalSessionHandler, enforcer casbin.Enforcer, enforcerUtilHelm rbac.EnforcerUtilHelm, enforcerUtil rbac.EnforcerUtil, helmAppService client.HelmAppService, userService user.UserService, k8sCommonService k8s.K8sCommonService, validator *validator.Validate, envVariables *util.EnvironmentVariables, fluxAppService fluxApplication.FluxApplicationService, argoApplicationReadService read.ArgoApplicationReadService, ) *K8sApplicationRestHandlerImpl { return &K8sApplicationRestHandlerImpl{ - logger: logger, - k8sApplicationService: k8sApplicationService, - pump: pump, - terminalSessionHandler: terminalSessionHandler, - enforcer: enforcer, - validator: validator, - enforcerUtilHelm: enforcerUtilHelm, - enforcerUtil: enforcerUtil, - helmAppService: helmAppService, - userService: userService, - k8sCommonService: k8sCommonService, - terminalEnvVariables: envVariables.TerminalEnvVariables, - fluxAppService: fluxAppService, - argoApplication: argoApplication, + logger: logger, + k8sApplicationService: k8sApplicationService, + pump: pump, + terminalSessionHandler: terminalSessionHandler, + enforcer: enforcer, + validator: validator, + enforcerUtilHelm: enforcerUtilHelm, + enforcerUtil: enforcerUtil, + helmAppService: helmAppService, + userService: userService, + k8sCommonService: k8sCommonService, + terminalEnvVariables: envVariables.TerminalEnvVariables, + fluxAppService: fluxAppService, + argoApplicationReadService: argoApplicationReadService, } } @@ -289,7 +290,7 @@ func (handler *K8sApplicationRestHandlerImpl) GetHostUrlsByBatch(w http.Response resourceTreeResponse = appDetail.ResourceTreeResponse } else if appType == bean2.ArgoAppType { - appIdentifier, err := argoApplication.DecodeExternalArgoAppId(appIdString) + appIdentifier, err := helper.DecodeExternalArgoAppId(appIdString) if err != nil { common.WriteJsonResp(w, err, nil, http.StatusBadRequest) return @@ -301,7 +302,7 @@ func (handler *K8sApplicationRestHandlerImpl) GetHostUrlsByBatch(w http.Response } //RBAC enforcer Ends - appDetail, err := handler.argoApplication.GetAppDetail(appIdentifier.AppName, appIdentifier.Namespace, appIdentifier.ClusterId) + appDetail, err := handler.argoApplicationReadService.GetAppDetail(appIdentifier.AppName, appIdentifier.Namespace, appIdentifier.ClusterId) if err != nil { apiError := clientErrors.ConvertToApiError(err) if apiError != nil { @@ -721,12 +722,12 @@ func (handler *K8sApplicationRestHandlerImpl) requestValidationAndRBAC(w http.Re } //RBAC enforcer ends here } else if request.AppType == bean2.ArgoAppType && request.ExternalArgoApplicationName != "" { - appIdentifier, err := argoApplication.DecodeExternalArgoAppId(request.AppId) + appIdentifier, err := helper.DecodeExternalArgoAppId(request.AppId) if err != nil { handler.logger.Errorw(bean2.AppIdDecodingError, "err", err, "appIdentifier", request.AppIdentifier) common.WriteJsonResp(w, err, nil, http.StatusBadRequest) } - valid, err := handler.k8sApplicationService.ValidateArgoResourceRequest(r.Context(), appIdentifier, request.K8sRequest) + valid, err := handler.argoApplicationReadService.ValidateArgoResourceRequest(r.Context(), appIdentifier, request.K8sRequest) if err != nil || !valid { handler.logger.Errorw("error in validating resource request", "err", err) common.WriteJsonResp(w, err, nil, http.StatusBadRequest) @@ -1145,14 +1146,14 @@ func (handler *K8sApplicationRestHandlerImpl) verifyRbacForAppRequests(token str envObject := "" switch request.AppType { case bean2.ArgoAppType: - argoAppIdentifier, err := argoApplication.DecodeExternalArgoAppId(request.AppId) + argoAppIdentifier, err := helper.DecodeExternalArgoAppId(request.AppId) if err != nil { handler.logger.Errorw("error in decoding appId", "err", err, "appId", request.AppId) return false, err } request.ClusterId = argoAppIdentifier.ClusterId request.ExternalArgoApplicationName = argoAppIdentifier.AppName - valid, err := handler.k8sApplicationService.ValidateArgoResourceRequest(r.Context(), argoAppIdentifier, request.K8sRequest) + valid, err := handler.argoApplicationReadService.ValidateArgoResourceRequest(r.Context(), argoAppIdentifier, request.K8sRequest) if err != nil || !valid { handler.logger.Errorw("error in validating resource request", "err", err) return false, err diff --git a/api/restHandler/GlobalPluginRestHandler.go b/api/restHandler/GlobalPluginRestHandler.go index 7fc25ec6b1..44a2305c0a 100644 --- a/api/restHandler/GlobalPluginRestHandler.go +++ b/api/restHandler/GlobalPluginRestHandler.go @@ -35,6 +35,7 @@ import ( type GlobalPluginRestHandler interface { PatchPlugin(w http.ResponseWriter, r *http.Request) + CreatePlugin(w http.ResponseWriter, r *http.Request) GetAllGlobalVariables(w http.ResponseWriter, r *http.Request) ListAllPlugins(w http.ResponseWriter, r *http.Request) @@ -46,6 +47,7 @@ type GlobalPluginRestHandler interface { GetPluginDetailByIds(w http.ResponseWriter, r *http.Request) GetAllUniqueTags(w http.ResponseWriter, r *http.Request) MigratePluginData(w http.ResponseWriter, r *http.Request) + GetAllPluginMinData(w http.ResponseWriter, r *http.Request) } func NewGlobalPluginRestHandler(logger *zap.SugaredLogger, globalPluginService plugin.GlobalPluginService, @@ -420,3 +422,68 @@ func (handler *GlobalPluginRestHandlerImpl) MigratePluginData(w http.ResponseWri } common.WriteJsonResp(w, nil, nil, http.StatusOK) } + +func (handler *GlobalPluginRestHandlerImpl) CreatePlugin(w http.ResponseWriter, r *http.Request) { + userId, err := handler.userService.GetLoggedInUser(r) + if userId == 0 || err != nil { + common.WriteJsonResp(w, err, "Unauthorized User", http.StatusUnauthorized) + return + } + token := r.Header.Get("token") + appId, err := common.ExtractIntQueryParam(w, r, "appId", 0) + if err != nil { + return + } + ok, err := handler.IsUserAuthorized(token, appId) + if err != nil { + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + if !ok { + common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) + return + } + decoder := json.NewDecoder(r.Body) + var pluginDataDto bean.PluginParentMetadataDto + err = decoder.Decode(&pluginDataDto) + if err != nil { + handler.logger.Errorw("request err, CreatePlugin", "error", err, "payload", pluginDataDto) + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + handler.logger.Infow("request payload received for creating plugins", pluginDataDto, "userId", userId) + + pluginVersionId, err := handler.globalPluginService.CreatePluginOrVersions(&pluginDataDto, userId) + if err != nil { + handler.logger.Errorw("service error, error in creating plugin", "pluginCreateRequestDto", pluginDataDto, "err", err) + common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) + return + } + + common.WriteJsonResp(w, nil, bean.NewPluginMinDto().WithPluginVersionId(pluginVersionId), http.StatusOK) +} + +func (handler *GlobalPluginRestHandlerImpl) GetAllPluginMinData(w http.ResponseWriter, r *http.Request) { + token := r.Header.Get("token") + appId, err := common.ExtractIntQueryParam(w, r, "appId", 0) + if err != nil { + return + } + ok, err := handler.IsUserAuthorized(token, appId) + if err != nil { + common.WriteJsonResp(w, err, nil, http.StatusBadRequest) + return + } + if !ok { + common.WriteJsonResp(w, fmt.Errorf("unauthorized user"), "Unauthorized User", http.StatusForbidden) + return + } + + pluginDetail, err := handler.globalPluginService.GetAllPluginMinData() + if err != nil { + handler.logger.Errorw("error in getting all unique tags", "err", err) + common.WriteJsonResp(w, err, nil, http.StatusInternalServerError) + return + } + common.WriteJsonResp(w, nil, pluginDetail, http.StatusOK) +} diff --git a/api/router/GlobalPluginRouter.go b/api/router/GlobalPluginRouter.go index 06950c3342..0d8154bf82 100644 --- a/api/router/GlobalPluginRouter.go +++ b/api/router/GlobalPluginRouter.go @@ -41,7 +41,8 @@ type GlobalPluginRouterImpl struct { func (impl *GlobalPluginRouterImpl) initGlobalPluginRouter(globalPluginRouter *mux.Router) { globalPluginRouter.Path("/migrate"). HandlerFunc(impl.globalPluginRestHandler.MigratePluginData).Methods("PUT") - + globalPluginRouter.Path("/create"). + HandlerFunc(impl.globalPluginRestHandler.CreatePlugin).Methods("POST") // versioning impact handling to be done for below apis, globalPluginRouter.Path(""). HandlerFunc(impl.globalPluginRestHandler.PatchPlugin).Methods("POST") @@ -68,5 +69,7 @@ func (impl *GlobalPluginRouterImpl) initGlobalPluginRouter(globalPluginRouter *m globalPluginRouter.Path("/list/tags"). HandlerFunc(impl.globalPluginRestHandler.GetAllUniqueTags).Methods("GET") + globalPluginRouter.Path("/list/v2/min"). + HandlerFunc(impl.globalPluginRestHandler.GetAllPluginMinData).Methods("GET") } diff --git a/vendor/github.com/argoproj/argo-cd/assets/badge.svg b/argocd-assets/badge.svg similarity index 100% rename from vendor/github.com/argoproj/argo-cd/assets/badge.svg rename to argocd-assets/badge.svg diff --git a/vendor/github.com/argoproj/argo-cd/assets/builtin-policy.csv b/argocd-assets/builtin-policy.csv similarity index 100% rename from vendor/github.com/argoproj/argo-cd/assets/builtin-policy.csv rename to argocd-assets/builtin-policy.csv diff --git a/vendor/github.com/argoproj/argo-cd/assets/model.conf b/argocd-assets/model.conf similarity index 100% rename from vendor/github.com/argoproj/argo-cd/assets/model.conf rename to argocd-assets/model.conf diff --git a/vendor/github.com/argoproj/argo-cd/assets/swagger.json b/argocd-assets/swagger.json similarity index 100% rename from vendor/github.com/argoproj/argo-cd/assets/swagger.json rename to argocd-assets/swagger.json diff --git a/cmd/external-app/wire_gen.go b/cmd/external-app/wire_gen.go index 5271cca4cd..ab3bca55cd 100644 --- a/cmd/external-app/wire_gen.go +++ b/cmd/external-app/wire_gen.go @@ -67,6 +67,7 @@ import ( "github.com/devtron-labs/devtron/pkg/appStore/values/repository" service4 "github.com/devtron-labs/devtron/pkg/appStore/values/service" "github.com/devtron-labs/devtron/pkg/argoApplication" + "github.com/devtron-labs/devtron/pkg/argoApplication/read" "github.com/devtron-labs/devtron/pkg/argoRepositoryCreds" "github.com/devtron-labs/devtron/pkg/attributes" "github.com/devtron-labs/devtron/pkg/auth/authentication" @@ -297,24 +298,25 @@ func InitializeApp() (*App, error) { deletePostProcessorImpl := service2.NewDeletePostProcessorImpl(sugaredLogger) appStoreDeploymentServiceImpl := service2.NewAppStoreDeploymentServiceImpl(sugaredLogger, installedAppRepositoryImpl, installedAppDBServiceImpl, appStoreDeploymentDBServiceImpl, chartGroupDeploymentRepositoryImpl, appStoreApplicationVersionRepositoryImpl, appRepositoryImpl, eaModeDeploymentServiceImpl, eaModeDeploymentServiceImpl, environmentServiceImpl, helmAppServiceImpl, installedAppVersionHistoryRepositoryImpl, environmentVariables, acdConfig, gitOpsConfigReadServiceImpl, deletePostProcessorImpl, appStoreValidatorImpl, deploymentConfigServiceImpl) fluxApplicationServiceImpl := fluxApplication.NewFluxApplicationServiceImpl(sugaredLogger, helmAppServiceImpl, clusterServiceImpl, helmAppClientImpl, pumpImpl) - argoApplicationServiceImpl := argoApplication.NewArgoApplicationServiceImpl(sugaredLogger, clusterRepositoryImpl, k8sServiceImpl, helmUserServiceImpl, helmAppClientImpl, helmAppServiceImpl) - helmAppRestHandlerImpl := client2.NewHelmAppRestHandlerImpl(sugaredLogger, helmAppServiceImpl, enforcerImpl, clusterServiceImpl, enforcerUtilHelmImpl, appStoreDeploymentServiceImpl, installedAppDBServiceImpl, userServiceImpl, attributesServiceImpl, serverEnvConfigServerEnvConfig, fluxApplicationServiceImpl, argoApplicationServiceImpl) - helmAppRouterImpl := client2.NewHelmAppRouterImpl(helmAppRestHandlerImpl) - k8sCommonServiceImpl := k8s2.NewK8sCommonServiceImpl(sugaredLogger, k8sServiceImpl, clusterServiceImpl, argoApplicationServiceImpl) - environmentRestHandlerImpl := cluster2.NewEnvironmentRestHandlerImpl(environmentServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceImpl, k8sServiceImpl, k8sCommonServiceImpl) - environmentRouterImpl := cluster2.NewEnvironmentRouterImpl(environmentRestHandlerImpl) k8sResourceHistoryRepositoryImpl := repository8.NewK8sResourceHistoryRepositoryImpl(db, sugaredLogger) k8sResourceHistoryServiceImpl := kubernetesResourceAuditLogs.Newk8sResourceHistoryServiceImpl(k8sResourceHistoryRepositoryImpl, sugaredLogger, appRepositoryImpl, environmentRepositoryImpl) + argoApplicationReadServiceImpl := read.NewArgoApplicationReadServiceImpl(sugaredLogger, clusterRepositoryImpl, k8sServiceImpl, helmUserServiceImpl, helmAppClientImpl, helmAppServiceImpl) + k8sCommonServiceImpl := k8s2.NewK8sCommonServiceImpl(sugaredLogger, k8sServiceImpl, clusterServiceImpl, argoApplicationReadServiceImpl) ephemeralContainersRepositoryImpl := repository2.NewEphemeralContainersRepositoryImpl(db, transactionUtilImpl) ephemeralContainerServiceImpl := cluster.NewEphemeralContainerServiceImpl(ephemeralContainersRepositoryImpl, sugaredLogger) - terminalSessionHandlerImpl := terminal.NewTerminalSessionHandlerImpl(environmentServiceImpl, clusterServiceImpl, sugaredLogger, k8sServiceImpl, ephemeralContainerServiceImpl, argoApplicationServiceImpl) - k8sApplicationServiceImpl, err := application.NewK8sApplicationServiceImpl(sugaredLogger, clusterServiceImpl, pumpImpl, helmAppServiceImpl, k8sServiceImpl, acdAuthConfig, k8sResourceHistoryServiceImpl, k8sCommonServiceImpl, terminalSessionHandlerImpl, ephemeralContainerServiceImpl, ephemeralContainersRepositoryImpl, argoApplicationServiceImpl, fluxApplicationServiceImpl) + terminalSessionHandlerImpl := terminal.NewTerminalSessionHandlerImpl(environmentServiceImpl, clusterServiceImpl, sugaredLogger, k8sServiceImpl, ephemeralContainerServiceImpl, argoApplicationReadServiceImpl) + k8sApplicationServiceImpl, err := application.NewK8sApplicationServiceImpl(sugaredLogger, clusterServiceImpl, pumpImpl, helmAppServiceImpl, k8sServiceImpl, acdAuthConfig, k8sResourceHistoryServiceImpl, k8sCommonServiceImpl, terminalSessionHandlerImpl, ephemeralContainerServiceImpl, ephemeralContainersRepositoryImpl, fluxApplicationServiceImpl) if err != nil { return nil, err } + argoApplicationServiceImpl := argoApplication.NewArgoApplicationServiceImpl(sugaredLogger, clusterRepositoryImpl, k8sServiceImpl, helmUserServiceImpl, helmAppClientImpl, helmAppServiceImpl, k8sApplicationServiceImpl, argoApplicationReadServiceImpl) + helmAppRestHandlerImpl := client2.NewHelmAppRestHandlerImpl(sugaredLogger, helmAppServiceImpl, enforcerImpl, clusterServiceImpl, enforcerUtilHelmImpl, appStoreDeploymentServiceImpl, installedAppDBServiceImpl, userServiceImpl, attributesServiceImpl, serverEnvConfigServerEnvConfig, fluxApplicationServiceImpl, argoApplicationServiceImpl) + helmAppRouterImpl := client2.NewHelmAppRouterImpl(helmAppRestHandlerImpl) + environmentRestHandlerImpl := cluster2.NewEnvironmentRestHandlerImpl(environmentServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceImpl, k8sServiceImpl, k8sCommonServiceImpl) + environmentRouterImpl := cluster2.NewEnvironmentRouterImpl(environmentRestHandlerImpl) ciPipelineRepositoryImpl := pipelineConfig.NewCiPipelineRepositoryImpl(db, sugaredLogger, transactionUtilImpl) enforcerUtilImpl := rbac.NewEnforcerUtilImpl(sugaredLogger, teamRepositoryImpl, appRepositoryImpl, environmentRepositoryImpl, pipelineRepositoryImpl, ciPipelineRepositoryImpl, clusterRepositoryImpl, enforcerImpl) - k8sApplicationRestHandlerImpl := application2.NewK8sApplicationRestHandlerImpl(sugaredLogger, k8sApplicationServiceImpl, pumpImpl, terminalSessionHandlerImpl, enforcerImpl, enforcerUtilHelmImpl, enforcerUtilImpl, helmAppServiceImpl, userServiceImpl, k8sCommonServiceImpl, validate, environmentVariables, fluxApplicationServiceImpl, argoApplicationServiceImpl) + k8sApplicationRestHandlerImpl := application2.NewK8sApplicationRestHandlerImpl(sugaredLogger, k8sApplicationServiceImpl, pumpImpl, terminalSessionHandlerImpl, enforcerImpl, enforcerUtilHelmImpl, enforcerUtilImpl, helmAppServiceImpl, userServiceImpl, k8sCommonServiceImpl, validate, environmentVariables, fluxApplicationServiceImpl, argoApplicationReadServiceImpl) k8sApplicationRouterImpl := application2.NewK8sApplicationRouterImpl(k8sApplicationRestHandlerImpl) chartRepositoryRestHandlerImpl := chartRepo2.NewChartRepositoryRestHandlerImpl(sugaredLogger, userServiceImpl, chartRepositoryServiceImpl, enforcerImpl, validate, deleteServiceImpl, attributesServiceImpl) chartRepositoryRouterImpl := chartRepo2.NewChartRepositoryRouterImpl(chartRepositoryRestHandlerImpl) @@ -428,7 +430,7 @@ func InitializeApp() (*App, error) { rbacRoleServiceImpl := user.NewRbacRoleServiceImpl(sugaredLogger, rbacRoleDataRepositoryImpl) rbacRoleRestHandlerImpl := user2.NewRbacRoleHandlerImpl(sugaredLogger, validate, rbacRoleServiceImpl, userServiceImpl, enforcerImpl, enforcerUtilImpl) rbacRoleRouterImpl := user2.NewRbacRoleRouterImpl(sugaredLogger, validate, rbacRoleRestHandlerImpl) - argoApplicationRestHandlerImpl := argoApplication2.NewArgoApplicationRestHandlerImpl(argoApplicationServiceImpl, sugaredLogger, enforcerImpl) + argoApplicationRestHandlerImpl := argoApplication2.NewArgoApplicationRestHandlerImpl(argoApplicationServiceImpl, argoApplicationReadServiceImpl, sugaredLogger, enforcerImpl) argoApplicationRouterImpl := argoApplication2.NewArgoApplicationRouterImpl(argoApplicationRestHandlerImpl) fluxApplicationRestHandlerImpl := fluxApplication2.NewFluxApplicationRestHandlerImpl(fluxApplicationServiceImpl, sugaredLogger, enforcerImpl) fluxApplicationRouterImpl := fluxApplication2.NewFluxApplicationRouterImpl(fluxApplicationRestHandlerImpl) diff --git a/go.mod b/go.mod index ddbebb37ba..d5f09c6b3d 100644 --- a/go.mod +++ b/go.mod @@ -22,7 +22,7 @@ require ( github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc github.com/deckarep/golang-set v1.8.0 github.com/devtron-labs/authenticator v0.4.35-0.20240809073103-6e11da8083f8 - github.com/devtron-labs/common-lib v0.16.1-0.20240904133334-7918e7c25b63 + github.com/devtron-labs/common-lib v0.16.1-0.20240911071031-2625327bc7b4 github.com/devtron-labs/go-bitbucket v0.9.60-beta github.com/devtron-labs/protos v0.0.3-0.20240802105333-92ee9bb85d80 github.com/evanphx/json-patch v5.7.0+incompatible @@ -76,6 +76,7 @@ require ( go.uber.org/zap v1.21.0 golang.org/x/crypto v0.25.0 golang.org/x/exp v0.0.0-20240222234643-814bf88cf225 + golang.org/x/mod v0.17.0 golang.org/x/oauth2 v0.21.0 google.golang.org/genproto/googleapis/api v0.0.0-20230822172742-b8732ec3820d google.golang.org/grpc v1.59.0 @@ -121,7 +122,6 @@ require ( github.com/apparentlymart/go-textseg v1.0.0 // indirect github.com/apparentlymart/go-textseg/v13 v13.0.0 // indirect github.com/argoproj/pkg v0.13.7-0.20230627120311-a4dd357b057e // indirect - github.com/aws/smithy-go v1.14.2 // indirect github.com/beorn7/perks v1.0.1 // indirect github.com/blang/semver/v4 v4.0.0 // indirect github.com/bmatcuk/doublestar/v4 v4.6.0 // indirect @@ -245,7 +245,6 @@ require ( go.starlark.net v0.0.0-20230525235612-a134d8f9ddca // indirect go.uber.org/atomic v1.10.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/mod v0.17.0 // indirect golang.org/x/net v0.27.0 // indirect golang.org/x/sync v0.7.0 // indirect golang.org/x/sys v0.22.0 // indirect diff --git a/go.sum b/go.sum index fcbc80679f..d4251e80e8 100644 --- a/go.sum +++ b/go.sum @@ -188,8 +188,8 @@ github.com/devtron-labs/argo-workflows/v3 v3.5.10 h1:6rxQOesOzDz6SgQCMDQNHaehsKF github.com/devtron-labs/argo-workflows/v3 v3.5.10/go.mod h1:/vqxcovDPT4zqr4DjR5v7CF8ggpY1l3TSa2CIG3jmjA= github.com/devtron-labs/authenticator v0.4.35-0.20240809073103-6e11da8083f8 h1:2+Q7Jdhpo/uMiaQiZZzAh+ZX7wEJIFuMFG6DEiMuo64= github.com/devtron-labs/authenticator v0.4.35-0.20240809073103-6e11da8083f8/go.mod h1:702R6WIf5y9UzKGoCGxQ+x3l5Ws+l0fXg2xlCpSGFZI= -github.com/devtron-labs/common-lib v0.16.1-0.20240904133334-7918e7c25b63 h1:C5SMozwP2rVIKItqEZs3PtWkBhNnEeHIm9xtnDkK5VA= -github.com/devtron-labs/common-lib v0.16.1-0.20240904133334-7918e7c25b63/go.mod h1:rAY9Xd6iz+OqNQ3nO3reVHapAVr1N6Osf4Irdc0A08Q= +github.com/devtron-labs/common-lib v0.16.1-0.20240911071031-2625327bc7b4 h1:OWhV5B2SQRWZges8cltVsyUrdA/8EByBjjRxX95qN7o= +github.com/devtron-labs/common-lib v0.16.1-0.20240911071031-2625327bc7b4/go.mod h1:rAY9Xd6iz+OqNQ3nO3reVHapAVr1N6Osf4Irdc0A08Q= github.com/devtron-labs/go-bitbucket v0.9.60-beta h1:VEx1jvDgdtDPS6A1uUFoaEi0l1/oLhbr+90xOwr6sDU= github.com/devtron-labs/go-bitbucket v0.9.60-beta/go.mod h1:GnuiCesvh8xyHeMCb+twm8lBR/kQzJYSKL28ZfObp1Y= github.com/devtron-labs/protos v0.0.3-0.20240802105333-92ee9bb85d80 h1:xwbTeijNTf4/j1v+tSfwVqwLVnReas/NqEKeQHvSTys= diff --git a/internal/sql/repository/CiArtifactRepository.go b/internal/sql/repository/CiArtifactRepository.go index 08710aac5b..9cf6a18d82 100644 --- a/internal/sql/repository/CiArtifactRepository.go +++ b/internal/sql/repository/CiArtifactRepository.go @@ -105,6 +105,8 @@ type CiArtifactRepository interface { Get(id int) (artifact *CiArtifact, err error) GetArtifactParentCiAndWorkflowDetailsByIds(ids []int) ([]*CiArtifact, error) GetByWfId(wfId int) (artifact *CiArtifact, err error) + IfArtifactExistByImage(imageName string, pipelineId int) (exist bool, err error) + IfArtifactExistByImageDigest(imageDigest string, imageName string, pipelineId int) (exist bool, err error) GetArtifactsByCDPipeline(cdPipelineId, limit int, parentId int, parentType bean.WorkflowType) ([]*CiArtifact, error) GetArtifactsByCDPipelineV3(listingFilterOpts *bean.ArtifactsListFilterOptions) ([]*CiArtifact, int, error) GetLatestArtifactTimeByCiPipelineIds(ciPipelineIds []int) ([]*CiArtifact, error) @@ -316,6 +318,29 @@ func (impl CiArtifactRepositoryImpl) GetArtifactsByCDPipeline(cdPipelineId, limi return artifactsAll, err } +func (impl CiArtifactRepositoryImpl) IfArtifactExistByImage(imageName string, pipelineId int) (exist bool, err error) { + count, err := impl.dbConnection.Model(&CiArtifact{}). + Where("image = ?", imageName). + Where("pipeline_id = ?", pipelineId). + Count() + if err != nil { + return false, err + } + return count > 0, nil +} + +func (impl CiArtifactRepositoryImpl) IfArtifactExistByImageDigest(imageDigest string, imageName string, pipelineId int) (exist bool, err error) { + count, err := impl.dbConnection.Model(&CiArtifact{}). + Where("image_digest = ?", imageDigest). + Where("image = ?", imageName). + Where("pipeline_id = ?", pipelineId). + Count() + if err != nil { + return false, err + } + return count > 0, nil +} + func (impl CiArtifactRepositoryImpl) GetArtifactsByCDPipelineV3(listingFilterOpts *bean.ArtifactsListFilterOptions) ([]*CiArtifact, int, error) { if listingFilterOpts.ParentStageType != bean.CI_WORKFLOW_TYPE && listingFilterOpts.ParentStageType != bean.WEBHOOK_WORKFLOW_TYPE { diff --git a/internal/util/ErrorUtil.go b/internal/util/ErrorUtil.go index 59a8d23441..43f3c9b942 100644 --- a/internal/util/ErrorUtil.go +++ b/internal/util/ErrorUtil.go @@ -26,6 +26,7 @@ import ( "google.golang.org/grpc/codes" "google.golang.org/grpc/status" "net/http" + "strconv" ) type ApiError struct { @@ -36,6 +37,14 @@ type ApiError struct { UserDetailMessage string `json:"userDetailMessage,omitempty"` } +func GetApiError(code int, userMessage, internalMessage string) *ApiError { + return &ApiError{ + HttpStatusCode: code, + Code: strconv.Itoa(code), + InternalMessage: internalMessage, + UserMessage: userMessage, + } +} func NewApiError() *ApiError { return &ApiError{} } diff --git a/pkg/argoApplication/ArgoApplicationService.go b/pkg/argoApplication/ArgoApplicationService.go index e75272b84f..3f2908c7e8 100644 --- a/pkg/argoApplication/ArgoApplicationService.go +++ b/pkg/argoApplication/ArgoApplicationService.go @@ -18,57 +18,56 @@ package argoApplication import ( "context" - "encoding/json" - "fmt" + "github.com/devtron-labs/common-lib/utils/k8s" + k8sCommonBean "github.com/devtron-labs/common-lib/utils/k8s/commonBean" "github.com/devtron-labs/devtron/api/helm-app/gRPC" openapi "github.com/devtron-labs/devtron/api/helm-app/openapiClient" "github.com/devtron-labs/devtron/api/helm-app/service" - - "github.com/devtron-labs/common-lib/utils/k8s" - k8sCommonBean "github.com/devtron-labs/common-lib/utils/k8s/commonBean" "github.com/devtron-labs/devtron/pkg/argoApplication/bean" + "github.com/devtron-labs/devtron/pkg/argoApplication/helper" + "github.com/devtron-labs/devtron/pkg/argoApplication/read" cluster2 "github.com/devtron-labs/devtron/pkg/cluster" clusterRepository "github.com/devtron-labs/devtron/pkg/cluster/repository" + k8s2 "github.com/devtron-labs/devtron/pkg/k8s" + "github.com/devtron-labs/devtron/pkg/k8s/application" "github.com/devtron-labs/devtron/util/argo" "go.uber.org/zap" "k8s.io/apimachinery/pkg/api/errors" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "k8s.io/apimachinery/pkg/labels" - "k8s.io/client-go/rest" ) type ArgoApplicationService interface { ListApplications(clusterIds []int) ([]*bean.ArgoApplicationListDto, error) - GetAppDetail(resourceName, resourceNamespace string, clusterId int) (*bean.ArgoApplicationDetailDto, error) - GetServerConfigIfClusterIsNotAddedOnDevtron(resourceResp *k8s.ManifestResponse, restConfig *rest.Config, - clusterWithApplicationObject clusterRepository.Cluster, clusterServerUrlIdMap map[string]int) (*rest.Config, error) - GetClusterConfigFromAllClusters(clusterId int) (*k8s.ClusterConfig, clusterRepository.Cluster, map[string]int, error) - GetRestConfigForExternalArgo(ctx context.Context, clusterId int, externalArgoApplicationName string) (*rest.Config, error) HibernateArgoApplication(ctx context.Context, app *bean.ArgoAppIdentifier, hibernateRequest *openapi.HibernateRequest) ([]*openapi.HibernateStatus, error) UnHibernateArgoApplication(ctx context.Context, app *bean.ArgoAppIdentifier, hibernateRequest *openapi.HibernateRequest) ([]*openapi.HibernateStatus, error) } type ArgoApplicationServiceImpl struct { - logger *zap.SugaredLogger - clusterRepository clusterRepository.ClusterRepository - k8sUtil *k8s.K8sServiceImpl - argoUserService argo.ArgoUserService - helmAppClient gRPC.HelmAppClient - helmAppService service.HelmAppService + logger *zap.SugaredLogger + clusterRepository clusterRepository.ClusterRepository + k8sUtil *k8s.K8sServiceImpl + argoUserService argo.ArgoUserService + helmAppClient gRPC.HelmAppClient + helmAppService service.HelmAppService + k8sApplicationService application.K8sApplicationService + readService read.ArgoApplicationReadService } func NewArgoApplicationServiceImpl(logger *zap.SugaredLogger, clusterRepository clusterRepository.ClusterRepository, k8sUtil *k8s.K8sServiceImpl, argoUserService argo.ArgoUserService, helmAppClient gRPC.HelmAppClient, - helmAppService service.HelmAppService) *ArgoApplicationServiceImpl { + helmAppService service.HelmAppService, + k8sApplicationService application.K8sApplicationService, + readService read.ArgoApplicationReadService) *ArgoApplicationServiceImpl { return &ArgoApplicationServiceImpl{ - logger: logger, - clusterRepository: clusterRepository, - k8sUtil: k8sUtil, - argoUserService: argoUserService, - helmAppService: helmAppService, - helmAppClient: helmAppClient, + logger: logger, + clusterRepository: clusterRepository, + k8sUtil: k8sUtil, + argoUserService: argoUserService, + helmAppService: helmAppService, + helmAppClient: helmAppClient, + k8sApplicationService: k8sApplicationService, + readService: readService, } } @@ -91,6 +90,14 @@ func (impl *ArgoApplicationServiceImpl) ListApplications(clusterIds []int) ([]*b } } + listReq := &k8s2.ResourceRequestBean{ + K8sRequest: &k8s.K8sRequestBean{ + ResourceIdentifier: k8s.ResourceIdentifier{ + Namespace: bean.AllNamespaces, + GroupVersionKind: bean.GvkForArgoApplication, + }, + }, + } // TODO: make goroutine and channel for optimization appListFinal := make([]*bean.ArgoApplicationListDto, 0) for _, cluster := range clusters { @@ -105,7 +112,7 @@ func (impl *ArgoApplicationServiceImpl) ListApplications(clusterIds []int) ([]*b impl.logger.Errorw("error in getting rest config by cluster Id", "err", err, "clusterId", clusterObj.Id) return nil, err } - resp, _, err := impl.k8sUtil.GetResourceList(context.Background(), restConfig, bean.GvkForArgoApplication, bean.AllNamespaces, true, nil) + resp, err := impl.k8sApplicationService.GetResourceListWithRestConfig(context.Background(), "", listReq, nil, restConfig, clusterObj.ClusterName) if err != nil { if errStatus, ok := err.(*errors.StatusError); ok { if errStatus.Status().Code == 404 { @@ -117,352 +124,57 @@ func (impl *ArgoApplicationServiceImpl) ListApplications(clusterIds []int) ([]*b impl.logger.Errorw("error in getting resource list", "err", err) return nil, err } - appLists := getApplicationListDtos(resp.Resources.Object, clusterObj.ClusterName, clusterObj.Id) + appLists := getApplicationListDtos(resp, clusterObj.ClusterName, clusterObj.Id) appListFinal = append(appListFinal, appLists...) } return appListFinal, nil } -func (impl *ArgoApplicationServiceImpl) GetAppDetail(resourceName, resourceNamespace string, clusterId int) (*bean.ArgoApplicationDetailDto, error) { - appDetail := &bean.ArgoApplicationDetailDto{ - ArgoApplicationListDto: &bean.ArgoApplicationListDto{ - Name: resourceName, - Namespace: resourceNamespace, - ClusterId: clusterId, - }, - } - clusters, err := impl.clusterRepository.FindAllActive() - if err != nil { - impl.logger.Errorw("error in getting all active clusters", "err", err) - return nil, err - } - var clusterWithApplicationObject clusterRepository.Cluster - clusterServerUrlIdMap := make(map[string]int, len(clusters)) - for _, cluster := range clusters { - if cluster.Id == clusterId { - clusterWithApplicationObject = cluster - } - clusterServerUrlIdMap[cluster.ServerUrl] = cluster.Id - } - if clusterWithApplicationObject.Id > 0 { - appDetail.ClusterName = clusterWithApplicationObject.ClusterName - } - if clusterWithApplicationObject.IsVirtualCluster { - return appDetail, nil - } else if len(clusterWithApplicationObject.ErrorInConnecting) != 0 { - return nil, fmt.Errorf("error in connecting to cluster") - } - clusterBean := cluster2.GetClusterBean(clusterWithApplicationObject) - clusterConfig := clusterBean.GetClusterConfig() - restConfig, err := impl.k8sUtil.GetRestConfigByCluster(clusterConfig) - if err != nil { - impl.logger.Errorw("error in getting rest config by cluster Id", "err", err, "clusterId", clusterWithApplicationObject.Id) - return nil, err - } - resp, err := impl.k8sUtil.GetResource(context.Background(), resourceNamespace, resourceName, bean.GvkForArgoApplication, restConfig) - if err != nil { - impl.logger.Errorw("error in getting resource list", "err", err) - return nil, err - } - var destinationServer string - var argoManagedResources []*bean.ArgoManagedResource - if resp != nil && resp.Manifest.Object != nil { - appDetail.Manifest = resp.Manifest.Object - appDetail.HealthStatus, appDetail.SyncStatus, destinationServer, argoManagedResources = - getHealthSyncStatusDestinationServerAndManagedResourcesForArgoK8sRawObject(resp.Manifest.Object) - } - appDeployedOnClusterId := 0 - if destinationServer == k8s.DefaultClusterUrl { - appDeployedOnClusterId = clusterWithApplicationObject.Id - } else if clusterIdFromMap, ok := clusterServerUrlIdMap[destinationServer]; ok { - appDeployedOnClusterId = clusterIdFromMap - } - var configOfClusterWhereAppIsDeployed bean.ArgoClusterConfigObj - if appDeployedOnClusterId < 1 { - // cluster is not added on devtron, need to get server config from secret which argo-cd saved - coreV1Client, err := impl.k8sUtil.GetCoreV1ClientByRestConfig(restConfig) - secrets, err := coreV1Client.Secrets(bean.AllNamespaces).List(context.Background(), v1.ListOptions{ - LabelSelector: labels.SelectorFromSet(labels.Set{"argocd.argoproj.io/secret-type": "cluster"}).String(), - }) - if err != nil { - impl.logger.Errorw("error in getting resource list, secrets", "err", err) - return nil, err - } - for _, secret := range secrets.Items { - if secret.Data != nil { - if val, ok := secret.Data["server"]; ok { - if string(val) == destinationServer { - if config, ok := secret.Data["config"]; ok { - err = json.Unmarshal(config, &configOfClusterWhereAppIsDeployed) - if err != nil { - impl.logger.Errorw("error in unmarshaling", "err", err) - return nil, err - } - break - } - } - } - } - } - } - resourceTreeResp, err := impl.getResourceTreeForExternalCluster(appDeployedOnClusterId, destinationServer, configOfClusterWhereAppIsDeployed, argoManagedResources) - if err != nil { - impl.logger.Errorw("error in getting resource tree response", "err", err) - return nil, err - } - appDetail.ResourceTree = resourceTreeResp - return appDetail, nil -} - -func (impl *ArgoApplicationServiceImpl) getResourceTreeForExternalCluster(clusterId int, destinationServer string, - configOfClusterWhereAppIsDeployed bean.ArgoClusterConfigObj, argoManagedResources []*bean.ArgoManagedResource) (*gRPC.ResourceTreeResponse, error) { - var resources []*gRPC.ExternalResourceDetail - for _, argoManagedResource := range argoManagedResources { - resources = append(resources, &gRPC.ExternalResourceDetail{ - Group: argoManagedResource.Group, - Kind: argoManagedResource.Kind, - Version: argoManagedResource.Version, - Name: argoManagedResource.Name, - Namespace: argoManagedResource.Namespace, - }) - } - var clusterConfigOfClusterWhereAppIsDeployed *gRPC.ClusterConfig - if len(configOfClusterWhereAppIsDeployed.BearerToken) > 0 { - clusterConfigOfClusterWhereAppIsDeployed = &gRPC.ClusterConfig{ - ApiServerUrl: destinationServer, - Token: configOfClusterWhereAppIsDeployed.BearerToken, - InsecureSkipTLSVerify: configOfClusterWhereAppIsDeployed.TlsClientConfig.Insecure, - KeyData: configOfClusterWhereAppIsDeployed.TlsClientConfig.KeyData, - CaData: configOfClusterWhereAppIsDeployed.TlsClientConfig.CaData, - CertData: configOfClusterWhereAppIsDeployed.TlsClientConfig.CertData, - } - } - resourceTreeResp, err := impl.helmAppService.GetResourceTreeForExternalResources(context.Background(), clusterId, clusterConfigOfClusterWhereAppIsDeployed, resources) - if err != nil { - impl.logger.Errorw("error in getting resource tree for external resources", "err", err) - return nil, err - } - return resourceTreeResp, nil -} - -func getApplicationListDtos(manifestObj map[string]interface{}, clusterName string, clusterId int) []*bean.ArgoApplicationListDto { +func getApplicationListDtos(resp *k8s.ClusterResourceListMap, clusterName string, clusterId int) []*bean.ArgoApplicationListDto { appLists := make([]*bean.ArgoApplicationListDto, 0) - // map of keys and index in row cells, initially set as 0 will be updated by object - keysToBeFetchedFromColumnDefinitions := map[string]int{k8sCommonBean.K8sResourceColumnDefinitionName: 0, - k8sCommonBean.K8sResourceColumnDefinitionHealthStatus: 0, k8sCommonBean.K8sResourceColumnDefinitionSyncStatus: 0} - keysToBeFetchedFromRawObject := []string{k8sCommonBean.K8sClusterResourceNamespaceKey} - - columnsDataRaw := manifestObj[k8sCommonBean.K8sClusterResourceColumnDefinitionKey] - if columnsDataRaw != nil { - columnsData := columnsDataRaw.([]interface{}) - for i, columnData := range columnsData { - columnDataMap := columnData.(map[string]interface{}) - for key := range keysToBeFetchedFromColumnDefinitions { - if columnDataMap[k8sCommonBean.K8sClusterResourceNameKey] == key { - keysToBeFetchedFromColumnDefinitions[key] = i - } + if resp != nil { + appLists = make([]*bean.ArgoApplicationListDto, len(resp.Data)) + for i, rowData := range resp.Data { + if rowData == nil { + continue } - } - } - - rowsDataRaw := manifestObj[k8sCommonBean.K8sClusterResourceRowsKey] - if rowsDataRaw != nil { - rowsData := rowsDataRaw.([]interface{}) - for _, rowData := range rowsData { appListDto := &bean.ArgoApplicationListDto{ ClusterId: clusterId, ClusterName: clusterName, } - rowDataMap := rowData.(map[string]interface{}) - rowCells := rowDataMap[k8sCommonBean.K8sClusterResourceCellKey].([]interface{}) - for key, value := range keysToBeFetchedFromColumnDefinitions { - resolvedValueFromRowCell := rowCells[value].(string) - switch key { - case k8sCommonBean.K8sResourceColumnDefinitionName: - appListDto.Name = resolvedValueFromRowCell - case k8sCommonBean.K8sResourceColumnDefinitionSyncStatus: - appListDto.SyncStatus = resolvedValueFromRowCell - case k8sCommonBean.K8sResourceColumnDefinitionHealthStatus: - appListDto.HealthStatus = resolvedValueFromRowCell + if rowData[k8sCommonBean.K8sClusterResourceNameKey] != nil { + if nameStr, ok := rowData[k8sCommonBean.K8sClusterResourceNameKey].(string); ok { + appListDto.Name = nameStr } } - rowObject := rowDataMap[k8sCommonBean.K8sClusterResourceObjectKey].(map[string]interface{}) - for _, key := range keysToBeFetchedFromRawObject { - switch key { - case k8sCommonBean.K8sClusterResourceNamespaceKey: - metadata := rowObject[k8sCommonBean.K8sClusterResourceMetadataKey].(map[string]interface{}) - appListDto.Namespace = metadata[k8sCommonBean.K8sClusterResourceNamespaceKey].(string) + if rowData[k8sCommonBean.K8sResourceColumnDefinitionSyncStatus] != nil { + if syncStatusStr, ok := rowData[k8sCommonBean.K8sResourceColumnDefinitionSyncStatus].(string); ok { + appListDto.SyncStatus = syncStatusStr } } - - appLists = append(appLists, appListDto) - } - } - return appLists -} - -func getHealthSyncStatusDestinationServerAndManagedResourcesForArgoK8sRawObject(obj map[string]interface{}) (string, - string, string, []*bean.ArgoManagedResource) { - var healthStatus, syncStatus, destinationServer string - argoManagedResources := make([]*bean.ArgoManagedResource, 0) - if specObjRaw, ok := obj[k8sCommonBean.Spec]; ok { - specObj := specObjRaw.(map[string]interface{}) - if destinationObjRaw, ok2 := specObj[bean.Destination]; ok2 { - destinationObj := destinationObjRaw.(map[string]interface{}) - if destinationServerIf, ok3 := destinationObj[bean.Server]; ok3 { - destinationServer = destinationServerIf.(string) - } - } - } - if statusObjRaw, ok := obj[k8sCommonBean.K8sClusterResourceStatusKey]; ok { - statusObj := statusObjRaw.(map[string]interface{}) - if healthObjRaw, ok2 := statusObj[k8sCommonBean.K8sClusterResourceHealthKey]; ok2 { - healthObj := healthObjRaw.(map[string]interface{}) - if healthStatusIf, ok3 := healthObj[k8sCommonBean.K8sClusterResourceStatusKey]; ok3 { - healthStatus = healthStatusIf.(string) - } - } - if syncObjRaw, ok2 := statusObj[k8sCommonBean.K8sClusterResourceSyncKey]; ok2 { - syncObj := syncObjRaw.(map[string]interface{}) - if syncStatusIf, ok3 := syncObj[k8sCommonBean.K8sClusterResourceStatusKey]; ok3 { - syncStatus = syncStatusIf.(string) - } - } - if resourceObjsRaw, ok2 := statusObj[k8sCommonBean.K8sClusterResourceResourcesKey]; ok2 { - resourceObjs := resourceObjsRaw.([]interface{}) - argoManagedResources = make([]*bean.ArgoManagedResource, 0, len(resourceObjs)) - for _, resourceObjRaw := range resourceObjs { - argoManagedResource := &bean.ArgoManagedResource{} - resourceObj := resourceObjRaw.(map[string]interface{}) - if groupRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceGroupKey]; ok { - argoManagedResource.Group = groupRaw.(string) - } - if kindRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceKindKey]; ok { - argoManagedResource.Kind = kindRaw.(string) + if rowData[k8sCommonBean.K8sResourceColumnDefinitionHealthStatus] != nil { + if healthStatusStr, ok := rowData[k8sCommonBean.K8sResourceColumnDefinitionHealthStatus].(string); ok { + appListDto.HealthStatus = healthStatusStr } - if versionRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceVersionKey]; ok { - argoManagedResource.Version = versionRaw.(string) - } - if nameRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceMetadataNameKey]; ok { - argoManagedResource.Name = nameRaw.(string) - } - if namespaceRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceNamespaceKey]; ok { - argoManagedResource.Namespace = namespaceRaw.(string) - } - argoManagedResources = append(argoManagedResources, argoManagedResource) } - } - } - return healthStatus, syncStatus, destinationServer, argoManagedResources -} - -func (impl *ArgoApplicationServiceImpl) GetServerConfigIfClusterIsNotAddedOnDevtron(resourceResp *k8s.ManifestResponse, restConfig *rest.Config, - clusterWithApplicationObject clusterRepository.Cluster, clusterServerUrlIdMap map[string]int) (*rest.Config, error) { - var destinationServer string - if resourceResp != nil && resourceResp.Manifest.Object != nil { - _, _, destinationServer, _ = - getHealthSyncStatusDestinationServerAndManagedResourcesForArgoK8sRawObject(resourceResp.Manifest.Object) - } - appDeployedOnClusterId := 0 - if destinationServer == k8s.DefaultClusterUrl { - appDeployedOnClusterId = clusterWithApplicationObject.Id - } else if clusterIdFromMap, ok := clusterServerUrlIdMap[destinationServer]; ok { - appDeployedOnClusterId = clusterIdFromMap - } - var configOfClusterWhereAppIsDeployed *bean.ArgoClusterConfigObj - if appDeployedOnClusterId < 1 { - // cluster is not added on devtron, need to get server config from secret which argo-cd saved - coreV1Client, err := impl.k8sUtil.GetCoreV1ClientByRestConfig(restConfig) - secrets, err := coreV1Client.Secrets(bean.AllNamespaces).List(context.Background(), v1.ListOptions{ - LabelSelector: labels.SelectorFromSet(labels.Set{"argocd.argoproj.io/secret-type": "cluster"}).String(), - }) - if err != nil { - impl.logger.Errorw("error in getting resource list, secrets", "err", err) - return nil, err - } - for _, secret := range secrets.Items { - if secret.Data != nil { - if val, ok := secret.Data[bean.Server]; ok { - if string(val) == destinationServer { - if config, ok := secret.Data[bean.Config]; ok { - err = json.Unmarshal(config, &configOfClusterWhereAppIsDeployed) - if err != nil { - impl.logger.Errorw("error in unmarshaling", "err", err) - return nil, err - } - break - } - } + if rowData[k8sCommonBean.K8sClusterResourceNamespaceKey] != nil { + if namespaceStr, ok := rowData[k8sCommonBean.K8sClusterResourceNamespaceKey].(string); ok { + appListDto.Namespace = namespaceStr } } - } - if configOfClusterWhereAppIsDeployed != nil { - restConfig.Host = destinationServer - restConfig.TLSClientConfig = rest.TLSClientConfig{ - Insecure: configOfClusterWhereAppIsDeployed.TlsClientConfig.Insecure, - KeyFile: configOfClusterWhereAppIsDeployed.TlsClientConfig.KeyData, - CAFile: configOfClusterWhereAppIsDeployed.TlsClientConfig.CaData, - CertFile: configOfClusterWhereAppIsDeployed.TlsClientConfig.CertData, - } - restConfig.BearerToken = configOfClusterWhereAppIsDeployed.BearerToken + appLists[i] = appListDto } } - return restConfig, nil -} - -func (impl *ArgoApplicationServiceImpl) GetClusterConfigFromAllClusters(clusterId int) (*k8s.ClusterConfig, clusterRepository.Cluster, map[string]int, error) { - clusters, err := impl.clusterRepository.FindAllActive() - var clusterWithApplicationObject clusterRepository.Cluster - if err != nil { - impl.logger.Errorw("error in getting all active clusters", "err", err) - return nil, clusterWithApplicationObject, nil, err - } - clusterServerUrlIdMap := make(map[string]int, len(clusters)) - for _, cluster := range clusters { - if cluster.Id == clusterId { - clusterWithApplicationObject = cluster - } - clusterServerUrlIdMap[cluster.ServerUrl] = cluster.Id - } - if len(clusterWithApplicationObject.ErrorInConnecting) != 0 { - return nil, clusterWithApplicationObject, nil, fmt.Errorf("error in connecting to cluster") - } - clusterBean := cluster2.GetClusterBean(clusterWithApplicationObject) - clusterConfig := clusterBean.GetClusterConfig() - return clusterConfig, clusterWithApplicationObject, clusterServerUrlIdMap, err -} - -func (impl *ArgoApplicationServiceImpl) GetRestConfigForExternalArgo(ctx context.Context, clusterId int, externalArgoApplicationName string) (*rest.Config, error) { - clusterConfig, clusterWithApplicationObject, clusterServerUrlIdMap, err := impl.GetClusterConfigFromAllClusters(clusterId) - if err != nil { - impl.logger.Errorw("error in getting cluster config", "err", err, "clusterId", clusterId) - return nil, err - } - restConfig, err := impl.k8sUtil.GetRestConfigByCluster(clusterConfig) - if err != nil { - impl.logger.Errorw("error in getting rest config", "err", err, "clusterId", clusterId) - return nil, err - } - resourceResp, err := impl.k8sUtil.GetResource(ctx, bean.DevtronCDNamespae, externalArgoApplicationName, bean.GvkForArgoApplication, restConfig) - if err != nil { - impl.logger.Errorw("not on external cluster", "err", err, "externalArgoApplicationName", externalArgoApplicationName) - return nil, err - } - restConfig, err = impl.GetServerConfigIfClusterIsNotAddedOnDevtron(resourceResp, restConfig, clusterWithApplicationObject, clusterServerUrlIdMap) - if err != nil { - impl.logger.Errorw("error in getting server config", "err", err, "cluster with application object", clusterWithApplicationObject) - return nil, err - } - return restConfig, nil + return appLists } func (impl *ArgoApplicationServiceImpl) HibernateArgoApplication(ctx context.Context, app *bean.ArgoAppIdentifier, hibernateRequest *openapi.HibernateRequest) ([]*openapi.HibernateStatus, error) { - _, clusterBean, _, err := impl.GetClusterConfigFromAllClusters(app.ClusterId) + _, clusterBean, _, err := impl.readService.GetClusterConfigFromAllClusters(app.ClusterId) if err != nil { impl.logger.Errorw("HibernateArgoApplication", "error in getting the cluster config", err, "clusterId", app.ClusterId, "appName", app.AppName) return nil, err } - conf := ConvertClusterBeanToGrpcConfig(clusterBean) + conf := helper.ConvertClusterBeanToGrpcConfig(clusterBean) req := service.HibernateReqAdaptor(hibernateRequest) req.ClusterConfig = conf @@ -476,12 +188,12 @@ func (impl *ArgoApplicationServiceImpl) HibernateArgoApplication(ctx context.Con } func (impl *ArgoApplicationServiceImpl) UnHibernateArgoApplication(ctx context.Context, app *bean.ArgoAppIdentifier, hibernateRequest *openapi.HibernateRequest) ([]*openapi.HibernateStatus, error) { - _, clusterBean, _, err := impl.GetClusterConfigFromAllClusters(app.ClusterId) + _, clusterBean, _, err := impl.readService.GetClusterConfigFromAllClusters(app.ClusterId) if err != nil { impl.logger.Errorw("HibernateArgoApplication", "error in getting the cluster config", err, "clusterId", app.ClusterId, "appName", app.AppName) return nil, err } - conf := ConvertClusterBeanToGrpcConfig(clusterBean) + conf := helper.ConvertClusterBeanToGrpcConfig(clusterBean) req := service.HibernateReqAdaptor(hibernateRequest) req.ClusterConfig = conf diff --git a/pkg/argoApplication/helper.go b/pkg/argoApplication/helper/helper.go similarity index 98% rename from pkg/argoApplication/helper.go rename to pkg/argoApplication/helper/helper.go index 97a80e2c4d..d931b07808 100644 --- a/pkg/argoApplication/helper.go +++ b/pkg/argoApplication/helper/helper.go @@ -1,4 +1,4 @@ -package argoApplication +package helper import ( "fmt" diff --git a/pkg/argoApplication/read/ArgoApplicationReadService.go b/pkg/argoApplication/read/ArgoApplicationReadService.go new file mode 100644 index 0000000000..4a815e99b4 --- /dev/null +++ b/pkg/argoApplication/read/ArgoApplicationReadService.go @@ -0,0 +1,402 @@ +package read + +import ( + "context" + "encoding/json" + "fmt" + "github.com/devtron-labs/common-lib/utils/k8s" + k8sCommonBean "github.com/devtron-labs/common-lib/utils/k8s/commonBean" + "github.com/devtron-labs/devtron/api/helm-app/gRPC" + "github.com/devtron-labs/devtron/api/helm-app/service" + "github.com/devtron-labs/devtron/pkg/argoApplication/bean" + cluster2 "github.com/devtron-labs/devtron/pkg/cluster" + clusterRepository "github.com/devtron-labs/devtron/pkg/cluster/repository" + clientErrors "github.com/devtron-labs/devtron/pkg/errors" + "github.com/devtron-labs/devtron/util/argo" + "go.uber.org/zap" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/client-go/rest" +) + +type ArgoApplicationReadService interface { + GetRestConfigForExternalArgo(ctx context.Context, clusterId int, externalArgoApplicationName string) (*rest.Config, error) + GetClusterConfigFromAllClusters(clusterId int) (*k8s.ClusterConfig, clusterRepository.Cluster, map[string]int, error) + ValidateArgoResourceRequest(ctx context.Context, appIdentifier *bean.ArgoAppIdentifier, request *k8s.K8sRequestBean) (bool, error) + GetAppDetail(resourceName, resourceNamespace string, clusterId int) (*bean.ArgoApplicationDetailDto, error) +} + +type ArgoApplicationReadServiceImpl struct { + logger *zap.SugaredLogger + clusterRepository clusterRepository.ClusterRepository + k8sUtil *k8s.K8sServiceImpl + argoUserService argo.ArgoUserService + helmAppClient gRPC.HelmAppClient + helmAppService service.HelmAppService +} + +func NewArgoApplicationReadServiceImpl(logger *zap.SugaredLogger, + clusterRepository clusterRepository.ClusterRepository, + k8sUtil *k8s.K8sServiceImpl, + argoUserService argo.ArgoUserService, helmAppClient gRPC.HelmAppClient, + helmAppService service.HelmAppService) *ArgoApplicationReadServiceImpl { + return &ArgoApplicationReadServiceImpl{ + logger: logger, + clusterRepository: clusterRepository, + k8sUtil: k8sUtil, + argoUserService: argoUserService, + helmAppService: helmAppService, + helmAppClient: helmAppClient, + } + +} + +func (impl *ArgoApplicationReadServiceImpl) GetRestConfigForExternalArgo(ctx context.Context, clusterId int, externalArgoApplicationName string) (*rest.Config, error) { + clusterConfig, clusterWithApplicationObject, clusterServerUrlIdMap, err := impl.GetClusterConfigFromAllClusters(clusterId) + if err != nil { + impl.logger.Errorw("error in getting cluster config", "err", err, "clusterId", clusterId) + return nil, err + } + restConfig, err := impl.k8sUtil.GetRestConfigByCluster(clusterConfig) + if err != nil { + impl.logger.Errorw("error in getting rest config", "err", err, "clusterId", clusterId) + return nil, err + } + resourceResp, err := impl.k8sUtil.GetResource(ctx, bean.DevtronCDNamespae, externalArgoApplicationName, bean.GvkForArgoApplication, restConfig) + if err != nil { + impl.logger.Errorw("not on external cluster", "err", err, "externalArgoApplicationName", externalArgoApplicationName) + return nil, err + } + restConfig, err = impl.GetServerConfigIfClusterIsNotAddedOnDevtron(resourceResp, restConfig, clusterWithApplicationObject, clusterServerUrlIdMap) + if err != nil { + impl.logger.Errorw("error in getting server config", "err", err, "cluster with application object", clusterWithApplicationObject) + return nil, err + } + return restConfig, nil +} + +func (impl *ArgoApplicationReadServiceImpl) GetServerConfigIfClusterIsNotAddedOnDevtron(resourceResp *k8s.ManifestResponse, restConfig *rest.Config, + clusterWithApplicationObject clusterRepository.Cluster, clusterServerUrlIdMap map[string]int) (*rest.Config, error) { + var destinationServer string + if resourceResp != nil && resourceResp.Manifest.Object != nil { + _, _, destinationServer, _ = + getHealthSyncStatusDestinationServerAndManagedResourcesForArgoK8sRawObject(resourceResp.Manifest.Object) + } + appDeployedOnClusterId := 0 + if destinationServer == k8s.DefaultClusterUrl { + appDeployedOnClusterId = clusterWithApplicationObject.Id + } else if clusterIdFromMap, ok := clusterServerUrlIdMap[destinationServer]; ok { + appDeployedOnClusterId = clusterIdFromMap + } + var configOfClusterWhereAppIsDeployed *bean.ArgoClusterConfigObj + if appDeployedOnClusterId < 1 { + // cluster is not added on devtron, need to get server config from secret which argo-cd saved + coreV1Client, err := impl.k8sUtil.GetCoreV1ClientByRestConfig(restConfig) + secrets, err := coreV1Client.Secrets(bean.AllNamespaces).List(context.Background(), v1.ListOptions{ + LabelSelector: labels.SelectorFromSet(labels.Set{"argocd.argoproj.io/secret-type": "cluster"}).String(), + }) + if err != nil { + impl.logger.Errorw("error in getting resource list, secrets", "err", err) + return nil, err + } + for _, secret := range secrets.Items { + if secret.Data != nil { + if val, ok := secret.Data[bean.Server]; ok { + if string(val) == destinationServer { + if config, ok := secret.Data[bean.Config]; ok { + err = json.Unmarshal(config, &configOfClusterWhereAppIsDeployed) + if err != nil { + impl.logger.Errorw("error in unmarshaling", "err", err) + return nil, err + } + break + } + } + } + } + } + if configOfClusterWhereAppIsDeployed != nil { + restConfig, err = impl.k8sUtil.GetRestConfigByCluster(&k8s.ClusterConfig{ + Host: destinationServer, + BearerToken: configOfClusterWhereAppIsDeployed.BearerToken, + InsecureSkipTLSVerify: configOfClusterWhereAppIsDeployed.TlsClientConfig.Insecure, + KeyData: configOfClusterWhereAppIsDeployed.TlsClientConfig.KeyData, + CAData: configOfClusterWhereAppIsDeployed.TlsClientConfig.CaData, + CertData: configOfClusterWhereAppIsDeployed.TlsClientConfig.CertData, + }) + if err != nil { + impl.logger.Errorw("error in GetRestConfigByCluster, GetServerConfigIfClusterIsNotAddedOnDevtron", "err", err, "serverUrl", destinationServer) + return nil, err + } + } + } + return restConfig, nil +} + +func (impl *ArgoApplicationReadServiceImpl) GetClusterConfigFromAllClusters(clusterId int) (*k8s.ClusterConfig, clusterRepository.Cluster, map[string]int, error) { + clusters, err := impl.clusterRepository.FindAllActive() + var clusterWithApplicationObject clusterRepository.Cluster + if err != nil { + impl.logger.Errorw("error in getting all active clusters", "err", err) + return nil, clusterWithApplicationObject, nil, err + } + clusterServerUrlIdMap := make(map[string]int, len(clusters)) + for _, cluster := range clusters { + if cluster.Id == clusterId { + clusterWithApplicationObject = cluster + } + clusterServerUrlIdMap[cluster.ServerUrl] = cluster.Id + } + if len(clusterWithApplicationObject.ErrorInConnecting) != 0 { + return nil, clusterWithApplicationObject, nil, fmt.Errorf("error in connecting to cluster") + } + clusterBean := cluster2.GetClusterBean(clusterWithApplicationObject) + clusterConfig := clusterBean.GetClusterConfig() + return clusterConfig, clusterWithApplicationObject, clusterServerUrlIdMap, err +} + +func (impl *ArgoApplicationReadServiceImpl) GetAppDetail(resourceName, resourceNamespace string, clusterId int) (*bean.ArgoApplicationDetailDto, error) { + appDetail := &bean.ArgoApplicationDetailDto{ + ArgoApplicationListDto: &bean.ArgoApplicationListDto{ + Name: resourceName, + Namespace: resourceNamespace, + ClusterId: clusterId, + }, + } + clusters, err := impl.clusterRepository.FindAllActive() + if err != nil { + impl.logger.Errorw("error in getting all active clusters", "err", err) + return nil, err + } + var clusterWithApplicationObject clusterRepository.Cluster + clusterServerUrlIdMap := make(map[string]int, len(clusters)) + for _, cluster := range clusters { + if cluster.Id == clusterId { + clusterWithApplicationObject = cluster + } + clusterServerUrlIdMap[cluster.ServerUrl] = cluster.Id + } + if clusterWithApplicationObject.Id > 0 { + appDetail.ClusterName = clusterWithApplicationObject.ClusterName + } + if clusterWithApplicationObject.IsVirtualCluster { + return appDetail, nil + } else if len(clusterWithApplicationObject.ErrorInConnecting) != 0 { + return nil, fmt.Errorf("error in connecting to cluster") + } + clusterBean := cluster2.GetClusterBean(clusterWithApplicationObject) + clusterConfig := clusterBean.GetClusterConfig() + restConfig, err := impl.k8sUtil.GetRestConfigByCluster(clusterConfig) + if err != nil { + impl.logger.Errorw("error in getting rest config by cluster Id", "err", err, "clusterId", clusterWithApplicationObject.Id) + return nil, err + } + resp, err := impl.k8sUtil.GetResource(context.Background(), resourceNamespace, resourceName, bean.GvkForArgoApplication, restConfig) + if err != nil { + impl.logger.Errorw("error in getting resource list", "err", err) + return nil, err + } + var destinationServer string + var argoManagedResources []*bean.ArgoManagedResource + if resp != nil && resp.Manifest.Object != nil { + appDetail.Manifest = resp.Manifest.Object + appDetail.HealthStatus, appDetail.SyncStatus, destinationServer, argoManagedResources = + getHealthSyncStatusDestinationServerAndManagedResourcesForArgoK8sRawObject(resp.Manifest.Object) + } + appDeployedOnClusterId := 0 + if destinationServer == k8s.DefaultClusterUrl { + appDeployedOnClusterId = clusterWithApplicationObject.Id + } else if clusterIdFromMap, ok := clusterServerUrlIdMap[destinationServer]; ok { + appDeployedOnClusterId = clusterIdFromMap + } + var configOfClusterWhereAppIsDeployed bean.ArgoClusterConfigObj + if appDeployedOnClusterId < 1 { + // cluster is not added on devtron, need to get server config from secret which argo-cd saved + coreV1Client, err := impl.k8sUtil.GetCoreV1ClientByRestConfig(restConfig) + secrets, err := coreV1Client.Secrets(bean.AllNamespaces).List(context.Background(), v1.ListOptions{ + LabelSelector: labels.SelectorFromSet(labels.Set{"argocd.argoproj.io/secret-type": "cluster"}).String(), + }) + if err != nil { + impl.logger.Errorw("error in getting resource list, secrets", "err", err) + return nil, err + } + for _, secret := range secrets.Items { + if secret.Data != nil { + if val, ok := secret.Data["server"]; ok { + if string(val) == destinationServer { + if config, ok := secret.Data["config"]; ok { + err = json.Unmarshal(config, &configOfClusterWhereAppIsDeployed) + if err != nil { + impl.logger.Errorw("error in unmarshaling", "err", err) + return nil, err + } + break + } + } + } + } + } + } + resourceTreeResp, err := impl.getResourceTreeForExternalCluster(appDeployedOnClusterId, destinationServer, configOfClusterWhereAppIsDeployed, argoManagedResources) + if err != nil { + impl.logger.Errorw("error in getting resource tree response", "err", err) + return nil, err + } + appDetail.ResourceTree = resourceTreeResp + return appDetail, nil +} + +func (impl *ArgoApplicationReadServiceImpl) getResourceTreeForExternalCluster(clusterId int, destinationServer string, + configOfClusterWhereAppIsDeployed bean.ArgoClusterConfigObj, argoManagedResources []*bean.ArgoManagedResource) (*gRPC.ResourceTreeResponse, error) { + var resources []*gRPC.ExternalResourceDetail + for _, argoManagedResource := range argoManagedResources { + resources = append(resources, &gRPC.ExternalResourceDetail{ + Group: argoManagedResource.Group, + Kind: argoManagedResource.Kind, + Version: argoManagedResource.Version, + Name: argoManagedResource.Name, + Namespace: argoManagedResource.Namespace, + }) + } + var clusterConfigOfClusterWhereAppIsDeployed *gRPC.ClusterConfig + if len(configOfClusterWhereAppIsDeployed.BearerToken) > 0 { + clusterConfigOfClusterWhereAppIsDeployed = &gRPC.ClusterConfig{ + ApiServerUrl: destinationServer, + Token: configOfClusterWhereAppIsDeployed.BearerToken, + InsecureSkipTLSVerify: configOfClusterWhereAppIsDeployed.TlsClientConfig.Insecure, + KeyData: configOfClusterWhereAppIsDeployed.TlsClientConfig.KeyData, + CaData: configOfClusterWhereAppIsDeployed.TlsClientConfig.CaData, + CertData: configOfClusterWhereAppIsDeployed.TlsClientConfig.CertData, + } + } + resourceTreeResp, err := impl.helmAppService.GetResourceTreeForExternalResources(context.Background(), clusterId, clusterConfigOfClusterWhereAppIsDeployed, resources) + if err != nil { + impl.logger.Errorw("error in getting resource tree for external resources", "err", err) + return nil, err + } + return resourceTreeResp, nil +} + +func (impl *ArgoApplicationReadServiceImpl) ValidateArgoResourceRequest(ctx context.Context, appIdentifier *bean.ArgoAppIdentifier, request *k8s.K8sRequestBean) (bool, error) { + app, err := impl.GetAppDetail(appIdentifier.AppName, appIdentifier.Namespace, appIdentifier.ClusterId) + if err != nil { + impl.logger.Errorw("error in getting app detail", "err", err, "appDetails", appIdentifier) + apiError := clientErrors.ConvertToApiError(err) + if apiError != nil { + err = apiError + } + return false, err + } + + valid := false + + for _, node := range app.ResourceTree.Nodes { + nodeDetails := k8s.ResourceIdentifier{ + Name: node.Name, + Namespace: node.Namespace, + GroupVersionKind: schema.GroupVersionKind{ + Group: node.Group, + Version: node.Version, + Kind: node.Kind, + }, + } + if nodeDetails == request.ResourceIdentifier { + valid = true + break + } + } + appDetail := &gRPC.AppDetail{ + ResourceTreeResponse: app.ResourceTree, + } + return validateContainerNameIfReqd(valid, request, appDetail), nil +} + +func validateContainerNameIfReqd(valid bool, request *k8s.K8sRequestBean, app *gRPC.AppDetail) bool { + if !valid { + requestContainerName := request.PodLogsRequest.ContainerName + podName := request.ResourceIdentifier.Name + for _, pod := range app.ResourceTreeResponse.PodMetadata { + if pod.Name == podName { + + // finding the container name in main Containers + for _, container := range pod.Containers { + if container == requestContainerName { + return true + } + } + + // finding the container name in init containers + for _, initContainer := range pod.InitContainers { + if initContainer == requestContainerName { + return true + } + } + + // finding the container name in ephemeral containers + for _, ephemeralContainer := range pod.EphemeralContainers { + if ephemeralContainer.Name == requestContainerName { + return true + } + } + + } + } + } + return valid +} + +func getHealthSyncStatusDestinationServerAndManagedResourcesForArgoK8sRawObject(obj map[string]interface{}) (string, + string, string, []*bean.ArgoManagedResource) { + var healthStatus, syncStatus, destinationServer string + argoManagedResources := make([]*bean.ArgoManagedResource, 0) + if specObjRaw, ok := obj[k8sCommonBean.Spec]; ok { + specObj := specObjRaw.(map[string]interface{}) + if destinationObjRaw, ok2 := specObj[bean.Destination]; ok2 { + destinationObj := destinationObjRaw.(map[string]interface{}) + if destinationServerIf, ok3 := destinationObj[bean.Server]; ok3 { + destinationServer = destinationServerIf.(string) + } + } + } + if statusObjRaw, ok := obj[k8sCommonBean.K8sClusterResourceStatusKey]; ok { + statusObj := statusObjRaw.(map[string]interface{}) + if healthObjRaw, ok2 := statusObj[k8sCommonBean.K8sClusterResourceHealthKey]; ok2 { + healthObj := healthObjRaw.(map[string]interface{}) + if healthStatusIf, ok3 := healthObj[k8sCommonBean.K8sClusterResourceStatusKey]; ok3 { + healthStatus = healthStatusIf.(string) + } + } + if syncObjRaw, ok2 := statusObj[k8sCommonBean.K8sClusterResourceSyncKey]; ok2 { + syncObj := syncObjRaw.(map[string]interface{}) + if syncStatusIf, ok3 := syncObj[k8sCommonBean.K8sClusterResourceStatusKey]; ok3 { + syncStatus = syncStatusIf.(string) + } + } + if resourceObjsRaw, ok2 := statusObj[k8sCommonBean.K8sClusterResourceResourcesKey]; ok2 { + resourceObjs := resourceObjsRaw.([]interface{}) + argoManagedResources = make([]*bean.ArgoManagedResource, 0, len(resourceObjs)) + for _, resourceObjRaw := range resourceObjs { + argoManagedResource := &bean.ArgoManagedResource{} + resourceObj := resourceObjRaw.(map[string]interface{}) + if groupRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceGroupKey]; ok { + argoManagedResource.Group = groupRaw.(string) + } + if kindRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceKindKey]; ok { + argoManagedResource.Kind = kindRaw.(string) + } + if versionRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceVersionKey]; ok { + argoManagedResource.Version = versionRaw.(string) + } + if nameRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceMetadataNameKey]; ok { + argoManagedResource.Name = nameRaw.(string) + } + if namespaceRaw, ok := resourceObj[k8sCommonBean.K8sClusterResourceNamespaceKey]; ok { + argoManagedResource.Namespace = namespaceRaw.(string) + } + argoManagedResources = append(argoManagedResources, argoManagedResource) + } + } + } + return healthStatus, syncStatus, destinationServer, argoManagedResources +} diff --git a/pkg/eventProcessor/bean/workflowEventBean.go b/pkg/eventProcessor/bean/workflowEventBean.go index bdcac00f6c..755defdd3e 100644 --- a/pkg/eventProcessor/bean/workflowEventBean.go +++ b/pkg/eventProcessor/bean/workflowEventBean.go @@ -18,7 +18,8 @@ package bean import ( "context" - "github.com/aws/aws-sdk-go-v2/service/ecr/types" + "encoding/json" + "github.com/devtron-labs/common-lib/utils/registry" "github.com/devtron-labs/devtron/api/bean" "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig" bean3 "github.com/devtron-labs/devtron/pkg/pipeline/bean" @@ -62,11 +63,6 @@ func (r *UserDeploymentRequest) WithPipelineOverrideId(id int) *UserDeploymentRe return r } -type ImageDetailsFromCR struct { - ImageDetails []types.ImageDetail `json:"imageDetails"` - Region string `json:"region"` -} - type CiCompleteEvent struct { CiProjectDetails []bean3.CiProjectDetails `json:"ciProjectDetails"` DockerImage string `json:"dockerImage" validate:"required,image-validator"` @@ -81,9 +77,30 @@ type CiCompleteEvent struct { AppName string `json:"appName"` IsArtifactUploaded bool `json:"isArtifactUploaded"` FailureReason string `json:"failureReason"` - ImageDetailsFromCR *ImageDetailsFromCR `json:"imageDetailsFromCR"` + ImageDetailsFromCR json.RawMessage `json:"imageDetailsFromCR"` PluginRegistryArtifactDetails map[string][]string `json:"PluginRegistryArtifactDetails"` PluginArtifactStage string `json:"pluginArtifactStage"` + pluginImageDetails *registry.ImageDetailsFromCR +} + +func (c *CiCompleteEvent) GetPluginImageDetails() *registry.ImageDetailsFromCR { + if c == nil { + return nil + } + return c.pluginImageDetails +} + +func (c *CiCompleteEvent) SetImageDetailsFromCR() error { + if c.ImageDetailsFromCR == nil { + return nil + } + var imageDetailsFromCR *registry.ImageDetailsFromCR + err := json.Unmarshal(c.ImageDetailsFromCR, &imageDetailsFromCR) + if err != nil { + return err + } + c.pluginImageDetails = imageDetailsFromCR + return nil } type DevtronAppReleaseContextType struct { diff --git a/pkg/eventProcessor/in/WorkflowEventProcessorService.go b/pkg/eventProcessor/in/WorkflowEventProcessorService.go index 2ac2f3a9c2..d01fb1bfe6 100644 --- a/pkg/eventProcessor/in/WorkflowEventProcessorService.go +++ b/pkg/eventProcessor/in/WorkflowEventProcessorService.go @@ -22,9 +22,9 @@ import ( "errors" "fmt" "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" - "github.com/aws/aws-sdk-go-v2/service/ecr/types" pubsub "github.com/devtron-labs/common-lib/pubsub-lib" "github.com/devtron-labs/common-lib/pubsub-lib/model" + "github.com/devtron-labs/common-lib/utils/registry" apiBean "github.com/devtron-labs/devtron/api/bean" client "github.com/devtron-labs/devtron/client/events" "github.com/devtron-labs/devtron/internal/sql/models" @@ -474,12 +474,25 @@ func (impl *WorkflowEventProcessorImpl) SubscribeCDWorkflowStatusUpdate() error return nil } +func (impl *WorkflowEventProcessorImpl) extractCiCompleteEventFrom(msg *model.PubSubMsg) (bean.CiCompleteEvent, error) { + ciCompleteEvent := bean.CiCompleteEvent{} + err := json.Unmarshal([]byte(msg.Data), &ciCompleteEvent) + if err != nil { + impl.logger.Error("error while unmarshalling json data", "error", err) + return ciCompleteEvent, err + } + err = ciCompleteEvent.SetImageDetailsFromCR() + if err != nil { + impl.logger.Error("error in unmarshalling imageDetailsFromCr results", "error", err) + return ciCompleteEvent, err + } + return ciCompleteEvent, nil +} + func (impl *WorkflowEventProcessorImpl) SubscribeCICompleteEvent() error { callback := func(msg *model.PubSubMsg) { - ciCompleteEvent := bean.CiCompleteEvent{} - err := json.Unmarshal([]byte(msg.Data), &ciCompleteEvent) + ciCompleteEvent, err := impl.extractCiCompleteEventFrom(msg) if err != nil { - impl.logger.Error("error while unmarshalling json data", "error", err) return } impl.logger.Debugw("ci complete event for ci", "ciPipelineId", ciCompleteEvent.PipelineId) @@ -501,34 +514,33 @@ func (impl *WorkflowEventProcessorImpl) SubscribeCICompleteEvent() error { ciCompleteEvent.PipelineId, "request: ", req, "error: ", err) return } - } else if ciCompleteEvent.ImageDetailsFromCR != nil { - if len(ciCompleteEvent.ImageDetailsFromCR.ImageDetails) > 0 { - imageDetails := globalUtil.GetReverseSortedImageDetails(ciCompleteEvent.ImageDetailsFromCR.ImageDetails) + } else if ciCompleteEvent.GetPluginImageDetails() != nil { + if len(ciCompleteEvent.GetPluginImageDetails().ImageDetails) > 0 { + imageDetails := registry.SortGenericImageDetailByCreatedOn(ciCompleteEvent.GetPluginImageDetails().ImageDetails, registry.Ascending) digestWorkflowMap, err := impl.webhookService.HandleMultipleImagesFromEvent(imageDetails, *ciCompleteEvent.WorkflowId) if err != nil { impl.logger.Errorw("error in getting digest workflow map", "err", err, "workflowId", ciCompleteEvent.WorkflowId) return } for _, detail := range imageDetails { - if detail.ImageTags == nil { + if detail == nil || len(detail.Image) == 0 { continue } - request, err := impl.BuildCIArtifactRequestForImageFromCR(detail, ciCompleteEvent.ImageDetailsFromCR.Region, ciCompleteEvent, digestWorkflowMap[*detail.ImageDigest].Id) + request, err := impl.buildCIArtifactRequestForImageFromCR(detail, ciCompleteEvent, digestWorkflowMap[detail.GetGenericImageDetailIdentifier()].Id) if err != nil { impl.logger.Error("Error while creating request for pipelineID", "pipelineId", ciCompleteEvent.PipelineId, "err", err) return } - resp, err := impl.ValidateAndHandleCiSuccessEvent(triggerContext, ciCompleteEvent.PipelineId, request, detail.ImagePushedAt) + resp, err := impl.ValidateAndHandleCiSuccessEvent(triggerContext, ciCompleteEvent.PipelineId, request, detail.LastUpdatedOn) if err != nil { return } impl.logger.Debug("response of handle ci success event for multiple images from plugin", "resp", resp) } } - } else { globalUtil.TriggerCIMetrics(ciCompleteEvent.Metrics, impl.globalEnvVariables.ExposeCiMetrics, ciCompleteEvent.PipelineName, ciCompleteEvent.AppName) - resp, err := impl.ValidateAndHandleCiSuccessEvent(triggerContext, ciCompleteEvent.PipelineId, req, &time.Time{}) + resp, err := impl.ValidateAndHandleCiSuccessEvent(triggerContext, ciCompleteEvent.PipelineId, req, time.Time{}) if err != nil { return } @@ -555,7 +567,7 @@ func (impl *WorkflowEventProcessorImpl) SubscribeCICompleteEvent() error { return nil } -func (impl *WorkflowEventProcessorImpl) ValidateAndHandleCiSuccessEvent(triggerContext triggerBean.TriggerContext, ciPipelineId int, request *wrokflowDagBean.CiArtifactWebhookRequest, imagePushedAt *time.Time) (int, error) { +func (impl *WorkflowEventProcessorImpl) ValidateAndHandleCiSuccessEvent(triggerContext triggerBean.TriggerContext, ciPipelineId int, request *wrokflowDagBean.CiArtifactWebhookRequest, imagePushedAt time.Time) (int, error) { validationErr := impl.validator.Struct(request) if validationErr != nil { impl.logger.Errorw("validation err, HandleCiSuccessEvent", "err", validationErr, "payload", request) @@ -643,13 +655,13 @@ func (impl *WorkflowEventProcessorImpl) BuildCiArtifactRequest(event bean.CiComp return request, nil } -func (impl *WorkflowEventProcessorImpl) BuildCIArtifactRequestForImageFromCR(imageDetails types.ImageDetail, region string, event bean.CiCompleteEvent, workflowId int) (*wrokflowDagBean.CiArtifactWebhookRequest, error) { +func (impl *WorkflowEventProcessorImpl) buildCIArtifactRequestForImageFromCR(imageDetails *registry.GenericImageDetail, event bean.CiCompleteEvent, workflowId int) (*wrokflowDagBean.CiArtifactWebhookRequest, error) { if event.TriggeredBy == 0 { event.TriggeredBy = 1 // system triggered event } request := &wrokflowDagBean.CiArtifactWebhookRequest{ - Image: globalUtil.ExtractEcrImage(*imageDetails.RegistryId, region, *imageDetails.RepositoryName, imageDetails.ImageTags[0]), - ImageDigest: *imageDetails.ImageDigest, + Image: imageDetails.Image, + ImageDigest: imageDetails.ImageDigest, DataSource: event.DataSource, PipelineName: event.PipelineName, UserId: event.TriggeredBy, diff --git a/pkg/k8s/K8sCommonService.go b/pkg/k8s/K8sCommonService.go index 09717b059b..6c8ecc2fb3 100644 --- a/pkg/k8s/K8sCommonService.go +++ b/pkg/k8s/K8sCommonService.go @@ -25,7 +25,7 @@ import ( "github.com/devtron-labs/devtron/api/bean" helmBean "github.com/devtron-labs/devtron/api/helm-app/service/bean" internalUtil "github.com/devtron-labs/devtron/internal/util" - "github.com/devtron-labs/devtron/pkg/argoApplication" + "github.com/devtron-labs/devtron/pkg/argoApplication/read" "github.com/devtron-labs/devtron/pkg/cluster" bean3 "github.com/devtron-labs/devtron/pkg/k8s/application/bean" "github.com/devtron-labs/devtron/util" @@ -71,7 +71,7 @@ type K8sCommonServiceImpl struct { K8sUtil *k8s.K8sServiceImpl clusterService cluster.ClusterService K8sApplicationServiceConfig *K8sApplicationServiceConfig - argoApplicationService argoApplication.ArgoApplicationService + argoApplicationReadService read.ArgoApplicationReadService } type K8sApplicationServiceConfig struct { BatchSize int `env:"BATCH_SIZE" envDefault:"5"` @@ -80,7 +80,7 @@ type K8sApplicationServiceConfig struct { func NewK8sCommonServiceImpl(Logger *zap.SugaredLogger, k8sUtils *k8s.K8sServiceImpl, clusterService cluster.ClusterService, - argoApplicationService argoApplication.ArgoApplicationService) *K8sCommonServiceImpl { + argoApplicationReadService read.ArgoApplicationReadService) *K8sCommonServiceImpl { cfg := &K8sApplicationServiceConfig{} err := env.Parse(cfg) if err != nil { @@ -91,7 +91,7 @@ func NewK8sCommonServiceImpl(Logger *zap.SugaredLogger, k8sUtils *k8s.K8sService K8sUtil: k8sUtils, clusterService: clusterService, K8sApplicationServiceConfig: cfg, - argoApplicationService: argoApplicationService, + argoApplicationReadService: argoApplicationReadService, } } @@ -190,7 +190,7 @@ func (impl *K8sCommonServiceImpl) GetRestConfigOfCluster(ctx context.Context, re //getting rest config by clusterId clusterId := request.ClusterId if len(request.ExternalArgoApplicationName) > 0 { - restConfig, err := impl.argoApplicationService.GetRestConfigForExternalArgo(ctx, clusterId, request.ExternalArgoApplicationName) + restConfig, err := impl.argoApplicationReadService.GetRestConfigForExternalArgo(ctx, clusterId, request.ExternalArgoApplicationName) if err != nil { impl.logger.Errorw("error in getting rest config", "err", err, "clusterId", clusterId, "externalArgoApplicationName", request.ExternalArgoApplicationName) return nil, err @@ -457,7 +457,7 @@ func (impl *K8sCommonServiceImpl) GetCoreClientByClusterId(clusterId int) (*kube } func (impl *K8sCommonServiceImpl) GetCoreClientByClusterIdForExternalArgoApps(req *cluster.EphemeralContainerRequest) (*kubernetes.Clientset, *clientV1.CoreV1Client, error) { - restConfig, err := impl.argoApplicationService.GetRestConfigForExternalArgo(context.Background(), req.ClusterId, req.ExternalArgoApplicationName) + restConfig, err := impl.argoApplicationReadService.GetRestConfigForExternalArgo(context.Background(), req.ClusterId, req.ExternalArgoApplicationName) if err != nil { impl.logger.Errorw("error in getting rest config", "err", err, "clusterId", req.ClusterId, "externalArgoApplicationName", req.ExternalArgoApplicationName) } diff --git a/pkg/k8s/application/k8sApplicationService.go b/pkg/k8s/application/k8sApplicationService.go index 39b1902b17..af5b7e33f2 100644 --- a/pkg/k8s/application/k8sApplicationService.go +++ b/pkg/k8s/application/k8sApplicationService.go @@ -25,7 +25,7 @@ import ( "github.com/devtron-labs/devtron/api/helm-app/gRPC" client "github.com/devtron-labs/devtron/api/helm-app/service" "github.com/devtron-labs/devtron/api/helm-app/service/bean" - bean4 "github.com/devtron-labs/devtron/pkg/argoApplication/bean" + "github.com/devtron-labs/devtron/pkg/argoApplication/helper" "github.com/devtron-labs/devtron/pkg/auth/authorisation/casbin" clientErrors "github.com/devtron-labs/devtron/pkg/errors" "github.com/devtron-labs/devtron/pkg/fluxApplication" @@ -45,7 +45,6 @@ import ( yamlUtil "github.com/devtron-labs/common-lib/utils/yaml" "github.com/devtron-labs/devtron/api/connector" "github.com/devtron-labs/devtron/api/helm-app/openapiClient" - "github.com/devtron-labs/devtron/pkg/argoApplication" "github.com/devtron-labs/devtron/pkg/cluster" "github.com/devtron-labs/devtron/pkg/cluster/repository" "github.com/devtron-labs/devtron/pkg/k8s" @@ -81,6 +80,8 @@ type K8sApplicationService interface { GetAllApiResourceGVKWithoutAuthorization(ctx context.Context, clusterId int) (*k8s2.GetAllApiResourcesResponse, error) GetAllApiResources(ctx context.Context, clusterId int, isSuperAdmin bool, userId int32) (*k8s2.GetAllApiResourcesResponse, error) GetResourceList(ctx context.Context, token string, request *k8s.ResourceRequestBean, validateResourceAccess func(token string, clusterName string, request k8s.ResourceRequestBean, casbinAction string) bool) (*k8s2.ClusterResourceListMap, error) + GetResourceListWithRestConfig(ctx context.Context, token string, request *k8s.ResourceRequestBean, validateResourceAccess func(token string, clusterName string, request k8s.ResourceRequestBean, casbinAction string) bool, + restConfig *rest.Config, clusterName string) (*k8s2.ClusterResourceListMap, error) ApplyResources(ctx context.Context, token string, request *k8s2.ApplyResourcesRequest, resourceRbacHandler func(token string, clusterName string, request k8s.ResourceRequestBean, casbinAction string) bool) ([]*k8s2.ApplyResourcesResponse, error) CreatePodEphemeralContainers(req *cluster.EphemeralContainerRequest) error TerminatePodEphemeralContainer(req cluster.EphemeralContainerRequest) (bool, error) @@ -90,7 +91,6 @@ type K8sApplicationService interface { DeleteResourceWithAudit(ctx context.Context, request *k8s.ResourceRequestBean, userId int32) (*k8s2.ManifestResponse, error) GetUrlsByBatchForIngress(ctx context.Context, resp []k8s.BatchResourceResponse) []interface{} ValidateFluxResourceRequest(ctx context.Context, appIdentifier *bean2.FluxAppIdentifier, request *k8s2.K8sRequestBean) (bool, error) - ValidateArgoResourceRequest(ctx context.Context, appIdentifier *bean4.ArgoAppIdentifier, request *k8s2.K8sRequestBean) (bool, error) } type K8sApplicationServiceImpl struct { @@ -106,15 +106,15 @@ type K8sApplicationServiceImpl struct { ephemeralContainerService cluster.EphemeralContainerService ephemeralContainerRepository repository.EphemeralContainersRepository ephemeralContainerConfig *EphemeralContainerConfig - argoApplicationService argoApplication.ArgoApplicationService - fluxApplicationService fluxApplication.FluxApplicationService + //argoApplicationService argoApplication.ArgoApplicationService + fluxApplicationService fluxApplication.FluxApplicationService } func NewK8sApplicationServiceImpl(Logger *zap.SugaredLogger, clusterService cluster.ClusterService, pump connector.Pump, helmAppService client.HelmAppService, K8sUtil *k8s2.K8sServiceImpl, aCDAuthConfig *util3.ACDAuthConfig, K8sResourceHistoryService kubernetesResourceAuditLogs.K8sResourceHistoryService, k8sCommonService k8s.K8sCommonService, terminalSession terminal.TerminalSessionHandler, ephemeralContainerService cluster.EphemeralContainerService, ephemeralContainerRepository repository.EphemeralContainersRepository, - argoApplicationService argoApplication.ArgoApplicationService, fluxApplicationService fluxApplication.FluxApplicationService) (*K8sApplicationServiceImpl, error) { + fluxApplicationService fluxApplication.FluxApplicationService) (*K8sApplicationServiceImpl, error) { ephemeralContainerConfig := &EphemeralContainerConfig{} err := env.Parse(ephemeralContainerConfig) if err != nil { @@ -134,8 +134,8 @@ func NewK8sApplicationServiceImpl(Logger *zap.SugaredLogger, clusterService clus ephemeralContainerService: ephemeralContainerService, ephemeralContainerRepository: ephemeralContainerRepository, ephemeralContainerConfig: ephemeralContainerConfig, - argoApplicationService: argoApplicationService, - fluxApplicationService: fluxApplicationService, + //argoApplicationService: argoApplicationService, + fluxApplicationService: fluxApplicationService, }, nil } @@ -249,7 +249,7 @@ func (impl *K8sApplicationServiceImpl) ValidatePodLogsRequestQuery(r *http.Reque request.DeploymentType = deploymentType // Validate App Id if request.AppType == bean3.ArgoAppType { - appIdentifier, err := argoApplication.DecodeExternalArgoAppId(appId) + appIdentifier, err := helper.DecodeExternalArgoAppId(appId) if err != nil { impl.logger.Errorw(bean3.AppIdDecodingError, "err", err, "appId", appId) return nil, err @@ -356,7 +356,7 @@ func (impl *K8sApplicationServiceImpl) ValidateTerminalRequestQuery(r *http.Requ request.ClusterId = fluxAppIdentifier.ClusterId } else if appType == bean3.ArgoAppType { - appIdentifier, err := argoApplication.DecodeExternalArgoAppId(request.ApplicationId) + appIdentifier, err := helper.DecodeExternalArgoAppId(request.ApplicationId) if err != nil { impl.logger.Errorw(bean3.InvalidAppId, "err", err, "appId", request.ApplicationId) return nil, nil, err @@ -364,7 +364,7 @@ func (impl *K8sApplicationServiceImpl) ValidateTerminalRequestQuery(r *http.Requ resourceRequestBean.ExternalArgoApplicationName = appIdentifier.AppName resourceRequestBean.ClusterId = appIdentifier.ClusterId request.ClusterId = appIdentifier.ClusterId - //request.ExternalArgoApplicationName = appIdentifier.AppName + request.ExternalArgoApplicationName = appIdentifier.AppName } } else { // Validate Cluster Id @@ -522,39 +522,6 @@ func (impl *K8sApplicationServiceImpl) validateResourceRequest(ctx context.Conte } return impl.validateContainerNameIfReqd(valid, request, app), nil } -func (impl *K8sApplicationServiceImpl) ValidateArgoResourceRequest(ctx context.Context, appIdentifier *bean4.ArgoAppIdentifier, request *k8s2.K8sRequestBean) (bool, error) { - app, err := impl.argoApplicationService.GetAppDetail(appIdentifier.AppName, appIdentifier.Namespace, appIdentifier.ClusterId) - if err != nil { - impl.logger.Errorw("error in getting app detail", "err", err, "appDetails", appIdentifier) - apiError := clientErrors.ConvertToApiError(err) - if apiError != nil { - err = apiError - } - return false, err - } - - valid := false - - for _, node := range app.ResourceTree.Nodes { - nodeDetails := k8s2.ResourceIdentifier{ - Name: node.Name, - Namespace: node.Namespace, - GroupVersionKind: schema.GroupVersionKind{ - Group: node.Group, - Version: node.Version, - Kind: node.Kind, - }, - } - if nodeDetails == request.ResourceIdentifier { - valid = true - break - } - } - appDetail := &gRPC.AppDetail{ - ResourceTreeResponse: app.ResourceTree, - } - return impl.validateContainerNameIfReqd(valid, request, appDetail), nil -} func (impl *K8sApplicationServiceImpl) ValidateFluxResourceRequest(ctx context.Context, appIdentifier *bean2.FluxAppIdentifier, request *k8s2.K8sRequestBean) (bool, error) { app, err := impl.fluxApplicationService.GetFluxAppDetail(ctx, appIdentifier) @@ -766,6 +733,13 @@ func (impl *K8sApplicationServiceImpl) GetResourceList(ctx context.Context, toke impl.logger.Errorw("error in getting rest config by cluster Id", "err", err, "clusterId", request.ClusterId) return resourceList, err } + return impl.GetResourceListWithRestConfig(ctx, token, request, validateResourceAccess, restConfig, clusterBean.ClusterName) +} + +func (impl *K8sApplicationServiceImpl) GetResourceListWithRestConfig(ctx context.Context, token string, request *k8s.ResourceRequestBean, + validateResourceAccess func(token string, clusterName string, request k8s.ResourceRequestBean, casbinAction string) bool, + restConfig *rest.Config, clusterName string) (*k8s2.ClusterResourceListMap, error) { + resourceList := &k8s2.ClusterResourceListMap{} k8sRequest := request.K8sRequest // store the copy of requested resource identifier resourceIdentifierCloned := k8sRequest.ResourceIdentifier @@ -785,22 +759,13 @@ func (impl *K8sApplicationServiceImpl) GetResourceList(ctx context.Context, toke resourceIdentifier.GroupVersionKind = schema.GroupVersionKind{Group: group, Kind: kind} } k8sRequest.ResourceIdentifier = resourceIdentifier - return validateResourceAccess(token, clusterBean.ClusterName, *request, casbin.ActionGet) + return validateResourceAccess(token, clusterName, *request, casbin.ActionGet) } resourceList, err = impl.K8sUtil.BuildK8sObjectListTableData(&resp.Resources, namespaced, request.K8sRequest.ResourceIdentifier.GroupVersionKind, false, checkForResourceCallback) if err != nil { impl.logger.Errorw("error on parsing for k8s resource", "err", err) return resourceList, err } - // Not used in FE side - - //k8sServerVersion, err := impl.k8sCommonService.GetK8sServerVersion(clusterId) - //if err != nil { - // impl.logger.Errorw("error in getting k8s server version", "clusterId", clusterId, "err", err) - // // return nil, err - //} else { - // resourceList.ServerVersion = k8sServerVersion.String() - //} return resourceList, nil } diff --git a/pkg/pipeline/AppDeploymentTypeChangeManager.go b/pkg/pipeline/AppDeploymentTypeChangeManager.go index a6130a2357..714bc8720f 100644 --- a/pkg/pipeline/AppDeploymentTypeChangeManager.go +++ b/pkg/pipeline/AppDeploymentTypeChangeManager.go @@ -744,7 +744,7 @@ func (impl *AppDeploymentTypeChangeManagerImpl) fetchDeletedApp(ctx context.Cont impl.logger.Errorw("error in getting application detail", "err", err, "deploymentAppName", pipeline.DeploymentAppName) } - if err != nil && checkAppReleaseNotExist(err) { + if err != nil && CheckAppReleaseNotExist(err) { successfulPipelines = impl.appendToDeploymentChangeStatusList( successfulPipelines, pipeline, diff --git a/pkg/pipeline/CiService.go b/pkg/pipeline/CiService.go index c960782585..eff0020693 100644 --- a/pkg/pipeline/CiService.go +++ b/pkg/pipeline/CiService.go @@ -21,6 +21,8 @@ import ( "errors" "fmt" "github.com/caarlos0/env" + "github.com/devtron-labs/common-lib/utils" + bean3 "github.com/devtron-labs/common-lib/utils/bean" "github.com/devtron-labs/devtron/pkg/infraConfig" "github.com/devtron-labs/devtron/pkg/pipeline/adapter" "github.com/devtron-labs/devtron/pkg/pipeline/bean/CiPipeline" @@ -78,6 +80,7 @@ type CiServiceImpl struct { eventClient client.EventClient eventFactory client.EventFactory ciPipelineRepository pipelineConfig.CiPipelineRepository + ciArtifactRepository repository5.CiArtifactRepository pipelineStageService PipelineStageService userService user.UserService ciTemplateService CiTemplateService @@ -99,6 +102,7 @@ func NewCiServiceImpl(Logger *zap.SugaredLogger, workflowService WorkflowService ciWorkflowRepository pipelineConfig.CiWorkflowRepository, eventClient client.EventClient, eventFactory client.EventFactory, ciPipelineRepository pipelineConfig.CiPipelineRepository, + ciArtifactRepository repository5.CiArtifactRepository, pipelineStageService PipelineStageService, userService user.UserService, ciTemplateService CiTemplateService, appCrudOperationService app.AppCrudOperationService, envRepository repository1.EnvironmentRepository, appRepository appRepository.AppRepository, @@ -122,6 +126,7 @@ func NewCiServiceImpl(Logger *zap.SugaredLogger, workflowService WorkflowService eventClient: eventClient, eventFactory: eventFactory, ciPipelineRepository: ciPipelineRepository, + ciArtifactRepository: ciArtifactRepository, pipelineStageService: pipelineStageService, userService: userService, ciTemplateService: ciTemplateService, @@ -158,15 +163,65 @@ func (impl *CiServiceImpl) GetCiMaterials(pipelineId int, ciMaterials []*pipelin } } -func (impl *CiServiceImpl) handleRuntimeParamsValidations(trigger types.Trigger, ciMaterials []*pipelineConfig.CiPipelineMaterial) error { +func (impl *CiServiceImpl) handleRuntimeParamsValidations(trigger types.Trigger, ciMaterials []*pipelineConfig.CiPipelineMaterial, workflowRequest *types.WorkflowRequest) error { + // externalCi artifact is meant only for CI_JOB + if trigger.PipelineType != string(CiPipeline.CI_JOB) { + return nil + } + // checking if user has given run time parameters for externalCiArtifact, if given then sending git material to Ci-Runner externalCiArtifact, exists := trigger.ExtraEnvironmentVariables[CiPipeline.ExtraEnvVarExternalCiArtifactKey] // validate externalCiArtifact as docker image if exists { + externalCiArtifact = strings.TrimSpace(externalCiArtifact) if !strings.Contains(externalCiArtifact, ":") { - impl.Logger.Errorw("validation error", "externalCiArtifact", externalCiArtifact) - return fmt.Errorf("invalid image name given in externalCiArtifact") + if utils.IsValidDockerTagName(externalCiArtifact) { + fullImageUrl, err := utils.BuildDockerImagePath(bean3.DockerRegistryInfo{ + DockerImageTag: externalCiArtifact, + DockerRegistryId: workflowRequest.DockerRegistryId, + DockerRegistryType: workflowRequest.DockerRegistryType, + DockerRegistryURL: workflowRequest.DockerRegistryURL, + DockerRepository: workflowRequest.DockerRepository, + }) + if err != nil { + impl.Logger.Errorw("Error in building docker image", "err", err) + return err + } + externalCiArtifact = fullImageUrl + } else { + impl.Logger.Errorw("validation error", "externalCiArtifact", externalCiArtifact) + return fmt.Errorf("invalid image name or url given in externalCiArtifact") + } + + } + + trigger.ExtraEnvironmentVariables[CiPipeline.ExtraEnvVarExternalCiArtifactKey] = externalCiArtifact + + var artifactExists bool + var err error + if trigger.ExtraEnvironmentVariables[CiPipeline.ExtraEnvVarImageDigestKey] == "" { + artifactExists, err = impl.ciArtifactRepository.IfArtifactExistByImage(externalCiArtifact, trigger.PipelineId) + if err != nil { + impl.Logger.Errorw("error in fetching ci artifact", "err", err) + return err + } + if artifactExists { + impl.Logger.Errorw("ci artifact already exists with same image name", "artifact", externalCiArtifact) + return fmt.Errorf("ci artifact already exists with same image name") + } + } else { + artifactExists, err = impl.ciArtifactRepository.IfArtifactExistByImageDigest(trigger.ExtraEnvironmentVariables[CiPipeline.ExtraEnvVarImageDigestKey], externalCiArtifact, trigger.PipelineId) + if err != nil { + impl.Logger.Errorw("error in fetching ci artifact", "err", err) + return err + } + if artifactExists { + impl.Logger.Errorw("ci artifact already exists with same digest", "artifact", externalCiArtifact) + return fmt.Errorf("ci artifact already exists with same digest") + } + } + } if trigger.PipelineType == string(CiPipeline.CI_JOB) && len(ciMaterials) != 0 && !exists && externalCiArtifact == "" { ciMaterials[0].GitMaterial = nil @@ -181,10 +236,7 @@ func (impl *CiServiceImpl) TriggerCiPipeline(trigger types.Trigger) (int, error) if err != nil { return 0, err } - err = impl.handleRuntimeParamsValidations(trigger, ciMaterials) - if err != nil { - return 0, err - } + ciPipelineScripts, err := impl.ciPipelineRepository.FindCiScriptsByCiPipelineId(trigger.PipelineId) if err != nil && !util.IsErrNoRows(err) { return 0, err @@ -265,6 +317,17 @@ func (impl *CiServiceImpl) TriggerCiPipeline(trigger types.Trigger) (int, error) impl.Logger.Errorw("make workflow req", "err", err) return 0, err } + err = impl.handleRuntimeParamsValidations(trigger, ciMaterials, workflowRequest) + if err != nil { + savedCiWf.Status = pipelineConfig.WorkflowAborted + savedCiWf.Message = err.Error() + err1 := impl.ciWorkflowRepository.UpdateWorkFlow(savedCiWf) + if err1 != nil { + impl.Logger.Errorw("could not save workflow, after failing due to conflicting image tag") + } + return 0, err + } + workflowRequest.Scope = scope workflowRequest.BuildxCacheModeMin = impl.buildxCacheFlags.BuildxCacheModeMin workflowRequest.AsyncBuildxCacheExport = impl.buildxCacheFlags.AsyncBuildxCacheExport diff --git a/pkg/pipeline/PipelineBuilder.go b/pkg/pipeline/PipelineBuilder.go index 7fdc24e702..d47772e3c6 100644 --- a/pkg/pipeline/PipelineBuilder.go +++ b/pkg/pipeline/PipelineBuilder.go @@ -284,7 +284,7 @@ type PipelineStrategy struct { Default bool `json:"default"` } -func checkAppReleaseNotExist(err error) bool { +func CheckAppReleaseNotExist(err error) bool { // RELEASE_NOT_EXIST check for helm App and NOT_FOUND check for argo app return strings.Contains(err.Error(), bean.NOT_FOUND) || strings.Contains(err.Error(), bean.RELEASE_NOT_EXIST) } diff --git a/pkg/pipeline/WebhookService.go b/pkg/pipeline/WebhookService.go index 1a461a9435..5b4b3446f6 100644 --- a/pkg/pipeline/WebhookService.go +++ b/pkg/pipeline/WebhookService.go @@ -21,8 +21,8 @@ import ( "encoding/json" "fmt" "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" - "github.com/aws/aws-sdk-go-v2/service/ecr/types" pubsub "github.com/devtron-labs/common-lib/pubsub-lib" + "github.com/devtron-labs/common-lib/utils/registry" "github.com/devtron-labs/devtron/internal/sql/repository" "github.com/devtron-labs/devtron/internal/sql/repository/pipelineConfig" "github.com/devtron-labs/devtron/pkg/pipeline/bean" @@ -50,14 +50,10 @@ type ExternalCiWebhookDto struct { AppName string `json:"appName"` IsArtifactUploaded bool `json:"isArtifactUploaded"` FailureReason string `json:"failureReason"` - ImageDetailsFromCR *ImageDetailsFromCR `json:"imageDetailsFromCR"` + ImageDetailsFromCR json.RawMessage `json:"imageDetailsFromCR"` PluginRegistryArtifactDetails map[string][]string `json:"PluginRegistryArtifactDetails"` PluginArtifactStage string `json:"pluginArtifactStage"` } -type ImageDetailsFromCR struct { - ImageDetails []types.ImageDetail `json:"imageDetails"` - Region string `json:"region"` -} type CiArtifactWebhookRequest struct { Image string `json:"image" validate:"required"` @@ -75,7 +71,7 @@ type CiArtifactWebhookRequest struct { type WebhookService interface { AuthenticateExternalCiWebhook(apiKey string) (int, error) - HandleMultipleImagesFromEvent(imageDetails []types.ImageDetail, ciWorkflowId int) (map[string]*pipelineConfig.CiWorkflow, error) + HandleMultipleImagesFromEvent(imageDetails []*registry.GenericImageDetail, ciWorkflowId int) (map[string]*pipelineConfig.CiWorkflow, error) GetTriggerValidateFuncs() []pubsub.ValidateMsg } @@ -136,7 +132,7 @@ func (impl WebhookServiceImpl) AuthenticateExternalCiWebhook(apiKey string) (int } // HandleMultipleImagesFromEvent handles multiple images from plugin and creates ci workflow for n-1 images for mapping in ci_artifact -func (impl *WebhookServiceImpl) HandleMultipleImagesFromEvent(imageDetails []types.ImageDetail, ciWorkflowId int) (map[string]*pipelineConfig.CiWorkflow, error) { +func (impl *WebhookServiceImpl) HandleMultipleImagesFromEvent(imageDetails []*registry.GenericImageDetail, ciWorkflowId int) (map[string]*pipelineConfig.CiWorkflow, error) { ciWorkflow, err := impl.ciWorkflowRepository.FindById(ciWorkflowId) if err != nil { impl.logger.Errorw("error in finding ci workflow by id ", "err", err, "ciWorkFlowId", ciWorkflowId) @@ -146,7 +142,7 @@ func (impl *WebhookServiceImpl) HandleMultipleImagesFromEvent(imageDetails []typ // creating n-1 workflows for rest images, oldest will be mapped to original workflow id. digestWorkflowMap := make(map[string]*pipelineConfig.CiWorkflow) // mapping oldest to original ciworkflowId - digestWorkflowMap[*imageDetails[0].ImageDigest] = ciWorkflow + digestWorkflowMap[imageDetails[0].GetGenericImageDetailIdentifier()] = ciWorkflow for i := 1; i < len(imageDetails); i++ { workflow := &pipelineConfig.CiWorkflow{ Name: ciWorkflow.Name + fmt.Sprintf("-child-%d", i), @@ -170,7 +166,7 @@ func (impl *WebhookServiceImpl) HandleMultipleImagesFromEvent(imageDetails []typ impl.logger.Errorw("error in saving workflow for child workflow", "err", err, "parentCiWorkflowId", ciWorkflowId) return nil, err } - digestWorkflowMap[*imageDetails[i].ImageDigest] = workflow + digestWorkflowMap[imageDetails[i].GetGenericImageDetailIdentifier()] = workflow } return digestWorkflowMap, nil diff --git a/pkg/plugin/GlobalPluginService.go b/pkg/plugin/GlobalPluginService.go index 55ff942789..5423ab22b2 100644 --- a/pkg/plugin/GlobalPluginService.go +++ b/pkg/plugin/GlobalPluginService.go @@ -24,6 +24,7 @@ import ( "github.com/devtron-labs/devtron/pkg/auth/user" "github.com/devtron-labs/devtron/pkg/auth/user/bean" repository2 "github.com/devtron-labs/devtron/pkg/pipeline/repository" + "github.com/devtron-labs/devtron/pkg/plugin/adaptor" bean2 "github.com/devtron-labs/devtron/pkg/plugin/bean" helper2 "github.com/devtron-labs/devtron/pkg/plugin/helper" "github.com/devtron-labs/devtron/pkg/plugin/repository" @@ -31,8 +32,8 @@ import ( "github.com/devtron-labs/devtron/pkg/sql" "github.com/go-pg/pg" "go.uber.org/zap" + "golang.org/x/mod/semver" "net/http" - "strconv" "strings" "time" ) @@ -73,9 +74,11 @@ type GlobalPluginService interface { GetDetailedPluginInfoByPluginId(pluginId int) (*bean2.PluginMetadataDto, error) GetAllDetailedPluginInfo() ([]*bean2.PluginMetadataDto, error) + CreatePluginOrVersions(pluginDto *bean2.PluginParentMetadataDto, userId int32) (int, error) ListAllPluginsV2(filter *bean2.PluginsListFilter) (*bean2.PluginsDto, error) GetPluginDetailV2(pluginVersionIds, parentPluginIds []int, fetchAllVersionDetails bool) (*bean2.PluginsDto, error) GetAllUniqueTags() (*bean2.PluginTagsDto, error) + GetAllPluginMinData() ([]*bean2.PluginMinDto, error) MigratePluginData() error } @@ -429,7 +432,7 @@ func (impl *GlobalPluginServiceImpl) validatePluginRequest(pluginReq *bean2.Plug return errors.New("invalid plugin type, should be of the type PRESET or SHARED") } - plugins, err := impl.globalPluginRepository.GetMetaDataForAllPlugins() + plugins, err := impl.globalPluginRepository.GetAllPluginMinData() if err != nil { impl.logger.Errorw("error in getting all plugins", "err", err) return err @@ -670,33 +673,10 @@ func (impl *GlobalPluginServiceImpl) UpdatePluginPipelineScript(dbPluginPipeline func (impl *GlobalPluginServiceImpl) saveDeepPluginStepData(pluginMetadataId int, pluginStepsReq []*bean2.PluginStepsDto, userId int32, tx *pg.Tx) error { for _, pluginStep := range pluginStepsReq { - pluginStepData := &repository.PluginStep{ - PluginId: pluginMetadataId, - Name: pluginStep.Name, - Description: pluginStep.Description, - Index: pluginStep.Index, - StepType: pluginStep.StepType, - RefPluginId: pluginStep.RefPluginId, - OutputDirectoryPath: pluginStep.OutputDirectoryPath, - DependentOnStep: pluginStep.DependentOnStep, - AuditLog: sql.NewDefaultAuditLog(userId), - } + pluginStepData := adaptor.GetPluginStepDbObject(pluginStep, pluginMetadataId, userId) //get the script saved for this plugin step if pluginStep.PluginPipelineScript != nil { - pluginPipelineScript := &repository.PluginPipelineScript{ - Script: pluginStep.PluginPipelineScript.Script, - StoreScriptAt: pluginStep.PluginPipelineScript.StoreScriptAt, - Type: pluginStep.PluginPipelineScript.Type, - DockerfileExists: pluginStep.PluginPipelineScript.DockerfileExists, - MountPath: pluginStep.PluginPipelineScript.MountPath, - MountCodeToContainer: pluginStep.PluginPipelineScript.MountCodeToContainer, - MountCodeToContainerPath: pluginStep.PluginPipelineScript.MountCodeToContainerPath, - MountDirectoryFromHost: pluginStep.PluginPipelineScript.MountDirectoryFromHost, - ContainerImagePath: pluginStep.PluginPipelineScript.ContainerImagePath, - ImagePullSecretType: pluginStep.PluginPipelineScript.ImagePullSecretType, - ImagePullSecret: pluginStep.PluginPipelineScript.ImagePullSecret, - AuditLog: sql.NewDefaultAuditLog(userId), - } + pluginPipelineScript := adaptor.GetPluginPipelineScriptDbObject(pluginStep.PluginPipelineScript, userId) pluginPipelineScript, err := impl.globalPluginRepository.SavePluginPipelineScript(pluginPipelineScript, tx) if err != nil { impl.logger.Errorw("error in saving plugin pipeline script", "pluginPipelineScript", pluginPipelineScript, "err", err) @@ -719,23 +699,7 @@ func (impl *GlobalPluginServiceImpl) saveDeepPluginStepData(pluginMetadataId int pluginStep.Id = pluginStepData.Id //create entry in plugin_step_variable for _, pluginStepVariable := range pluginStep.PluginStepVariable { - pluginStepVariableData := &repository.PluginStepVariable{ - PluginStepId: pluginStepData.Id, - Name: pluginStepVariable.Name, - Format: pluginStepVariable.Format, - Description: pluginStepVariable.Description, - IsExposed: pluginStepVariable.IsExposed, - AllowEmptyValue: pluginStepVariable.AllowEmptyValue, - DefaultValue: pluginStepVariable.DefaultValue, - Value: pluginStepVariable.Value, - VariableType: pluginStepVariable.VariableType, - ValueType: pluginStepVariable.ValueType, - PreviousStepIndex: pluginStepVariable.PreviousStepIndex, - VariableStepIndex: pluginStepVariable.VariableStepIndex, - VariableStepIndexInPlugin: pluginStepVariable.VariableStepIndexInPlugin, - ReferenceVariableName: pluginStepVariable.ReferenceVariableName, - AuditLog: sql.NewDefaultAuditLog(userId), - } + pluginStepVariableData := adaptor.GetPluginStepVariableDbObject(pluginStepData.Id, pluginStepVariable, userId) pluginStepVariableData, err = impl.globalPluginRepository.SavePluginStepVariables(pluginStepVariableData, tx) if err != nil { impl.logger.Errorw("error in saving plugin step variable", "pluginStepVariableData", pluginStepVariableData, "err", err) @@ -744,14 +708,7 @@ func (impl *GlobalPluginServiceImpl) saveDeepPluginStepData(pluginMetadataId int pluginStepVariable.Id = pluginStepVariableData.Id //create entry in plugin_step_condition for _, pluginStepCondition := range pluginStepVariable.PluginStepCondition { - pluginStepConditionData := &repository.PluginStepCondition{ - PluginStepId: pluginStepData.Id, - ConditionVariableId: pluginStepVariableData.Id, - ConditionType: pluginStepCondition.ConditionType, - ConditionalOperator: pluginStepCondition.ConditionalOperator, - ConditionalValue: pluginStepCondition.ConditionalValue, - AuditLog: sql.NewDefaultAuditLog(userId), - } + pluginStepConditionData := adaptor.GetPluginStepConditionDbObject(pluginStepData.Id, pluginStepVariableData.Id, pluginStepCondition, userId) pluginStepConditionData, err = impl.globalPluginRepository.SavePluginStepConditions(pluginStepConditionData, tx) if err != nil { impl.logger.Errorw("error in saving plugin step condition", "pluginStepConditionData", pluginStepConditionData, "err", err) @@ -768,7 +725,6 @@ func (impl *GlobalPluginServiceImpl) updatePlugin(pluginUpdateReq *bean2.PluginM if len(pluginUpdateReq.Type) == 0 { return nil, errors.New("invalid plugin type, should be of the type PRESET or SHARED") } - dbConnection := impl.globalPluginRepository.GetConnection() tx, err := dbConnection.Begin() if err != nil { @@ -856,6 +812,7 @@ func (impl *GlobalPluginServiceImpl) updatePlugin(pluginUpdateReq *bean2.PluginM return nil, err } } + if len(pluginStepsToUpdate) > 0 { err = impl.updateDeepPluginStepData(pluginStepsToUpdate, pluginStepVariables, pluginStepConditions, pluginSteps, userId, tx) if err != nil { @@ -1386,7 +1343,6 @@ func filterPluginStepData(existingPluginStepsInDb []*repository.PluginStep, plug } else { return nil, nil, pluginStepUpdateReq } - return newPluginStepsToCreate, pluginStepsToRemove, pluginStepsToUpdate } @@ -1805,28 +1761,59 @@ func (impl *GlobalPluginServiceImpl) ListAllPluginsV2(filter *bean2.PluginsListF return pluginDetails, nil } +func (impl *GlobalPluginServiceImpl) validateDetailRequest(pluginVersions []*repository.PluginMetadata, pluginVersionIds, parentPluginIds []int) error { + pluginVersionsIdMap, pluginParentIdMap := make(map[int]bool, len(pluginVersionIds)), make(map[int]bool, len(parentPluginIds)) + allPlugins, err := impl.globalPluginRepository.GetAllPluginMinData() + if err != nil { + impl.logger.Errorw("validateDetailRequest, error in getting all plugins parent metadata", "err", err) + return err + } + for _, pluginVersion := range pluginVersions { + pluginVersionsIdMap[pluginVersion.Id] = true + } + for _, plugin := range allPlugins { + pluginParentIdMap[plugin.Id] = true + } + for _, versionId := range pluginVersionIds { + if _, ok := pluginVersionsIdMap[versionId]; !ok { + errorMsg := fmt.Sprintf("there are some plugin version ids in request that do not exist:- %d", versionId) + return util.GetApiError(http.StatusBadRequest, errorMsg, errorMsg) + } + } + for _, pluginId := range parentPluginIds { + if _, ok := pluginParentIdMap[pluginId]; !ok { + errorMsg := fmt.Sprintf("there are some plugin parent ids in request that do not exist %d", pluginId) + return util.GetApiError(http.StatusBadRequest, errorMsg, errorMsg) + } + } + return nil +} // GetPluginDetailV2 returns all details of the of a plugin version according to the pluginVersionIds and parentPluginIds // provided by user, and minimal data for all versions of that plugin. func (impl *GlobalPluginServiceImpl) GetPluginDetailV2(pluginVersionIds, parentPluginIds []int, fetchAllVersionDetails bool) (*bean2.PluginsDto, error) { + var err error + pluginVersionsMetadata, err := impl.globalPluginRepository.GetMetaDataForAllPlugins() + if err != nil { + impl.logger.Errorw("GetPluginDetailV2, error in getting all plugins versions metadata", "err", err) + return nil, err + } + err = impl.validateDetailRequest(pluginVersionsMetadata, pluginVersionIds, parentPluginIds) + if err != nil { + return nil, err + } pluginParentMetadataDtos := make([]*bean2.PluginParentMetadataDto, 0, len(pluginVersionIds)+len(parentPluginIds)) if len(pluginVersionIds) == 0 && len(parentPluginIds) == 0 { - return nil, &util.ApiError{HttpStatusCode: http.StatusBadRequest, Code: strconv.Itoa(http.StatusBadRequest), InternalMessage: bean2.NoPluginOrParentIdProvidedErr, UserMessage: bean2.NoPluginOrParentIdProvidedErr} + return nil, util.GetApiError(http.StatusBadRequest, bean2.NoPluginOrParentIdProvidedErr, bean2.NoPluginOrParentIdProvidedErr) } pluginVersionIdsMap, parentPluginIdsMap := helper2.GetPluginVersionAndParentPluginIdsMap(pluginVersionIds, parentPluginIds) - var err error pluginParentMetadataIds := make([]int, 0, len(pluginVersionIds)+len(parentPluginIds)) pluginVersionsIdToInclude := make(map[int]bool, len(pluginVersionIds)+len(parentPluginIds)) - pluginVersionsMetadata, err := impl.globalPluginRepository.GetMetaDataForAllPlugins() - if err != nil { - impl.logger.Errorw("GetPluginDetailV2, error in getting all plugins versions metadata", "err", err) - return nil, err - } filteredPluginVersionMetadata := helper2.GetPluginVersionsMetadataByVersionAndParentPluginIds(pluginVersionsMetadata, pluginVersionIdsMap, parentPluginIdsMap) if len(filteredPluginVersionMetadata) == 0 { - return nil, &util.ApiError{HttpStatusCode: http.StatusNotFound, Code: strconv.Itoa(http.StatusNotFound), InternalMessage: bean2.NoPluginFoundForThisSearchQueryErr, UserMessage: bean2.NoPluginFoundForThisSearchQueryErr} + return nil, util.GetApiError(http.StatusNotFound, bean2.NoPluginFoundForThisSearchQueryErr, bean2.NoPluginFoundForThisSearchQueryErr) } for _, version := range filteredPluginVersionMetadata { _, found := pluginVersionIdsMap[version.Id] @@ -1884,7 +1871,6 @@ func (impl *GlobalPluginServiceImpl) MigratePluginData() error { // MigratePluginDataToParentPluginMetadata migrates pre-existing plugin metadata from plugin_metadata table into plugin_parent_metadata table, // and also populate plugin_parent_metadata_id in plugin_metadata. -// this operation will happen only once when the get all plugin list v2 api is being called, returns error if any func (impl *GlobalPluginServiceImpl) MigratePluginDataToParentPluginMetadata(pluginsMetadata []*repository.PluginMetadata) error { dbConnection := impl.globalPluginRepository.GetConnection() tx, err := dbConnection.Begin() @@ -1948,3 +1934,303 @@ func (impl *GlobalPluginServiceImpl) MigratePluginDataToParentPluginMetadata(plu } return nil } + +func (impl *GlobalPluginServiceImpl) GetAllPluginMinData() ([]*bean2.PluginMinDto, error) { + pluginsParentMinData, err := impl.globalPluginRepository.GetAllPluginMinData() + if err != nil { + impl.logger.Errorw("GetAllPluginMinData, error in getting all plugin parent metadata min data", "err", err) + return nil, err + } + pluginMinList := make([]*bean2.PluginMinDto, 0, len(pluginsParentMinData)) + for _, item := range pluginsParentMinData { + //since creating new version of preset plugin is disabled for end user, hence ignoring PRESET plugin in min list + if item.Type == repository.PLUGIN_TYPE_PRESET { + continue + } + pluginMinList = append(pluginMinList, bean2.NewPluginMinDto().WithParentPluginId(item.Id).WithPluginName(item.Name).WithIcon(item.Icon)) + } + return pluginMinList, nil +} + +func (impl *GlobalPluginServiceImpl) checkValidationOnPluginNameAndIdentifier(pluginReq *bean2.PluginParentMetadataDto) error { + plugins, err := impl.globalPluginRepository.GetAllPluginMinData() + if err != nil { + impl.logger.Errorw("error in getting all plugins", "err", err) + return err + } + for _, plugin := range plugins { + if plugin.Identifier == pluginReq.PluginIdentifier { + return util.GetApiError(http.StatusConflict, bean2.PluginWithSameIdentifierExistsError, bean2.PluginWithSameIdentifierExistsError) + } + if plugin.Name == pluginReq.Name { + return util.GetApiError(http.StatusConflict, bean2.PluginWithSameNameExistError, bean2.PluginWithSameNameExistError) + } + } + return nil +} + +func (impl *GlobalPluginServiceImpl) checkValidationOnVersion(pluginReq *bean2.PluginParentMetadataDto) error { + pluginVersions, err := impl.globalPluginRepository.GetPluginVersionsByParentId(pluginReq.Id) + if err != nil { + impl.logger.Errorw("checkValidationOnVersion, error in getting all plugins versions by parentPluginId", "parentPluginId", pluginReq.Id, "err", err) + return err + } + for _, pluginVersion := range pluginVersions { + if pluginReq.Versions != nil && len(pluginReq.Versions.DetailedPluginVersionData) > 0 && pluginReq.Versions.DetailedPluginVersionData[0] != nil { + // if plugin version from req is already created then return error + if pluginVersion.PluginVersion == pluginReq.Versions.DetailedPluginVersionData[0].Version { + return util.GetApiError(http.StatusBadRequest, bean2.PluginVersionAlreadyExistError, bean2.PluginVersionAlreadyExistError) + } + } + + } + return nil +} + +func (impl *GlobalPluginServiceImpl) validateV2PluginRequest(pluginReq *bean2.PluginParentMetadataDto) error { + if pluginReq.Versions == nil || len(pluginReq.Versions.DetailedPluginVersionData) == 0 || pluginReq.Versions.DetailedPluginVersionData[0] == nil { + return util.GetApiError(http.StatusBadRequest, bean2.NoStepDataToProceedError, bean2.NoStepDataToProceedError) + } + if pluginReq.Id == 0 { + //create plugin req. + err := impl.checkValidationOnPluginNameAndIdentifier(pluginReq) + if err != nil { + impl.logger.Errorw("error in checkValidationOnPluginNameAndIdentifier", "err", err) + return err + } + } else { + err := impl.checkValidationOnVersion(pluginReq) + if err != nil { + impl.logger.Errorw("error in checkValidationOnPluginNameAndIdentifier", "err", err) + return err + } + } + version := pluginReq.Versions.DetailedPluginVersionData[0].Version + if !strings.Contains(version, "v") { + version = fmt.Sprintf("v%s", version) + } + // semantic versioning validation on plugin's version + if !semver.IsValid(version) { + return util.GetApiError(http.StatusBadRequest, bean2.PluginVersionNotSemanticallyCorrectError, bean2.PluginVersionNotSemanticallyCorrectError) + } + //validate icon url and size + if len(pluginReq.Icon) > 0 { + err := utils.FetchIconAndCheckSize(pluginReq.Icon, bean2.PluginIconMaxSizeInBytes) + if err != nil { + errMsg := fmt.Sprintf("%s err:= %s", bean2.PluginIconNotCorrectOrReachableError, err.Error()) + return util.GetApiError(http.StatusBadRequest, errMsg, errMsg) + } + } + return nil +} + +func (impl *GlobalPluginServiceImpl) createPluginTagAndRelations(pluginReq *bean2.PluginsVersionDetail, userId int32, tx *pg.Tx) error { + if pluginReq.AreNewTagsPresent { + err := impl.CreateNewPluginTagsAndRelationsIfRequiredV2(pluginReq, userId, tx) + if err != nil { + impl.logger.Errorw("createPluginTagAndRelations, error in CreateNewPluginTagsAndRelationsIfRequired", "tags", pluginReq.Tags, "err", err) + return err + } + } else if len(pluginReq.Tags) > 0 { + err := impl.CreatePluginTagRelations(pluginReq, userId, tx) + if err != nil { + impl.logger.Errorw("createPluginTagAndRelations, error in CreatePluginTagRelations", "tags", pluginReq.Tags, "err", err) + return err + } + } + return nil +} + +func (impl *GlobalPluginServiceImpl) CreatePluginTagRelations(pluginReq *bean2.PluginsVersionDetail, userId int32, tx *pg.Tx) error { + tags, err := impl.globalPluginRepository.GetPluginTagByNames(pluginReq.Tags) + if err != nil { + impl.logger.Errorw("CreatePluginTagRelations, error in GetPluginTagByNames", "tags", pluginReq.Tags, "err", err) + return err + } + newPluginTagRelationsToCreate := make([]*repository.PluginTagRelation, 0, len(pluginReq.Tags)) + for _, tag := range tags { + newPluginTagRelationsToCreate = append(newPluginTagRelationsToCreate, repository.NewPluginTagRelation().CreateAuditLog(userId).WithTagAndPluginId(tag.Id, pluginReq.Id)) + } + + if len(newPluginTagRelationsToCreate) > 0 { + err = impl.globalPluginRepository.SavePluginTagRelationInBulk(newPluginTagRelationsToCreate, tx) + if err != nil { + impl.logger.Errorw("CreatePluginTagRelations, error in saving plugin tag relation in bulk", "newPluginTagRelationsToCreate", newPluginTagRelationsToCreate, "err", err) + return err + } + } + return nil +} + +func (impl *GlobalPluginServiceImpl) createPluginStepDataAndTagRelations(pluginVersionId int, pluginVersionDetail *bean2.PluginsVersionDetail, userId int32, tx *pg.Tx) error { + if len(pluginVersionDetail.PluginSteps) > 0 { + err := impl.saveDeepPluginStepData(pluginVersionId, pluginVersionDetail.PluginSteps, userId, tx) + if err != nil { + impl.logger.Errorw("createNewPluginVersionOfExistingPlugin, error in saving plugin step data", "err", err) + return err + } + } else { + return util.GetApiError(http.StatusBadRequest, bean2.PluginStepsNotProvidedError, bean2.PluginStepsNotProvidedError) + } + + err := impl.createPluginTagAndRelations(pluginVersionDetail, userId, tx) + if err != nil { + impl.logger.Errorw("createNewPlugin, error in createPluginTagAndRelations", "tags", pluginVersionDetail.Tags, "err", err) + return err + } + return nil +} + +func (impl *GlobalPluginServiceImpl) createNewPlugin(tx *pg.Tx, pluginDto *bean2.PluginParentMetadataDto, userId int32) (int, error) { + pluginParentMetadata, err := impl.globalPluginRepository.SavePluginParentMetadata(tx, adaptor.GetPluginParentMetadataDbObject(pluginDto, userId)) + if err != nil { + impl.logger.Errorw("createNewPlugin, error in saving plugin parent metadata", "pluginDto", pluginDto, "err", err) + return 0, err + } + pluginDto.Id = pluginParentMetadata.Id + pluginVersionDto := adaptor.GetPluginVersionMetadataDbObject(pluginDto, userId). + WithPluginParentMetadataId(pluginParentMetadata.Id). + WithIsLatestFlag(true) + + pluginVersionMetadata, err := impl.globalPluginRepository.SavePluginMetadata(pluginVersionDto, tx) + if err != nil { + impl.logger.Errorw("createNewPlugin, error in saving plugin version metadata", "pluginDto", pluginDto, "err", err) + return 0, err + } + pluginDto.Versions.DetailedPluginVersionData[0].Id = pluginVersionMetadata.Id + + pluginStageMapping := &repository.PluginStageMapping{ + PluginId: pluginParentMetadata.Id, + StageType: repository.CI_CD, + AuditLog: sql.NewDefaultAuditLog(userId), + } + _, err = impl.globalPluginRepository.SavePluginStageMapping(pluginStageMapping, tx) + if err != nil { + impl.logger.Errorw("createNewPlugin, error in saving plugin stage mapping", "pluginDto", pluginDto, "err", err) + return 0, err + } + + err = impl.createPluginStepDataAndTagRelations(pluginVersionMetadata.Id, pluginDto.Versions.DetailedPluginVersionData[0], userId, tx) + if err != nil { + impl.logger.Errorw("createNewPlugin, error in createPluginStepDataAndTagRelations", "pluginDto", pluginDto, "err", err) + return 0, err + } + return pluginVersionMetadata.Id, nil +} + +func (impl *GlobalPluginServiceImpl) createNewPluginVersionOfExistingPlugin(tx *pg.Tx, pluginDto *bean2.PluginParentMetadataDto, userId int32) (int, error) { + var pluginParentMinData *repository.PluginParentMetadata + var err error + pluginParentMinData, err = impl.globalPluginRepository.GetPluginParentMinDataById(pluginDto.Id) + if err != nil { + impl.logger.Errorw("createNewPluginVersionOfExistingPlugin, error in getting plugin parent metadata", "pluginDto", pluginDto, "err", err) + return 0, err + } + // before saving new plugin version marking previous version's isLatest as false. + err = impl.globalPluginRepository.MarkPreviousPluginVersionLatestFalse(pluginParentMinData.Id) + if err != nil { + impl.logger.Errorw("createNewPluginVersionOfExistingPlugin, error in MarkPreviousPluginVersionLatestFalse", "pluginParentId", pluginDto.Id, "err", err) + return 0, err + } + pluginDto.Name = pluginParentMinData.Name + pluginVersionDto := adaptor.GetPluginVersionMetadataDbObject(pluginDto, userId). + WithPluginParentMetadataId(pluginParentMinData.Id). + WithIsLatestFlag(true) + + pluginVersionMetadata, err := impl.globalPluginRepository.SavePluginMetadata(pluginVersionDto, tx) + if err != nil { + impl.logger.Errorw("createNewPluginVersionOfExistingPlugin, error in saving plugin version metadata", "pluginDto", pluginDto, "err", err) + return 0, err + } + pluginDto.Versions.DetailedPluginVersionData[0].Id = pluginVersionMetadata.Id + + err = impl.createPluginStepDataAndTagRelations(pluginVersionMetadata.Id, pluginDto.Versions.DetailedPluginVersionData[0], userId, tx) + if err != nil { + impl.logger.Errorw("createNewPluginVersionOfExistingPlugin, error in createPluginStepDataAndTagRelations", "pluginDto", pluginDto, "err", err) + return 0, err + } + return pluginVersionMetadata.Id, nil +} + +func (impl *GlobalPluginServiceImpl) CreatePluginOrVersions(pluginDto *bean2.PluginParentMetadataDto, userId int32) (int, error) { + err := impl.validateV2PluginRequest(pluginDto) + if err != nil { + impl.logger.Errorw("CreatePluginOrVersions, error in validating create plugin request", "pluginReqDto", pluginDto, "err", err) + return 0, err + } + + dbConnection := impl.globalPluginRepository.GetConnection() + tx, err := dbConnection.Begin() + if err != nil { + return 0, err + } + // Rollback tx on error. + defer tx.Rollback() + var versionMetadataId int + if pluginDto.Id > 0 { + // create new version of existing plugin req. + versionMetadataId, err = impl.createNewPluginVersionOfExistingPlugin(tx, pluginDto, userId) + if err != nil { + impl.logger.Errorw("CreatePluginOrVersions, error in creating new version of an existing plugin", "existingPluginName", pluginDto.Name, "err", err) + return 0, err + } + } else { + // create new plugin req. + versionMetadataId, err = impl.createNewPlugin(tx, pluginDto, userId) + if err != nil { + impl.logger.Errorw("CreatePluginOrVersions, error in creating new plugin", "pluginDto", pluginDto, "err", err) + return 0, err + } + } + err = tx.Commit() + if err != nil { + impl.logger.Errorw("CreatePluginOrVersions, error in committing db transaction", "err", err) + return 0, err + } + return versionMetadataId, nil +} + +func (impl *GlobalPluginServiceImpl) CreateNewPluginTagsAndRelationsIfRequiredV2(pluginReq *bean2.PluginsVersionDetail, userId int32, tx *pg.Tx) error { + allPluginTags, err := impl.globalPluginRepository.GetAllPluginTags() + if err != nil { + impl.logger.Errorw("CreateNewPluginTagsAndRelationsIfRequiredV2, error in getting all plugin tags", "err", err) + return err + } + existingTagMap := make(map[string]*repository.PluginTag, len(allPluginTags)) + for _, tag := range allPluginTags { + existingTagMap[tag.Name] = tag + } + //check for new tags, then create new plugin_tag and plugin_tag_relation entry in db when new tags are present in request + newPluginTagsToCreate := make([]*repository.PluginTag, 0, len(pluginReq.Tags)) + newPluginTagRelationsToCreate := make([]*repository.PluginTagRelation, 0, len(pluginReq.Tags)) + + for _, tagReq := range pluginReq.Tags { + if _, ok := existingTagMap[tagReq]; !ok { + newPluginTagsToCreate = append(newPluginTagsToCreate, repository.NewPluginTag().CreateAuditLog(userId).WithName(tagReq)) + } + } + + if len(newPluginTagsToCreate) > 0 { + err = impl.globalPluginRepository.SavePluginTagInBulk(newPluginTagsToCreate, tx) + if err != nil { + impl.logger.Errorw("CreateNewPluginTagsAndRelationsIfRequiredV2, error in saving plugin tag", "newPluginTags", newPluginTagsToCreate, "err", err) + return err + } + for _, newTag := range newPluginTagsToCreate { + existingTagMap[newTag.Name] = newTag + } + } + + for _, tag := range pluginReq.Tags { + newPluginTagRelationsToCreate = append(newPluginTagRelationsToCreate, repository.NewPluginTagRelation().CreateAuditLog(userId).WithTagAndPluginId(existingTagMap[tag].Id, pluginReq.Id)) + } + + if len(newPluginTagRelationsToCreate) > 0 { + err = impl.globalPluginRepository.SavePluginTagRelationInBulk(newPluginTagRelationsToCreate, tx) + if err != nil { + impl.logger.Errorw("CreateNewPluginTagsAndRelationsIfRequiredV2, error in saving plugin tag relation in bulk", "newPluginTagRelationsToCreate", newPluginTagRelationsToCreate, "err", err) + return err + } + } + return nil +} diff --git a/pkg/plugin/adaptor/adaptor.go b/pkg/plugin/adaptor/adaptor.go new file mode 100644 index 0000000000..e5e0f50e9d --- /dev/null +++ b/pkg/plugin/adaptor/adaptor.go @@ -0,0 +1,80 @@ +package adaptor + +import ( + bean2 "github.com/devtron-labs/devtron/pkg/plugin/bean" + "github.com/devtron-labs/devtron/pkg/plugin/repository" + "github.com/devtron-labs/devtron/pkg/sql" +) + +func GetPluginParentMetadataDbObject(pluginDto *bean2.PluginParentMetadataDto, userId int32) *repository.PluginParentMetadata { + return repository.NewPluginParentMetadata().CreateAuditLog(userId). + WithBasicMetadata(pluginDto.Name, pluginDto.PluginIdentifier, pluginDto.Description, pluginDto.Icon, repository.PLUGIN_TYPE_SHARED) +} + +func GetPluginVersionMetadataDbObject(pluginDto *bean2.PluginParentMetadataDto, userId int32) *repository.PluginMetadata { + versionDto := pluginDto.Versions.DetailedPluginVersionData[0] + return repository.NewPluginVersionMetadata().CreateAuditLog(userId).WithBasicMetadata(pluginDto.Name, versionDto.Description, versionDto.Version, versionDto.DocLink) +} + +func GetPluginStepDbObject(pluginStepDto *bean2.PluginStepsDto, pluginVersionMetadataId int, userId int32) *repository.PluginStep { + return &repository.PluginStep{ + PluginId: pluginVersionMetadataId, + Name: pluginStepDto.Name, + Description: pluginStepDto.Description, + Index: 1, + StepType: repository.PLUGIN_STEP_TYPE_INLINE, + RefPluginId: pluginStepDto.RefPluginId, + OutputDirectoryPath: pluginStepDto.OutputDirectoryPath, + DependentOnStep: pluginStepDto.DependentOnStep, + AuditLog: sql.NewDefaultAuditLog(userId), + } +} +func GetPluginPipelineScriptDbObject(pluginPipelineScript *bean2.PluginPipelineScript, userId int32) *repository.PluginPipelineScript { + return &repository.PluginPipelineScript{ + Script: pluginPipelineScript.Script, + StoreScriptAt: pluginPipelineScript.StoreScriptAt, + Type: pluginPipelineScript.Type, + DockerfileExists: pluginPipelineScript.DockerfileExists, + MountPath: pluginPipelineScript.MountPath, + MountCodeToContainer: pluginPipelineScript.MountCodeToContainer, + MountCodeToContainerPath: pluginPipelineScript.MountCodeToContainerPath, + MountDirectoryFromHost: pluginPipelineScript.MountDirectoryFromHost, + ContainerImagePath: pluginPipelineScript.ContainerImagePath, + ImagePullSecretType: pluginPipelineScript.ImagePullSecretType, + ImagePullSecret: pluginPipelineScript.ImagePullSecret, + AuditLog: sql.NewDefaultAuditLog(userId), + } + +} + +func GetPluginStepVariableDbObject(pluginStepId int, pluginVariableDto *bean2.PluginVariableDto, userId int32) *repository.PluginStepVariable { + return &repository.PluginStepVariable{ + PluginStepId: pluginStepId, + Name: pluginVariableDto.Name, + Format: pluginVariableDto.Format, + Description: pluginVariableDto.Description, + IsExposed: true, //currently hard coding this, later after plugin creation gets more mature will let user decide + AllowEmptyValue: pluginVariableDto.AllowEmptyValue, + DefaultValue: pluginVariableDto.DefaultValue, + Value: pluginVariableDto.Value, + VariableType: pluginVariableDto.VariableType, + ValueType: pluginVariableDto.ValueType, + PreviousStepIndex: pluginVariableDto.PreviousStepIndex, + VariableStepIndex: 1, //currently hard coding this, later after plugin creation gets more mature will let user decide + VariableStepIndexInPlugin: pluginVariableDto.VariableStepIndexInPlugin, + ReferenceVariableName: pluginVariableDto.ReferenceVariableName, + AuditLog: sql.NewDefaultAuditLog(userId), + } +} + +func GetPluginStepConditionDbObject(stepDataId, pluginStepVariableId int, pluginStepCondition *bean2.PluginStepCondition, + userId int32) *repository.PluginStepCondition { + return &repository.PluginStepCondition{ + PluginStepId: stepDataId, + ConditionVariableId: pluginStepVariableId, + ConditionType: pluginStepCondition.ConditionType, + ConditionalOperator: pluginStepCondition.ConditionalOperator, + ConditionalValue: pluginStepCondition.ConditionalValue, + AuditLog: sql.NewDefaultAuditLog(userId), + } +} diff --git a/pkg/plugin/bean/bean.go b/pkg/plugin/bean/bean.go index 55424f3caa..c31d346332 100644 --- a/pkg/plugin/bean/bean.go +++ b/pkg/plugin/bean/bean.go @@ -13,7 +13,6 @@ * See the License for the specific language governing permissions and * limitations under the License. */ - package bean import ( @@ -44,15 +43,47 @@ type PluginListComponentDto struct { //created new struct for backward compatibi } type PluginMetadataDto struct { - Id int `json:"id"` - Name string `json:"name"` - Description string `json:"description"` - Type string `json:"type,omitempty" validate:"oneof=SHARED PRESET"` // SHARED, PRESET etc - Icon string `json:"icon,omitempty"` - Tags []string `json:"tags"` - Action int `json:"action,omitempty"` - PluginStage string `json:"pluginStage,omitempty"` - PluginSteps []*PluginStepsDto `json:"pluginSteps,omitempty"` + Id int `json:"id"` + Name string `json:"name" validate:"required,min=3,max=100,global-entity-name"` + Description string `json:"description" validate:"max=300"` + Type string `json:"type,omitempty" validate:"oneof=SHARED PRESET"` // SHARED, PRESET etc + Icon string `json:"icon,omitempty"` + Tags []string `json:"tags"` + Action int `json:"action,omitempty"` + PluginStage string `json:"pluginStage,omitempty"` + PluginSteps []*PluginStepsDto `json:"pluginSteps,omitempty"` + AreNewTagsPresent bool `json:"areNewTagsPresent,omitempty"` +} + +type PluginMinDto struct { + ParentPluginId int `json:"id,omitempty"` + PluginName string `json:"name,omitempty"` + Icon string `json:"icon,omitempty"` + PluginVersionId int `json:"pluginVersionId,omitempty"` +} + +func NewPluginMinDto() *PluginMinDto { + return &PluginMinDto{} +} + +func (r *PluginMinDto) WithParentPluginId(id int) *PluginMinDto { + r.ParentPluginId = id + return r +} + +func (r *PluginMinDto) WithPluginName(name string) *PluginMinDto { + r.PluginName = name + return r +} + +func (r *PluginMinDto) WithIcon(icon string) *PluginMinDto { + r.Icon = icon + return r +} + +func (r *PluginMinDto) WithPluginVersionId(versionId int) *PluginMinDto { + r.PluginVersionId = versionId + return r } type PluginsDto struct { @@ -76,9 +107,9 @@ func (r *PluginsDto) WithTotalCount(count int) *PluginsDto { type PluginParentMetadataDto struct { Id int `json:"id"` - Name string `json:"name"` - PluginIdentifier string `json:"pluginIdentifier"` - Description string `json:"description"` + Name string `json:"name" validate:"required,min=3,max=100,global-entity-name"` + PluginIdentifier string `json:"pluginIdentifier" validate:"required,min=3,max=100,global-entity-name"` + Description string `json:"description" validate:"max=300"` Type string `json:"type,omitempty" validate:"oneof=SHARED PRESET"` Icon string `json:"icon,omitempty"` Versions *PluginVersions `json:"pluginVersions"` @@ -124,17 +155,6 @@ type PluginVersions struct { MinimalPluginVersionData []*PluginsVersionDetail `json:"minimalPluginVersionData"` // contains only few metadata } -type PluginMinDto struct { - PluginName string `json:"pluginName"` - PluginVersions []*PluginVersionsMinDto `json:"pluginVersions"` - Icon string `json:"icon"` -} - -type PluginVersionsMinDto struct { - Id int `json:"id"` - Version string `json:"version"` -} - func NewPluginVersions() *PluginVersions { return &PluginVersions{} } @@ -154,7 +174,7 @@ type PluginsVersionDetail struct { InputVariables []*PluginVariableDto `json:"inputVariables"` OutputVariables []*PluginVariableDto `json:"outputVariables"` DocLink string `json:"docLink"` - Version string `json:"pluginVersion"` + Version string `json:"pluginVersion" validate:"max=50,min=3"` IsLatest bool `json:"isLatest"` UpdatedBy string `json:"updatedBy"` CreatedOn time.Time `json:"-"` @@ -336,10 +356,18 @@ type RegistryCredentials struct { } const ( - NoPluginOrParentIdProvidedErr = "no value for pluginVersionIds and parentPluginIds provided in query param" - NoPluginFoundForThisSearchQueryErr = "unable to find desired plugin for the query filter" + NoPluginOrParentIdProvidedErr = "no value for pluginVersionIds and parentPluginIds provided in query param" + NoPluginFoundForThisSearchQueryErr = "unable to find desired plugin for the query filter" + PluginStepsNotProvidedError = "plugin steps not provided" + PluginWithSameNameExistError = "plugin with the same name exists, please choose another name" + PluginWithSameIdentifierExistsError = "plugin with the same identifier exists, please choose another identifier name" + PluginVersionNotSemanticallyCorrectError = "please provide a plugin version that adheres to Semantic Versioning 2.0.0 to ensure compatibility and proper versioning" + PluginIconNotCorrectOrReachableError = "cannot validate icon, make sure that provided url link is reachable" + PluginVersionAlreadyExistError = "this plugin version already exists, please provide another plugin version" + NoStepDataToProceedError = "no step data provided to save, please provide a plugin step to proceed further" ) const ( - SpecialCharsRegex = ` !"#$%&'()*+,./:;<=>?@[\]^_{|}~` + "`" + SpecialCharsRegex = ` !"#$%&'()*+,./:;<=>?@[\]^_{|}~` + "`" + PluginIconMaxSizeInBytes = 2 * 1024 * 1024 ) diff --git a/pkg/plugin/repository/GlobalPluginRepository.go b/pkg/plugin/repository/GlobalPluginRepository.go index 8b65093523..9cc50748f2 100644 --- a/pkg/plugin/repository/GlobalPluginRepository.go +++ b/pkg/plugin/repository/GlobalPluginRepository.go @@ -99,6 +99,16 @@ func (r *PluginParentMetadata) CreateAuditLog(userId int32) *PluginParentMetadat return r } +func (r *PluginParentMetadata) WithBasicMetadata(name, identifier, description, icon string, pluginType PluginType) *PluginParentMetadata { + r.Name = name + r.Identifier = identifier + r.Description = description + r.Icon = icon + r.Type = pluginType + r.Deleted = false + return r +} + // SetParentPluginMetadata method signature used only for migration purposes, sets pluginVersionsMetadata into plugin_parent_metadata func (r *PluginParentMetadata) SetParentPluginMetadata(pluginMetadata *PluginMetadata) *PluginParentMetadata { r.Name = pluginMetadata.Name @@ -135,6 +145,38 @@ type PluginMetadata struct { sql.AuditLog } +func NewPluginVersionMetadata() *PluginMetadata { + return &PluginMetadata{} +} + +func (r *PluginMetadata) CreateAuditLog(userId int32) *PluginMetadata { + r.CreatedBy = userId + r.CreatedOn = time.Now() + r.UpdatedBy = userId + r.UpdatedOn = time.Now() + return r +} + +func (r *PluginMetadata) WithBasicMetadata(name, description, pluginVersion, docLink string) *PluginMetadata { + r.Name = name + r.PluginVersion = pluginVersion + r.Description = description + r.DocLink = docLink + r.Deleted = false + r.IsDeprecated = false + return r +} + +func (r *PluginMetadata) WithPluginParentMetadataId(parentId int) *PluginMetadata { + r.PluginParentMetadataId = parentId + return r +} + +func (r *PluginMetadata) WithIsLatestFlag(isLatest bool) *PluginMetadata { + r.IsLatest = isLatest + return r +} + type PluginTag struct { tableName struct{} `sql:"plugin_tag" pg:",discard_unknown_columns"` Id int `sql:"id,pk"` @@ -143,6 +185,23 @@ type PluginTag struct { sql.AuditLog } +func NewPluginTag() *PluginTag { + return &PluginTag{} +} + +func (r *PluginTag) WithName(name string) *PluginTag { + r.Name = name + return r +} + +func (r *PluginTag) CreateAuditLog(userId int32) *PluginTag { + r.CreatedBy = userId + r.CreatedOn = time.Now() + r.UpdatedBy = userId + r.UpdatedOn = time.Now() + return r +} + type PluginTagRelation struct { tableName struct{} `sql:"plugin_tag_relation" pg:",discard_unknown_columns"` Id int `sql:"id,pk"` @@ -151,6 +210,24 @@ type PluginTagRelation struct { sql.AuditLog } +func NewPluginTagRelation() *PluginTagRelation { + return &PluginTagRelation{} +} + +func (r *PluginTagRelation) WithTagAndPluginId(tagId, pluginId int) *PluginTagRelation { + r.TagId = tagId + r.PluginId = pluginId + return r +} + +func (r *PluginTagRelation) CreateAuditLog(userId int32) *PluginTagRelation { + r.CreatedBy = userId + r.CreatedOn = time.Now() + r.UpdatedBy = userId + r.UpdatedOn = time.Now() + return r +} + // Below two tables are used at pipeline-steps level too type PluginPipelineScript struct { @@ -247,7 +324,9 @@ type GlobalPluginRepository interface { GetMetaDataForAllPlugins() ([]*PluginMetadata, error) GetMetaDataForPluginWithStageType(stageType int) ([]*PluginMetadata, error) GetMetaDataByPluginId(pluginId int) (*PluginMetadata, error) + GetMetaDataByPluginIds(pluginIds []int) ([]*PluginMetadata, error) GetAllPluginTags() ([]*PluginTag, error) + GetPluginTagByNames(tagNames []string) ([]*PluginTag, error) GetAllPluginTagRelations() ([]*PluginTagRelation, error) GetTagsByPluginId(pluginId int) ([]string, error) GetScriptDetailById(id int) (*PluginPipelineScript, error) @@ -264,10 +343,14 @@ type GlobalPluginRepository interface { GetConditionsByPluginId(pluginId int) ([]*PluginStepCondition, error) GetPluginStageMappingByPluginId(pluginId int) (*PluginStageMapping, error) GetConnection() (dbConnection *pg.DB) + GetPluginVersionsByParentId(parentPluginId int) ([]*PluginMetadata, error) GetPluginParentMetadataByIdentifier(pluginIdentifier string) (*PluginParentMetadata, error) GetAllFilteredPluginParentMetadata(searchKey string, tags []string) ([]*PluginParentMetadata, error) GetPluginParentMetadataByIds(ids []int) ([]*PluginParentMetadata, error) + GetAllPluginMinData() ([]*PluginParentMetadata, error) + GetPluginParentMinDataById(id int) (*PluginParentMetadata, error) + MarkPreviousPluginVersionLatestFalse(pluginParentId int) error SavePluginMetadata(pluginMetadata *PluginMetadata, tx *pg.Tx) (*PluginMetadata, error) SavePluginStageMapping(pluginStageMapping *PluginStageMapping, tx *pg.Tx) (*PluginStageMapping, error) @@ -351,6 +434,19 @@ func (impl *GlobalPluginRepositoryImpl) GetAllPluginTags() ([]*PluginTag, error) return tags, nil } +func (impl *GlobalPluginRepositoryImpl) GetPluginTagByNames(tagNames []string) ([]*PluginTag, error) { + var tags []*PluginTag + err := impl.dbConnection.Model(&tags). + Where("deleted = ?", false). + Where("name in (?)", pg.In(tagNames)). + Select() + if err != nil { + impl.logger.Errorw("err in getting all tags by names", "tagNames", tagNames, "err", err) + return nil, err + } + return tags, nil +} + func (impl *GlobalPluginRepositoryImpl) GetAllPluginTagRelations() ([]*PluginTagRelation, error) { var rel []*PluginTagRelation err := impl.dbConnection.Model(&rel). @@ -385,6 +481,18 @@ func (impl *GlobalPluginRepositoryImpl) GetMetaDataByPluginId(pluginId int) (*Pl return &plugin, nil } +func (impl *GlobalPluginRepositoryImpl) GetMetaDataByPluginIds(pluginIds []int) ([]*PluginMetadata, error) { + var plugins []*PluginMetadata + err := impl.dbConnection.Model(&plugins). + Where("deleted = ?", false). + Where("id in (?)", pg.In(pluginIds)).Select() + if err != nil { + impl.logger.Errorw("err in getting plugins by pluginIds", "pluginIds", pluginIds, "err", err) + return nil, err + } + return plugins, nil +} + func (impl *GlobalPluginRepositoryImpl) GetStepsByPluginIds(pluginIds []int) ([]*PluginStep, error) { var pluginSteps []*PluginStep err := impl.dbConnection.Model(&pluginSteps). @@ -511,6 +619,20 @@ func (impl *GlobalPluginRepositoryImpl) GetPluginByName(pluginName string) ([]*P } +func (impl *GlobalPluginRepositoryImpl) GetPluginVersionsByParentId(parentPluginId int) ([]*PluginMetadata, error) { + var plugin []*PluginMetadata + err := impl.dbConnection.Model(&plugin). + Where("plugin_parent_metadata_id = ?", parentPluginId). + Where("deleted = ?", false). + Where("is_deprecated = ?", false). + Select() + if err != nil { + impl.logger.Errorw("err in getting pluginVersionMetadata by parentPluginId", "parentPluginId", parentPluginId, "err", err) + return nil, err + } + return plugin, nil +} + func (impl *GlobalPluginRepositoryImpl) GetAllPluginMetaData() ([]*PluginMetadata, error) { var plugins []*PluginMetadata err := impl.dbConnection.Model(&plugins).Where("deleted = ?", false).Select() @@ -700,6 +822,18 @@ func (impl *GlobalPluginRepositoryImpl) GetPluginParentMetadataByIdentifier(plug return &pluginParentMetadata, nil } +func (impl *GlobalPluginRepositoryImpl) GetPluginParentMinDataById(id int) (*PluginParentMetadata, error) { + var pluginParentMetadata PluginParentMetadata + err := impl.dbConnection.Model(&pluginParentMetadata). + Column("plugin_parent_metadata.id", "plugin_parent_metadata.name"). + Where("id = ?", id). + Where("deleted = ?", false).Select() + if err != nil { + return nil, err + } + return &pluginParentMetadata, nil +} + func (impl *GlobalPluginRepositoryImpl) SavePluginParentMetadata(tx *pg.Tx, pluginParentMetadata *PluginParentMetadata) (*PluginParentMetadata, error) { err := tx.Insert(pluginParentMetadata) return pluginParentMetadata, err @@ -712,24 +846,20 @@ func (impl *GlobalPluginRepositoryImpl) UpdatePluginMetadataInBulk(pluginsMetada func (impl *GlobalPluginRepositoryImpl) GetAllFilteredPluginParentMetadata(searchKey string, tags []string) ([]*PluginParentMetadata, error) { var plugins []*PluginParentMetadata - subQuery := "select ppm.id, ppm.identifier,ppm.name,ppm.description,ppm.type,ppm.icon,ppm.deleted,ppm.created_by, ppm.created_on,ppm.updated_by,ppm.updated_on from plugin_parent_metadata ppm" + + query := "select ppm.id, ppm.identifier,ppm.name,ppm.description,ppm.type,ppm.icon,ppm.deleted,ppm.created_by, ppm.created_on,ppm.updated_by,ppm.updated_on from plugin_parent_metadata ppm" + " inner join plugin_metadata pm on pm.plugin_parent_metadata_id=ppm.id" - whereCondition := fmt.Sprintf(" where ppm.deleted=false") - orderCondition := fmt.Sprintf(" ORDER BY ppm.id asc") + whereCondition := fmt.Sprintf(" where ppm.deleted=false AND pm.deleted=false AND pm.is_latest=true") if len(tags) > 0 { - subQuery = "select DISTINCT ON(ppm.id) ppm.id, ppm.identifier,ppm.name,ppm.description,ppm.type,ppm.icon,ppm.deleted,ppm.created_by, ppm.created_on,ppm.updated_by,ppm.updated_on from plugin_parent_metadata ppm" + - " inner join plugin_metadata pm on pm.plugin_parent_metadata_id=ppm.id" + - " left join plugin_tag_relation ptr on ptr.plugin_id=pm.id" + - " left join plugin_tag pt on ptr.tag_id=pt.id" - whereCondition += fmt.Sprintf(" AND pm.deleted=false AND pt.deleted=false AND pt.name in (%s)", helper.GetCommaSepratedStringWithComma(tags)) + tagFilterSubQuery := fmt.Sprintf("select ptr.plugin_id from plugin_tag_relation ptr inner join plugin_tag pt on ptr.tag_id =pt.id where pt.deleted =false and pt.name in (%s) group by ptr.plugin_id having count(ptr.plugin_id )=%d", helper.GetCommaSepratedStringWithComma(tags), len(tags)) + whereCondition += fmt.Sprintf(" AND pm.id in (%s)", tagFilterSubQuery) } if len(searchKey) > 0 { searchKeyLike := "%" + searchKey + "%" whereCondition += fmt.Sprintf(" AND (pm.description ilike '%s' or pm.name ilike '%s')", searchKeyLike, searchKeyLike) } - whereCondition += fmt.Sprintf(" AND pm.is_latest=true") - subQuery += whereCondition + orderCondition - query := fmt.Sprintf(" select * from (%s) x ORDER BY name asc;", subQuery) + orderCondition := " ORDER BY ppm.name asc;" + + query += whereCondition + orderCondition _, err := impl.dbConnection.Query(&plugins, query) if err != nil { return nil, err @@ -749,3 +879,29 @@ func (impl *GlobalPluginRepositoryImpl) GetPluginParentMetadataByIds(ids []int) } return plugins, nil } + +func (impl *GlobalPluginRepositoryImpl) GetAllPluginMinData() ([]*PluginParentMetadata, error) { + var plugins []*PluginParentMetadata + err := impl.dbConnection.Model(&plugins). + Column("plugin_parent_metadata.id", "plugin_parent_metadata.name", "plugin_parent_metadata.type", "plugin_parent_metadata.icon", "plugin_parent_metadata.identifier"). + Where("deleted = ?", false). + Select() + if err != nil { + impl.logger.Errorw("err in getting all plugin parent metadata min data", "err", err) + return nil, err + } + return plugins, nil +} + +func (impl *GlobalPluginRepositoryImpl) MarkPreviousPluginVersionLatestFalse(pluginParentId int) error { + var model PluginMetadata + _, err := impl.dbConnection.Model(&model). + Set("is_latest = ?", false). + Where("id = (select id from plugin_metadata where plugin_parent_metadata_id = ? and is_latest =true order by created_on desc limit ?)", pluginParentId, 1). + Update() + if err != nil { + impl.logger.Errorw("error in updating last version isLatest as false for a plugin parent id", "pluginParentId", pluginParentId, "err", err) + return err + } + return nil +} diff --git a/pkg/plugin/utils/utils.go b/pkg/plugin/utils/utils.go index 6d78a29143..168e694d89 100644 --- a/pkg/plugin/utils/utils.go +++ b/pkg/plugin/utils/utils.go @@ -21,9 +21,11 @@ import ( "fmt" bean2 "github.com/devtron-labs/devtron/pkg/plugin/bean" "github.com/devtron-labs/devtron/pkg/plugin/repository" + "net/http" "regexp" "sort" "strings" + "time" ) func GetStageType(stageTypeReq string) (int, error) { @@ -72,3 +74,26 @@ func SortPluginsVersionDetailSliceByCreatedOn(pluginsVersionDetail []*bean2.Plug return false }) } + +func FetchIconAndCheckSize(url string, maxSize int64) error { + client := http.Client{ + Timeout: 5 * time.Second, + } + iconResp, err := client.Get(url) + if err != nil { + return fmt.Errorf("error in fetching icon : %s", err.Error()) + } + if iconResp != nil { + if iconResp.StatusCode >= 200 && iconResp.StatusCode < 300 { + if iconResp.ContentLength > maxSize { + return fmt.Errorf("icon size too large") + } + iconResp.Body.Close() + } else { + return fmt.Errorf("error in fetching icon : %s", iconResp.Status) + } + } else { + return fmt.Errorf("error in fetching icon : empty response") + } + return nil +} diff --git a/pkg/terminal/terminalSesion.go b/pkg/terminal/terminalSesion.go index 6d0e2a8fa0..ba9a485975 100644 --- a/pkg/terminal/terminalSesion.go +++ b/pkg/terminal/terminalSesion.go @@ -26,7 +26,7 @@ import ( "github.com/caarlos0/env" "github.com/devtron-labs/common-lib/utils/k8s" "github.com/devtron-labs/devtron/internal/middleware" - "github.com/devtron-labs/devtron/pkg/argoApplication" + "github.com/devtron-labs/devtron/pkg/argoApplication/read" "github.com/devtron-labs/devtron/pkg/cluster" "github.com/devtron-labs/devtron/pkg/cluster/repository" errors1 "github.com/juju/errors" @@ -447,24 +447,24 @@ type TerminalSessionHandler interface { } type TerminalSessionHandlerImpl struct { - environmentService cluster.EnvironmentService - clusterService cluster.ClusterService - logger *zap.SugaredLogger - k8sUtil *k8s.K8sServiceImpl - ephemeralContainerService cluster.EphemeralContainerService - argoApplicationService argoApplication.ArgoApplicationService + environmentService cluster.EnvironmentService + clusterService cluster.ClusterService + logger *zap.SugaredLogger + k8sUtil *k8s.K8sServiceImpl + ephemeralContainerService cluster.EphemeralContainerService + argoApplicationReadService read.ArgoApplicationReadService } func NewTerminalSessionHandlerImpl(environmentService cluster.EnvironmentService, clusterService cluster.ClusterService, logger *zap.SugaredLogger, k8sUtil *k8s.K8sServiceImpl, ephemeralContainerService cluster.EphemeralContainerService, - argoApplicationService argoApplication.ArgoApplicationService) *TerminalSessionHandlerImpl { + argoApplicationReadService read.ArgoApplicationReadService) *TerminalSessionHandlerImpl { return &TerminalSessionHandlerImpl{ - environmentService: environmentService, - clusterService: clusterService, - logger: logger, - k8sUtil: k8sUtil, - ephemeralContainerService: ephemeralContainerService, - argoApplicationService: argoApplicationService, + environmentService: environmentService, + clusterService: clusterService, + logger: logger, + k8sUtil: k8sUtil, + ephemeralContainerService: ephemeralContainerService, + argoApplicationReadService: argoApplicationReadService, } } @@ -531,7 +531,7 @@ func (impl *TerminalSessionHandlerImpl) getClientSetAndRestConfigForTerminalConn var restConfig *rest.Config var err error if len(req.ExternalArgoApplicationName) > 0 { - restConfig, err = impl.argoApplicationService.GetRestConfigForExternalArgo(context.Background(), req.ClusterId, req.ExternalArgoApplicationName) + restConfig, err = impl.argoApplicationReadService.GetRestConfigForExternalArgo(context.Background(), req.ClusterId, req.ExternalArgoApplicationName) if err != nil { impl.logger.Errorw("error in getting rest config", "err", err, "clusterId", req.ClusterId, "externalArgoApplicationName", req.ExternalArgoApplicationName) return nil, nil, err @@ -652,7 +652,7 @@ func (impl *TerminalSessionHandlerImpl) saveEphemeralContainerTerminalAccessAudi var restConfig *rest.Config var err error if len(req.ExternalArgoApplicationName) > 0 { - restConfig, err = impl.argoApplicationService.GetRestConfigForExternalArgo(context.Background(), req.ClusterId, req.ExternalArgoApplicationName) + restConfig, err = impl.argoApplicationReadService.GetRestConfigForExternalArgo(context.Background(), req.ClusterId, req.ExternalArgoApplicationName) if err != nil { impl.logger.Errorw("error in getting rest config", "err", err, "clusterId", req.ClusterId, "externalArgoApplicationName", req.ExternalArgoApplicationName) return err diff --git a/pkg/workflow/dag/WorkflowDagExecutor.go b/pkg/workflow/dag/WorkflowDagExecutor.go index 86dd35d045..511f76279e 100644 --- a/pkg/workflow/dag/WorkflowDagExecutor.go +++ b/pkg/workflow/dag/WorkflowDagExecutor.go @@ -71,7 +71,7 @@ import ( ) type WorkflowDagExecutor interface { - HandleCiSuccessEvent(triggerContext triggerBean.TriggerContext, ciPipelineId int, request *bean2.CiArtifactWebhookRequest, imagePushedAt *time.Time) (id int, err error) + HandleCiSuccessEvent(triggerContext triggerBean.TriggerContext, ciPipelineId int, request *bean2.CiArtifactWebhookRequest, imagePushedAt time.Time) (id int, err error) HandlePreStageSuccessEvent(triggerContext triggerBean.TriggerContext, cdStageCompleteEvent eventProcessorBean.CdStageCompleteEvent) error HandleDeploymentSuccessEvent(triggerContext triggerBean.TriggerContext, pipelineOverride *chartConfig.PipelineOverride) error HandlePostStageSuccessEvent(triggerContext triggerBean.TriggerContext, cdWorkflowId int, cdPipelineId int, triggeredBy int32, pluginRegistryImageDetails map[string][]string) error @@ -687,7 +687,7 @@ func (impl *WorkflowDagExecutorImpl) HandlePostStageSuccessEvent(triggerContext return nil } -func (impl *WorkflowDagExecutorImpl) HandleCiSuccessEvent(triggerContext triggerBean.TriggerContext, ciPipelineId int, request *bean2.CiArtifactWebhookRequest, imagePushedAt *time.Time) (id int, err error) { +func (impl *WorkflowDagExecutorImpl) HandleCiSuccessEvent(triggerContext triggerBean.TriggerContext, ciPipelineId int, request *bean2.CiArtifactWebhookRequest, imagePushedAt time.Time) (id int, err error) { impl.logger.Infow("webhook for artifact save", "req", request) if request.WorkflowId != nil { savedWorkflow, err := impl.ciWorkflowRepository.FindById(*request.WorkflowId) @@ -730,7 +730,7 @@ func (impl *WorkflowDagExecutorImpl) HandleCiSuccessEvent(triggerContext trigger createdOn := time.Now() updatedOn := time.Now() if !imagePushedAt.IsZero() { - createdOn = *imagePushedAt + createdOn = imagePushedAt } buildArtifact := &repository.CiArtifact{ Image: request.Image, diff --git a/scripts/sql/283_user_group.down.sql b/scripts/sql/283_user_group.down.sql new file mode 100644 index 0000000000..9374d97580 --- /dev/null +++ b/scripts/sql/283_user_group.down.sql @@ -0,0 +1,8 @@ +DROP INDEX IF EXISTS idx_unique_user_group_user_id; +DROP TABLE IF EXISTS "public"."user_group_mapping"; +DROP INDEX IF EXISTS idx_unique_user_group_name; +DROP INDEX IF EXISTS idx_unique_user_group_identifier; +DROP TABLE IF EXISTS "public"."user_group"; +DROP SEQUENCE IF EXISTS "public"."id_seq_user_group_mapping"; +DROP SEQUENCE IF EXISTS "public"."id_seq_user_group"; +ALTER TABLE user_auto_assigned_groups RENAME TO user_groups; \ No newline at end of file diff --git a/scripts/sql/283_user_group.up.sql b/scripts/sql/283_user_group.up.sql new file mode 100644 index 0000000000..dd3e2a7a44 --- /dev/null +++ b/scripts/sql/283_user_group.up.sql @@ -0,0 +1,42 @@ +CREATE SEQUENCE IF NOT EXISTS id_seq_user_group; +CREATE TABLE IF NOT EXISTS public.user_group +( + "id" int NOT NULL DEFAULT nextval('id_seq_user_group'::regclass), + "name" VARCHAR(50) NOT NULL, + "identifier" VARCHAR(50) NOT NULL, + "description" TEXT NOT NULL, + "active" bool NOT NULL, + "created_on" timestamptz NOT NULL, + "created_by" int4 NOT NULL, + "updated_on" timestamptz NOT NULL, + "updated_by" int4 NOT NULL, + PRIMARY KEY ("id") + ); + +CREATE UNIQUE INDEX idx_unique_user_group_name + ON user_group (name) + WHERE active = true; + +CREATE UNIQUE INDEX idx_unique_user_group_identifier + ON user_group (identifier) + WHERE active = true; + +CREATE SEQUENCE IF NOT EXISTS id_seq_user_group_mapping; +CREATE TABLE IF NOT EXISTS public.user_group_mapping +( + "id" int NOT NULL DEFAULT nextval('id_seq_user_group_mapping'::regclass), + "user_id" int NOT NULL, + "user_group_id" int NOT NULL, + "created_on" timestamptz NOT NULL, + "created_by" int4 NOT NULL, + "updated_on" timestamptz NOT NULL, + "updated_by" int4 NOT NULL, + PRIMARY KEY ("id"), + CONSTRAINT "user_group_mapping_user_group_id_fkey" FOREIGN KEY ("user_group_id") REFERENCES "public"."user_group" ("id"), + CONSTRAINT "user_group_mapping_user_id_fkey" FOREIGN KEY ("user_id") REFERENCES "public"."users" ("id") + ); + +CREATE UNIQUE INDEX idx_unique_user_group_user_id + ON user_group_mapping(user_id,user_group_id); + +ALTER TABLE user_groups RENAME TO user_auto_assigned_groups; diff --git a/scripts/sql/284_polling_plugin_v2.down.sql b/scripts/sql/284_polling_plugin_v2.down.sql new file mode 100644 index 0000000000..4ca19c7bbe --- /dev/null +++ b/scripts/sql/284_polling_plugin_v2.down.sql @@ -0,0 +1,5 @@ +-- revert the container image path of the polling plugin version 1.0.0 +UPDATE plugin_pipeline_script +SET container_image_path ='quay.io/devtron/poll-container-image:97a996a5-545-16654' +WHERE container_image_path ='quay.io/devtron/devtron-plugins:polling-plugin-v1.0.1' +AND deleted = false; \ No newline at end of file diff --git a/scripts/sql/284_polling_plugin_v2.up.sql b/scripts/sql/284_polling_plugin_v2.up.sql new file mode 100644 index 0000000000..f939005ef5 --- /dev/null +++ b/scripts/sql/284_polling_plugin_v2.up.sql @@ -0,0 +1,30 @@ +-- update the container image path for the polling plugin version 1.0.0 +UPDATE plugin_pipeline_script +SET container_image_path ='quay.io/devtron/devtron-plugins:polling-plugin-v1.0.1' +WHERE container_image_path ='quay.io/devtron/poll-container-image:97a996a5-545-16654' +AND deleted = false; + +-- create plugin_parent_metadata for the polling plugin, if not exists +INSERT INTO "plugin_parent_metadata" ("id", "name", "identifier", "description", "type", "icon", "deleted", "created_on", "created_by", "updated_on", "updated_by") +SELECT nextval('id_seq_plugin_parent_metadata'), 'Pull images from container repository','pull-images-from-container-repository','Polls a container repository and pulls images stored in the repository which can be used for deployment.','PRESET','https://raw.githubusercontent.com/devtron-labs/devtron/main/assets/plugin-poll-container-registry.png','f', 'now()', 1, 'now()', 1 + WHERE NOT EXISTS ( + SELECT 1 + FROM plugin_parent_metadata + WHERE identifier='pull-images-from-container-repository' + AND deleted = false +); + +-- update the plugin_metadata with the plugin_parent_metadata_id +UPDATE plugin_metadata +SET plugin_parent_metadata_id = ( + SELECT id + FROM plugin_parent_metadata + WHERE identifier='pull-images-from-container-repository' + AND deleted = false +) +WHERE name='Pull images from container repository' + AND ( + plugin_parent_metadata_id IS NULL + OR plugin_parent_metadata_id = 0 + ) + AND deleted = false; \ No newline at end of file diff --git a/scripts/sql/285_release_channel.down.sql b/scripts/sql/285_release_channel.down.sql new file mode 100644 index 0000000000..3ec9165761 --- /dev/null +++ b/scripts/sql/285_release_channel.down.sql @@ -0,0 +1,3 @@ +DELETE FROM devtron_resource_schema where devtron_resource_id in (select id from devtron_resource where kind in('release-channel')); + +DELETE FROM devtron_resource where kind in('release-channel'); \ No newline at end of file diff --git a/scripts/sql/285_release_channel.up.sql b/scripts/sql/285_release_channel.up.sql new file mode 100644 index 0000000000..cbcc0bc310 --- /dev/null +++ b/scripts/sql/285_release_channel.up.sql @@ -0,0 +1,206 @@ +INSERT INTO devtron_resource(kind, display_name, icon,is_exposed, parent_kind_id, deleted, created_on, created_by, updated_on, + updated_by) +VALUES ('release-channel', 'Release Channel', '',false, 0, false, now(), 1, now(), 1); + +INSERT INTO devtron_resource_schema(devtron_resource_id, version, schema, sample_schema, latest, created_on, created_by, updated_on, + updated_by) +VALUES ((select id from devtron_resource where kind = 'release-channel'), 'alpha1', + '{ + "type": "object", + "title": "Release Channel Schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "required": + [ + "version", + "kind", + "overview" + ], + "properties": + { + "kind": + { + "const": "release-channel" + }, + "version": + { + "enum": + [ + "alpha1" + ], + "type": "string" + }, + "overview": + { + "type": "object", + "properties": + { + "id": + { + "type": "number" + }, + "icon": + { + "type": "string", + "format": "uri" + }, + "name": + { + "type": "string" + }, + "tags": + { + "additionalProperties": + { + "type": "string" + } + }, + "idType": + { + "enum": + [ + "resourceObjectId", + "oldObjectId" + ], + "type": "string" + }, + "default": + { + "type": "boolean" + }, + "metadata": + { + "type": "object", + "properties": + {} + }, + "createdBy": + { + "type": "object", + "refType": "#/references/users" + }, + "createdOn": + { + "type": "string" + }, + "description": + { + "type": "string" + }, + "releaseChannelId": + { + "type": "string" + } + }, + "required": + [ + "id", + "idType", + "releaseChannelId" + ] + }, + "dependencies": + { + "type": "array" + } + } +}','{ + "type": "object", + "title": "Release Channel Schema", + "$schema": "https://json-schema.org/draft/2020-12/schema", + "required": + [ + "version", + "kind", + "overview" + ], + "properties": + { + "kind": + { + "const": "release-channel" + }, + "version": + { + "enum": + [ + "alpha1" + ], + "type": "string" + }, + "overview": + { + "type": "object", + "properties": + { + "id": + { + "type": "number" + }, + "icon": + { + "type": "string", + "format": "uri" + }, + "name": + { + "type": "string" + }, + "tags": + { + "additionalProperties": + { + "type": "string" + } + }, + "idType": + { + "enum": + [ + "resourceObjectId", + "oldObjectId" + ], + "type": "string" + }, + "default": + { + "type": "boolean" + }, + "metadata": + { + "type": "object", + "properties": + {} + }, + "createdBy": + { + "type": "object", + "refType": "#/references/users" + }, + "createdOn": + { + "type": "string" + }, + "description": + { + "type": "string" + }, + "releaseChannelId": + { + "type": "string" + } + }, + "required": + [ + "id", + "idType", + "releaseChannelId" + ] + }, + "dependencies": + { + "type": "array" + } + } +}',true, now(), 1, now(), 1); + + diff --git a/util/helper.go b/util/helper.go index bd158ae788..d2f632fc31 100644 --- a/util/helper.go +++ b/util/helper.go @@ -21,7 +21,6 @@ import ( "compress/gzip" "encoding/json" "fmt" - "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/devtron-labs/devtron/internal/middleware" "github.com/juju/errors" "io" @@ -31,7 +30,6 @@ import ( "os" "path/filepath" "regexp" - "sort" "strconv" "strings" "time" @@ -342,20 +340,6 @@ func MatchRegexExpression(exp string, text string) (bool, error) { return matched, nil } -func GetLatestImageAccToImagePushedAt(imageDetails []types.ImageDetail) types.ImageDetail { - sort.Slice(imageDetails, func(i, j int) bool { - return imageDetails[i].ImagePushedAt.After(*imageDetails[j].ImagePushedAt) - }) - return imageDetails[0] -} - -func GetReverseSortedImageDetails(imageDetails []types.ImageDetail) []types.ImageDetail { - sort.Slice(imageDetails, func(i, j int) bool { - return imageDetails[i].ImagePushedAt.Before(*imageDetails[j].ImagePushedAt) - }) - return imageDetails -} - func GetRandomStringOfGivenLength(length int) string { const charset = "abcdefghijklmnopqrstuvwxyz" + "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/LICENSE.txt b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/LICENSE.txt deleted file mode 100644 index d645695673..0000000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/LICENSE.txt +++ /dev/null @@ -1,202 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. - - END OF TERMS AND CONDITIONS - - APPENDIX: How to apply the Apache License to your work. - - To apply the Apache License to your work, attach the following - boilerplate notice, with the fields enclosed by brackets "[]" - replaced with your own identifying information. (Don't include - the brackets!) The text should be enclosed in the appropriate - comment syntax for the file format. We also recommend that a - file or class name and description of purpose be included on the - same "printed page" as the copyright notice for easier - identification within third-party archives. - - Copyright [yyyy] [name of copyright owner] - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go deleted file mode 100644 index d782c4ec9c..0000000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go +++ /dev/null @@ -1,326 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -type EncryptionType string - -// Enum values for EncryptionType -const ( - EncryptionTypeAes256 EncryptionType = "AES256" - EncryptionTypeKms EncryptionType = "KMS" -) - -// Values returns all known values for EncryptionType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (EncryptionType) Values() []EncryptionType { - return []EncryptionType{ - "AES256", - "KMS", - } -} - -type FindingSeverity string - -// Enum values for FindingSeverity -const ( - FindingSeverityInformational FindingSeverity = "INFORMATIONAL" - FindingSeverityLow FindingSeverity = "LOW" - FindingSeverityMedium FindingSeverity = "MEDIUM" - FindingSeverityHigh FindingSeverity = "HIGH" - FindingSeverityCritical FindingSeverity = "CRITICAL" - FindingSeverityUndefined FindingSeverity = "UNDEFINED" -) - -// Values returns all known values for FindingSeverity. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (FindingSeverity) Values() []FindingSeverity { - return []FindingSeverity{ - "INFORMATIONAL", - "LOW", - "MEDIUM", - "HIGH", - "CRITICAL", - "UNDEFINED", - } -} - -type ImageActionType string - -// Enum values for ImageActionType -const ( - ImageActionTypeExpire ImageActionType = "EXPIRE" -) - -// Values returns all known values for ImageActionType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ImageActionType) Values() []ImageActionType { - return []ImageActionType{ - "EXPIRE", - } -} - -type ImageFailureCode string - -// Enum values for ImageFailureCode -const ( - ImageFailureCodeInvalidImageDigest ImageFailureCode = "InvalidImageDigest" - ImageFailureCodeInvalidImageTag ImageFailureCode = "InvalidImageTag" - ImageFailureCodeImageTagDoesNotMatchDigest ImageFailureCode = "ImageTagDoesNotMatchDigest" - ImageFailureCodeImageNotFound ImageFailureCode = "ImageNotFound" - ImageFailureCodeMissingDigestAndTag ImageFailureCode = "MissingDigestAndTag" - ImageFailureCodeImageReferencedByManifestList ImageFailureCode = "ImageReferencedByManifestList" - ImageFailureCodeKmsError ImageFailureCode = "KmsError" -) - -// Values returns all known values for ImageFailureCode. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ImageFailureCode) Values() []ImageFailureCode { - return []ImageFailureCode{ - "InvalidImageDigest", - "InvalidImageTag", - "ImageTagDoesNotMatchDigest", - "ImageNotFound", - "MissingDigestAndTag", - "ImageReferencedByManifestList", - "KmsError", - } -} - -type ImageTagMutability string - -// Enum values for ImageTagMutability -const ( - ImageTagMutabilityMutable ImageTagMutability = "MUTABLE" - ImageTagMutabilityImmutable ImageTagMutability = "IMMUTABLE" -) - -// Values returns all known values for ImageTagMutability. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ImageTagMutability) Values() []ImageTagMutability { - return []ImageTagMutability{ - "MUTABLE", - "IMMUTABLE", - } -} - -type LayerAvailability string - -// Enum values for LayerAvailability -const ( - LayerAvailabilityAvailable LayerAvailability = "AVAILABLE" - LayerAvailabilityUnavailable LayerAvailability = "UNAVAILABLE" -) - -// Values returns all known values for LayerAvailability. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (LayerAvailability) Values() []LayerAvailability { - return []LayerAvailability{ - "AVAILABLE", - "UNAVAILABLE", - } -} - -type LayerFailureCode string - -// Enum values for LayerFailureCode -const ( - LayerFailureCodeInvalidLayerDigest LayerFailureCode = "InvalidLayerDigest" - LayerFailureCodeMissingLayerDigest LayerFailureCode = "MissingLayerDigest" -) - -// Values returns all known values for LayerFailureCode. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (LayerFailureCode) Values() []LayerFailureCode { - return []LayerFailureCode{ - "InvalidLayerDigest", - "MissingLayerDigest", - } -} - -type LifecyclePolicyPreviewStatus string - -// Enum values for LifecyclePolicyPreviewStatus -const ( - LifecyclePolicyPreviewStatusInProgress LifecyclePolicyPreviewStatus = "IN_PROGRESS" - LifecyclePolicyPreviewStatusComplete LifecyclePolicyPreviewStatus = "COMPLETE" - LifecyclePolicyPreviewStatusExpired LifecyclePolicyPreviewStatus = "EXPIRED" - LifecyclePolicyPreviewStatusFailed LifecyclePolicyPreviewStatus = "FAILED" -) - -// Values returns all known values for LifecyclePolicyPreviewStatus. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (LifecyclePolicyPreviewStatus) Values() []LifecyclePolicyPreviewStatus { - return []LifecyclePolicyPreviewStatus{ - "IN_PROGRESS", - "COMPLETE", - "EXPIRED", - "FAILED", - } -} - -type ReplicationStatus string - -// Enum values for ReplicationStatus -const ( - ReplicationStatusInProgress ReplicationStatus = "IN_PROGRESS" - ReplicationStatusComplete ReplicationStatus = "COMPLETE" - ReplicationStatusFailed ReplicationStatus = "FAILED" -) - -// Values returns all known values for ReplicationStatus. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ReplicationStatus) Values() []ReplicationStatus { - return []ReplicationStatus{ - "IN_PROGRESS", - "COMPLETE", - "FAILED", - } -} - -type RepositoryFilterType string - -// Enum values for RepositoryFilterType -const ( - RepositoryFilterTypePrefixMatch RepositoryFilterType = "PREFIX_MATCH" -) - -// Values returns all known values for RepositoryFilterType. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (RepositoryFilterType) Values() []RepositoryFilterType { - return []RepositoryFilterType{ - "PREFIX_MATCH", - } -} - -type ScanFrequency string - -// Enum values for ScanFrequency -const ( - ScanFrequencyScanOnPush ScanFrequency = "SCAN_ON_PUSH" - ScanFrequencyContinuousScan ScanFrequency = "CONTINUOUS_SCAN" - ScanFrequencyManual ScanFrequency = "MANUAL" -) - -// Values returns all known values for ScanFrequency. Note that this can be -// expanded in the future, and so it is only as up to date as the client. The -// ordering of this slice is not guaranteed to be stable across updates. -func (ScanFrequency) Values() []ScanFrequency { - return []ScanFrequency{ - "SCAN_ON_PUSH", - "CONTINUOUS_SCAN", - "MANUAL", - } -} - -type ScanningConfigurationFailureCode string - -// Enum values for ScanningConfigurationFailureCode -const ( - ScanningConfigurationFailureCodeRepositoryNotFound ScanningConfigurationFailureCode = "REPOSITORY_NOT_FOUND" -) - -// Values returns all known values for ScanningConfigurationFailureCode. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (ScanningConfigurationFailureCode) Values() []ScanningConfigurationFailureCode { - return []ScanningConfigurationFailureCode{ - "REPOSITORY_NOT_FOUND", - } -} - -type ScanningRepositoryFilterType string - -// Enum values for ScanningRepositoryFilterType -const ( - ScanningRepositoryFilterTypeWildcard ScanningRepositoryFilterType = "WILDCARD" -) - -// Values returns all known values for ScanningRepositoryFilterType. Note that -// this can be expanded in the future, and so it is only as up to date as the -// client. The ordering of this slice is not guaranteed to be stable across -// updates. -func (ScanningRepositoryFilterType) Values() []ScanningRepositoryFilterType { - return []ScanningRepositoryFilterType{ - "WILDCARD", - } -} - -type ScanStatus string - -// Enum values for ScanStatus -const ( - ScanStatusInProgress ScanStatus = "IN_PROGRESS" - ScanStatusComplete ScanStatus = "COMPLETE" - ScanStatusFailed ScanStatus = "FAILED" - ScanStatusUnsupportedImage ScanStatus = "UNSUPPORTED_IMAGE" - ScanStatusActive ScanStatus = "ACTIVE" - ScanStatusPending ScanStatus = "PENDING" - ScanStatusScanEligibilityExpired ScanStatus = "SCAN_ELIGIBILITY_EXPIRED" - ScanStatusFindingsUnavailable ScanStatus = "FINDINGS_UNAVAILABLE" -) - -// Values returns all known values for ScanStatus. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. -func (ScanStatus) Values() []ScanStatus { - return []ScanStatus{ - "IN_PROGRESS", - "COMPLETE", - "FAILED", - "UNSUPPORTED_IMAGE", - "ACTIVE", - "PENDING", - "SCAN_ELIGIBILITY_EXPIRED", - "FINDINGS_UNAVAILABLE", - } -} - -type ScanType string - -// Enum values for ScanType -const ( - ScanTypeBasic ScanType = "BASIC" - ScanTypeEnhanced ScanType = "ENHANCED" -) - -// Values returns all known values for ScanType. Note that this can be expanded in -// the future, and so it is only as up to date as the client. The ordering of this -// slice is not guaranteed to be stable across updates. -func (ScanType) Values() []ScanType { - return []ScanType{ - "BASIC", - "ENHANCED", - } -} - -type TagStatus string - -// Enum values for TagStatus -const ( - TagStatusTagged TagStatus = "TAGGED" - TagStatusUntagged TagStatus = "UNTAGGED" - TagStatusAny TagStatus = "ANY" -) - -// Values returns all known values for TagStatus. Note that this can be expanded -// in the future, and so it is only as up to date as the client. The ordering of -// this slice is not guaranteed to be stable across updates. -func (TagStatus) Values() []TagStatus { - return []TagStatus{ - "TAGGED", - "UNTAGGED", - "ANY", - } -} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go deleted file mode 100644 index 4b4782c5a5..0000000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go +++ /dev/null @@ -1,905 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - "fmt" - smithy "github.com/aws/smithy-go" -) - -// The specified layer upload does not contain any layer parts. -type EmptyUploadException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *EmptyUploadException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *EmptyUploadException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *EmptyUploadException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "EmptyUploadException" - } - return *e.ErrorCodeOverride -} -func (e *EmptyUploadException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified image has already been pushed, and there were no changes to the -// manifest or image tag after the last push. -type ImageAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ImageAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ImageAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ImageAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ImageAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *ImageAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified image digest does not match the digest that Amazon ECR calculated -// for the image. -type ImageDigestDoesNotMatchException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ImageDigestDoesNotMatchException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ImageDigestDoesNotMatchException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ImageDigestDoesNotMatchException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ImageDigestDoesNotMatchException" - } - return *e.ErrorCodeOverride -} -func (e *ImageDigestDoesNotMatchException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The image requested does not exist in the specified repository. -type ImageNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ImageNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ImageNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ImageNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ImageNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *ImageNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified image is tagged with a tag that already exists. The repository is -// configured for tag immutability. -type ImageTagAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ImageTagAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ImageTagAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ImageTagAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ImageTagAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *ImageTagAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The layer digest calculation performed by Amazon ECR upon receipt of the image -// layer does not match the digest specified. -type InvalidLayerException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidLayerException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidLayerException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidLayerException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidLayerException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidLayerException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The layer part size is not valid, or the first byte specified is not -// consecutive to the last byte of a previous layer part upload. -type InvalidLayerPartException struct { - Message *string - - ErrorCodeOverride *string - - RegistryId *string - RepositoryName *string - UploadId *string - LastValidByteReceived *int64 - - noSmithyDocumentSerde -} - -func (e *InvalidLayerPartException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidLayerPartException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidLayerPartException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidLayerPartException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidLayerPartException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified parameter is invalid. Review the available parameters for the API -// request. -type InvalidParameterException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidParameterException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidParameterException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidParameterException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidParameterException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidParameterException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// An invalid parameter has been specified. Tag keys can have a maximum character -// length of 128 characters, and tag values can have a maximum length of 256 -// characters. -type InvalidTagParameterException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *InvalidTagParameterException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *InvalidTagParameterException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *InvalidTagParameterException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "InvalidTagParameterException" - } - return *e.ErrorCodeOverride -} -func (e *InvalidTagParameterException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The operation failed due to a KMS exception. -type KmsException struct { - Message *string - - ErrorCodeOverride *string - - KmsError *string - - noSmithyDocumentSerde -} - -func (e *KmsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *KmsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *KmsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "KmsException" - } - return *e.ErrorCodeOverride -} -func (e *KmsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The image layer already exists in the associated repository. -type LayerAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *LayerAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *LayerAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *LayerAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "LayerAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *LayerAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified layer is not available because it is not associated with an -// image. Unassociated image layers may be cleaned up at any time. -type LayerInaccessibleException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *LayerInaccessibleException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *LayerInaccessibleException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *LayerInaccessibleException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "LayerInaccessibleException" - } - return *e.ErrorCodeOverride -} -func (e *LayerInaccessibleException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// Layer parts must be at least 5 MiB in size. -type LayerPartTooSmallException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *LayerPartTooSmallException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *LayerPartTooSmallException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *LayerPartTooSmallException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "LayerPartTooSmallException" - } - return *e.ErrorCodeOverride -} -func (e *LayerPartTooSmallException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified layers could not be found, or the specified layer is not valid -// for this repository. -type LayersNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *LayersNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *LayersNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *LayersNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "LayersNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *LayersNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The lifecycle policy could not be found, and no policy is set to the repository. -type LifecyclePolicyNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *LifecyclePolicyNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *LifecyclePolicyNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *LifecyclePolicyNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "LifecyclePolicyNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *LifecyclePolicyNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The previous lifecycle policy preview request has not completed. Wait and try -// again. -type LifecyclePolicyPreviewInProgressException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *LifecyclePolicyPreviewInProgressException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *LifecyclePolicyPreviewInProgressException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *LifecyclePolicyPreviewInProgressException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "LifecyclePolicyPreviewInProgressException" - } - return *e.ErrorCodeOverride -} -func (e *LifecyclePolicyPreviewInProgressException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// There is no dry run for this repository. -type LifecyclePolicyPreviewNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *LifecyclePolicyPreviewNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *LifecyclePolicyPreviewNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *LifecyclePolicyPreviewNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "LifecyclePolicyPreviewNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *LifecyclePolicyPreviewNotFoundException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The operation did not succeed because it would have exceeded a service limit -// for your account. For more information, see Amazon ECR service quotas (https://docs.aws.amazon.com/AmazonECR/latest/userguide/service-quotas.html) -// in the Amazon Elastic Container Registry User Guide. -type LimitExceededException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *LimitExceededException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *LimitExceededException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *LimitExceededException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "LimitExceededException" - } - return *e.ErrorCodeOverride -} -func (e *LimitExceededException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// A pull through cache rule with these settings already exists for the private -// registry. -type PullThroughCacheRuleAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *PullThroughCacheRuleAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *PullThroughCacheRuleAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *PullThroughCacheRuleAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "PullThroughCacheRuleAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *PullThroughCacheRuleAlreadyExistsException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The pull through cache rule was not found. Specify a valid pull through cache -// rule and try again. -type PullThroughCacheRuleNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *PullThroughCacheRuleNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *PullThroughCacheRuleNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *PullThroughCacheRuleNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "PullThroughCacheRuleNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *PullThroughCacheRuleNotFoundException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The manifest list is referencing an image that does not exist. -type ReferencedImagesNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ReferencedImagesNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ReferencedImagesNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ReferencedImagesNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ReferencedImagesNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *ReferencedImagesNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The registry doesn't have an associated registry policy. -type RegistryPolicyNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *RegistryPolicyNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *RegistryPolicyNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *RegistryPolicyNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "RegistryPolicyNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *RegistryPolicyNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified repository already exists in the specified registry. -type RepositoryAlreadyExistsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *RepositoryAlreadyExistsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *RepositoryAlreadyExistsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *RepositoryAlreadyExistsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "RepositoryAlreadyExistsException" - } - return *e.ErrorCodeOverride -} -func (e *RepositoryAlreadyExistsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified repository contains images. To delete a repository that contains -// images, you must force the deletion with the force parameter. -type RepositoryNotEmptyException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *RepositoryNotEmptyException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *RepositoryNotEmptyException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *RepositoryNotEmptyException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "RepositoryNotEmptyException" - } - return *e.ErrorCodeOverride -} -func (e *RepositoryNotEmptyException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified repository could not be found. Check the spelling of the -// specified repository and ensure that you are performing operations on the -// correct registry. -type RepositoryNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *RepositoryNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *RepositoryNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *RepositoryNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "RepositoryNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *RepositoryNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified repository and registry combination does not have an associated -// repository policy. -type RepositoryPolicyNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *RepositoryPolicyNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *RepositoryPolicyNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *RepositoryPolicyNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "RepositoryPolicyNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *RepositoryPolicyNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified image scan could not be found. Ensure that image scanning is -// enabled on the repository and try again. -type ScanNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ScanNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ScanNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ScanNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ScanNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *ScanNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// These errors are usually caused by a server-side issue. -type ServerException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ServerException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ServerException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ServerException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ServerException" - } - return *e.ErrorCodeOverride -} -func (e *ServerException) ErrorFault() smithy.ErrorFault { return smithy.FaultServer } - -// The list of tags on the repository is over the limit. The maximum number of -// tags that can be applied to a repository is 50. -type TooManyTagsException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *TooManyTagsException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *TooManyTagsException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *TooManyTagsException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "TooManyTagsException" - } - return *e.ErrorCodeOverride -} -func (e *TooManyTagsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The image is of a type that cannot be scanned. -type UnsupportedImageTypeException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedImageTypeException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedImageTypeException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedImageTypeException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedImageTypeException" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedImageTypeException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// The specified upstream registry isn't supported. -type UnsupportedUpstreamRegistryException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UnsupportedUpstreamRegistryException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UnsupportedUpstreamRegistryException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UnsupportedUpstreamRegistryException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UnsupportedUpstreamRegistryException" - } - return *e.ErrorCodeOverride -} -func (e *UnsupportedUpstreamRegistryException) ErrorFault() smithy.ErrorFault { - return smithy.FaultClient -} - -// The upload could not be found, or the specified upload ID is not valid for this -// repository. -type UploadNotFoundException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *UploadNotFoundException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *UploadNotFoundException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *UploadNotFoundException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "UploadNotFoundException" - } - return *e.ErrorCodeOverride -} -func (e *UploadNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } - -// There was an exception validating this request. -type ValidationException struct { - Message *string - - ErrorCodeOverride *string - - noSmithyDocumentSerde -} - -func (e *ValidationException) Error() string { - return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) -} -func (e *ValidationException) ErrorMessage() string { - if e.Message == nil { - return "" - } - return *e.Message -} -func (e *ValidationException) ErrorCode() string { - if e == nil || e.ErrorCodeOverride == nil { - return "ValidationException" - } - return *e.ErrorCodeOverride -} -func (e *ValidationException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go deleted file mode 100644 index 1dbaf77259..0000000000 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go +++ /dev/null @@ -1,882 +0,0 @@ -// Code generated by smithy-go-codegen DO NOT EDIT. - -package types - -import ( - smithydocument "github.com/aws/smithy-go/document" - "time" -) - -// This data type is used in the ImageScanFinding data type. -type Attribute struct { - - // The attribute key. - // - // This member is required. - Key *string - - // The value assigned to the attribute key. - Value *string - - noSmithyDocumentSerde -} - -// An object representing authorization data for an Amazon ECR registry. -type AuthorizationData struct { - - // A base64-encoded string that contains authorization data for the specified - // Amazon ECR registry. When the string is decoded, it is presented in the format - // user:password for private registry authentication using docker login . - AuthorizationToken *string - - // The Unix time in seconds and milliseconds when the authorization token expires. - // Authorization tokens are valid for 12 hours. - ExpiresAt *time.Time - - // The registry URL to use for this authorization token in a docker login command. - // The Amazon ECR registry URL format is - // https://aws_account_id.dkr.ecr.region.amazonaws.com . For example, - // https://012345678910.dkr.ecr.us-east-1.amazonaws.com .. - ProxyEndpoint *string - - noSmithyDocumentSerde -} - -// The image details of the Amazon ECR container image. -type AwsEcrContainerImageDetails struct { - - // The architecture of the Amazon ECR container image. - Architecture *string - - // The image author of the Amazon ECR container image. - Author *string - - // The image hash of the Amazon ECR container image. - ImageHash *string - - // The image tags attached to the Amazon ECR container image. - ImageTags []string - - // The platform of the Amazon ECR container image. - Platform *string - - // The date and time the Amazon ECR container image was pushed. - PushedAt *time.Time - - // The registry the Amazon ECR container image belongs to. - Registry *string - - // The name of the repository the Amazon ECR container image resides in. - RepositoryName *string - - noSmithyDocumentSerde -} - -// The CVSS score for a finding. -type CvssScore struct { - - // The base CVSS score used for the finding. - BaseScore float64 - - // The vector string of the CVSS score. - ScoringVector *string - - // The source of the CVSS score. - Source *string - - // The version of CVSS used for the score. - Version *string - - noSmithyDocumentSerde -} - -// Details on adjustments Amazon Inspector made to the CVSS score for a finding. -type CvssScoreAdjustment struct { - - // The metric used to adjust the CVSS score. - Metric *string - - // The reason the CVSS score has been adjustment. - Reason *string - - noSmithyDocumentSerde -} - -// Information about the CVSS score. -type CvssScoreDetails struct { - - // An object that contains details about adjustment Amazon Inspector made to the - // CVSS score. - Adjustments []CvssScoreAdjustment - - // The CVSS score. - Score float64 - - // The source for the CVSS score. - ScoreSource *string - - // The vector for the CVSS score. - ScoringVector *string - - // The CVSS version used in scoring. - Version *string - - noSmithyDocumentSerde -} - -// An object representing a filter on a DescribeImages operation. -type DescribeImagesFilter struct { - - // The tag status with which to filter your DescribeImages results. You can filter - // results based on whether they are TAGGED or UNTAGGED . - TagStatus TagStatus - - noSmithyDocumentSerde -} - -// The encryption configuration for the repository. This determines how the -// contents of your repository are encrypted at rest. By default, when no -// encryption configuration is set or the AES256 encryption type is used, Amazon -// ECR uses server-side encryption with Amazon S3-managed encryption keys which -// encrypts your data at rest using an AES-256 encryption algorithm. This does not -// require any action on your part. For more control over the encryption of the -// contents of your repository, you can use server-side encryption with Key -// Management Service key stored in Key Management Service (KMS) to encrypt your -// images. For more information, see Amazon ECR encryption at rest (https://docs.aws.amazon.com/AmazonECR/latest/userguide/encryption-at-rest.html) -// in the Amazon Elastic Container Registry User Guide. -type EncryptionConfiguration struct { - - // The encryption type to use. If you use the KMS encryption type, the contents of - // the repository will be encrypted using server-side encryption with Key - // Management Service key stored in KMS. When you use KMS to encrypt your data, you - // can either use the default Amazon Web Services managed KMS key for Amazon ECR, - // or specify your own KMS key, which you already created. For more information, - // see Protecting data using server-side encryption with an KMS key stored in Key - // Management Service (SSE-KMS) (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingKMSEncryption.html) - // in the Amazon Simple Storage Service Console Developer Guide. If you use the - // AES256 encryption type, Amazon ECR uses server-side encryption with Amazon - // S3-managed encryption keys which encrypts the images in the repository using an - // AES-256 encryption algorithm. For more information, see Protecting data using - // server-side encryption with Amazon S3-managed encryption keys (SSE-S3) (https://docs.aws.amazon.com/AmazonS3/latest/dev/UsingServerSideEncryption.html) - // in the Amazon Simple Storage Service Console Developer Guide. - // - // This member is required. - EncryptionType EncryptionType - - // If you use the KMS encryption type, specify the KMS key to use for encryption. - // The alias, key ID, or full ARN of the KMS key can be specified. The key must - // exist in the same Region as the repository. If no key is specified, the default - // Amazon Web Services managed KMS key for Amazon ECR will be used. - KmsKey *string - - noSmithyDocumentSerde -} - -// The details of an enhanced image scan. This is returned when enhanced scanning -// is enabled for your private registry. -type EnhancedImageScanFinding struct { - - // The Amazon Web Services account ID associated with the image. - AwsAccountId *string - - // The description of the finding. - Description *string - - // The Amazon Resource Number (ARN) of the finding. - FindingArn *string - - // The date and time that the finding was first observed. - FirstObservedAt *time.Time - - // The date and time that the finding was last observed. - LastObservedAt *time.Time - - // An object that contains the details of a package vulnerability finding. - PackageVulnerabilityDetails *PackageVulnerabilityDetails - - // An object that contains the details about how to remediate a finding. - Remediation *Remediation - - // Contains information on the resources involved in a finding. - Resources []Resource - - // The Amazon Inspector score given to the finding. - Score float64 - - // An object that contains details of the Amazon Inspector score. - ScoreDetails *ScoreDetails - - // The severity of the finding. - Severity *string - - // The status of the finding. - Status *string - - // The title of the finding. - Title *string - - // The type of the finding. - Type *string - - // The date and time the finding was last updated at. - UpdatedAt *time.Time - - noSmithyDocumentSerde -} - -// An object representing an Amazon ECR image. -type Image struct { - - // An object containing the image tag and image digest associated with an image. - ImageId *ImageIdentifier - - // The image manifest associated with the image. - ImageManifest *string - - // The manifest media type of the image. - ImageManifestMediaType *string - - // The Amazon Web Services account ID associated with the registry containing the - // image. - RegistryId *string - - // The name of the repository associated with the image. - RepositoryName *string - - noSmithyDocumentSerde -} - -// An object that describes an image returned by a DescribeImages operation. -type ImageDetail struct { - - // The artifact media type of the image. - ArtifactMediaType *string - - // The sha256 digest of the image manifest. - ImageDigest *string - - // The media type of the image manifest. - ImageManifestMediaType *string - - // The date and time, expressed in standard JavaScript date format, at which the - // current image was pushed to the repository. - ImagePushedAt *time.Time - - // A summary of the last completed image scan. - ImageScanFindingsSummary *ImageScanFindingsSummary - - // The current state of the scan. - ImageScanStatus *ImageScanStatus - - // The size, in bytes, of the image in the repository. If the image is a manifest - // list, this will be the max size of all manifests in the list. Beginning with - // Docker version 1.9, the Docker client compresses image layers before pushing - // them to a V2 Docker registry. The output of the docker images command shows the - // uncompressed image size, so it may return a larger image size than the image - // sizes returned by DescribeImages . - ImageSizeInBytes *int64 - - // The list of tags associated with this image. - ImageTags []string - - // The date and time, expressed in standard JavaScript date format, when Amazon - // ECR recorded the last image pull. Amazon ECR refreshes the last image pull - // timestamp at least once every 24 hours. For example, if you pull an image once a - // day then the lastRecordedPullTime timestamp will indicate the exact time that - // the image was last pulled. However, if you pull an image once an hour, because - // Amazon ECR refreshes the lastRecordedPullTime timestamp at least once every 24 - // hours, the result may not be the exact time that the image was last pulled. - LastRecordedPullTime *time.Time - - // The Amazon Web Services account ID associated with the registry to which this - // image belongs. - RegistryId *string - - // The name of the repository to which this image belongs. - RepositoryName *string - - noSmithyDocumentSerde -} - -// An object representing an Amazon ECR image failure. -type ImageFailure struct { - - // The code associated with the failure. - FailureCode ImageFailureCode - - // The reason for the failure. - FailureReason *string - - // The image ID associated with the failure. - ImageId *ImageIdentifier - - noSmithyDocumentSerde -} - -// An object with identifying information for an image in an Amazon ECR repository. -type ImageIdentifier struct { - - // The sha256 digest of the image manifest. - ImageDigest *string - - // The tag used for the image. - ImageTag *string - - noSmithyDocumentSerde -} - -// The status of the replication process for an image. -type ImageReplicationStatus struct { - - // The failure code for a replication that has failed. - FailureCode *string - - // The destination Region for the image replication. - Region *string - - // The Amazon Web Services account ID associated with the registry to which the - // image belongs. - RegistryId *string - - // The image replication status. - Status ReplicationStatus - - noSmithyDocumentSerde -} - -// Contains information about an image scan finding. -type ImageScanFinding struct { - - // A collection of attributes of the host from which the finding is generated. - Attributes []Attribute - - // The description of the finding. - Description *string - - // The name associated with the finding, usually a CVE number. - Name *string - - // The finding severity. - Severity FindingSeverity - - // A link containing additional details about the security vulnerability. - Uri *string - - noSmithyDocumentSerde -} - -// The details of an image scan. -type ImageScanFindings struct { - - // Details about the enhanced scan findings from Amazon Inspector. - EnhancedFindings []EnhancedImageScanFinding - - // The image vulnerability counts, sorted by severity. - FindingSeverityCounts map[string]int32 - - // The findings from the image scan. - Findings []ImageScanFinding - - // The time of the last completed image scan. - ImageScanCompletedAt *time.Time - - // The time when the vulnerability data was last scanned. - VulnerabilitySourceUpdatedAt *time.Time - - noSmithyDocumentSerde -} - -// A summary of the last completed image scan. -type ImageScanFindingsSummary struct { - - // The image vulnerability counts, sorted by severity. - FindingSeverityCounts map[string]int32 - - // The time of the last completed image scan. - ImageScanCompletedAt *time.Time - - // The time when the vulnerability data was last scanned. - VulnerabilitySourceUpdatedAt *time.Time - - noSmithyDocumentSerde -} - -// The image scanning configuration for a repository. -type ImageScanningConfiguration struct { - - // The setting that determines whether images are scanned after being pushed to a - // repository. If set to true , images will be scanned after being pushed. If this - // parameter is not specified, it will default to false and images will not be - // scanned unless a scan is manually started with the API_StartImageScan (https://docs.aws.amazon.com/AmazonECR/latest/APIReference/API_StartImageScan.html) - // API. - ScanOnPush bool - - noSmithyDocumentSerde -} - -// The current status of an image scan. -type ImageScanStatus struct { - - // The description of the image scan status. - Description *string - - // The current state of an image scan. - Status ScanStatus - - noSmithyDocumentSerde -} - -// An object representing an Amazon ECR image layer. -type Layer struct { - - // The availability status of the image layer. - LayerAvailability LayerAvailability - - // The sha256 digest of the image layer. - LayerDigest *string - - // The size, in bytes, of the image layer. - LayerSize *int64 - - // The media type of the layer, such as - // application/vnd.docker.image.rootfs.diff.tar.gzip or - // application/vnd.oci.image.layer.v1.tar+gzip . - MediaType *string - - noSmithyDocumentSerde -} - -// An object representing an Amazon ECR image layer failure. -type LayerFailure struct { - - // The failure code associated with the failure. - FailureCode LayerFailureCode - - // The reason for the failure. - FailureReason *string - - // The layer digest associated with the failure. - LayerDigest *string - - noSmithyDocumentSerde -} - -// The filter for the lifecycle policy preview. -type LifecyclePolicyPreviewFilter struct { - - // The tag status of the image. - TagStatus TagStatus - - noSmithyDocumentSerde -} - -// The result of the lifecycle policy preview. -type LifecyclePolicyPreviewResult struct { - - // The type of action to be taken. - Action *LifecyclePolicyRuleAction - - // The priority of the applied rule. - AppliedRulePriority *int32 - - // The sha256 digest of the image manifest. - ImageDigest *string - - // The date and time, expressed in standard JavaScript date format, at which the - // current image was pushed to the repository. - ImagePushedAt *time.Time - - // The list of tags associated with this image. - ImageTags []string - - noSmithyDocumentSerde -} - -// The summary of the lifecycle policy preview request. -type LifecyclePolicyPreviewSummary struct { - - // The number of expiring images. - ExpiringImageTotalCount *int32 - - noSmithyDocumentSerde -} - -// The type of action to be taken. -type LifecyclePolicyRuleAction struct { - - // The type of action to be taken. - Type ImageActionType - - noSmithyDocumentSerde -} - -// An object representing a filter on a ListImages operation. -type ListImagesFilter struct { - - // The tag status with which to filter your ListImages results. You can filter - // results based on whether they are TAGGED or UNTAGGED . - TagStatus TagStatus - - noSmithyDocumentSerde -} - -// Information about a package vulnerability finding. -type PackageVulnerabilityDetails struct { - - // An object that contains details about the CVSS score of a finding. - Cvss []CvssScore - - // One or more URLs that contain details about this vulnerability type. - ReferenceUrls []string - - // One or more vulnerabilities related to the one identified in this finding. - RelatedVulnerabilities []string - - // The source of the vulnerability information. - Source *string - - // A URL to the source of the vulnerability information. - SourceUrl *string - - // The date and time that this vulnerability was first added to the vendor's - // database. - VendorCreatedAt *time.Time - - // The severity the vendor has given to this vulnerability type. - VendorSeverity *string - - // The date and time the vendor last updated this vulnerability in their database. - VendorUpdatedAt *time.Time - - // The ID given to this vulnerability. - VulnerabilityId *string - - // The packages impacted by this vulnerability. - VulnerablePackages []VulnerablePackage - - noSmithyDocumentSerde -} - -// The details of a pull through cache rule. -type PullThroughCacheRule struct { - - // The date and time the pull through cache was created. - CreatedAt *time.Time - - // The Amazon ECR repository prefix associated with the pull through cache rule. - EcrRepositoryPrefix *string - - // The Amazon Web Services account ID associated with the registry the pull - // through cache rule is associated with. - RegistryId *string - - // The upstream registry URL associated with the pull through cache rule. - UpstreamRegistryUrl *string - - noSmithyDocumentSerde -} - -// Details about the recommended course of action to remediate the finding. -type Recommendation struct { - - // The recommended course of action to remediate the finding. - Text *string - - // The URL address to the CVE remediation recommendations. - Url *string - - noSmithyDocumentSerde -} - -// The scanning configuration for a private registry. -type RegistryScanningConfiguration struct { - - // The scanning rules associated with the registry. - Rules []RegistryScanningRule - - // The type of scanning configured for the registry. - ScanType ScanType - - noSmithyDocumentSerde -} - -// The details of a scanning rule for a private registry. -type RegistryScanningRule struct { - - // The repository filters associated with the scanning configuration for a private - // registry. - // - // This member is required. - RepositoryFilters []ScanningRepositoryFilter - - // The frequency that scans are performed at for a private registry. When the - // ENHANCED scan type is specified, the supported scan frequencies are - // CONTINUOUS_SCAN and SCAN_ON_PUSH . When the BASIC scan type is specified, the - // SCAN_ON_PUSH scan frequency is supported. If scan on push is not specified, then - // the MANUAL scan frequency is set by default. - // - // This member is required. - ScanFrequency ScanFrequency - - noSmithyDocumentSerde -} - -// Information on how to remediate a finding. -type Remediation struct { - - // An object that contains information about the recommended course of action to - // remediate the finding. - Recommendation *Recommendation - - noSmithyDocumentSerde -} - -// The replication configuration for a registry. -type ReplicationConfiguration struct { - - // An array of objects representing the replication destinations and repository - // filters for a replication configuration. - // - // This member is required. - Rules []ReplicationRule - - noSmithyDocumentSerde -} - -// An array of objects representing the destination for a replication rule. -type ReplicationDestination struct { - - // The Region to replicate to. - // - // This member is required. - Region *string - - // The Amazon Web Services account ID of the Amazon ECR private registry to - // replicate to. When configuring cross-Region replication within your own - // registry, specify your own account ID. - // - // This member is required. - RegistryId *string - - noSmithyDocumentSerde -} - -// An array of objects representing the replication destinations and repository -// filters for a replication configuration. -type ReplicationRule struct { - - // An array of objects representing the destination for a replication rule. - // - // This member is required. - Destinations []ReplicationDestination - - // An array of objects representing the filters for a replication rule. Specifying - // a repository filter for a replication rule provides a method for controlling - // which repositories in a private registry are replicated. - RepositoryFilters []RepositoryFilter - - noSmithyDocumentSerde -} - -// An object representing a repository. -type Repository struct { - - // The date and time, in JavaScript date format, when the repository was created. - CreatedAt *time.Time - - // The encryption configuration for the repository. This determines how the - // contents of your repository are encrypted at rest. - EncryptionConfiguration *EncryptionConfiguration - - // The image scanning configuration for a repository. - ImageScanningConfiguration *ImageScanningConfiguration - - // The tag mutability setting for the repository. - ImageTagMutability ImageTagMutability - - // The Amazon Web Services account ID associated with the registry that contains - // the repository. - RegistryId *string - - // The Amazon Resource Name (ARN) that identifies the repository. The ARN contains - // the arn:aws:ecr namespace, followed by the region of the repository, Amazon Web - // Services account ID of the repository owner, repository namespace, and - // repository name. For example, - // arn:aws:ecr:region:012345678910:repository-namespace/repository-name . - RepositoryArn *string - - // The name of the repository. - RepositoryName *string - - // The URI for the repository. You can use this URI for container image push and - // pull operations. - RepositoryUri *string - - noSmithyDocumentSerde -} - -// The filter settings used with image replication. Specifying a repository filter -// to a replication rule provides a method for controlling which repositories in a -// private registry are replicated. If no filters are added, the contents of all -// repositories are replicated. -type RepositoryFilter struct { - - // The repository filter details. When the PREFIX_MATCH filter type is specified, - // this value is required and should be the repository name prefix to configure - // replication for. - // - // This member is required. - Filter *string - - // The repository filter type. The only supported value is PREFIX_MATCH , which is - // a repository name prefix specified with the filter parameter. - // - // This member is required. - FilterType RepositoryFilterType - - noSmithyDocumentSerde -} - -// The details of the scanning configuration for a repository. -type RepositoryScanningConfiguration struct { - - // The scan filters applied to the repository. - AppliedScanFilters []ScanningRepositoryFilter - - // The ARN of the repository. - RepositoryArn *string - - // The name of the repository. - RepositoryName *string - - // The scan frequency for the repository. - ScanFrequency ScanFrequency - - // Whether or not scan on push is configured for the repository. - ScanOnPush bool - - noSmithyDocumentSerde -} - -// The details about any failures associated with the scanning configuration of a -// repository. -type RepositoryScanningConfigurationFailure struct { - - // The failure code. - FailureCode ScanningConfigurationFailureCode - - // The reason for the failure. - FailureReason *string - - // The name of the repository. - RepositoryName *string - - noSmithyDocumentSerde -} - -// Details about the resource involved in a finding. -type Resource struct { - - // An object that contains details about the resource involved in a finding. - Details *ResourceDetails - - // The ID of the resource. - Id *string - - // The tags attached to the resource. - Tags map[string]string - - // The type of resource. - Type *string - - noSmithyDocumentSerde -} - -// Contains details about the resource involved in the finding. -type ResourceDetails struct { - - // An object that contains details about the Amazon ECR container image involved - // in the finding. - AwsEcrContainerImage *AwsEcrContainerImageDetails - - noSmithyDocumentSerde -} - -// The details of a scanning repository filter. For more information on how to use -// filters, see Using filters (https://docs.aws.amazon.com/AmazonECR/latest/userguide/image-scanning.html#image-scanning-filters) -// in the Amazon Elastic Container Registry User Guide. -type ScanningRepositoryFilter struct { - - // The filter to use when scanning. - // - // This member is required. - Filter *string - - // The type associated with the filter. - // - // This member is required. - FilterType ScanningRepositoryFilterType - - noSmithyDocumentSerde -} - -// Information about the Amazon Inspector score given to a finding. -type ScoreDetails struct { - - // An object that contains details about the CVSS score given to a finding. - Cvss *CvssScoreDetails - - noSmithyDocumentSerde -} - -// The metadata to apply to a resource to help you categorize and organize them. -// Each tag consists of a key and a value, both of which you define. Tag keys can -// have a maximum character length of 128 characters, and tag values can have a -// maximum length of 256 characters. -type Tag struct { - - // One part of a key-value pair that make up a tag. A key is a general label that - // acts like a category for more specific tag values. - // - // This member is required. - Key *string - - // A value acts as a descriptor within a tag category (key). - // - // This member is required. - Value *string - - noSmithyDocumentSerde -} - -// Information on the vulnerable package identified by a finding. -type VulnerablePackage struct { - - // The architecture of the vulnerable package. - Arch *string - - // The epoch of the vulnerable package. - Epoch *int32 - - // The file path of the vulnerable package. - FilePath *string - - // The name of the vulnerable package. - Name *string - - // The package manager of the vulnerable package. - PackageManager *string - - // The release of the vulnerable package. - Release *string - - // The source layer hash of the vulnerable package. - SourceLayerHash *string - - // The version of the vulnerable package. - Version *string - - noSmithyDocumentSerde -} - -type noSmithyDocumentSerde = smithydocument.NoSerde diff --git a/vendor/github.com/aws/smithy-go/.gitignore b/vendor/github.com/aws/smithy-go/.gitignore deleted file mode 100644 index c92d6105eb..0000000000 --- a/vendor/github.com/aws/smithy-go/.gitignore +++ /dev/null @@ -1,26 +0,0 @@ -# Eclipse -.classpath -.project -.settings/ - -# Intellij -.idea/ -*.iml -*.iws - -# Mac -.DS_Store - -# Maven -target/ -**/dependency-reduced-pom.xml - -# Gradle -/.gradle -build/ -*/out/ -*/*/out/ - -# VS Code -bin/ -.vscode/ diff --git a/vendor/github.com/aws/smithy-go/.travis.yml b/vendor/github.com/aws/smithy-go/.travis.yml deleted file mode 100644 index f8d1035cc3..0000000000 --- a/vendor/github.com/aws/smithy-go/.travis.yml +++ /dev/null @@ -1,28 +0,0 @@ -language: go -sudo: true -dist: bionic - -branches: - only: - - main - -os: - - linux - - osx - # Travis doesn't work with windows and Go tip - #- windows - -go: - - tip - -matrix: - allow_failures: - - go: tip - -before_install: - - if [ "$TRAVIS_OS_NAME" = "windows" ]; then choco install make; fi - - (cd /tmp/; go get golang.org/x/lint/golint) - -script: - - make go test -v ./...; - diff --git a/vendor/github.com/aws/smithy-go/CHANGELOG.md b/vendor/github.com/aws/smithy-go/CHANGELOG.md deleted file mode 100644 index b9171b88b9..0000000000 --- a/vendor/github.com/aws/smithy-go/CHANGELOG.md +++ /dev/null @@ -1,182 +0,0 @@ -# Release (2023-08-18) - -* No change notes available for this release. - -# Release (2023-08-07) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.14.1 - * **Bug Fix**: Prevent duplicated error returns in EndpointResolverV2 default implementation. - -# Release (2023-07-31) - -## General Highlights -* **Feature**: Adds support for smithy-modeled endpoint resolution. - -# Release (2022-12-02) - -* No change notes available for this release. - -# Release (2022-10-24) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.13.4 - * **Bug Fix**: fixed document type checking for encoding nested types - -# Release (2022-09-14) - -* No change notes available for this release. - -# Release (v1.13.2) - -* No change notes available for this release. - -# Release (v1.13.1) - -* No change notes available for this release. - -# Release (v1.13.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.13.0 - * **Feature**: Adds support for the Smithy httpBearerAuth authentication trait to smithy-go. This allows the SDK to support the bearer authentication flow for API operations decorated with httpBearerAuth. An API client will need to be provided with its own bearer.TokenProvider implementation or use the bearer.StaticTokenProvider implementation. - -# Release (v1.12.1) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.12.1 - * **Bug Fix**: Fixes a bug where JSON object keys were not escaped. - -# Release (v1.12.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.12.0 - * **Feature**: `transport/http`: Add utility for setting context metadata when operation serializer automatically assigns content-type default value. - -# Release (v1.11.3) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.11.3 - * **Dependency Update**: Updates smithy-go unit test dependency go-cmp to 0.5.8. - -# Release (v1.11.2) - -* No change notes available for this release. - -# Release (v1.11.1) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.11.1 - * **Bug Fix**: Updates the smithy-go HTTP Request to correctly handle building the request to an http.Request. Related to [aws/aws-sdk-go-v2#1583](https://github.com/aws/aws-sdk-go-v2/issues/1583) - -# Release (v1.11.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.11.0 - * **Feature**: Updates deserialization of header list to supported quoted strings - -# Release (v1.10.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.10.0 - * **Feature**: Add `ptr.Duration`, `ptr.ToDuration`, `ptr.DurationSlice`, `ptr.ToDurationSlice`, `ptr.DurationMap`, and `ptr.ToDurationMap` functions for the `time.Duration` type. - -# Release (v1.9.1) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.9.1 - * **Documentation**: Fixes various typos in Go package documentation. - -# Release (v1.9.0) - -## Module Highlights -* `github.com/aws/smithy-go`: v1.9.0 - * **Feature**: sync: OnceErr, can be used to concurrently record a signal when an error has occurred. - * **Bug Fix**: `transport/http`: CloseResponseBody and ErrorCloseResponseBody middleware have been updated to ensure that the body is fully drained before closing. - -# Release v1.8.1 - -### Smithy Go Module -* **Bug Fix**: Fixed an issue that would cause the HTTP Content-Length to be set to 0 if the stream body was not set. - * Fixes [aws/aws-sdk-go-v2#1418](https://github.com/aws/aws-sdk-go-v2/issues/1418) - -# Release v1.8.0 - -### Smithy Go Module - -* `time`: Add support for parsing additional DateTime timestamp format ([#324](https://github.com/aws/smithy-go/pull/324)) - * Adds support for parsing DateTime timestamp formatted time similar to RFC 3339, but without the `Z` character, nor UTC offset. - * Fixes [#1387](https://github.com/aws/aws-sdk-go-v2/issues/1387) - -# Release v1.7.0 - -### Smithy Go Module -* `ptr`: Handle error for deferred file close call ([#314](https://github.com/aws/smithy-go/pull/314)) - * Handle error for defer close call -* `middleware`: Add Clone to Metadata ([#318](https://github.com/aws/smithy-go/pull/318)) - * Adds a new Clone method to the middleware Metadata type. This provides a shallow clone of the entries in the Metadata. -* `document`: Add new package for document shape serialization support ([#310](https://github.com/aws/smithy-go/pull/310)) - -### Codegen -* Add Smithy Document Shape Support ([#310](https://github.com/aws/smithy-go/pull/310)) - * Adds support for Smithy Document shapes and supporting types for protocols to implement support - -# Release v1.6.0 (2021-07-15) - -### Smithy Go Module -* `encoding/httpbinding`: Support has been added for encoding `float32` and `float64` values that are `NaN`, `Infinity`, or `-Infinity`. ([#316](https://github.com/aws/smithy-go/pull/316)) - -### Codegen -* Adds support for handling `float32` and `float64` `NaN` values in HTTP Protocol Unit Tests. ([#316](https://github.com/aws/smithy-go/pull/316)) -* Adds support protocol generator implementations to override the error code string returned by `ErrorCode` methods on generated error types. ([#315](https://github.com/aws/smithy-go/pull/315)) - -# Release v1.5.0 (2021-06-25) - -### Smithy Go module -* `time`: Update time parsing to not be as strict for HTTPDate and DateTime ([#307](https://github.com/aws/smithy-go/pull/307)) - * Fixes [#302](https://github.com/aws/smithy-go/issues/302) by changing time to UTC before formatting so no local offset time is lost. - -### Codegen -* Adds support for integrating client members via plugins ([#301](https://github.com/aws/smithy-go/pull/301)) -* Fix serialization of enum types marked with payload trait ([#296](https://github.com/aws/smithy-go/pull/296)) -* Update generation of API client modules to include a manifest of files generated ([#283](https://github.com/aws/smithy-go/pull/283)) -* Update Group Java group ID for smithy-go generator ([#298](https://github.com/aws/smithy-go/pull/298)) -* Support the delegation of determining the errors that can occur for an operation ([#304](https://github.com/aws/smithy-go/pull/304)) -* Support for marking and documenting deprecated client config fields. ([#303](https://github.com/aws/smithy-go/pull/303)) - -# Release v1.4.0 (2021-05-06) - -### Smithy Go module -* `encoding/xml`: Fix escaping of Next Line and Line Start in XML Encoder ([#267](https://github.com/aws/smithy-go/pull/267)) - -### Codegen -* Add support for Smithy 1.7 ([#289](https://github.com/aws/smithy-go/pull/289)) -* Add support for httpQueryParams location -* Add support for model renaming conflict resolution with service closure - -# Release v1.3.1 (2021-04-08) - -### Smithy Go module -* `transport/http`: Loosen endpoint hostname validation to allow specifying port numbers. ([#279](https://github.com/aws/smithy-go/pull/279)) -* `io`: Fix RingBuffer panics due to out of bounds index. ([#282](https://github.com/aws/smithy-go/pull/282)) - -# Release v1.3.0 (2021-04-01) - -### Smithy Go module -* `transport/http`: Add utility to safely join string to url path, and url raw query. - -### Codegen -* Update HttpBindingProtocolGenerator to use http/transport JoinPath and JoinQuery utility. - -# Release v1.2.0 (2021-03-12) - -### Smithy Go module -* Fix support for parsing shortened year format in HTTP Date header. -* Fix GitHub APIDiff action workflow to get gorelease tool correctly. -* Fix codegen artifact unit test for Go 1.16 - -### Codegen -* Fix generating paginator nil parameter handling before usage. -* Fix Serialize unboxed members decorated as required. -* Add ability to define resolvers at both client construction and operation invocation. -* Support for extending paginators with custom runtime trait diff --git a/vendor/github.com/aws/smithy-go/CODE_OF_CONDUCT.md b/vendor/github.com/aws/smithy-go/CODE_OF_CONDUCT.md deleted file mode 100644 index 5b627cfa60..0000000000 --- a/vendor/github.com/aws/smithy-go/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,4 +0,0 @@ -## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact -opensource-codeofconduct@amazon.com with any additional questions or comments. diff --git a/vendor/github.com/aws/smithy-go/CONTRIBUTING.md b/vendor/github.com/aws/smithy-go/CONTRIBUTING.md deleted file mode 100644 index c4b6a1c508..0000000000 --- a/vendor/github.com/aws/smithy-go/CONTRIBUTING.md +++ /dev/null @@ -1,59 +0,0 @@ -# Contributing Guidelines - -Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional -documentation, we greatly value feedback and contributions from our community. - -Please read through this document before submitting any issues or pull requests to ensure we have all the necessary -information to effectively respond to your bug report or contribution. - - -## Reporting Bugs/Feature Requests - -We welcome you to use the GitHub issue tracker to report bugs or suggest features. - -When filing an issue, please check existing open, or recently closed, issues to make sure somebody else hasn't already -reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: - -* A reproducible test case or series of steps -* The version of our code being used -* Any modifications you've made relevant to the bug -* Anything unusual about your environment or deployment - - -## Contributing via Pull Requests -Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: - -1. You are working against the latest source on the *main* branch. -2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. -3. You open an issue to discuss any significant work - we would hate for your time to be wasted. - -To send us a pull request, please: - -1. Fork the repository. -2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. -3. Ensure local tests pass. -4. Commit to your fork using clear commit messages. -5. Send us a pull request, answering any default questions in the pull request interface. -6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. - -GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and -[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). - - -## Finding contributions to work on -Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any 'help wanted' issues is a great place to start. - - -## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact -opensource-codeofconduct@amazon.com with any additional questions or comments. - - -## Security issue notifications -If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. - - -## Licensing - -See the [LICENSE](LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. diff --git a/vendor/github.com/aws/smithy-go/LICENSE b/vendor/github.com/aws/smithy-go/LICENSE deleted file mode 100644 index 67db858821..0000000000 --- a/vendor/github.com/aws/smithy-go/LICENSE +++ /dev/null @@ -1,175 +0,0 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. diff --git a/vendor/github.com/aws/smithy-go/Makefile b/vendor/github.com/aws/smithy-go/Makefile deleted file mode 100644 index 4b3c209373..0000000000 --- a/vendor/github.com/aws/smithy-go/Makefile +++ /dev/null @@ -1,97 +0,0 @@ -PRE_RELEASE_VERSION ?= - -RELEASE_MANIFEST_FILE ?= -RELEASE_CHGLOG_DESC_FILE ?= - -REPOTOOLS_VERSION ?= latest -REPOTOOLS_MODULE = github.com/awslabs/aws-go-multi-module-repository-tools -REPOTOOLS_CMD_CALCULATE_RELEASE = ${REPOTOOLS_MODULE}/cmd/calculaterelease@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_CALCULATE_RELEASE_ADDITIONAL_ARGS ?= -REPOTOOLS_CMD_UPDATE_REQUIRES = ${REPOTOOLS_MODULE}/cmd/updaterequires@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_UPDATE_MODULE_METADATA = ${REPOTOOLS_MODULE}/cmd/updatemodulemeta@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_GENERATE_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/generatechangelog@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_CHANGELOG = ${REPOTOOLS_MODULE}/cmd/changelog@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_TAG_RELEASE = ${REPOTOOLS_MODULE}/cmd/tagrelease@${REPOTOOLS_VERSION} -REPOTOOLS_CMD_MODULE_VERSION = ${REPOTOOLS_MODULE}/cmd/moduleversion@${REPOTOOLS_VERSION} - -UNIT_TEST_TAGS= -BUILD_TAGS= - -ifneq ($(PRE_RELEASE_VERSION),) - REPOTOOLS_CMD_CALCULATE_RELEASE_ADDITIONAL_ARGS += -preview=${PRE_RELEASE_VERSION} -endif - -smithy-publish-local: - cd codegen && ./gradlew publishToMavenLocal - -smithy-build: - cd codegen && ./gradlew build - -smithy-clean: - cd codegen && ./gradlew clean - -################## -# Linting/Verify # -################## -.PHONY: verify vet - -verify: vet - -vet: - go vet ${BUILD_TAGS} --all ./... - -################ -# Unit Testing # -################ -.PHONY: unit unit-race unit-test unit-race-test - -unit: verify - go vet ${BUILD_TAGS} --all ./... && \ - go test ${BUILD_TAGS} ${RUN_NONE} ./... && \ - go test -timeout=1m ${UNIT_TEST_TAGS} ./... - -unit-race: verify - go vet ${BUILD_TAGS} --all ./... && \ - go test ${BUILD_TAGS} ${RUN_NONE} ./... && \ - go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./... - -unit-test: verify - go test -timeout=1m ${UNIT_TEST_TAGS} ./... - -unit-race-test: verify - go test -timeout=1m ${UNIT_TEST_TAGS} -race -cpu=4 ./... - -##################### -# Release Process # -##################### -.PHONY: preview-release pre-release-validation release - -preview-release: - go run ${REPOTOOLS_CMD_CALCULATE_RELEASE} ${REPOTOOLS_CMD_CALCULATE_RELEASE_ADDITIONAL_ARGS} - -pre-release-validation: - @if [[ -z "${RELEASE_MANIFEST_FILE}" ]]; then \ - echo "RELEASE_MANIFEST_FILE is required to specify the file to write the release manifest" && false; \ - fi - @if [[ -z "${RELEASE_CHGLOG_DESC_FILE}" ]]; then \ - echo "RELEASE_CHGLOG_DESC_FILE is required to specify the file to write the release notes" && false; \ - fi - -release: pre-release-validation - go run ${REPOTOOLS_CMD_CALCULATE_RELEASE} -o ${RELEASE_MANIFEST_FILE} ${REPOTOOLS_CMD_CALCULATE_RELEASE_ADDITIONAL_ARGS} - go run ${REPOTOOLS_CMD_UPDATE_REQUIRES} -release ${RELEASE_MANIFEST_FILE} - go run ${REPOTOOLS_CMD_UPDATE_MODULE_METADATA} -release ${RELEASE_MANIFEST_FILE} - go run ${REPOTOOLS_CMD_GENERATE_CHANGELOG} -release ${RELEASE_MANIFEST_FILE} -o ${RELEASE_CHGLOG_DESC_FILE} - go run ${REPOTOOLS_CMD_CHANGELOG} rm -all - go run ${REPOTOOLS_CMD_TAG_RELEASE} -release ${RELEASE_MANIFEST_FILE} - -module-version: - @go run ${REPOTOOLS_CMD_MODULE_VERSION} . - -############## -# Repo Tools # -############## -.PHONY: install-changelog - -install-changelog: - go install ${REPOTOOLS_MODULE}/cmd/changelog@${REPOTOOLS_VERSION} diff --git a/vendor/github.com/aws/smithy-go/NOTICE b/vendor/github.com/aws/smithy-go/NOTICE deleted file mode 100644 index 616fc58894..0000000000 --- a/vendor/github.com/aws/smithy-go/NOTICE +++ /dev/null @@ -1 +0,0 @@ -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/vendor/github.com/aws/smithy-go/README.md b/vendor/github.com/aws/smithy-go/README.md deleted file mode 100644 index a4bb43fbe9..0000000000 --- a/vendor/github.com/aws/smithy-go/README.md +++ /dev/null @@ -1,12 +0,0 @@ -## Smithy Go - -[![Go Build Status](https://github.com/aws/smithy-go/actions/workflows/go.yml/badge.svg?branch=main)](https://github.com/aws/smithy-go/actions/workflows/go.yml)[![Codegen Build Status](https://github.com/aws/smithy-go/actions/workflows/codegen.yml/badge.svg?branch=main)](https://github.com/aws/smithy-go/actions/workflows/codegen.yml) - -[Smithy](https://smithy.io/) code generators for Go. - -**WARNING: All interfaces are subject to change.** - -## License - -This project is licensed under the Apache-2.0 License. - diff --git a/vendor/github.com/aws/smithy-go/doc.go b/vendor/github.com/aws/smithy-go/doc.go deleted file mode 100644 index 87b0c74b75..0000000000 --- a/vendor/github.com/aws/smithy-go/doc.go +++ /dev/null @@ -1,2 +0,0 @@ -// Package smithy provides the core components for a Smithy SDK. -package smithy diff --git a/vendor/github.com/aws/smithy-go/document.go b/vendor/github.com/aws/smithy-go/document.go deleted file mode 100644 index dec498c57b..0000000000 --- a/vendor/github.com/aws/smithy-go/document.go +++ /dev/null @@ -1,10 +0,0 @@ -package smithy - -// Document provides access to loosely structured data in a document-like -// format. -// -// Deprecated: See the github.com/aws/smithy-go/document package. -type Document interface { - UnmarshalDocument(interface{}) error - GetValue() (interface{}, error) -} diff --git a/vendor/github.com/aws/smithy-go/document/doc.go b/vendor/github.com/aws/smithy-go/document/doc.go deleted file mode 100644 index 03055b7a1c..0000000000 --- a/vendor/github.com/aws/smithy-go/document/doc.go +++ /dev/null @@ -1,12 +0,0 @@ -// Package document provides interface definitions and error types for document types. -// -// A document is a protocol-agnostic type which supports a JSON-like data-model. You can use this type to send -// UTF-8 strings, arbitrary precision numbers, booleans, nulls, a list of these values, and a map of UTF-8 -// strings to these values. -// -// API Clients expose document constructors in their respective client document packages which must be used to -// Marshal and Unmarshal Go types to and from their respective protocol representations. -// -// See the Marshaler and Unmarshaler type documentation for more details on how to Go types can be converted to and from -// document types. -package document diff --git a/vendor/github.com/aws/smithy-go/document/document.go b/vendor/github.com/aws/smithy-go/document/document.go deleted file mode 100644 index 8f852d95c6..0000000000 --- a/vendor/github.com/aws/smithy-go/document/document.go +++ /dev/null @@ -1,153 +0,0 @@ -package document - -import ( - "fmt" - "math/big" - "strconv" -) - -// Marshaler is an interface for a type that marshals a document to its protocol-specific byte representation and -// returns the resulting bytes. A non-nil error will be returned if an error is encountered during marshaling. -// -// Marshal supports basic scalars (int,uint,float,bool,string), big.Int, and big.Float, maps, slices, and structs. -// Anonymous nested types are flattened based on Go anonymous type visibility. -// -// When defining struct types. the `document` struct tag can be used to control how the value will be -// marshaled into the resulting protocol document. -// -// // Field is ignored -// Field int `document:"-"` -// -// // Field object of key "myName" -// Field int `document:"myName"` -// -// // Field object key of key "myName", and -// // Field is omitted if the field is a zero value for the type. -// Field int `document:"myName,omitempty"` -// -// // Field object key of "Field", and -// // Field is omitted if the field is a zero value for the type. -// Field int `document:",omitempty"` -// -// All struct fields, including anonymous fields, are marshaled unless the -// any of the following conditions are meet. -// -// - the field is not exported -// - document field tag is "-" -// - document field tag specifies "omitempty", and is a zero value. -// -// Pointer and interface values are encoded as the value pointed to or -// contained in the interface. A nil value encodes as a null -// value unless `omitempty` struct tag is provided. -// -// Channel, complex, and function values are not encoded and will be skipped -// when walking the value to be marshaled. -// -// time.Time is not supported and will cause the Marshaler to return an error. These values should be represented -// by your application as a string or numerical representation. -// -// Errors that occur when marshaling will stop the marshaler, and return the error. -// -// Marshal cannot represent cyclic data structures and will not handle them. -// Passing cyclic structures to Marshal will result in an infinite recursion. -type Marshaler interface { - MarshalSmithyDocument() ([]byte, error) -} - -// Unmarshaler is an interface for a type that unmarshals a document from its protocol-specific representation, and -// stores the result into the value pointed by v. If v is nil or not a pointer then InvalidUnmarshalError will be -// returned. -// -// Unmarshaler supports the same encodings produced by a document Marshaler. This includes support for the `document` -// struct field tag for controlling how struct fields are unmarshaled. -// -// Both generic interface{} and concrete types are valid unmarshal destination types. When unmarshaling a document -// into an empty interface the Unmarshaler will store one of these values: -// bool, for boolean values -// document.Number, for arbitrary-precision numbers (int64, float64, big.Int, big.Float) -// string, for string values -// []interface{}, for array values -// map[string]interface{}, for objects -// nil, for null values -// -// When unmarshaling, any error that occurs will halt the unmarshal and return the error. -type Unmarshaler interface { - UnmarshalSmithyDocument(v interface{}) error -} - -type noSerde interface { - noSmithyDocumentSerde() -} - -// NoSerde is a sentinel value to indicate that a given type should not be marshaled or unmarshaled -// into a protocol document. -type NoSerde struct{} - -func (n NoSerde) noSmithyDocumentSerde() {} - -var _ noSerde = (*NoSerde)(nil) - -// IsNoSerde returns whether the given type implements the no smithy document serde interface. -func IsNoSerde(x interface{}) bool { - _, ok := x.(noSerde) - return ok -} - -// Number is an arbitrary precision numerical value -type Number string - -// Int64 returns the number as a string. -func (n Number) String() string { - return string(n) -} - -// Int64 returns the number as an int64. -func (n Number) Int64() (int64, error) { - return n.intOfBitSize(64) -} - -func (n Number) intOfBitSize(bitSize int) (int64, error) { - return strconv.ParseInt(string(n), 10, bitSize) -} - -// Uint64 returns the number as a uint64. -func (n Number) Uint64() (uint64, error) { - return n.uintOfBitSize(64) -} - -func (n Number) uintOfBitSize(bitSize int) (uint64, error) { - return strconv.ParseUint(string(n), 10, bitSize) -} - -// Float32 returns the number parsed as a 32-bit float, returns a float64. -func (n Number) Float32() (float64, error) { - return n.floatOfBitSize(32) -} - -// Float64 returns the number as a float64. -func (n Number) Float64() (float64, error) { - return n.floatOfBitSize(64) -} - -// Float64 returns the number as a float64. -func (n Number) floatOfBitSize(bitSize int) (float64, error) { - return strconv.ParseFloat(string(n), bitSize) -} - -// BigFloat attempts to convert the number to a big.Float, returns an error if the operation fails. -func (n Number) BigFloat() (*big.Float, error) { - f, ok := (&big.Float{}).SetString(string(n)) - if !ok { - return nil, fmt.Errorf("failed to convert to big.Float") - } - return f, nil -} - -// BigInt attempts to convert the number to a big.Int, returns an error if the operation fails. -func (n Number) BigInt() (*big.Int, error) { - f, ok := (&big.Int{}).SetString(string(n), 10) - if !ok { - return nil, fmt.Errorf("failed to convert to big.Float") - } - return f, nil -} diff --git a/vendor/github.com/aws/smithy-go/document/errors.go b/vendor/github.com/aws/smithy-go/document/errors.go deleted file mode 100644 index 046a7a7653..0000000000 --- a/vendor/github.com/aws/smithy-go/document/errors.go +++ /dev/null @@ -1,75 +0,0 @@ -package document - -import ( - "fmt" - "reflect" -) - -// UnmarshalTypeError is an error type representing an error -// unmarshaling a Smithy document to a Go value type. This is different -// from UnmarshalError in that it does not wrap an underlying error type. -type UnmarshalTypeError struct { - Value string - Type reflect.Type -} - -// Error returns the string representation of the error. -// Satisfying the error interface. -func (e *UnmarshalTypeError) Error() string { - return fmt.Sprintf("unmarshal failed, cannot unmarshal %s into Go value type %s", - e.Value, e.Type.String()) -} - -// An InvalidUnmarshalError is an error type representing an invalid type -// encountered while unmarshaling a Smithy document to a Go value type. -type InvalidUnmarshalError struct { - Type reflect.Type -} - -// Error returns the string representation of the error. -// Satisfying the error interface. -func (e *InvalidUnmarshalError) Error() string { - var msg string - if e.Type == nil { - msg = "cannot unmarshal to nil value" - } else if e.Type.Kind() != reflect.Ptr { - msg = fmt.Sprintf("cannot unmarshal to non-pointer value, got %s", e.Type.String()) - } else { - msg = fmt.Sprintf("cannot unmarshal to nil value, %s", e.Type.String()) - } - - return fmt.Sprintf("unmarshal failed, %s", msg) -} - -// An UnmarshalError wraps an error that occurred while unmarshaling a -// Smithy document into a Go type. This is different from -// UnmarshalTypeError in that it wraps the underlying error that occurred. -type UnmarshalError struct { - Err error - Value string - Type reflect.Type -} - -// Unwrap returns the underlying unmarshaling error -func (e *UnmarshalError) Unwrap() error { - return e.Err -} - -// Error returns the string representation of the error. -// Satisfying the error interface. -func (e *UnmarshalError) Error() string { - return fmt.Sprintf("unmarshal failed, cannot unmarshal %q into %s, %v", - e.Value, e.Type.String(), e.Err) -} - -// An InvalidMarshalError is an error type representing an error -// occurring when marshaling a Go value type. -type InvalidMarshalError struct { - Message string -} - -// Error returns the string representation of the error. -// Satisfying the error interface. -func (e *InvalidMarshalError) Error() string { - return fmt.Sprintf("marshal failed, %s", e.Message) -} diff --git a/vendor/github.com/aws/smithy-go/errors.go b/vendor/github.com/aws/smithy-go/errors.go deleted file mode 100644 index d6948d0206..0000000000 --- a/vendor/github.com/aws/smithy-go/errors.go +++ /dev/null @@ -1,137 +0,0 @@ -package smithy - -import "fmt" - -// APIError provides the generic API and protocol agnostic error type all SDK -// generated exception types will implement. -type APIError interface { - error - - // ErrorCode returns the error code for the API exception. - ErrorCode() string - // ErrorMessage returns the error message for the API exception. - ErrorMessage() string - // ErrorFault returns the fault for the API exception. - ErrorFault() ErrorFault -} - -// GenericAPIError provides a generic concrete API error type that SDKs can use -// to deserialize error responses into. Should be used for unmodeled or untyped -// errors. -type GenericAPIError struct { - Code string - Message string - Fault ErrorFault -} - -// ErrorCode returns the error code for the API exception. -func (e *GenericAPIError) ErrorCode() string { return e.Code } - -// ErrorMessage returns the error message for the API exception. -func (e *GenericAPIError) ErrorMessage() string { return e.Message } - -// ErrorFault returns the fault for the API exception. -func (e *GenericAPIError) ErrorFault() ErrorFault { return e.Fault } - -func (e *GenericAPIError) Error() string { - return fmt.Sprintf("api error %s: %s", e.Code, e.Message) -} - -var _ APIError = (*GenericAPIError)(nil) - -// OperationError decorates an underlying error which occurred while invoking -// an operation with names of the operation and API. -type OperationError struct { - ServiceID string - OperationName string - Err error -} - -// Service returns the name of the API service the error occurred with. -func (e *OperationError) Service() string { return e.ServiceID } - -// Operation returns the name of the API operation the error occurred with. -func (e *OperationError) Operation() string { return e.OperationName } - -// Unwrap returns the nested error if any, or nil. -func (e *OperationError) Unwrap() error { return e.Err } - -func (e *OperationError) Error() string { - return fmt.Sprintf("operation error %s: %s, %v", e.ServiceID, e.OperationName, e.Err) -} - -// DeserializationError provides a wrapper for an error that occurs during -// deserialization. -type DeserializationError struct { - Err error // original error - Snapshot []byte -} - -// Error returns a formatted error for DeserializationError -func (e *DeserializationError) Error() string { - const msg = "deserialization failed" - if e.Err == nil { - return msg - } - return fmt.Sprintf("%s, %v", msg, e.Err) -} - -// Unwrap returns the underlying Error in DeserializationError -func (e *DeserializationError) Unwrap() error { return e.Err } - -// ErrorFault provides the type for a Smithy API error fault. -type ErrorFault int - -// ErrorFault enumeration values -const ( - FaultUnknown ErrorFault = iota - FaultServer - FaultClient -) - -func (f ErrorFault) String() string { - switch f { - case FaultServer: - return "server" - case FaultClient: - return "client" - default: - return "unknown" - } -} - -// SerializationError represents an error that occurred while attempting to serialize a request -type SerializationError struct { - Err error // original error -} - -// Error returns a formatted error for SerializationError -func (e *SerializationError) Error() string { - const msg = "serialization failed" - if e.Err == nil { - return msg - } - return fmt.Sprintf("%s: %v", msg, e.Err) -} - -// Unwrap returns the underlying Error in SerializationError -func (e *SerializationError) Unwrap() error { return e.Err } - -// CanceledError is the error that will be returned by an API request that was -// canceled. API operations given a Context may return this error when -// canceled. -type CanceledError struct { - Err error -} - -// CanceledError returns true to satisfy interfaces checking for canceled errors. -func (*CanceledError) CanceledError() bool { return true } - -// Unwrap returns the underlying error, if there was one. -func (e *CanceledError) Unwrap() error { - return e.Err -} - -func (e *CanceledError) Error() string { - return fmt.Sprintf("canceled, %v", e.Err) -} diff --git a/vendor/github.com/aws/smithy-go/go_module_metadata.go b/vendor/github.com/aws/smithy-go/go_module_metadata.go deleted file mode 100644 index 997c309246..0000000000 --- a/vendor/github.com/aws/smithy-go/go_module_metadata.go +++ /dev/null @@ -1,6 +0,0 @@ -// Code generated by internal/repotools/cmd/updatemodulemeta DO NOT EDIT. - -package smithy - -// goModuleVersion is the tagged release for this module -const goModuleVersion = "1.14.2" diff --git a/vendor/github.com/aws/smithy-go/local-mod-replace.sh b/vendor/github.com/aws/smithy-go/local-mod-replace.sh deleted file mode 100644 index 800bf37695..0000000000 --- a/vendor/github.com/aws/smithy-go/local-mod-replace.sh +++ /dev/null @@ -1,39 +0,0 @@ -#1/usr/bin/env bash - -PROJECT_DIR="" -SMITHY_SOURCE_DIR=$(cd `dirname $0` && pwd) - -usage() { - echo "Usage: $0 [-s SMITHY_SOURCE_DIR] [-d PROJECT_DIR]" 1>&2 - exit 1 -} - -while getopts "hs:d:" options; do - case "${options}" in - s) - SMITHY_SOURCE_DIR=${OPTARG} - if [ "$SMITHY_SOURCE_DIR" == "" ]; then - echo "path to smithy-go source directory is required" || exit - usage - fi - ;; - d) - PROJECT_DIR=${OPTARG} - ;; - h) - usage - ;; - *) - usage - ;; - esac -done - -if [ "$PROJECT_DIR" != "" ]; then - cd $PROJECT_DIR || exit -fi - -go mod graph | awk '{print $1}' | cut -d '@' -f 1 | sort | uniq | grep "github.com/aws/smithy-go" | while read x; do - repPath=${x/github.com\/aws\/smithy-go/${SMITHY_SOURCE_DIR}} - echo -replace $x=$repPath -done | xargs go mod edit diff --git a/vendor/github.com/aws/smithy-go/modman.toml b/vendor/github.com/aws/smithy-go/modman.toml deleted file mode 100644 index 20295cdd2a..0000000000 --- a/vendor/github.com/aws/smithy-go/modman.toml +++ /dev/null @@ -1,11 +0,0 @@ -[dependencies] - "github.com/google/go-cmp" = "v0.5.8" - "github.com/jmespath/go-jmespath" = "v0.4.0" - -[modules] - - [modules.codegen] - no_tag = true - - [modules."codegen/smithy-go-codegen/build/test-generated/go/internal/testmodule"] - no_tag = true diff --git a/vendor/github.com/aws/smithy-go/properties.go b/vendor/github.com/aws/smithy-go/properties.go deleted file mode 100644 index 17d659c539..0000000000 --- a/vendor/github.com/aws/smithy-go/properties.go +++ /dev/null @@ -1,52 +0,0 @@ -package smithy - -// PropertiesReader provides an interface for reading metadata from the -// underlying metadata container. -type PropertiesReader interface { - Get(key interface{}) interface{} -} - -// Properties provides storing and reading metadata values. Keys may be any -// comparable value type. Get and set will panic if key is not a comparable -// value type. -// -// Properties uses lazy initialization, and Set method must be called as an -// addressable value, or pointer. Not doing so may cause key/value pair to not -// be set. -type Properties struct { - values map[interface{}]interface{} -} - -// Get attempts to retrieve the value the key points to. Returns nil if the -// key was not found. -// -// Panics if key type is not comparable. -func (m *Properties) Get(key interface{}) interface{} { - return m.values[key] -} - -// Set stores the value pointed to by the key. If a value already exists at -// that key it will be replaced with the new value. -// -// Set method must be called as an addressable value, or pointer. If Set is not -// called as an addressable value or pointer, the key value pair being set may -// be lost. -// -// Panics if the key type is not comparable. -func (m *Properties) Set(key, value interface{}) { - if m.values == nil { - m.values = map[interface{}]interface{}{} - } - m.values[key] = value -} - -// Has returns whether the key exists in the metadata. -// -// Panics if the key type is not comparable. -func (m *Properties) Has(key interface{}) bool { - if m.values == nil { - return false - } - _, ok := m.values[key] - return ok -} diff --git a/vendor/github.com/aws/smithy-go/validation.go b/vendor/github.com/aws/smithy-go/validation.go deleted file mode 100644 index b5eedc1f90..0000000000 --- a/vendor/github.com/aws/smithy-go/validation.go +++ /dev/null @@ -1,140 +0,0 @@ -package smithy - -import ( - "bytes" - "fmt" - "strings" -) - -// An InvalidParamsError provides wrapping of invalid parameter errors found when -// validating API operation input parameters. -type InvalidParamsError struct { - // Context is the base context of the invalid parameter group. - Context string - errs []InvalidParamError -} - -// Add adds a new invalid parameter error to the collection of invalid -// parameters. The context of the invalid parameter will be updated to reflect -// this collection. -func (e *InvalidParamsError) Add(err InvalidParamError) { - err.SetContext(e.Context) - e.errs = append(e.errs, err) -} - -// AddNested adds the invalid parameter errors from another InvalidParamsError -// value into this collection. The nested errors will have their nested context -// updated and base context to reflect the merging. -// -// Use for nested validations errors. -func (e *InvalidParamsError) AddNested(nestedCtx string, nested InvalidParamsError) { - for _, err := range nested.errs { - err.SetContext(e.Context) - err.AddNestedContext(nestedCtx) - e.errs = append(e.errs, err) - } -} - -// Len returns the number of invalid parameter errors -func (e *InvalidParamsError) Len() int { - return len(e.errs) -} - -// Error returns the string formatted form of the invalid parameters. -func (e InvalidParamsError) Error() string { - w := &bytes.Buffer{} - fmt.Fprintf(w, "%d validation error(s) found.\n", len(e.errs)) - - for _, err := range e.errs { - fmt.Fprintf(w, "- %s\n", err.Error()) - } - - return w.String() -} - -// Errs returns a slice of the invalid parameters -func (e InvalidParamsError) Errs() []error { - errs := make([]error, len(e.errs)) - for i := 0; i < len(errs); i++ { - errs[i] = e.errs[i] - } - - return errs -} - -// An InvalidParamError represents an invalid parameter error type. -type InvalidParamError interface { - error - - // Field name the error occurred on. - Field() string - - // SetContext updates the context of the error. - SetContext(string) - - // AddNestedContext updates the error's context to include a nested level. - AddNestedContext(string) -} - -type invalidParamError struct { - context string - nestedContext string - field string - reason string -} - -// Error returns the string version of the invalid parameter error. -func (e invalidParamError) Error() string { - return fmt.Sprintf("%s, %s.", e.reason, e.Field()) -} - -// Field Returns the field and context the error occurred. -func (e invalidParamError) Field() string { - sb := &strings.Builder{} - sb.WriteString(e.context) - if sb.Len() > 0 { - if len(e.nestedContext) == 0 || (len(e.nestedContext) > 0 && e.nestedContext[:1] != "[") { - sb.WriteRune('.') - } - } - if len(e.nestedContext) > 0 { - sb.WriteString(e.nestedContext) - sb.WriteRune('.') - } - sb.WriteString(e.field) - return sb.String() -} - -// SetContext updates the base context of the error. -func (e *invalidParamError) SetContext(ctx string) { - e.context = ctx -} - -// AddNestedContext prepends a context to the field's path. -func (e *invalidParamError) AddNestedContext(ctx string) { - if len(e.nestedContext) == 0 { - e.nestedContext = ctx - return - } - // Check if our nested context is an index into a slice or map - if e.nestedContext[:1] != "[" { - e.nestedContext = fmt.Sprintf("%s.%s", ctx, e.nestedContext) - return - } - e.nestedContext = ctx + e.nestedContext -} - -// An ParamRequiredError represents an required parameter error. -type ParamRequiredError struct { - invalidParamError -} - -// NewErrParamRequired creates a new required parameter error. -func NewErrParamRequired(field string) *ParamRequiredError { - return &ParamRequiredError{ - invalidParamError{ - field: field, - reason: fmt.Sprintf("missing required field"), - }, - } -} diff --git a/vendor/github.com/devtron-labs/common-lib/blob-storage/GCPBlob.go b/vendor/github.com/devtron-labs/common-lib/blob-storage/GCPBlob.go index 1a50e4bf16..dc64c2310a 100644 --- a/vendor/github.com/devtron-labs/common-lib/blob-storage/GCPBlob.go +++ b/vendor/github.com/devtron-labs/common-lib/blob-storage/GCPBlob.go @@ -19,6 +19,7 @@ package blob_storage import ( "cloud.google.com/go/storage" "context" + "errors" "fmt" "google.golang.org/api/iterator" "google.golang.org/api/option" @@ -91,8 +92,10 @@ func (impl *GCPBlob) getLatestVersion(storageClient *storage.Client, request *Bl var latestTimestampInMillis int64 = 0 for { objectAttrs, err := objects.Next() - if err == iterator.Done { + if errors.Is(err, iterator.Done) { break + } else if err != nil { + return 0, err } objectName := objectAttrs.Name if objectName != fileName { diff --git a/vendor/github.com/devtron-labs/common-lib/git-manager/GitCliManager.go b/vendor/github.com/devtron-labs/common-lib/git-manager/GitCliManager.go index f49f8b1903..38b27f4d71 100644 --- a/vendor/github.com/devtron-labs/common-lib/git-manager/GitCliManager.go +++ b/vendor/github.com/devtron-labs/common-lib/git-manager/GitCliManager.go @@ -19,6 +19,7 @@ package git_manager import ( "fmt" "github.com/devtron-labs/common-lib/git-manager/util" + "github.com/sirupsen/logrus" "log" "os" "os/exec" @@ -286,14 +287,16 @@ func (impl *GitCliManagerImpl) Clone(gitContext GitContext, prj CiProjectDetails } _, msgMsg, cErr = impl.shallowClone(gitContext, checkoutPath, prj.GitRepository, checkoutBranch) if cErr != nil { - log.Fatal("could not clone repo ", " err: ", cErr, "msgMsg: ", msgMsg) + logrus.Error("could not clone repo ", "msgMsg: ", msgMsg, " err: ", cErr) + return "", msgMsg, cErr } projectName := util.GetProjectName(prj.GitRepository) projRootDir := filepath.Join(checkoutPath, projectName) _, msgMsg, cErr = impl.moveFilesFromSourceToDestination(projRootDir, checkoutPath) if cErr != nil { - log.Fatal("could not move files between files ", "err: ", cErr, "msgMsg: ", msgMsg) + logrus.Error("could not move files between files ", "msgMsg: ", msgMsg, "err: ", cErr) + return "", msgMsg, cErr } return response, msgMsg, cErr } diff --git a/vendor/github.com/devtron-labs/common-lib/git-manager/GitManager.go b/vendor/github.com/devtron-labs/common-lib/git-manager/GitManager.go index e41e9fd716..38ead6bed4 100644 --- a/vendor/github.com/devtron-labs/common-lib/git-manager/GitManager.go +++ b/vendor/github.com/devtron-labs/common-lib/git-manager/GitManager.go @@ -21,6 +21,7 @@ import ( "fmt" "github.com/devtron-labs/common-lib/git-manager/util" "github.com/devtron-labs/common-lib/utils" + "github.com/sirupsen/logrus" "log" "os" "path/filepath" @@ -129,13 +130,15 @@ func (impl *GitManager) CloneAndCheckout(ciProjectDetails []CiProjectDetails, wo cErr = util.CreateSshPrivateKeyOnDisk(index, prj.GitOptions.SshPrivateKey) cErr = util.CreateSshPrivateKeyOnDisk(index, prj.GitOptions.SshPrivateKey) if cErr != nil { - log.Fatal("could not create ssh private key on disk ", " err ", cErr) + logrus.Error("could not create ssh private key on disk ", " err ", cErr) + return cErr } } _, msgMsg, cErr := impl.GitCliManager.Clone(gitContext, prj) if cErr != nil { - log.Fatal("could not clone repo ", " err ", cErr, "msgMsg", msgMsg) + logrus.Error("could not clone repo ", "msgMsg", msgMsg, " err ", cErr) + return cErr } // checkout code @@ -153,7 +156,8 @@ func (impl *GitManager) CloneAndCheckout(ciProjectDetails []CiProjectDetails, wo log.Println("checkout commit in branch fix : ", checkoutSource) msgMsg, cErr = impl.GitCliManager.GitCheckout(gitContext, prj.CheckoutPath, checkoutSource, authMode, prj.FetchSubmodules, prj.GitRepository) if cErr != nil { - log.Fatal("could not checkout hash ", " err ", cErr, "msgMsg", msgMsg) + logrus.Error("could not checkout hash ", "errMsg", msgMsg, "err ", cErr) + return cErr } } else if prj.SourceType == SOURCE_TYPE_WEBHOOK { @@ -163,7 +167,8 @@ func (impl *GitManager) CloneAndCheckout(ciProjectDetails []CiProjectDetails, wo targetCheckout := webhookDataData[WEBHOOK_SELECTOR_TARGET_CHECKOUT_NAME] if len(targetCheckout) == 0 { - log.Fatal("could not get target checkout from request data") + logrus.Error("could not get 'target checkout' from request data", "webhookData", webhookDataData) + return fmt.Errorf("could not get 'target checkout' from request data") } log.Println("checkout commit in webhook : ", targetCheckout) @@ -171,7 +176,7 @@ func (impl *GitManager) CloneAndCheckout(ciProjectDetails []CiProjectDetails, wo // checkout target hash msgMsg, cErr = impl.GitCliManager.GitCheckout(gitContext, prj.CheckoutPath, targetCheckout, authMode, prj.FetchSubmodules, prj.GitRepository) if cErr != nil { - log.Fatal("could not checkout ", "targetCheckout ", targetCheckout, " err ", cErr, " msgMsg", msgMsg) + logrus.Error("could not checkout ", "targetCheckout ", targetCheckout, " errMsg", msgMsg, " err ", cErr) return cErr } @@ -181,7 +186,8 @@ func (impl *GitManager) CloneAndCheckout(ciProjectDetails []CiProjectDetails, wo // throw error if source checkout is empty if len(sourceCheckout) == 0 { - log.Fatal("sourceCheckout is empty") + logrus.Error("'source checkout' is empty", "webhookData", webhookDataData) + return fmt.Errorf("'source checkout' is empty") } log.Println("merge commit in webhook : ", sourceCheckout) @@ -189,14 +195,11 @@ func (impl *GitManager) CloneAndCheckout(ciProjectDetails []CiProjectDetails, wo // merge source _, msgMsg, cErr = impl.GitCliManager.Merge(filepath.Join(gitContext.WorkingDir, prj.CheckoutPath), sourceCheckout) if cErr != nil { - log.Fatal("could not merge ", "sourceCheckout ", sourceCheckout, " err ", cErr, " msgMsg", msgMsg) + logrus.Error("could not merge ", "sourceCheckout ", sourceCheckout, " errMsg", msgMsg, " err ", cErr) return cErr } - } - } - } return nil } diff --git a/vendor/github.com/devtron-labs/common-lib/utils/CommonUtils.go b/vendor/github.com/devtron-labs/common-lib/utils/CommonUtils.go index 671e4502fd..95c0f3b747 100644 --- a/vendor/github.com/devtron-labs/common-lib/utils/CommonUtils.go +++ b/vendor/github.com/devtron-labs/common-lib/utils/CommonUtils.go @@ -18,13 +18,20 @@ package utils import ( "fmt" + "github.com/devtron-labs/common-lib/git-manager/util" + "github.com/devtron-labs/common-lib/utils/bean" + "log" "math/rand" + "path" + "regexp" "strings" "time" ) var chars = []rune("abcdefghijklmnopqrstuvwxyz0123456789") +const DOCKER_REGISTRY_TYPE_DOCKERHUB = "docker-hub" + // Generates random string func Generate(size int) string { rand.Seed(time.Now().UnixNano()) @@ -47,3 +54,31 @@ func GetUrlWithScheme(url string) (urlWithScheme string) { } return urlWithScheme } + +func IsValidDockerTagName(tagName string) bool { + regString := "^[a-zA-Z0-9_][a-zA-Z0-9_.-]{0,127}$" + regexpCompile := regexp.MustCompile(regString) + if regexpCompile.MatchString(tagName) { + return true + } else { + return false + } +} + +func BuildDockerImagePath(dockerInfo bean.DockerRegistryInfo) (string, error) { + dest := "" + if DOCKER_REGISTRY_TYPE_DOCKERHUB == dockerInfo.DockerRegistryType { + dest = dockerInfo.DockerRepository + ":" + dockerInfo.DockerImageTag + } else { + registryUrl := dockerInfo.DockerRegistryURL + u, err := util.ParseUrl(registryUrl) + if err != nil { + log.Println("not a valid docker repository url") + return "", err + } + u.Path = path.Join(u.Path, "/", dockerInfo.DockerRepository) + dockerRegistryURL := u.Host + u.Path + dest = dockerRegistryURL + ":" + dockerInfo.DockerImageTag + } + return dest, nil +} diff --git a/vendor/github.com/devtron-labs/common-lib/utils/bean/bean.go b/vendor/github.com/devtron-labs/common-lib/utils/bean/bean.go index 1c018920e8..11a4015f40 100644 --- a/vendor/github.com/devtron-labs/common-lib/utils/bean/bean.go +++ b/vendor/github.com/devtron-labs/common-lib/utils/bean/bean.go @@ -53,3 +53,11 @@ func (r *DockerAuthConfig) GetEncodedRegistryAuth() (string, error) { } return base64.StdEncoding.EncodeToString(encodedJSON), nil } + +type DockerRegistryInfo struct { + DockerImageTag string `json:"dockerImageTag"` + DockerRegistryId string `json:"dockerRegistryId"` + DockerRegistryType string `json:"dockerRegistryType"` + DockerRegistryURL string `json:"dockerRegistryURL"` + DockerRepository string `json:"dockerRepository"` +} diff --git a/vendor/github.com/devtron-labs/common-lib/utils/registry/bean.go b/vendor/github.com/devtron-labs/common-lib/utils/registry/bean.go new file mode 100644 index 0000000000..457453268f --- /dev/null +++ b/vendor/github.com/devtron-labs/common-lib/utils/registry/bean.go @@ -0,0 +1,18 @@ +package registry + +type registry string + +func (r registry) String() string { + return string(r) +} + +const ( + DOCKER_REGISTRY_TYPE_ECR registry = "ecr" + DOCKER_REGISTRY_TYPE_ACR registry = "acr" + DOCKER_REGISTRY_TYPE_DOCKERHUB registry = "docker-hub" + DOCKER_REGISTRY_TYPE_OTHER registry = "other" + REGISTRY_TYPE_ARTIFACT_REGISTRY registry = "artifact-registry" + REGISTRY_TYPE_GCR registry = "gcr" +) + +const JSON_KEY_USERNAME = "_json_key" diff --git a/vendor/github.com/devtron-labs/common-lib/utils/registry/pluginArtifact.go b/vendor/github.com/devtron-labs/common-lib/utils/registry/pluginArtifact.go new file mode 100644 index 0000000000..4d8f6ae2cb --- /dev/null +++ b/vendor/github.com/devtron-labs/common-lib/utils/registry/pluginArtifact.go @@ -0,0 +1,101 @@ +package registry + +import ( + "fmt" + "sort" + "time" +) + +type version string + +const ( + V1 version = "v1" + V2 version = "v2" +) + +type ImageDetailsFromCR struct { + Version version `json:"version"` + ImageDetails []*GenericImageDetail `json:"imageDetails"` +} + +func NewImageDetailsFromCR(version version) *ImageDetailsFromCR { + return &ImageDetailsFromCR{ + Version: version, + } +} + +func (i *ImageDetailsFromCR) AddImageDetails(imageDetails ...*GenericImageDetail) *ImageDetailsFromCR { + if i == nil { + return i + } + i.ImageDetails = append(i.ImageDetails, imageDetails...) + return i +} + +type GenericImageDetail struct { + Image string `json:"image"` + ImageDigest string `json:"imageDigest"` + LastUpdatedOn time.Time `json:"imagePushedAt"` +} + +func (g *GenericImageDetail) SetImage(image *string) *GenericImageDetail { + if image == nil { + return g + } + g.Image = *image + return g +} + +func (g *GenericImageDetail) SetImageDigest(imageDigest *string) *GenericImageDetail { + if imageDigest == nil { + return g + } + g.ImageDigest = *imageDigest + return g +} + +func (g *GenericImageDetail) SetLastUpdatedOn(imagePushedAt *time.Time) *GenericImageDetail { + if imagePushedAt == nil { + return g + } + g.LastUpdatedOn = *imagePushedAt + return g +} + +func (g *GenericImageDetail) GetGenericImageDetailIdentifier() string { + if g == nil { + return "" + } + return fmt.Sprintf("%s-%s", g.Image, g.ImageDigest) +} + +func NewGenericImageDetailFromPlugin() *GenericImageDetail { + return &GenericImageDetail{} +} + +type OrderBy string + +const ( + Ascending = "ASC" + Descending = "DSC" // default +) + +// SortGenericImageDetailByCreatedOn is used to sort the list of GenericImageDetail by GenericImageDetail.LastUpdatedOn +// - OrderBy - default value Descending +// - Original Slice is not manipulated, returns a new slice +func SortGenericImageDetailByCreatedOn(images []*GenericImageDetail, orderBy OrderBy) []*GenericImageDetail { + if len(images) == 0 { + return images + } + // don't modify the original slice + sortedImages := make([]*GenericImageDetail, len(images)) + copy(sortedImages, images) + // sort by createdOn in descending order + sort.Slice(sortedImages, func(i, j int) bool { + if orderBy == Ascending { + return sortedImages[i].LastUpdatedOn.Before(sortedImages[j].LastUpdatedOn) + } + return sortedImages[i].LastUpdatedOn.After(sortedImages[j].LastUpdatedOn) + }) + return sortedImages +} diff --git a/vendor/modules.txt b/vendor/modules.txt index 8d25722e99..7c6ee426b7 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -240,13 +240,6 @@ github.com/aws/aws-sdk-go/service/sso/ssoiface github.com/aws/aws-sdk-go/service/ssooidc github.com/aws/aws-sdk-go/service/sts github.com/aws/aws-sdk-go/service/sts/stsiface -# github.com/aws/aws-sdk-go-v2/service/ecr v1.20.0 -## explicit; go 1.15 -github.com/aws/aws-sdk-go-v2/service/ecr/types -# github.com/aws/smithy-go v1.14.2 -## explicit; go 1.15 -github.com/aws/smithy-go -github.com/aws/smithy-go/document # github.com/beorn7/perks v1.0.1 ## explicit; go 1.11 github.com/beorn7/perks/quantile @@ -351,7 +344,7 @@ github.com/devtron-labs/authenticator/jwt github.com/devtron-labs/authenticator/middleware github.com/devtron-labs/authenticator/oidc github.com/devtron-labs/authenticator/password -# github.com/devtron-labs/common-lib v0.16.1-0.20240904133334-7918e7c25b63 +# github.com/devtron-labs/common-lib v0.16.1-0.20240911071031-2625327bc7b4 ## explicit; go 1.21 github.com/devtron-labs/common-lib/async github.com/devtron-labs/common-lib/blob-storage @@ -373,6 +366,7 @@ github.com/devtron-labs/common-lib/utils/k8s github.com/devtron-labs/common-lib/utils/k8s/commonBean github.com/devtron-labs/common-lib/utils/k8s/health github.com/devtron-labs/common-lib/utils/k8sObjectsUtil +github.com/devtron-labs/common-lib/utils/registry github.com/devtron-labs/common-lib/utils/remoteConnection/bean github.com/devtron-labs/common-lib/utils/runTime github.com/devtron-labs/common-lib/utils/yaml diff --git a/wire_gen.go b/wire_gen.go index 76510b4eab..9ad1f1575a 100644 --- a/wire_gen.go +++ b/wire_gen.go @@ -1,6 +1,6 @@ // Code generated by Wire. DO NOT EDIT. -//go:generate go run github.com/google/wire/cmd/wire +//go:generate go run -mod=mod github.com/google/wire/cmd/wire //go:build !wireinject // +build !wireinject @@ -119,6 +119,7 @@ import ( service3 "github.com/devtron-labs/devtron/pkg/appStore/values/service" appWorkflow2 "github.com/devtron-labs/devtron/pkg/appWorkflow" "github.com/devtron-labs/devtron/pkg/argoApplication" + "github.com/devtron-labs/devtron/pkg/argoApplication/read" "github.com/devtron-labs/devtron/pkg/argoRepositoryCreds" "github.com/devtron-labs/devtron/pkg/asyncProvider" "github.com/devtron-labs/devtron/pkg/attributes" @@ -157,7 +158,7 @@ import ( "github.com/devtron-labs/devtron/pkg/deploymentGroup" "github.com/devtron-labs/devtron/pkg/devtronResource" "github.com/devtron-labs/devtron/pkg/devtronResource/history/deployment/cdPipeline" - "github.com/devtron-labs/devtron/pkg/devtronResource/read" + read2 "github.com/devtron-labs/devtron/pkg/devtronResource/read" repository8 "github.com/devtron-labs/devtron/pkg/devtronResource/repository" "github.com/devtron-labs/devtron/pkg/dockerRegistry" "github.com/devtron-labs/devtron/pkg/eventProcessor" @@ -399,8 +400,8 @@ func InitializeApp() (*App, error) { if err != nil { return nil, err } - argoApplicationServiceImpl := argoApplication.NewArgoApplicationServiceImpl(sugaredLogger, clusterRepositoryImpl, k8sServiceImpl, argoUserServiceImpl, helmAppClientImpl, helmAppServiceImpl) - k8sCommonServiceImpl := k8s2.NewK8sCommonServiceImpl(sugaredLogger, k8sServiceImpl, clusterServiceImplExtended, argoApplicationServiceImpl) + argoApplicationReadServiceImpl := read.NewArgoApplicationReadServiceImpl(sugaredLogger, clusterRepositoryImpl, k8sServiceImpl, argoUserServiceImpl, helmAppClientImpl, helmAppServiceImpl) + k8sCommonServiceImpl := k8s2.NewK8sCommonServiceImpl(sugaredLogger, k8sServiceImpl, clusterServiceImplExtended, argoApplicationReadServiceImpl) environmentRestHandlerImpl := cluster3.NewEnvironmentRestHandlerImpl(environmentServiceImpl, sugaredLogger, userServiceImpl, validate, enforcerImpl, deleteServiceExtendedImpl, k8sServiceImpl, k8sCommonServiceImpl) environmentRouterImpl := cluster3.NewEnvironmentRouterImpl(environmentRestHandlerImpl) transactionUtilImpl := sql.NewTransactionUtilImpl(db) @@ -460,7 +461,7 @@ func InitializeApp() (*App, error) { appStatusServiceImpl := appStatus2.NewAppStatusServiceImpl(appStatusRepositoryImpl, sugaredLogger, enforcerImpl, enforcerUtilImpl) scopedVariableRepositoryImpl := repository7.NewScopedVariableRepository(db, sugaredLogger, transactionUtilImpl) devtronResourceSearchableKeyRepositoryImpl := repository8.NewDevtronResourceSearchableKeyRepositoryImpl(sugaredLogger, db) - devtronResourceSearchableKeyServiceImpl, err := read.NewDevtronResourceSearchableKeyServiceImpl(sugaredLogger, devtronResourceSearchableKeyRepositoryImpl) + devtronResourceSearchableKeyServiceImpl, err := read2.NewDevtronResourceSearchableKeyServiceImpl(sugaredLogger, devtronResourceSearchableKeyRepositoryImpl) if err != nil { return nil, err } @@ -575,7 +576,7 @@ func InitializeApp() (*App, error) { deploymentTemplateHistoryServiceImpl := history.NewDeploymentTemplateHistoryServiceImpl(sugaredLogger, deploymentTemplateHistoryRepositoryImpl, pipelineRepositoryImpl, chartRepositoryImpl, userServiceImpl, cdWorkflowRepositoryImpl, scopedVariableManagerImpl, deployedAppMetricsServiceImpl, chartRefServiceImpl) chartServiceImpl := chart.NewChartServiceImpl(chartRepositoryImpl, sugaredLogger, chartTemplateServiceImpl, chartRepoRepositoryImpl, appRepositoryImpl, utilMergeUtil, envConfigOverrideRepositoryImpl, pipelineConfigRepositoryImpl, environmentRepositoryImpl, deploymentTemplateHistoryServiceImpl, scopedVariableManagerImpl, deployedAppMetricsServiceImpl, chartRefServiceImpl, gitOpsConfigReadServiceImpl, deploymentConfigServiceImpl) ciCdPipelineOrchestratorImpl := pipeline.NewCiCdPipelineOrchestrator(appRepositoryImpl, sugaredLogger, materialRepositoryImpl, pipelineRepositoryImpl, ciPipelineRepositoryImpl, ciPipelineMaterialRepositoryImpl, cdWorkflowRepositoryImpl, clientImpl, ciCdConfig, appWorkflowRepositoryImpl, environmentRepositoryImpl, attributesServiceImpl, appCrudOperationServiceImpl, userAuthServiceImpl, prePostCdScriptHistoryServiceImpl, pipelineStageServiceImpl, gitMaterialHistoryServiceImpl, ciPipelineHistoryServiceImpl, ciTemplateServiceImpl, dockerArtifactStoreRepositoryImpl, ciArtifactRepositoryImpl, configMapServiceImpl, customTagServiceImpl, genericNoteServiceImpl, chartServiceImpl, transactionUtilImpl, gitOpsConfigReadServiceImpl, deploymentConfigServiceImpl) - ciServiceImpl := pipeline.NewCiServiceImpl(sugaredLogger, workflowServiceImpl, ciPipelineMaterialRepositoryImpl, ciWorkflowRepositoryImpl, eventRESTClientImpl, eventSimpleFactoryImpl, ciPipelineRepositoryImpl, pipelineStageServiceImpl, userServiceImpl, ciTemplateServiceImpl, appCrudOperationServiceImpl, environmentRepositoryImpl, appRepositoryImpl, scopedVariableManagerImpl, customTagServiceImpl, pluginInputVariableParserImpl, globalPluginServiceImpl, infraProviderImpl, ciCdPipelineOrchestratorImpl) + ciServiceImpl := pipeline.NewCiServiceImpl(sugaredLogger, workflowServiceImpl, ciPipelineMaterialRepositoryImpl, ciWorkflowRepositoryImpl, eventRESTClientImpl, eventSimpleFactoryImpl, ciPipelineRepositoryImpl, ciArtifactRepositoryImpl, pipelineStageServiceImpl, userServiceImpl, ciTemplateServiceImpl, appCrudOperationServiceImpl, environmentRepositoryImpl, appRepositoryImpl, scopedVariableManagerImpl, customTagServiceImpl, pluginInputVariableParserImpl, globalPluginServiceImpl, infraProviderImpl, ciCdPipelineOrchestratorImpl) ciLogServiceImpl, err := pipeline.NewCiLogServiceImpl(sugaredLogger, ciServiceImpl, k8sServiceImpl) if err != nil { return nil, err @@ -713,9 +714,9 @@ func InitializeApp() (*App, error) { k8sResourceHistoryServiceImpl := kubernetesResourceAuditLogs.Newk8sResourceHistoryServiceImpl(k8sResourceHistoryRepositoryImpl, sugaredLogger, appRepositoryImpl, environmentRepositoryImpl) ephemeralContainersRepositoryImpl := repository.NewEphemeralContainersRepositoryImpl(db, transactionUtilImpl) ephemeralContainerServiceImpl := cluster2.NewEphemeralContainerServiceImpl(ephemeralContainersRepositoryImpl, sugaredLogger) - terminalSessionHandlerImpl := terminal.NewTerminalSessionHandlerImpl(environmentServiceImpl, clusterServiceImplExtended, sugaredLogger, k8sServiceImpl, ephemeralContainerServiceImpl, argoApplicationServiceImpl) + terminalSessionHandlerImpl := terminal.NewTerminalSessionHandlerImpl(environmentServiceImpl, clusterServiceImplExtended, sugaredLogger, k8sServiceImpl, ephemeralContainerServiceImpl, argoApplicationReadServiceImpl) fluxApplicationServiceImpl := fluxApplication.NewFluxApplicationServiceImpl(sugaredLogger, helmAppServiceImpl, clusterServiceImplExtended, helmAppClientImpl, pumpImpl) - k8sApplicationServiceImpl, err := application2.NewK8sApplicationServiceImpl(sugaredLogger, clusterServiceImplExtended, pumpImpl, helmAppServiceImpl, k8sServiceImpl, acdAuthConfig, k8sResourceHistoryServiceImpl, k8sCommonServiceImpl, terminalSessionHandlerImpl, ephemeralContainerServiceImpl, ephemeralContainersRepositoryImpl, argoApplicationServiceImpl, fluxApplicationServiceImpl) + k8sApplicationServiceImpl, err := application2.NewK8sApplicationServiceImpl(sugaredLogger, clusterServiceImplExtended, pumpImpl, helmAppServiceImpl, k8sServiceImpl, acdAuthConfig, k8sResourceHistoryServiceImpl, k8sCommonServiceImpl, terminalSessionHandlerImpl, ephemeralContainerServiceImpl, ephemeralContainersRepositoryImpl, fluxApplicationServiceImpl) if err != nil { return nil, err } @@ -868,9 +869,10 @@ func InitializeApp() (*App, error) { appRouterImpl := app3.NewAppRouterImpl(appFilteringRouterImpl, appListingRouterImpl, appInfoRouterImpl, pipelineTriggerRouterImpl, pipelineConfigRouterImpl, pipelineHistoryRouterImpl, pipelineStatusRouterImpl, appWorkflowRouterImpl, devtronAppAutoCompleteRouterImpl, appWorkflowRestHandlerImpl, appListingRestHandlerImpl, appFilteringRestHandlerImpl) coreAppRestHandlerImpl := restHandler.NewCoreAppRestHandlerImpl(sugaredLogger, userServiceImpl, validate, enforcerUtilImpl, enforcerImpl, appCrudOperationServiceImpl, pipelineBuilderImpl, gitRegistryConfigImpl, chartServiceImpl, configMapServiceImpl, appListingServiceImpl, propertiesConfigServiceImpl, appWorkflowServiceImpl, materialRepositoryImpl, gitProviderRepositoryImpl, appWorkflowRepositoryImpl, environmentRepositoryImpl, configMapRepositoryImpl, chartRepositoryImpl, teamServiceImpl, argoUserServiceImpl, pipelineStageServiceImpl, ciPipelineRepositoryImpl) coreAppRouterImpl := router.NewCoreAppRouterImpl(coreAppRestHandlerImpl) + argoApplicationServiceImpl := argoApplication.NewArgoApplicationServiceImpl(sugaredLogger, clusterRepositoryImpl, k8sServiceImpl, argoUserServiceImpl, helmAppClientImpl, helmAppServiceImpl, k8sApplicationServiceImpl, argoApplicationReadServiceImpl) helmAppRestHandlerImpl := client3.NewHelmAppRestHandlerImpl(sugaredLogger, helmAppServiceImpl, enforcerImpl, clusterServiceImplExtended, enforcerUtilHelmImpl, appStoreDeploymentServiceImpl, installedAppDBServiceImpl, userServiceImpl, attributesServiceImpl, serverEnvConfigServerEnvConfig, fluxApplicationServiceImpl, argoApplicationServiceImpl) helmAppRouterImpl := client3.NewHelmAppRouterImpl(helmAppRestHandlerImpl) - k8sApplicationRestHandlerImpl := application3.NewK8sApplicationRestHandlerImpl(sugaredLogger, k8sApplicationServiceImpl, pumpImpl, terminalSessionHandlerImpl, enforcerImpl, enforcerUtilHelmImpl, enforcerUtilImpl, helmAppServiceImpl, userServiceImpl, k8sCommonServiceImpl, validate, environmentVariables, fluxApplicationServiceImpl, argoApplicationServiceImpl) + k8sApplicationRestHandlerImpl := application3.NewK8sApplicationRestHandlerImpl(sugaredLogger, k8sApplicationServiceImpl, pumpImpl, terminalSessionHandlerImpl, enforcerImpl, enforcerUtilHelmImpl, enforcerUtilImpl, helmAppServiceImpl, userServiceImpl, k8sCommonServiceImpl, validate, environmentVariables, fluxApplicationServiceImpl, argoApplicationReadServiceImpl) k8sApplicationRouterImpl := application3.NewK8sApplicationRouterImpl(k8sApplicationRestHandlerImpl) pProfRestHandlerImpl := restHandler.NewPProfRestHandler(userServiceImpl, enforcerImpl) pProfRouterImpl := router.NewPProfRouter(sugaredLogger, pProfRestHandlerImpl) @@ -955,7 +957,7 @@ func InitializeApp() (*App, error) { deploymentConfigurationRouterImpl := router.NewDeploymentConfigurationRouter(deploymentConfigurationRestHandlerImpl) infraConfigRestHandlerImpl := infraConfig2.NewInfraConfigRestHandlerImpl(sugaredLogger, infraConfigServiceImpl, userServiceImpl, enforcerImpl, enforcerUtilImpl, validate) infraConfigRouterImpl := infraConfig2.NewInfraProfileRouterImpl(infraConfigRestHandlerImpl) - argoApplicationRestHandlerImpl := argoApplication2.NewArgoApplicationRestHandlerImpl(argoApplicationServiceImpl, sugaredLogger, enforcerImpl) + argoApplicationRestHandlerImpl := argoApplication2.NewArgoApplicationRestHandlerImpl(argoApplicationServiceImpl, argoApplicationReadServiceImpl, sugaredLogger, enforcerImpl) argoApplicationRouterImpl := argoApplication2.NewArgoApplicationRouterImpl(argoApplicationRestHandlerImpl) deploymentHistoryServiceImpl := cdPipeline.NewDeploymentHistoryServiceImpl(sugaredLogger, cdHandlerImpl, imageTaggingServiceImpl, pipelineRepositoryImpl, deployedConfigurationHistoryServiceImpl) apiReqDecoderServiceImpl := devtronResource.NewAPIReqDecoderServiceImpl(sugaredLogger, pipelineRepositoryImpl)