diff --git a/tibuild/api/api.go b/tibuild/api/api.go index 089d2e0..06a8e45 100644 --- a/tibuild/api/api.go +++ b/tibuild/api/api.go @@ -102,7 +102,7 @@ func routeRestAPI(router *gin.Engine, cfg *configs.ConfigYaml) { panic(err) } devBuildGroup := apiGroup.Group("/devbuilds") - devBuildHandler := controllers.NewDevBuildHandler(context.Background(), jenkins, database.DBConn.DB, cfg.TiBuild.AdminPasswd) + devBuildHandler := controllers.NewDevBuildHandler(context.Background(), jenkins, database.DBConn.DB, cfg.AuthConfig) { devBuildGroup.POST("", devBuildHandler.Create) devBuildGroup.GET("", devBuildHandler.List) diff --git a/tibuild/commons/configs/config.go b/tibuild/commons/configs/config.go index 3252ddd..91ea3ee 100644 --- a/tibuild/commons/configs/config.go +++ b/tibuild/commons/configs/config.go @@ -31,9 +31,12 @@ type ConfigYaml struct { Token string } - TiBuild struct { - AdminPasswd string - } + AuthConfig TiBuildAuthCfg +} + +type TiBuildAuthCfg struct { + AdminPasswd string + TiBuildPasswd string } var Config = &ConfigYaml{} @@ -41,5 +44,8 @@ var Config = &ConfigYaml{} // Load config from file into 'Config' variable func LoadConfig(file string) { fmt.Printf("file:%s\n", file) - configor.Load(Config, file) + err := configor.Load(Config, file) + if err != nil { + panic(err) + } } diff --git a/tibuild/commons/configs/config_test.go b/tibuild/commons/configs/config_test.go index 7a4cc72..3c17608 100644 --- a/tibuild/commons/configs/config_test.go +++ b/tibuild/commons/configs/config_test.go @@ -2,9 +2,12 @@ package configs import ( "testing" + + "github.com/stretchr/testify/assert" ) func TestLoadConfig(t *testing.T) { - t.Skip() - LoadConfig("../../config.yaml") + LoadConfig("../../configs/config.yaml") + cfg := Config.AuthConfig + assert.NotEmpty(t, cfg.TiBuildPasswd) } diff --git a/tibuild/pkg/rest/controller/dev_build_handler.go b/tibuild/pkg/rest/controller/dev_build_handler.go index b23acac..5779949 100644 --- a/tibuild/pkg/rest/controller/dev_build_handler.go +++ b/tibuild/pkg/rest/controller/dev_build_handler.go @@ -10,22 +10,23 @@ import ( "github.com/gin-gonic/gin" "gorm.io/gorm" + "github.com/PingCAP-QE/ee-apps/tibuild/commons/configs" "github.com/PingCAP-QE/ee-apps/tibuild/pkg/rest/repo" "github.com/PingCAP-QE/ee-apps/tibuild/pkg/rest/service" ) type DevBuildHandler struct { - svc service.DevBuildService - admin_passwd string + svc service.DevBuildService + auth configs.TiBuildAuthCfg } -func NewDevBuildHandler(ctx context.Context, jenkins service.Jenkins, db *gorm.DB, admin_passwd string) *DevBuildHandler { +func NewDevBuildHandler(ctx context.Context, jenkins service.Jenkins, db *gorm.DB, auth configs.TiBuildAuthCfg) *DevBuildHandler { db.AutoMigrate(&service.DevBuild{}) return &DevBuildHandler{svc: service.DevbuildServer{ Repo: repo.DevBuildRepo{Db: db}, Jenkins: jenkins, Now: time.Now}, - admin_passwd: admin_passwd, + auth: auth, } } @@ -34,11 +35,23 @@ func (h DevBuildHandler) authenticate(c *gin.Context) (context.Context, error) { if !ok { return c.Request.Context(), nil } - if user != service.AdminUserName || passwd != h.admin_passwd { - return nil, fmt.Errorf("authenticate error%w", service.ErrAuth) - } - ctx := context.WithValue(c.Request.Context(), service.KeyOfUserName, user) - return ctx, nil + if user == service.AdminUserName { + if passwd == h.auth.AdminPasswd { + ctx := context.WithValue(c.Request.Context(), service.KeyOfUserName, user) + return ctx, nil + } else { + return nil, fmt.Errorf("authenticate error%w", service.ErrAuth) + } + } + if user == service.TibuildUserName { + if passwd == h.auth.TiBuildPasswd { + ctx := context.WithValue(c.Request.Context(), service.KeyOfUserName, user) + return ctx, nil + } else { + return nil, fmt.Errorf("authenticate error%w", service.ErrAuth) + } + } + return c.Request.Context(), nil } // CreateDevbuild godoc diff --git a/tibuild/pkg/rest/service/dev_build_service.go b/tibuild/pkg/rest/service/dev_build_service.go index 8ee12ea..d556199 100644 --- a/tibuild/pkg/rest/service/dev_build_service.go +++ b/tibuild/pkg/rest/service/dev_build_service.go @@ -81,7 +81,7 @@ func (s DevbuildServer) Create(ctx context.Context, req DevBuild, option DevBuil } func validate_permission(ctx context.Context, req DevBuild) error { - if req.Spec.TargetImage != "" && ctx.Value(KeyOfUserName) != AdminUserName { + if req.Spec.TargetImg != "" && ctx.Value(KeyOfUserName) != AdminUserName { return fmt.Errorf("targetImage deny because of permission") } return nil diff --git a/tibuild/pkg/rest/service/dev_build_service_test.go b/tibuild/pkg/rest/service/dev_build_service_test.go index c0c5516..7bb72be 100644 --- a/tibuild/pkg/rest/service/dev_build_service_test.go +++ b/tibuild/pkg/rest/service/dev_build_service_test.go @@ -149,7 +149,7 @@ func TestDevBuildCreate(t *testing.T) { _, err := server.Create(context.TODO(), obj, DevBuildSaveOption{}) require.NoError(t, err) - obj.Spec.TargetImage = "hub.pingcap.net/temp/tidb:somefeat" + obj.Spec.TargetImg = "hub.pingcap.net/temp/tidb:somefeat" _, err = server.Create(context.TODO(), obj, DevBuildSaveOption{}) require.ErrorIs(t, err, ErrAuth) diff --git a/tibuild/pkg/rest/service/model.go b/tibuild/pkg/rest/service/model.go index 502ad07..a12debf 100644 --- a/tibuild/pkg/rest/service/model.go +++ b/tibuild/pkg/rest/service/model.go @@ -169,7 +169,7 @@ type DevBuildSpec struct { IsPushGCR bool `json:"isPushGCR,omitempty"` Features string `json:"features,omitempty" gorm:"type:varchar(128)"` IsHotfix bool `json:"isHotfix,omitempty"` - TargetImage string `json:"targetImage,omitempty" gorm:"type:varchar(128)"` + TargetImg string `json:"targetImg,omitempty" gorm:"type:varchar(128)"` } type GitRef string @@ -270,3 +270,4 @@ type TibuildCtxKey string var KeyOfUserName TibuildCtxKey = "username" const AdminUserName = "admin" +const TibuildUserName = "tibuild" diff --git a/tibuild/tbctl/tbctl.py b/tibuild/tbctl/tbctl.py index be65ca0..6934e6b 100644 --- a/tibuild/tbctl/tbctl.py +++ b/tibuild/tbctl/tbctl.py @@ -12,6 +12,7 @@ NOBLOCK = False BUILD_CREATED_BY = '' +BASIC_AUTH_CREDENTIAL='' def dev_build_url(build_id: int): @@ -35,11 +36,14 @@ def trigger(args): "buildEnv": ' '.join(args.buildEnv) if args.buildEnv else '', "productDockerfile": args.productDockerfile, "productBaseImg": args.productBaseImg, - "builderImg":args.builderImg}} + "builderImg":args.builderImg, + "targetImg": args.targetImg}} headers = { "Content-Type": "application/json", "Accept": "application/json", } + if BASIC_AUTH_CREDENTIAL: + headers['Authorization']="BASIC " + BASIC_AUTH_CREDENTIAL body = json.dumps(data).encode() req = urllib.request.Request(f"{devbuild_url}?dryrun={args.dryrun}", body, headers, method="POST") build_id = 0 @@ -107,6 +111,7 @@ def get_artifact(build: dict) -> str: if __name__ == "__main__": NOBLOCK = bool(os.environ.get('NOBLOCK')) BUILD_CREATED_BY = os.environ.get('BUILD_CREATED_BY') or '' + BASIC_AUTH_CREDENTIAL = os.environ.get('BASIC_AUTH_CREDENTIAL') or '' top_parser = argparse.ArgumentParser( prog='tbctl', description='tibuild commandline client' @@ -133,6 +138,7 @@ def get_artifact(build: dict) -> str: parser_trigger.add_argument('--productDockerfile', help='dockerfile url for product') parser_trigger.add_argument('--productBaseImg', help='product base image') parser_trigger.add_argument('--builderImg', help='specify docker image for builder') + parser_trigger.add_argument('--targetImage', help=argparse.SUPPRESS) parser_trigger.set_defaults(handler=trigger) parser_poll = devbuild.add_parser('poll') parser_poll.add_argument('build_id', type=int, help="the triggered build id")