core/cmd/cmd.go
File `cmd.go` has 664 lines of code (exceeds 500 allowed). Consider refactoring.// Copyright © 2023 Horizoncd.//// 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. package cmd import ( "context" "encoding/gob" "encoding/json" "flag" "fmt" "io/ioutil" "log" "net/http" "os" "os/signal" "regexp" "sync" "syscall" "time" "github.com/horizoncd/horizon/core/config" accessctl "github.com/horizoncd/horizon/core/controller/access" accesstokenctl "github.com/horizoncd/horizon/core/controller/accesstoken" applicationctl "github.com/horizoncd/horizon/core/controller/application" applicationregionctl "github.com/horizoncd/horizon/core/controller/applicationregion" badgectl "github.com/horizoncd/horizon/core/controller/badge" "github.com/horizoncd/horizon/core/controller/build" clusterctl "github.com/horizoncd/horizon/core/controller/cluster" codectl "github.com/horizoncd/horizon/core/controller/code" environmentctl "github.com/horizoncd/horizon/core/controller/environment" environmentregionctl "github.com/horizoncd/horizon/core/controller/environmentregion" envtemplatectl "github.com/horizoncd/horizon/core/controller/envtemplate" eventctl "github.com/horizoncd/horizon/core/controller/event" groupctl "github.com/horizoncd/horizon/core/controller/group" idpctl "github.com/horizoncd/horizon/core/controller/idp" memberctl "github.com/horizoncd/horizon/core/controller/member" oauthservicectl "github.com/horizoncd/horizon/core/controller/oauth" oauthappctl "github.com/horizoncd/horizon/core/controller/oauthapp" oauthcheckctl "github.com/horizoncd/horizon/core/controller/oauthcheck" prctl "github.com/horizoncd/horizon/core/controller/pipelinerun" regionctl "github.com/horizoncd/horizon/core/controller/region" registryctl "github.com/horizoncd/horizon/core/controller/registry" roltctl "github.com/horizoncd/horizon/core/controller/role" scopectl "github.com/horizoncd/horizon/core/controller/scope" tagctl "github.com/horizoncd/horizon/core/controller/tag" templatectl "github.com/horizoncd/horizon/core/controller/template" templateschematagctl "github.com/horizoncd/horizon/core/controller/templateschematag" terminalctl "github.com/horizoncd/horizon/core/controller/terminal" userctl "github.com/horizoncd/horizon/core/controller/user" webhookctl "github.com/horizoncd/horizon/core/controller/webhook" accessapi "github.com/horizoncd/horizon/core/http/api/v1/access" "github.com/horizoncd/horizon/core/http/api/v1/accesstoken" "github.com/horizoncd/horizon/core/http/api/v1/application" "github.com/horizoncd/horizon/core/http/api/v1/applicationregion" "github.com/horizoncd/horizon/core/http/api/v1/cluster" codeapi "github.com/horizoncd/horizon/core/http/api/v1/code" "github.com/horizoncd/horizon/core/http/api/v1/environment" "github.com/horizoncd/horizon/core/http/api/v1/environmentregion" "github.com/horizoncd/horizon/core/http/api/v1/envtemplate" "github.com/horizoncd/horizon/core/http/api/v1/event" "github.com/horizoncd/horizon/core/http/api/v1/group" "github.com/horizoncd/horizon/core/http/api/v1/idp" "github.com/horizoncd/horizon/core/http/api/v1/member" "github.com/horizoncd/horizon/core/http/api/v1/oauthapp" "github.com/horizoncd/horizon/core/http/api/v1/oauthserver" "github.com/horizoncd/horizon/core/http/api/v1/pipelinerun" "github.com/horizoncd/horizon/core/http/api/v1/region" "github.com/horizoncd/horizon/core/http/api/v1/registry" roleapi "github.com/horizoncd/horizon/core/http/api/v1/role" "github.com/horizoncd/horizon/core/http/api/v1/scope" "github.com/horizoncd/horizon/core/http/api/v1/tag" "github.com/horizoncd/horizon/core/http/api/v1/template" accessv2 "github.com/horizoncd/horizon/core/http/api/v2/access" accesstokenv2 "github.com/horizoncd/horizon/core/http/api/v2/accesstoken" applicationregionv2 "github.com/horizoncd/horizon/core/http/api/v2/applicationregion" "github.com/horizoncd/horizon/core/http/api/v2/badge" clusterv2 "github.com/horizoncd/horizon/core/http/api/v2/cluster" codev2 "github.com/horizoncd/horizon/core/http/api/v2/code" environmentv2 "github.com/horizoncd/horizon/core/http/api/v2/environment" environmentregionv2 "github.com/horizoncd/horizon/core/http/api/v2/environmentregion" eventv2 "github.com/horizoncd/horizon/core/http/api/v2/event" groupv2 "github.com/horizoncd/horizon/core/http/api/v2/group" idpv2 "github.com/horizoncd/horizon/core/http/api/v2/idp" memberv2 "github.com/horizoncd/horizon/core/http/api/v2/member" oauthappv2 "github.com/horizoncd/horizon/core/http/api/v2/oauthapp" pipelinerunv2 "github.com/horizoncd/horizon/core/http/api/v2/pipelinerun" regionv2 "github.com/horizoncd/horizon/core/http/api/v2/region" registryv2 "github.com/horizoncd/horizon/core/http/api/v2/registry" rolev2 "github.com/horizoncd/horizon/core/http/api/v2/role" scopev2 "github.com/horizoncd/horizon/core/http/api/v2/scope" tagv2 "github.com/horizoncd/horizon/core/http/api/v2/tag" templateschematagv2 "github.com/horizoncd/horizon/core/http/api/v2/templateschematag" terminalv2 "github.com/horizoncd/horizon/core/http/api/v2/terminal" userv2 "github.com/horizoncd/horizon/core/http/api/v2/user" webhookv2 "github.com/horizoncd/horizon/core/http/api/v2/webhook" "github.com/horizoncd/horizon/core/middleware" "github.com/horizoncd/horizon/core/middleware/auth" "github.com/horizoncd/horizon/core/middleware/requestid" gitlablib "github.com/horizoncd/horizon/lib/gitlab" "github.com/horizoncd/horizon/pkg/admission" "github.com/horizoncd/horizon/pkg/cd" clustermetrcis "github.com/horizoncd/horizon/pkg/cluster/metrics" admissionconfig "github.com/horizoncd/horizon/pkg/config/admission" "github.com/horizoncd/horizon/pkg/environment/service" eventservice "github.com/horizoncd/horizon/pkg/event/service" "github.com/horizoncd/horizon/pkg/grafana" "github.com/horizoncd/horizon/pkg/jobs" "github.com/horizoncd/horizon/pkg/jobs/autofree" "github.com/horizoncd/horizon/pkg/jobs/clean" "github.com/horizoncd/horizon/pkg/jobs/eventhandler" "github.com/horizoncd/horizon/pkg/jobs/grafanasync" "github.com/horizoncd/horizon/pkg/jobs/k8sevent" jobwebhook "github.com/horizoncd/horizon/pkg/jobs/webhook" prservice "github.com/horizoncd/horizon/pkg/pr/service" "github.com/horizoncd/horizon/pkg/regioninformers" "github.com/horizoncd/horizon/pkg/token/generator" tokenservice "github.com/horizoncd/horizon/pkg/token/service" tokenstore "github.com/horizoncd/horizon/pkg/token/store" "github.com/horizoncd/horizon/pkg/util/kube" "github.com/horizoncd/horizon/pkg/workload" templateschematagapi "github.com/horizoncd/horizon/core/http/api/v1/templateschematag" terminalapi "github.com/horizoncd/horizon/core/http/api/v1/terminal" "github.com/horizoncd/horizon/core/http/api/v1/user" "github.com/horizoncd/horizon/core/http/api/v1/webhook" appv2 "github.com/horizoncd/horizon/core/http/api/v2/application" buildAPI "github.com/horizoncd/horizon/core/http/api/v2/build" envtemplatev2 "github.com/horizoncd/horizon/core/http/api/v2/envtemplate" templatev2 "github.com/horizoncd/horizon/core/http/api/v2/template" "github.com/horizoncd/horizon/core/http/health" "github.com/horizoncd/horizon/core/http/metrics" admissionmiddle "github.com/horizoncd/horizon/core/middleware/admission" ginlogmiddle "github.com/horizoncd/horizon/core/middleware/ginlog" logmiddle "github.com/horizoncd/horizon/core/middleware/log" metricsmiddle "github.com/horizoncd/horizon/core/middleware/metrics" prehandlemiddle "github.com/horizoncd/horizon/core/middleware/prehandle" scopemiddle "github.com/horizoncd/horizon/core/middleware/scope" tagmiddle "github.com/horizoncd/horizon/core/middleware/tag" tokenmiddle "github.com/horizoncd/horizon/core/middleware/token" usermiddle "github.com/horizoncd/horizon/core/middleware/user" "github.com/horizoncd/horizon/lib/orm" "github.com/horizoncd/horizon/pkg/application/gitrepo" applicationservice "github.com/horizoncd/horizon/pkg/application/service" userauth "github.com/horizoncd/horizon/pkg/authentication/user" "github.com/horizoncd/horizon/pkg/cluster/code" clustergitrepo "github.com/horizoncd/horizon/pkg/cluster/gitrepo" clusterservice "github.com/horizoncd/horizon/pkg/cluster/service" "github.com/horizoncd/horizon/pkg/cluster/tekton/factory" oauthconfig "github.com/horizoncd/horizon/pkg/config/oauth" "github.com/horizoncd/horizon/pkg/config/pprof" roleconfig "github.com/horizoncd/horizon/pkg/config/role" groupservice "github.com/horizoncd/horizon/pkg/group/service" memberservice "github.com/horizoncd/horizon/pkg/member/service" oauthdao "github.com/horizoncd/horizon/pkg/oauth/dao" oauthmanager "github.com/horizoncd/horizon/pkg/oauth/manager" scopeservice "github.com/horizoncd/horizon/pkg/oauth/scope" "github.com/horizoncd/horizon/pkg/param" "github.com/horizoncd/horizon/pkg/param/managerparam" "github.com/horizoncd/horizon/pkg/rbac" "github.com/horizoncd/horizon/pkg/rbac/role" "github.com/horizoncd/horizon/pkg/templaterelease/output" templateschemarepo "github.com/horizoncd/horizon/pkg/templaterelease/schema/repo" "github.com/horizoncd/horizon/pkg/templaterepo" userservice "github.com/horizoncd/horizon/pkg/user/service" callbacks "github.com/horizoncd/horizon/pkg/util/ormcallbacks" "github.com/gin-gonic/gin" "github.com/go-redis/redis/v8" "github.com/gorilla/sessions" "github.com/rbcervilla/redisstore/v8" "github.com/sirupsen/logrus" "gopkg.in/yaml.v3") // Flags defines agent CLI flags.type Flags struct { ConfigFile string RoleConfigFile string ScopeRoleFile string BuildJSONSchemaFile string BuildUISchemaFile string Dev bool Environment string LogLevel string} type RegisterRouter interface { RegisterRoute(engine *gin.Engine)} // ParseFlags parses agent CLI flags.func ParseFlags() *Flags { var flags Flags flag.StringVar( &flags.ConfigFile, "config", "", "configuration file path") flag.StringVar( &flags.RoleConfigFile, "roles", "", "roles file path") flag.StringVar( &flags.ScopeRoleFile, "scopes", "", "configuration file path") flag.StringVar(&flags.BuildJSONSchemaFile, "buildjsonschema", "", "build json schema file path") flag.StringVar(&flags.BuildUISchemaFile, "builduischema", "", "build ui schema file path") flag.BoolVar( &flags.Dev, "dev", false, "if true, turn off the usermiddleware to skip login") flag.StringVar( &flags.Environment, "environment", "production", "environment string tag") flag.StringVar( &flags.LogLevel, "loglevel", "info", "the loglevel(panic/fatal/error/warn/info/debug/trace))") flag.Parse() return &flags} func InitAdmissionWebhook(config admissionconfig.Admission) { admission.NewHTTPWebhooks(config)} func InitLog(flags *Flags) { if flags.Environment == "production" { logrus.SetFormatter(&logrus.JSONFormatter{}) } else { logrus.SetFormatter(&logrus.TextFormatter{}) } logrus.SetOutput(os.Stdout) level, err := logrus.ParseLevel(flags.LogLevel) if err != nil { panic(err) } logrus.SetLevel(level)} func runPProfServer(config *pprof.Config) { if config.Enabled { go func() { if err := http.ListenAndServe(fmt.Sprintf(":%d", config.Port), nil); err != nil { log.Printf("[pprof] failed to start, error: %s", err.Error()) } }() log.Printf("[pprof] Listening and serving HTTP on :%d", config.Port) }} func LoadConfig(flags *Flags) (*config.Config, error) { coreConfig, err := config.LoadConfig(flags.ConfigFile) if err != nil { return nil, err } _, err = json.MarshalIndent(coreConfig, "", " ") if err != nil { return nil, err } return coreConfig, nil} Function `Init` has 392 lines of code (exceeds 50 allowed). Consider refactoring.
Function `Init` has a Cognitive Complexity of 28 (exceeds 20 allowed). Consider refactoring.func Init(ctx context.Context, flags *Flags, coreConfig *config.Config) { // init roles file, err := os.OpenFile(flags.RoleConfigFile, os.O_RDONLY, 0644) if err != nil { panic(err) } content, err := ioutil.ReadAll(file) if err != nil { panic(err) } var roleConfig roleconfig.Config if err := yaml.Unmarshal(content, &roleConfig); err != nil { panic(err) } log.Printf("the roleConfig = %+v\n", roleConfig) // init db mysqlDB, err := orm.NewMySQLDB(&orm.MySQL{ Host: coreConfig.DBConfig.Host, Port: coreConfig.DBConfig.Port, Username: coreConfig.DBConfig.Username, Password: coreConfig.DBConfig.Password, Database: coreConfig.DBConfig.Database, PrometheusEnabled: coreConfig.DBConfig.PrometheusEnabled, }) if err != nil { panic(err) } callbacks.RegisterCustomCallbacks(mysqlDB) redisClient := redis.NewClient(&redis.Options{ Network: coreConfig.RedisConfig.Protocol, Addr: coreConfig.RedisConfig.Address, Password: coreConfig.RedisConfig.Password, DB: int(coreConfig.RedisConfig.DB), }) // session store store, err := redisstore.NewRedisStore(context.Background(), redisClient) if err != nil { panic(err) } store.Options(sessions.Options{ Path: "/", MaxAge: int(coreConfig.SessionConfig.MaxAge), }) // https://pkg.go.dev/github.com/gorilla/sessions#section-readme gob.Register(&userauth.DefaultInfo{}) // init manager parameter manager := managerparam.InitManager(mysqlDB) gitlabGitops, err := gitlablib.New(coreConfig.GitopsRepoConfig.Token, coreConfig.GitopsRepoConfig.URL) if err != nil { panic(err) } // check existence of gitops root group rootGroupPath := coreConfig.GitopsRepoConfig.RootGroupPath rootGroup, err := gitlabGitops.GetGroup(ctx, rootGroupPath) if err != nil { log.Printf("failed to get gitops root group, error: %s, start to create it", err.Error()) rootGroup, err = gitlabGitops.CreateGroup(ctx, rootGroupPath, rootGroupPath, nil, coreConfig.GitopsRepoConfig.DefaultVisibility) if err != nil { panic(err) } } applicationGitRepo, err := gitrepo.NewApplicationGitlabRepo(ctx, gitlabGitops, gitrepo.ApplicationGitRepoConfig{ RootGroup: rootGroup, DefaultBranch: coreConfig.GitopsRepoConfig.DefaultBranch, DefaultVisibility: coreConfig.GitopsRepoConfig.DefaultVisibility, }) if err != nil { panic(err) } templateRepo, err := templaterepo.NewRepo(coreConfig.TemplateRepo) if err != nil { panic(err) } clusterGitRepo, err := clustergitrepo.NewClusterGitlabRepo(ctx, rootGroup, templateRepo, gitlabGitops, coreConfig.GitopsRepoConfig.DefaultBranch, coreConfig.GitopsRepoConfig.DefaultVisibility) if err != nil { panic(err) } templateSchemaGetter := templateschemarepo.NewSchemaGetter(ctx, templateRepo, manager) outputGetter, err := output.NewOutPutGetter(ctx, templateRepo, manager) if err != nil { panic(err) } gitGetter, err := code.NewGitGetter(ctx, coreConfig.CodeGitRepos) if err != nil { panic(err) } tektonFty, err := factory.NewFactory(coreConfig.TektonMapper) if err != nil { panic(err) } oauthAppDAO := oauthdao.NewDAO(mysqlDB) tokenStore := tokenstore.NewStore(mysqlDB) oauthManager := oauthmanager.NewManager(oauthAppDAO, tokenStore, generator.NewAuthorizeGenerator(), coreConfig.Oauth.AuthorizeCodeExpireIn, coreConfig.Oauth.AccessTokenExpireIn, coreConfig.Oauth.RefreshTokenExpireIn) roleService, err := role.NewFileRoleFrom2(context.TODO(), roleConfig) if err != nil { panic(err) } mservice := memberservice.NewService(roleService, oauthManager, manager) rbacAuthorizer := rbac.NewAuthorizer(roleService, mservice) // init scope service scopeFile, err := os.OpenFile(flags.ScopeRoleFile, os.O_RDONLY, 0644) if err != nil { panic(err) } content, err = ioutil.ReadAll(scopeFile) if err != nil { panic(err) } var oauthConfig oauthconfig.Scopes if err = yaml.Unmarshal(content, &oauthConfig); err != nil { panic(err) } log.Printf("the oauthScopeConfig = %+v\n", oauthConfig) scopeService, err := scopeservice.NewFileScopeService(oauthConfig) if err != nil { panic(err) } autoFreeSvc := service.New(coreConfig.AutoFreeConfig.SupportedEnvs) // init build schema controller readJSONFileFunc := func(filePath string) map[string]interface{} { fileFd, err := os.OpenFile(filePath, os.O_RDONLY, 0644) if err != nil { panic(err) } fileContent, err := ioutil.ReadAll(fileFd) if err != nil { panic(err) } var schemaFile map[string]interface{} err = json.Unmarshal(fileContent, &schemaFile) if err != nil { panic(err) } return schemaFile } buildSchema := &build.Schema{ JSONSchema: readJSONFileFunc(flags.BuildJSONSchemaFile), UISchema: readJSONFileFunc(flags.BuildUISchemaFile), } groupSvc := groupservice.NewService(manager) eventSvc := eventservice.New(manager) applicationSvc := applicationservice.NewService(groupSvc, manager) clusterSvc := clusterservice.NewService(applicationSvc, clusterGitRepo, manager) userSvc := userservice.NewService(manager) tokenSvc := tokenservice.NewService(manager, coreConfig.TokenConfig) // init kube client _, client, err := kube.BuildClient(coreConfig.KubeConfig) if err != nil { panic(err) } grafanaService := grafana.NewService(coreConfig.GrafanaConfig, manager, client) regionInformers := regioninformers.NewRegionInformers(manager.RegionMgr, 0) regionInformers.Register(workload.Resources...) go regionInformers.WatchRegion(ctx, 60*time.Second) parameter := ¶m.Param{ Manager: manager, OauthManager: oauthManager, AutoFreeSvc: autoFreeSvc, MemberService: mservice, ApplicationSvc: applicationSvc, ClusterSvc: clusterSvc, GroupSvc: groupSvc, EventSvc: eventSvc, UserSvc: userSvc, TokenSvc: tokenSvc, RoleService: roleService, ScopeService: scopeService, ApplicationGitRepo: applicationGitRepo, TemplateSchemaGetter: templateSchemaGetter, CD: cd.NewCD(regionInformers, clusterGitRepo, coreConfig.ArgoCDMapper, coreConfig.RegionArgoCDMapper, coreConfig.GitopsRepoConfig.DefaultBranch), K8sUtil: cd.NewK8sUtil(regionInformers, manager.EventMgr), OutputGetter: outputGetter, TektonFty: tektonFty, ClusterGitRepo: clusterGitRepo, PRService: prservice.NewService(manager), GitGetter: gitGetter, GrafanaService: grafanaService, BuildSchema: buildSchema, } var ( authnSkippers = []middleware.Skipper{ middleware.MethodAndPathSkipper("*", regexp.MustCompile("(^/apis/front/.*)|(^/health)|(^/metrics)|(^/apis/login)|"+ "(^/apis/core/v[12]/roles)|(^/apis/internal/.*)|(^/login/oauth/authorize)|(^/login/oauth/access_token)")), middleware.MethodAndPathSkipper(http.MethodGet, regexp.MustCompile("^/apis/core/v[12]/idps/endpoints")), middleware.MethodAndPathSkipper(http.MethodGet, regexp.MustCompile("^/apis/core/v[12]/login/callback")), middleware.MethodAndPathSkipper(http.MethodPost, regexp.MustCompile("^/apis/core/v[12]/logout")), middleware.MethodAndPathSkipper(http.MethodPost, regexp.MustCompile("^/apis/core/v[12]/users/login")), middleware.MethodAndPathSkipper(http.MethodGet, regexp.MustCompile("^/apis/core/v[12]/users/self")), } authzSkippers = []middleware.Skipper{ middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/apis/core/v[12]/templates$")), } ) authzSkippers = append(authzSkippers, authnSkippers...) var ( // init controller memberCtl = memberctl.NewController(parameter) applicationCtl = applicationctl.NewController(parameter) envTemplateCtl = envtemplatectl.NewController(parameter) clusterCtl = clusterctl.NewController(coreConfig, parameter) prCtl = prctl.NewController(coreConfig, parameter) templateCtl = templatectl.NewController(parameter, templateRepo) roleCtl = roltctl.NewController(parameter) terminalCtl = terminalctl.NewController(parameter) codeGitCtl = codectl.NewController(gitGetter) tagCtl = tagctl.NewController(parameter) templateSchemaTagCtl = templateschematagctl.NewController(parameter) accessCtl = accessctl.NewController(rbacAuthorizer, authzSkippers...) applicationRegionCtl = applicationregionctl.NewController(parameter) groupCtl = groupctl.NewController(parameter) oauthCheckerCtl = oauthcheckctl.NewOauthChecker(parameter) oauthAppCtl = oauthappctl.NewController(parameter) oauthServerCtl = oauthservicectl.NewController(parameter) regionCtl = regionctl.NewController(parameter) userCtl = userctl.NewController(parameter) environmentCtl = environmentctl.NewController(parameter) environmentregionCtl = environmentregionctl.NewController(parameter) registryCtl = registryctl.NewController(parameter) idpCtrl = idpctl.NewController(parameter) buildSchemaCtrl = build.NewController(buildSchema) accessTokenCtl = accesstokenctl.NewController(parameter) scopeCtl = scopectl.NewController(parameter) webhookCtl = webhookctl.NewController(parameter) eventCtl = eventctl.NewController(parameter) badgeCtl = badgectl.NewController(parameter) ) var ( // init v1 API groupAPI = group.NewAPI(groupCtl) userAPI = user.NewAPI(userCtl, store) applicationAPI = application.NewAPI(applicationCtl) envTemplateAPI = envtemplate.NewAPI(envTemplateCtl) memberAPI = member.NewAPI(memberCtl, roleService) clusterAPI = cluster.NewAPI(clusterCtl) prAPI = pipelinerun.NewAPI(prCtl) environmentAPI = environment.NewAPI(environmentCtl) regionAPI = region.NewAPI(regionCtl, tagCtl) environmentRegionAPI = environmentregion.NewAPI(environmentregionCtl) registryAPI = registry.NewAPI(registryCtl) roleAPI = roleapi.NewAPI(roleCtl) terminalAPI = terminalapi.NewAPI(terminalCtl) codeGitAPI = codeapi.NewAPI(codeGitCtl) tagAPI = tag.NewAPI(tagCtl) templateSchemaTagAPI = templateschematagapi.NewAPI(templateSchemaTagCtl) templateAPI = template.NewAPI(templateCtl, templateSchemaTagCtl) accessAPI = accessapi.NewAPI(accessCtl) applicationRegionAPI = applicationregion.NewAPI(applicationRegionCtl) oauthAppAPI = oauthapp.NewAPI(oauthAppCtl) oauthServerAPI = oauthserver.NewAPI(oauthServerCtl, oauthAppCtl, coreConfig.Oauth.OauthHTMLLocation, scopeService) idpAPI = idp.NewAPI(idpCtrl, store) accessTokenAPI = accesstoken.NewAPI(accessTokenCtl, roleService, scopeService) scopeAPI = scope.NewAPI(scopeCtl) webhookAPI = webhook.NewAPI(webhookCtl) eventAPI = event.NewAPI(eventCtl) // init v2 API accessAPIV2 = accessv2.NewAPI(accessCtl) accessTokenAPIV2 = accesstokenv2.NewAPI(accessTokenCtl, roleService, scopeService) applicationAPIV2 = appv2.NewAPI(applicationCtl) applicationRegionAPIV2 = applicationregionv2.NewAPI(applicationRegionCtl) buildSchemaAPI = buildAPI.NewAPI(buildSchemaCtrl) clusterAPIV2 = clusterv2.NewAPI(clusterCtl) codeGitAPIV2 = codev2.NewAPI(codeGitCtl) environmentAPIV2 = environmentv2.NewAPI(environmentCtl) environmentRegionAPIV2 = environmentregionv2.NewAPI(environmentregionCtl) envtemplateAPIV2 = envtemplatev2.NewAPI(envTemplateCtl) eventAPIV2 = eventv2.NewAPI(eventCtl) groupAPIV2 = groupv2.NewAPI(groupCtl) idpAPIV2 = idpv2.NewAPI(idpCtrl, store) memberAPIV2 = memberv2.NewAPI(memberCtl, roleService) oauthAppAPIV2 = oauthappv2.NewAPI(oauthAppCtl) pipelinerunAPIV2 = pipelinerunv2.NewAPI(prCtl) regionAPIV2 = regionv2.NewAPI(regionCtl, tagCtl) registryAPIV2 = registryv2.NewAPI(registryCtl) roleAPIV2 = rolev2.NewAPI(roleCtl) scopeAPIV2 = scopev2.NewAPI(scopeCtl) tagAPIV2 = tagv2.NewAPI(tagCtl) templateAPIV2 = templatev2.NewAPI(templateCtl, templateSchemaTagCtl) templateSchemaTagAPIV2 = templateschematagv2.NewAPI(templateSchemaTagCtl) terminalAPIV2 = terminalv2.NewAPI(terminalCtl) userAPIV2 = userv2.NewAPI(userCtl, store) webhookAPIV2 = webhookv2.NewAPI(webhookCtl) badgeAPIV2 = badge.NewAPI(badgeCtl) ) // start jobs cleaner := clean.New(coreConfig.Clean, manager) autoFreeJob := func(ctx context.Context) { autofree.Run(ctx, &coreConfig.AutoFreeConfig, manager.UserMgr, clusterCtl, prCtl) } eventHandlerJob, eventHandlerSvc := eventhandler.New(ctx, coreConfig.EventHandlerConfig, manager) webhookJob, _ := jobwebhook.New(ctx, eventHandlerSvc, coreConfig.WebhookConfig, manager) grafanaSyncJob := func(ctx context.Context) { grafanasync.Run(ctx, coreConfig, manager, client) } k8seventJob := k8sevent.New(coreConfig.KubernetesEvent, regionInformers, manager, mysqlDB) go jobs.Run(ctx, &coreConfig.JobConfig, eventHandlerJob, webhookJob, k8seventJob.Run, cleaner.Run, autoFreeJob, grafanaSyncJob) // init server r := gin.New() // use middleware middlewares := []gin.HandlerFunc{ ginlogmiddle.Middleware(gin.DefaultWriter, "/health", "/metrics"), gin.Recovery(), requestid.Middleware(), // requestID middleware, attach a requestID to context logmiddle.Middleware(), // log middleware, attach a logger to context metricsmiddle.Middleware( // metrics middleware middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/health")), middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/metrics"))), scopemiddle.Middleware(parameter, applicationRegionCtl, manager), tokenmiddle.MiddleWare(oauthCheckerCtl, authnSkippers...), // user middleware, check user and attach current user to context. usermiddle.Middleware(parameter, store, coreConfig, middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/health")), middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/metrics")), middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/apis/front/v1/terminal")), middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/apis/front/v2/buildschema")), middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/login/oauth/access_token")), middleware.MethodAndPathSkipper("*", regexp.MustCompile("^/apis/internal/v2/.*")), middleware.MethodAndPathSkipper(http.MethodGet, regexp.MustCompile("^/apis/core/v[12]/idps/endpoints")), middleware.MethodAndPathSkipper(http.MethodPost, regexp.MustCompile("^/apis/core/v[12]/users/login"))), prehandlemiddle.Middleware(r, manager), auth.Middleware(rbacAuthorizer, authzSkippers...), tagmiddle.Middleware(), admissionmiddle.Middleware(authzSkippers...), } r.Use(middlewares...) gin.ForceConsoleColor() // register routes health.RegisterRoutes(r) clustermetrcis.NewMetrics(manager) metrics.RegisterRoutes(r) // v1 registerV1Group := []RegisterRouter{ groupAPI, templateAPI, userAPI, applicationAPI, envTemplateAPI, clusterAPI, prAPI, environmentAPI, regionAPI, environmentRegionAPI, registryAPI, memberAPI, roleAPI, terminalAPI, codeGitAPI, tagAPI, templateSchemaTagAPI, accessAPI, applicationRegionAPI, oauthAppAPI, oauthServerAPI, idpAPI, accessTokenAPI, scopeAPI, webhookAPI, eventAPI, } // v2 registerV2Group := []RegisterRouter{ groupAPIV2, accessAPIV2, accessTokenAPIV2, applicationAPIV2, applicationRegionAPIV2, buildSchemaAPI, clusterAPIV2, codeGitAPIV2, environmentAPIV2, environmentRegionAPIV2, envtemplateAPIV2, eventAPIV2, idpAPIV2, memberAPIV2, oauthAppAPIV2, pipelinerunAPIV2, regionAPIV2, registryAPIV2, roleAPIV2, scopeAPIV2, tagAPIV2, templateAPIV2, templateSchemaTagAPIV2, terminalAPIV2, userAPIV2, webhookAPIV2, badgeAPIV2, } // start cloud event server go runCloudEventServer( tektonFty, coreConfig.CloudEventServerConfig, parameter, ginlogmiddle.Middleware(gin.DefaultWriter, "/health", "/metrics"), requestid.Middleware(), ) // merge routes registerAll := append(registerV1Group, registerV2Group...) for _, register := range registerAll { register.RegisterRoute(r) } // start api server log.Printf("Server started") log.Print(r.Run(fmt.Sprintf(":%d", coreConfig.ServerConfig.Port)))} // Run runs the agent.func Run(flags *Flags) { ctx, cancelFunc := context.WithCancel(context.Background()) setTasksBeforeExit(cancelFunc) configs, err := LoadConfig(flags) if err != nil { panic(err) } InitAdmissionWebhook(configs.Admission) // enable pprof runPProfServer(&configs.PProf) // init log InitLog(flags) // init api Init(ctx, flags, configs)} // setTasksBeforeExit set stop funcs which will be executed after sigterm and sigint catchedfunc setTasksBeforeExit(stopFuncs ...func()) { sig := make(chan os.Signal, 1) signal.Notify(sig, syscall.SIGTERM, syscall.SIGINT) go func() { s := <-sig log.Printf("got %s signal, stop tasks...\n", s) if len(stopFuncs) == 0 { return } wg := sync.WaitGroup{} wg.Add(len(stopFuncs)) for _, stopFunc := range stopFuncs { go func(stop func()) { stop() }(stopFunc) } wg.Wait() log.Printf("all tasks stopped, exit now.") }()}