Merge pull request #4342 from yixingjia/apimonitor

Add monitor API for Harbor components
This commit is contained in:
Daniel Jiang 2018-03-16 14:56:58 +08:00 committed by GitHub
commit cbedf099b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 85 additions and 9 deletions

2
.gitignore vendored
View File

@ -31,6 +31,8 @@ src/ui_ng/typings/
**/*yarn-error.log.*
.idea/
.DS_Store
.project
.vscode/
**/node_modules
**/ssl/
**/proxy.config.json

View File

@ -0,0 +1,14 @@
package api
import (
"net/http"
"github.com/vmware/harbor/src/common/utils/log"
)
// Ping monitor the server status
func Ping(w http.ResponseWriter, r *http.Request) {
if err := writeJSON(w, "Pong"); err != nil {
log.Errorf("Failed to write response: %v", err)
return
}
}

View File

@ -0,0 +1,16 @@
package api
import(
"testing"
"net/http/httptest"
"net/http"
"github.com/stretchr/testify/assert"
"io/ioutil"
)
func TestPing(t *testing.T) {
w := httptest.NewRecorder()
Ping(w, nil)
assert.Equal(t, http.StatusOK, w.Code)
result, _:= ioutil.ReadAll(w.Body)
assert.Equal(t, "\"Pong\"", string(result))
}

View File

@ -31,7 +31,10 @@ func NewHandler() http.Handler {
"uiSecret": os.Getenv("UI_SECRET"),
"jobserviceSecret": os.Getenv("JOBSERVICE_SECRET"),
}
h = newAuthHandler(auth.NewSecretAuthenticator(secrets), h)
insecureAPIs := map[string]bool{
"/api/ping":true,
}
h = newAuthHandler(auth.NewSecretAuthenticator(secrets), h, insecureAPIs)
h = gorilla_handlers.LoggingHandler(os.Stdout, h)
return h
}
@ -39,12 +42,14 @@ func NewHandler() http.Handler {
type authHandler struct {
authenticator auth.Authenticator
handler http.Handler
insecureAPIs map[string]bool
}
func newAuthHandler(authenticator auth.Authenticator, handler http.Handler) http.Handler {
func newAuthHandler(authenticator auth.Authenticator, handler http.Handler, insecureAPIs map[string]bool) http.Handler {
return &authHandler{
authenticator: authenticator,
handler: handler,
insecureAPIs: insecureAPIs,
}
}
@ -56,6 +61,12 @@ func (a *authHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
return
}
if a.insecureAPIs !=nil && a.insecureAPIs[r.URL.Path] {
if a.handler != nil {
a.handler.ServeHTTP(w, r)
}
return
}
valid, err := a.authenticator.Authenticate(r)
if err != nil {
log.Errorf("failed to authenticate request: %v", err)

View File

@ -45,28 +45,40 @@ func TestNewAuthHandler(t *testing.T) {
cases := []struct {
authenticator auth.Authenticator
handler http.Handler
insecureAPIs map[string]bool
responseCode int
requestURL string
}{
{nil, nil, http.StatusOK},
{nil, nil, nil, http.StatusOK,"http://localhost/good"},
{&fakeAuthenticator{
authenticated: false,
err: nil,
}, nil, http.StatusUnauthorized},
}, nil, nil, http.StatusUnauthorized,"http://localhost/hello"},
{&fakeAuthenticator{
authenticated: false,
err: errors.New("error"),
}, nil, http.StatusInternalServerError},
}, nil, nil, http.StatusInternalServerError,"http://localhost/hello"},
{&fakeAuthenticator{
authenticated: true,
err: nil,
}, &fakeHandler{http.StatusNotFound}, http.StatusNotFound},
}, &fakeHandler{http.StatusNotFound}, nil, http.StatusNotFound,"http://localhost/notexsit"},
{&fakeAuthenticator{
authenticated: false,
err: nil,
}, &fakeHandler{http.StatusOK},map[string]bool{"/api/ping":true,},http.StatusOK,"http://localhost/api/ping"},
}
for _, c := range cases {
handler := newAuthHandler(c.authenticator, c.handler)
handler := newAuthHandler(c.authenticator, c.handler, c.insecureAPIs)
w := httptest.NewRecorder()
handler.ServeHTTP(w, nil)
r := httptest.NewRequest("GET",c.requestURL,nil)
handler.ServeHTTP(w, r)
assert.Equal(t, c.responseCode, w.Code, "unexpected response code")
}
handler := NewHandler()
w := httptest.NewRecorder()
r := httptest.NewRequest("GET","http://localhost/api/ping",nil)
handler.ServeHTTP(w,r)
}

View File

@ -27,5 +27,6 @@ func newRouter() http.Handler {
r.HandleFunc("/api/configurations", api.UpdateCfgs).Methods("PUT")
r.HandleFunc("/api/configurations/reset", api.ResetCfgs).Methods("POST")
r.HandleFunc("/api/systeminfo/capacity", api.Capacity).Methods("GET")
r.HandleFunc("/api/ping", api.Ping).Methods("GET")
return r
}

View File

@ -138,7 +138,7 @@ func init() {
beego.Router("/api/replications", &ReplicationAPI{})
beego.Router("/api/labels", &LabelAPI{}, "post:Post;get:List")
beego.Router("/api/labels/:id([0-9]+", &LabelAPI{}, "get:Get;put:Put;delete:Delete")
beego.Router("/api/ping", &SystemInfoAPI{}, "get:Ping")
_ = updateInitPassword(1, "Harbor12345")
if err := core.Init(); err != nil {
@ -991,6 +991,11 @@ func (a testapi) GetGeneralInfo() (int, []byte, error) {
return request(_sling, jsonAcceptHeader)
}
func (a testapi) Ping() (int, []byte, error) {
_sling := sling.New().Get(a.basePath).Path("/api/ping")
return request(_sling, jsonAcceptHeader)
}
//Get system cert
func (a testapi) CertGet(authInfo usrInfo) (int, []byte, error) {
_sling := sling.New().Get(a.basePath)

View File

@ -247,3 +247,9 @@ func getClairVulnStatus() *models.ClairVulnerabilityStatus {
res.Details = details
return res
}
// Ping ping the harbor UI service.
func (sia *SystemInfoAPI) Ping() {
sia.Data["json"] = "Pong"
sia.ServeJSON()
}

View File

@ -91,3 +91,10 @@ func TestGetCert(t *testing.T) {
}
CommonDelUser()
}
func TestPing(t *testing.T) {
apiTest := newHarborAPI()
code, _, err := apiTest.Ping()
assert := assert.New(t)
assert.Nil(err, fmt.Sprintf("Unexpected Error: %v", err))
assert.Equal(200, code, fmt.Sprintf("Unexpected status code: %d", code))
}

View File

@ -60,6 +60,7 @@ func initRouters() {
}
// API
beego.Router("/api/ping", &api.SystemInfoAPI{}, "get:Ping")
beego.Router("/api/search", &api.SearchAPI{})
beego.Router("/api/projects/", &api.ProjectAPI{}, "get:List;post:Post")
beego.Router("/api/projects/:id([0-9]+)/logs", &api.ProjectAPI{}, "get:Logs")
@ -114,6 +115,7 @@ func initRouters() {
beego.Router("/service/token", &token.Handler{})
beego.Router("/registryproxy/*", &controllers.RegistryProxy{}, "*:Handle")
//Error pages
beego.ErrorController(&controllers.ErrorController{})