added HTTP API to list policies

This commit is contained in:
Jarek Kowalski
2018-06-16 08:46:56 -07:00
parent a6f2e8c3f3
commit 70ecebb769
5 changed files with 94 additions and 7 deletions

View File

@@ -0,0 +1,42 @@
package server
import (
"net/http"
"github.com/kopia/kopia/snapshot"
)
type policyListEntry struct {
ID string `json:"id"`
Source snapshot.SourceInfo `json:"source"`
Policy *snapshot.Policy `json:"policy"`
}
type policyListResponse struct {
Policies []*policyListEntry `json:"policies"`
}
func (s *Server) handlePolicyList(r *http.Request) (interface{}, *apiError) {
policies, err := s.policyManager.ListPolicies()
if err != nil {
return nil, internalServerError(err)
}
resp := &policyListResponse{
Policies: []*policyListEntry{},
}
for _, pol := range policies {
src := pol.Source()
if !sourceMatchesURLFilter(src, r.URL.Query()) {
continue
}
resp.Policies = append(resp.Policies, &policyListEntry{
ID: pol.ID(),
Source: src,
Policy: pol,
})
}
return resp, nil
}

View File

@@ -2,6 +2,8 @@
import (
"net/http"
"net/url"
"strings"
"time"
"github.com/kopia/kopia/fs"
@@ -31,15 +33,21 @@ func (s *Server) handleSourceSnapshotList(r *http.Request) (interface{}, *apiErr
return nil, internalServerError(err)
}
resp := &snapshotListResponse{}
resp := &snapshotListResponse{
Snapshots: []*snapshotListEntry{},
}
groups := snapshot.GroupBySource(manifests)
for _, grp := range groups {
pol, err := s.policyManager.GetEffectivePolicy(grp[0].Source)
first := grp[0]
if !sourceMatchesURLFilter(first.Source, r.URL.Query()) {
continue
}
pol, err := s.policyManager.GetEffectivePolicy(first.Source)
if err == nil {
pol.RetentionPolicy.ComputeRetentionReasons(grp)
}
for _, m := range grp {
resp.Snapshots = append(resp.Snapshots, convertSnapshotManifest(m))
}
@@ -48,8 +56,22 @@ func (s *Server) handleSourceSnapshotList(r *http.Request) (interface{}, *apiErr
return resp, nil
}
func sourceMatchesURLFilter(src snapshot.SourceInfo, query url.Values) bool {
if v := query.Get("host"); v != "" && src.Host != v {
return false
}
if v := query.Get("userName"); v != "" && src.UserName != v {
return false
}
if v := query.Get("path"); v != "" && !strings.Contains(src.Path, v) {
return false
}
return true
}
func convertSnapshotManifest(m *snapshot.Manifest) *snapshotListEntry {
return &snapshotListEntry{
e := &snapshotListEntry{
ID: m.ID,
Source: m.Source,
Description: m.Description,
@@ -57,7 +79,12 @@ func convertSnapshotManifest(m *snapshot.Manifest) *snapshotListEntry {
EndTime: m.EndTime,
IncompleteReason: m.IncompleteReason,
RootEntry: m.RootObjectID().String(),
Summary: m.RootEntry.DirSummary,
RetentionReasons: m.RetentionReasons,
}
if re := m.RootEntry; re != nil {
e.Summary = re.DirSummary
}
return e
}

View File

@@ -10,9 +10,14 @@ type sourcesListResponse struct {
}
func (s *Server) handleSourcesList(r *http.Request) (interface{}, *apiError) {
resp := &sourcesListResponse{}
resp := &sourcesListResponse{
Sources: []sourceStatus{},
}
for _, v := range s.sourceManagers {
if !sourceMatchesURLFilter(v.src, r.URL.Query()) {
continue
}
resp.Sources = append(resp.Sources, v.Status())
}

View File

@@ -31,6 +31,7 @@ func (s *Server) APIHandlers() http.Handler {
p.Get("/api/v1/status", s.handleAPI(s.handleStatus))
p.Get("/api/v1/sources", s.handleAPI(s.handleSourcesList))
p.Get("/api/v1/snapshots", s.handleAPI(s.handleSourceSnapshotList))
p.Get("/api/v1/policies", s.handleAPI(s.handlePolicyList))
return p
}

View File

@@ -31,6 +31,18 @@ func (p *Policy) String() string {
return buf.String()
}
func (p *Policy) ID() string {
return p.Labels["id"]
}
func (p *Policy) Source() SourceInfo {
return SourceInfo{
Host: p.Labels["hostname"],
UserName: p.Labels["username"],
Path: p.Labels["path"],
}
}
// MergePolicies computes the policy by applying the specified list of policies in order.
func MergePolicies(policies []*Policy) *Policy {
var merged Policy