mirror of
https://github.com/goharbor/harbor.git
synced 2024-11-22 18:25:56 +01:00
return unified error format by the chart repo API update the prov file status at anytime
This commit is contained in:
parent
c5a79fb55b
commit
ce52f54e29
@ -83,24 +83,26 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
|
||||
return
|
||||
}
|
||||
|
||||
//Get and check namespace
|
||||
//even we get the data from cache
|
||||
var namespace string
|
||||
|
||||
repoValue := req.Context().Value(NamespaceContextKey)
|
||||
if repoValue != nil {
|
||||
if ns, ok := repoValue.(string); ok {
|
||||
namespace = ns
|
||||
}
|
||||
}
|
||||
|
||||
if len(strings.TrimSpace(namespace)) == 0 {
|
||||
WriteInternalError(w, errors.New("failed to extract namespace from the request"))
|
||||
return
|
||||
}
|
||||
|
||||
//Query cache
|
||||
chartDetails := mh.chartCache.GetChart(chartV.Digest)
|
||||
if chartDetails == nil {
|
||||
//NOT hit!!
|
||||
var namespace string
|
||||
|
||||
repoValue := req.Context().Value(NamespaceContextKey)
|
||||
if repoValue != nil {
|
||||
if ns, ok := repoValue.(string); ok {
|
||||
namespace = ns
|
||||
}
|
||||
}
|
||||
|
||||
if len(strings.TrimSpace(namespace)) == 0 {
|
||||
WriteInternalError(w, errors.New("failed to extract namespace from the request"))
|
||||
return
|
||||
}
|
||||
|
||||
content, err := mh.getChartVersionContent(namespace, chartV.URLs[0])
|
||||
if err != nil {
|
||||
WriteInternalError(w, err)
|
||||
@ -115,26 +117,6 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
|
||||
}
|
||||
chartDetails.Metadata = chartV
|
||||
|
||||
//Generate the security report
|
||||
//prov file share same endpoint with the chart version
|
||||
//Just add .prov suffix to the chart version to form the path of prov file
|
||||
//Anyway, there will be a report about the digital signature status
|
||||
chartDetails.Security = &SecurityReport{
|
||||
Signature: &DigitalSignature{
|
||||
Signed: false,
|
||||
},
|
||||
}
|
||||
//Try to get the prov file to confirm if it is exitsing
|
||||
provFilePath := fmt.Sprintf("%s.prov", chartV.URLs[0])
|
||||
provBytes, err := mh.getChartVersionContent(namespace, provFilePath)
|
||||
if err == nil && len(provBytes) > 0 {
|
||||
chartDetails.Security.Signature.Signed = true
|
||||
chartDetails.Security.Signature.Provenance = provFilePath
|
||||
} else {
|
||||
//Just log it
|
||||
hlog.Errorf("Failed to get prov file for chart %s with error: %s, got %d bytes", chartV.Name, err.Error(), len(provBytes))
|
||||
}
|
||||
|
||||
//Put it into the cache for next access
|
||||
mh.chartCache.PutChart(chartDetails)
|
||||
} else {
|
||||
@ -144,6 +126,28 @@ func (mh *ManipulationHandler) GetChartVersion(w http.ResponseWriter, req *http.
|
||||
chartDetails.Metadata.Version,
|
||||
chartDetails.Metadata.Digest)
|
||||
}
|
||||
//The change of prov file will not cause any influence to the digest of chart,
|
||||
//and then the digital signature status should be not cached
|
||||
//
|
||||
//Generate the security report
|
||||
//prov file share same endpoint with the chart version
|
||||
//Just add .prov suffix to the chart version to form the path of prov file
|
||||
//Anyway, there will be a report about the digital signature status
|
||||
chartDetails.Security = &SecurityReport{
|
||||
Signature: &DigitalSignature{
|
||||
Signed: false,
|
||||
},
|
||||
}
|
||||
//Try to get the prov file to confirm if it is exitsing
|
||||
provFilePath := fmt.Sprintf("%s.prov", chartV.URLs[0])
|
||||
provBytes, err := mh.getChartVersionContent(namespace, provFilePath)
|
||||
if err == nil && len(provBytes) > 0 {
|
||||
chartDetails.Security.Signature.Signed = true
|
||||
chartDetails.Security.Signature.Provenance = provFilePath
|
||||
} else {
|
||||
//Just log it
|
||||
hlog.Errorf("Failed to get prov file for chart %s with error: %s, got %d bytes", chartV.Name, err.Error(), len(provBytes))
|
||||
}
|
||||
|
||||
bytes, err := json.Marshal(chartDetails)
|
||||
if err != nil {
|
||||
|
@ -263,13 +263,13 @@ func (cra *ChartRepositoryAPI) requireNamespace(namespace string) bool {
|
||||
existsing, err := cra.ProjectMgr.Exists(namespace)
|
||||
if err != nil {
|
||||
//Check failed with error
|
||||
cra.RenderError(http.StatusInternalServerError, fmt.Sprintf("failed to check existence of namespace %s with error: %s", namespace, err.Error()))
|
||||
cra.renderError(http.StatusInternalServerError, fmt.Sprintf("failed to check existence of namespace %s with error: %s", namespace, err.Error()))
|
||||
return false
|
||||
}
|
||||
|
||||
//Not existing
|
||||
if !existsing {
|
||||
cra.HandleBadRequest(fmt.Sprintf("namespace %s is not existing", namespace))
|
||||
cra.renderError(http.StatusBadRequest, fmt.Sprintf("namespace %s is not existing", namespace))
|
||||
return false
|
||||
}
|
||||
|
||||
@ -312,7 +312,7 @@ func (cra *ChartRepositoryAPI) requireAccess(namespace string, accessLevel uint)
|
||||
}
|
||||
default:
|
||||
//access rejected for invalid scope
|
||||
cra.RenderError(http.StatusForbidden, "unrecognized access scope")
|
||||
cra.renderError(http.StatusForbidden, "unrecognized access scope")
|
||||
return false
|
||||
}
|
||||
|
||||
@ -320,40 +320,21 @@ func (cra *ChartRepositoryAPI) requireAccess(namespace string, accessLevel uint)
|
||||
if err != nil {
|
||||
//Unauthenticated, return 401
|
||||
if !cra.SecurityCtx.IsAuthenticated() {
|
||||
cra.HandleUnauthorized()
|
||||
cra.renderError(http.StatusUnauthorized, "Unauthorized")
|
||||
return false
|
||||
}
|
||||
|
||||
//Authenticated, return 403
|
||||
cra.RenderError(http.StatusForbidden, err.Error())
|
||||
cra.renderError(http.StatusForbidden, err.Error())
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
//Initialize the chart service controller
|
||||
func initializeChartController() (*chartserver.Controller, error) {
|
||||
addr, err := config.GetChartMuseumEndpoint()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to get the endpoint URL of chart storage server: %s", err.Error())
|
||||
}
|
||||
|
||||
addr = strings.TrimSuffix(addr, "/")
|
||||
url, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
return nil, errors.New("Endpoint URL of chart storage server is malformed")
|
||||
}
|
||||
|
||||
controller, err := chartserver.NewController(url)
|
||||
if err != nil {
|
||||
return nil, errors.New("Failed to initialize chart API controller")
|
||||
}
|
||||
|
||||
hlog.Debugf("Chart storage server is set to %s", url.String())
|
||||
hlog.Info("API controller for chart repository server is successfully initialized")
|
||||
|
||||
return controller, nil
|
||||
//write error message with unified format
|
||||
func (cra *ChartRepositoryAPI) renderError(code int, text string) {
|
||||
chartserver.WriteError(cra.Ctx.ResponseWriter, code, errors.New(text))
|
||||
}
|
||||
|
||||
//formFile is used to represent the uploaded files in the form
|
||||
@ -417,6 +398,30 @@ func (cra *ChartRepositoryAPI) rewriteFileContent(files []formFile, request *htt
|
||||
return nil
|
||||
}
|
||||
|
||||
//Initialize the chart service controller
|
||||
func initializeChartController() (*chartserver.Controller, error) {
|
||||
addr, err := config.GetChartMuseumEndpoint()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to get the endpoint URL of chart storage server: %s", err.Error())
|
||||
}
|
||||
|
||||
addr = strings.TrimSuffix(addr, "/")
|
||||
url, err := url.Parse(addr)
|
||||
if err != nil {
|
||||
return nil, errors.New("Endpoint URL of chart storage server is malformed")
|
||||
}
|
||||
|
||||
controller, err := chartserver.NewController(url)
|
||||
if err != nil {
|
||||
return nil, errors.New("Failed to initialize chart API controller")
|
||||
}
|
||||
|
||||
hlog.Debugf("Chart storage server is set to %s", url.String())
|
||||
hlog.Info("API controller for chart repository server is successfully initialized")
|
||||
|
||||
return controller, nil
|
||||
}
|
||||
|
||||
//Check if the request content type is "multipart/form-data"
|
||||
func isMultipartFormData(req *http.Request) bool {
|
||||
return strings.Contains(req.Header.Get(headerContentType), contentTypeMultipart)
|
||||
|
Loading…
Reference in New Issue
Block a user