From 9ec8b4d6346cce3d664911aae06ff0bb86dd6677 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Wed, 17 Jan 2018 17:07:10 +0800 Subject: [PATCH 1/4] Support multiple status in query string of replication job listing API --- src/ui/api/replication_job.go | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/src/ui/api/replication_job.go b/src/ui/api/replication_job.go index 2acda5604..f2446688f 100644 --- a/src/ui/api/replication_job.go +++ b/src/ui/api/replication_job.go @@ -82,7 +82,7 @@ func (ra *RepJobAPI) List() { } repository := ra.GetString("repository") - status := ra.GetString("status") + statuses := ra.GetStrings("status") var startTime *time.Time startTimeStr := ra.GetString("start_time") @@ -108,15 +108,11 @@ func (ra *RepJobAPI) List() { page, pageSize := ra.GetPaginationParams() - statuses := []string{} - if len(status) > 0 { - statuses = append(statuses, status) - } jobs, total, err := dao.FilterRepJobs(policyID, repository, statuses, startTime, endTime, pageSize, pageSize*(page-1)) if err != nil { - log.Errorf("failed to filter jobs according policy ID %d, repository %s, status %s, start time %v, end time %v: %v", - policyID, repository, status, startTime, endTime, err) + log.Errorf("failed to filter jobs according policy ID %d, repository %s, status %v, start time %v, end time %v: %v", + policyID, repository, statuses, startTime, endTime, err) ra.CustomAbort(http.StatusInternalServerError, "") } From 611709a7be60d31b4041436c0b80976e176e6d87 Mon Sep 17 00:00:00 2001 From: Wenkai Yin Date: Thu, 18 Jan 2018 14:47:00 +0800 Subject: [PATCH 2/4] Add pagination support in listing replication policy API --- docs/swagger.yaml | 12 ++++++++++ src/common/dao/dao_test.go | 8 ++++++- src/common/dao/replication_job.go | 22 ++++++++++++++++- src/common/utils/test/policy_manager.go | 4 ++-- src/replication/core/controller.go | 19 +++++++-------- src/replication/models/policy.go | 9 ++++--- src/replication/policy/manager.go | 29 +++++++++++----------- src/ui/api/replication_policy.go | 32 +++++++++++++++---------- 8 files changed, 91 insertions(+), 44 deletions(-) diff --git a/docs/swagger.yaml b/docs/swagger.yaml index e06318577..3fe439e13 100644 --- a/docs/swagger.yaml +++ b/docs/swagger.yaml @@ -1511,6 +1511,18 @@ paths: format: int64 required: false description: Relevant project ID. + - name: page + in: query + type: integer + format: int32 + required: false + description: 'The page nubmer.' + - name: page_size + in: query + type: integer + format: int32 + required: false + description: 'The size of per page.' tags: - Products responses: diff --git a/src/common/dao/dao_test.go b/src/common/dao/dao_test.go index 2159f93ad..2ccb8739a 100644 --- a/src/common/dao/dao_test.go +++ b/src/common/dao/dao_test.go @@ -21,6 +21,7 @@ import ( "github.com/astaxie/beego/orm" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" "github.com/vmware/harbor/src/common" "github.com/vmware/harbor/src/common/models" "github.com/vmware/harbor/src/common/utils" @@ -1253,8 +1254,13 @@ func TestDeleteRepTarget(t *testing.T) { } } +func TestGetTotalOfRepPolicies(t *testing.T) { + _, err := GetTotalOfRepPolicies("", 1) + require.Nil(t, err) +} + func TestFilterRepPolicies(t *testing.T) { - _, err := FilterRepPolicies("name", 0) + _, err := FilterRepPolicies("name", 0, 0, 0) if err != nil { t.Fatalf("failed to filter policy: %v", err) } diff --git a/src/common/dao/replication_job.go b/src/common/dao/replication_job.go index b97319cf0..a37a63f20 100644 --- a/src/common/dao/replication_job.go +++ b/src/common/dao/replication_job.go @@ -139,8 +139,23 @@ func GetRepPolicy(id int64) (*models.RepPolicy, error) { return &policy, nil } +// GetTotalOfRepPolicies returns the total count of replication policies +func GetTotalOfRepPolicies(name string, projectID int64) (int64, error) { + qs := GetOrmer().QueryTable(&models.RepPolicy{}).Filter("deleted", 0) + + if len(name) != 0 { + qs = qs.Filter("name__icontains", name) + } + + if projectID != 0 { + qs = qs.Filter("project_id", projectID) + } + + return qs.Count() +} + // FilterRepPolicies filters policies by name and project ID -func FilterRepPolicies(name string, projectID int64) ([]*models.RepPolicy, error) { +func FilterRepPolicies(name string, projectID, page, pageSize int64) ([]*models.RepPolicy, error) { o := GetOrmer() var args []interface{} @@ -170,6 +185,11 @@ func FilterRepPolicies(name string, projectID int64) ([]*models.RepPolicy, error sql += `group by rp.id order by rp.creation_time` + if page > 0 && pageSize > 0 { + sql += ` limit ? offset ?` + args = append(args, pageSize, (page-1)*pageSize) + } + var policies []*models.RepPolicy if _, err := o.Raw(sql, args).QueryRows(&policies); err != nil { return nil, err diff --git a/src/common/utils/test/policy_manager.go b/src/common/utils/test/policy_manager.go index 492c88e00..768a88087 100644 --- a/src/common/utils/test/policy_manager.go +++ b/src/common/utils/test/policy_manager.go @@ -22,8 +22,8 @@ import ( type FakePolicyManager struct { } -func (f *FakePolicyManager) GetPolicies(query models.QueryParameter) ([]models.ReplicationPolicy, error) { - return []models.ReplicationPolicy{}, nil +func (f *FakePolicyManager) GetPolicies(query models.QueryParameter) (*models.ReplicationPolicyQueryResult, error) { + return &models.ReplicationPolicyQueryResult{}, nil } func (f *FakePolicyManager) GetPolicy(id int64) (models.ReplicationPolicy, error) { diff --git a/src/replication/core/controller.go b/src/replication/core/controller.go index 9065e6284..07ec4a9a1 100644 --- a/src/replication/core/controller.go +++ b/src/replication/core/controller.go @@ -98,18 +98,17 @@ func (ctl *DefaultController) Init() error { return nil } - //Build query parameters - query := models.QueryParameter{ - TriggerType: replication.TriggerKindSchedule, - } - - policies, err := ctl.policyManager.GetPolicies(query) + policies, err := ctl.policyManager.GetPolicies(models.QueryParameter{}) if err != nil { return err } - if policies != nil && len(policies) > 0 { - for _, policy := range policies { - if err := ctl.triggerManager.SetupTrigger(&policy); err != nil { + if policies != nil && len(policies.Policies) > 0 { + for _, policy := range policies.Policies { + if policy.Trigger == nil || policy.Trigger.Kind != replication.TriggerKindSchedule { + continue + } + + if err := ctl.triggerManager.SetupTrigger(policy); err != nil { log.Errorf("failed to setup trigger for policy %v: %v", policy, err) } } @@ -209,7 +208,7 @@ func (ctl *DefaultController) GetPolicy(policyID int64) (models.ReplicationPolic } //GetPolicies is delegation of GetPoliciemodels.ReplicationPolicy{}s of Policy.Manager -func (ctl *DefaultController) GetPolicies(query models.QueryParameter) ([]models.ReplicationPolicy, error) { +func (ctl *DefaultController) GetPolicies(query models.QueryParameter) (*models.ReplicationPolicyQueryResult, error) { return ctl.policyManager.GetPolicies(query) } diff --git a/src/replication/models/policy.go b/src/replication/models/policy.go index f6ab0217d..022d84a14 100644 --- a/src/replication/models/policy.go +++ b/src/replication/models/policy.go @@ -27,12 +27,15 @@ type QueryParameter struct { //Size of each page, couple with page PageSize int64 - //Query by the type of trigger - TriggerType string - //Query by project ID ProjectID int64 //Query by name Name string } + +// ReplicationPolicyQueryResult is the query result of replication policy +type ReplicationPolicyQueryResult struct { + Total int64 + Policies []*ReplicationPolicy +} diff --git a/src/replication/policy/manager.go b/src/replication/policy/manager.go index a6049dbfe..f06f6b33c 100644 --- a/src/replication/policy/manager.go +++ b/src/replication/policy/manager.go @@ -26,7 +26,7 @@ import ( // Manager defines the method a policy manger should implement type Manager interface { - GetPolicies(models.QueryParameter) ([]models.ReplicationPolicy, error) + GetPolicies(models.QueryParameter) (*models.ReplicationPolicyQueryResult, error) GetPolicy(int64) (models.ReplicationPolicy, error) CreatePolicy(models.ReplicationPolicy) (int64, error) UpdatePolicy(models.ReplicationPolicy) error @@ -42,27 +42,28 @@ func NewDefaultManager() *DefaultManager { } //GetPolicies returns all the policies -func (m *DefaultManager) GetPolicies(query models.QueryParameter) ([]models.ReplicationPolicy, error) { - result := []models.ReplicationPolicy{} - //TODO support more query conditions other than name and project ID - policies, err := dao.FilterRepPolicies(query.Name, query.ProjectID) +func (m *DefaultManager) GetPolicies(query models.QueryParameter) (*models.ReplicationPolicyQueryResult, error) { + result := &models.ReplicationPolicyQueryResult{ + Policies: []*models.ReplicationPolicy{}, + } + total, err := dao.GetTotalOfRepPolicies(query.Name, query.ProjectID) if err != nil { - return result, err + return nil, err + } + result.Total = total + + policies, err := dao.FilterRepPolicies(query.Name, query.ProjectID, query.Page, query.PageSize) + if err != nil { + return nil, err } for _, policy := range policies { ply, err := convertFromPersistModel(policy) if err != nil { - return []models.ReplicationPolicy{}, err + return nil, err } - if len(query.TriggerType) > 0 { - if ply.Trigger.Kind != query.TriggerType { - continue - } - } - - result = append(result, ply) + result.Policies = append(result.Policies, &ply) } return result, nil diff --git a/src/ui/api/replication_policy.go b/src/ui/api/replication_policy.go index 6a843fe6a..a182e1d2e 100644 --- a/src/ui/api/replication_policy.go +++ b/src/ui/api/replication_policy.go @@ -89,28 +89,34 @@ func (pa *RepPolicyAPI) List() { } queryParam.ProjectID = projectID } + queryParam.Page, queryParam.PageSize = pa.GetPaginationParams() - result := []*api_models.ReplicationPolicy{} - - policies, err := core.GlobalController.GetPolicies(queryParam) + result, err := core.GlobalController.GetPolicies(queryParam) if err != nil { log.Errorf("failed to get policies: %v, query parameters: %v", err, queryParam) pa.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) } - for _, policy := range policies { - if !pa.SecurityCtx.HasAllPerm(policy.ProjectIDs[0]) { - continue + var total int64 + policies := []*api_models.ReplicationPolicy{} + if result != nil { + total = result.Total + for _, policy := range result.Policies { + if !pa.SecurityCtx.HasAllPerm(policy.ProjectIDs[0]) { + continue + } + ply, err := convertFromRepPolicy(pa.ProjectMgr, *policy) + if err != nil { + pa.ParseAndHandleError(fmt.Sprintf("failed to convert from replication policy"), err) + return + } + policies = append(policies, ply) } - ply, err := convertFromRepPolicy(pa.ProjectMgr, policy) - if err != nil { - pa.ParseAndHandleError(fmt.Sprintf("failed to convert from replication policy"), err) - return - } - result = append(result, ply) } - pa.Data["json"] = result + pa.SetPaginationHeader(total, queryParam.Page, queryParam.PageSize) + + pa.Data["json"] = policies pa.ServeJSON() } From ea6fcd2aa16b0dd2c509b398dd576c6af551dc42 Mon Sep 17 00:00:00 2001 From: "Deng, Qian" Date: Thu, 18 Jan 2018 16:20:41 +0800 Subject: [PATCH 3/4] Fix UAA edit password bug Fix UAA edit password bug Fix password edit bug Remove unused code Fix some tslint issue --- src/ui_ng/lib/package.json | 2 +- src/ui_ng/lib/pkg/package.json | 2 +- src/ui_ng/lib/src/config/config.ts | 8 + src/ui_ng/lib/tslint.json | 12 +- src/ui_ng/package.json | 2 +- .../account-settings-modal.component.html | 2 +- .../account-settings-modal.component.ts | 9 +- .../config/auth/config-auth.component.html | 2 +- .../app/config/auth/config-auth.component.ts | 21 +- .../src/app/config/config.component.1.html | 62 ------ src/ui_ng/src/app/config/config.component.ts | 204 +++++++++--------- .../inline-alert/inline-alert.component.ts | 4 +- src/ui_ng/tslint.json | 12 +- 13 files changed, 143 insertions(+), 199 deletions(-) delete mode 100644 src/ui_ng/src/app/config/config.component.1.html diff --git a/src/ui_ng/lib/package.json b/src/ui_ng/lib/package.json index c54f1e16f..8ac07e5ba 100644 --- a/src/ui_ng/lib/package.json +++ b/src/ui_ng/lib/package.json @@ -1,6 +1,6 @@ { "name": "harbor-ui", - "version": "0.6.22", + "version": "0.6.24", "description": "Harbor shared UI components based on Clarity and Angular4", "scripts": { "start": "ng serve --host 0.0.0.0 --port 4500 --proxy-config proxy.config.json", diff --git a/src/ui_ng/lib/pkg/package.json b/src/ui_ng/lib/pkg/package.json index 129332a39..15eeef28a 100644 --- a/src/ui_ng/lib/pkg/package.json +++ b/src/ui_ng/lib/pkg/package.json @@ -1,6 +1,6 @@ { "name": "harbor-ui", - "version": "0.6.22", + "version": "0.6.24", "description": "Harbor shared UI components based on Clarity and Angular4", "author": "VMware", "module": "index.js", diff --git a/src/ui_ng/lib/src/config/config.ts b/src/ui_ng/lib/src/config/config.ts index decc1fd95..f3b80b8d7 100644 --- a/src/ui_ng/lib/src/config/config.ts +++ b/src/ui_ng/lib/src/config/config.ts @@ -65,6 +65,10 @@ export class Configuration { ldap_uid: StringValueItem; ldap_url: StringValueItem; ldap_verify_cert: BoolValueItem; + uaa_client_id: StringValueItem; + uaa_client_secret?: StringValueItem; + uaa_endpoint: StringValueItem; + uaa_verify_cert: BoolValueItem; email_host: StringValueItem; email_identity: StringValueItem; email_from: StringValueItem; @@ -91,6 +95,10 @@ export class Configuration { this.ldap_uid = new StringValueItem("", true); this.ldap_url = new StringValueItem("", true); this.ldap_verify_cert = new BoolValueItem(true, true); + this.uaa_client_id = new StringValueItem("", true); + this.uaa_client_secret = new StringValueItem("", true); + this.uaa_endpoint = new StringValueItem("", true); + this.uaa_verify_cert = new BoolValueItem(false, true); this.email_host = new StringValueItem("", true); this.email_identity = new StringValueItem("", true); this.email_from = new StringValueItem("", true); diff --git a/src/ui_ng/lib/tslint.json b/src/ui_ng/lib/tslint.json index eb187d020..283c238ec 100644 --- a/src/ui_ng/lib/tslint.json +++ b/src/ui_ng/lib/tslint.json @@ -9,18 +9,15 @@ "check-space" ], "curly": true, - "eofline": true, - "forin": true, + "eofline": false, + "forin": false, "indent": [ true, "spaces" ], "label-position": true, "label-undefined": true, - "max-line-length": [ - false, - 140 - ], + "max-line-length": false, "member-access": false, "member-ordering": [ true, @@ -74,7 +71,8 @@ ], "quotemark": [ true, - "single" + "double", + "avoid-escape" ], "radix": true, "semicolon": [ diff --git a/src/ui_ng/package.json b/src/ui_ng/package.json index d4255e7ca..809a8b4b3 100644 --- a/src/ui_ng/package.json +++ b/src/ui_ng/package.json @@ -31,7 +31,7 @@ "clarity-icons": "^0.10.17", "clarity-ui": "^0.10.17", "core-js": "^2.4.1", - "harbor-ui": "0.6.23", + "harbor-ui": "0.6.24", "intl": "^1.2.5", "mutationobserver-shim": "^0.3.2", "ngx-cookie": "^1.0.0", diff --git a/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.html b/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.html index f46d45058..36d754823 100644 --- a/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.html +++ b/src/ui_ng/src/app/account/account-settings/account-settings-modal.component.html @@ -1,6 +1,6 @@ - +