From a9fa22269c7e6cc8b2ee356af5c7440128fa3930 Mon Sep 17 00:00:00 2001 From: cd1989 Date: Wed, 10 Apr 2019 09:38:14 +0800 Subject: [PATCH] Check health status when add/update registry Signed-off-by: cd1989 --- src/core/api/registry.go | 80 ++++++++++++++++++++++------------- src/core/api/registry_test.go | 43 +++++++++---------- 2 files changed, 70 insertions(+), 53 deletions(-) diff --git a/src/core/api/registry.go b/src/core/api/registry.go index fbeafdf78..a5576bcd3 100644 --- a/src/core/api/registry.go +++ b/src/core/api/registry.go @@ -129,24 +129,24 @@ func (t *RegistryAPI) Ping() { func (t *RegistryAPI) Get() { id := t.GetIDFromURL() - registry, err := t.manager.Get(id) + r, err := t.manager.Get(id) if err != nil { log.Errorf("failed to get registry %d: %v", id, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return } - if registry == nil { + if r == nil { t.HandleNotFound(fmt.Sprintf("registry %d not found", id)) return } // Hide access secret - if registry.Credential != nil && len(registry.Credential.AccessSecret) != 0 { - registry.Credential.AccessSecret = "*****" + if r.Credential != nil && len(r.Credential.AccessSecret) != 0 { + r.Credential.AccessSecret = "*****" } - t.Data["json"] = registry + t.Data["json"] = r t.ServeJSON() } @@ -164,9 +164,9 @@ func (t *RegistryAPI) List() { } // Hide passwords - for _, registry := range registries { - if registry.Credential != nil && len(registry.Credential.AccessSecret) != 0 { - registry.Credential.AccessSecret = "*****" + for _, r := range registries { + if r.Credential != nil && len(r.Credential.AccessSecret) != 0 { + r.Credential.AccessSecret = "*****" } } @@ -177,24 +177,34 @@ func (t *RegistryAPI) List() { // Post creates a registry func (t *RegistryAPI) Post() { - registry := &model.Registry{} - t.DecodeJSONReqAndValidate(registry) + r := &model.Registry{} + t.DecodeJSONReqAndValidate(r) - reg, err := t.manager.GetByName(registry.Name) + reg, err := t.manager.GetByName(r.Name) if err != nil { - log.Errorf("failed to get registry %s: %v", registry.Name, err) + log.Errorf("failed to get registry %s: %v", r.Name, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return } if reg != nil { - t.HandleConflict(fmt.Sprintf("name '%s' is already used", registry.Name)) + t.HandleConflict(fmt.Sprintf("name '%s' is already used", r.Name)) return } - id, err := t.manager.Add(registry) + status, err := registry.CheckHealthStatus(r) if err != nil { - log.Errorf("Add registry '%s' error: %v", registry.URL, err) + t.HandleBadRequest(fmt.Sprintf("health check to registry %s failed: %v", r.URL, err)) + return + } + if status != model.Healthy { + t.HandleBadRequest(fmt.Sprintf("registry %s is unhealthy: %s", r.URL, status)) + return + } + + id, err := t.manager.Add(r) + if err != nil { + log.Errorf("Add registry '%s' error: %v", r.URL, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return } @@ -206,14 +216,14 @@ func (t *RegistryAPI) Post() { func (t *RegistryAPI) Put() { id := t.GetIDFromURL() - registry, err := t.manager.Get(id) + r, err := t.manager.Get(id) if err != nil { log.Errorf("Get registry by id %d error: %v", id, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return } - if registry == nil { + if r == nil { t.HandleNotFound(fmt.Sprintf("Registry %d not found", id)) return } @@ -221,36 +231,36 @@ func (t *RegistryAPI) Put() { req := models.RegistryUpdateRequest{} t.DecodeJSONReq(&req) - originalName := registry.Name + originalName := r.Name if req.Name != nil { - registry.Name = *req.Name + r.Name = *req.Name } if req.Description != nil { - registry.Description = *req.Description + r.Description = *req.Description } if req.URL != nil { - registry.URL = *req.URL + r.URL = *req.URL } if req.CredentialType != nil { - registry.Credential.Type = (model.CredentialType)(*req.CredentialType) + r.Credential.Type = (model.CredentialType)(*req.CredentialType) } if req.AccessKey != nil { - registry.Credential.AccessKey = *req.AccessKey + r.Credential.AccessKey = *req.AccessKey } if req.AccessSecret != nil { - registry.Credential.AccessSecret = *req.AccessSecret + r.Credential.AccessSecret = *req.AccessSecret } if req.Insecure != nil { - registry.Insecure = *req.Insecure + r.Insecure = *req.Insecure } - t.Validate(registry) + t.Validate(r) - if registry.Name != originalName { - reg, err := t.manager.GetByName(registry.Name) + if r.Name != originalName { + reg, err := t.manager.GetByName(r.Name) if err != nil { - log.Errorf("Get registry by name '%s' error: %v", registry.Name, err) + log.Errorf("Get registry by name '%s' error: %v", r.Name, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return } @@ -261,7 +271,17 @@ func (t *RegistryAPI) Put() { } } - if err := t.manager.Update(registry); err != nil { + status, err := registry.CheckHealthStatus(r) + if err != nil { + t.HandleBadRequest(fmt.Sprintf("health check to registry %s failed: %v", r.URL, err)) + return + } + if status != model.Healthy { + t.HandleBadRequest(fmt.Sprintf("registry %s is unhealthy: %s", r.URL, status)) + return + } + + if err := t.manager.Update(r); err != nil { log.Errorf("Update registry %d error: %v", id, err) t.CustomAbort(http.StatusInternalServerError, http.StatusText(http.StatusInternalServerError)) return diff --git a/src/core/api/registry_test.go b/src/core/api/registry_test.go index 407d1814c..9180af838 100644 --- a/src/core/api/registry_test.go +++ b/src/core/api/registry_test.go @@ -15,24 +15,16 @@ import ( var ( testRegistry = &model.Registry{ - Name: "test1", - URL: "https://127.0.0.1", - Type: "harbor", - Credential: &model.Credential{ - Type: model.CredentialTypeBasic, - AccessKey: "admin", - AccessSecret: "Harbor12345", - }, + Name: "test1", + URL: "https://goharbor.io", + Type: "harbor", + Credential: nil, } testRegistry2 = &model.Registry{ - Name: "test2", - URL: "https://test2.harbor.io", - Type: "harbor", - Credential: &model.Credential{ - Type: model.CredentialTypeBasic, - AccessKey: "admin", - AccessSecret: "Harbor12345", - }, + Name: "test2", + URL: "https://goharbor.io", + Type: "harbor", + Credential: nil, } ) @@ -120,11 +112,16 @@ func (suite *RegistrySuite) TestPost() { func (suite *RegistrySuite) TestPing() { assert := assert.New(suite.T()) + code, err := suite.testAPI.RegistryPing(*admin, &pingReq{ + ID: &suite.defaultRegistry.ID, + }) + assert.Nil(err) + assert.Equal(http.StatusOK, code) + var id int64 = -1 - code, err := suite.testAPI.RegistryPing(*admin, - &pingReq{ - ID: &id, - }) + code, err = suite.testAPI.RegistryPing(*admin, &pingReq{ + ID: &id, + }) assert.Nil(err) assert.Equal(http.StatusNotFound, code) @@ -143,9 +140,9 @@ func (suite *RegistrySuite) TestRegistryPut() { assert := assert.New(suite.T()) // Update as admin, should succeed - newKey := "NewKey" + description := "foobar" updateReq := &models.RegistryUpdateRequest{ - AccessKey: &newKey, + Description: &description, } code, err := suite.testAPI.RegistryUpdate(*admin, suite.defaultRegistry.ID, updateReq) assert.Nil(err) @@ -153,7 +150,7 @@ func (suite *RegistrySuite) TestRegistryPut() { updated, code, err := suite.testAPI.RegistryGet(*admin, suite.defaultRegistry.ID) assert.Nil(err) assert.Equal(http.StatusOK, code) - assert.Equal("NewKey", updated.Credential.AccessKey) + assert.Equal("foobar", updated.Description) // Update as user, should fail code, err = suite.testAPI.RegistryUpdate(*testUser, suite.defaultRegistry.ID, updateReq)