Skip to content

Commit e8e1e62

Browse files
authored
Merge pull request #190 from cvegagimenez/feat/add-immutable-rules
Add immutable rules to projects
2 parents 4ef80a2 + d03c8fa commit e8e1e62

File tree

4 files changed

+581
-0
lines changed

4 files changed

+581
-0
lines changed
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
package immutable
2+
3+
import (
4+
"context"
5+
immutableapi "github.com/mittwald/goharbor-client/v5/apiv2/internal/api/client/immutable"
6+
"github.com/mittwald/goharbor-client/v5/apiv2/pkg/config"
7+
8+
v2client "github.com/mittwald/goharbor-client/v5/apiv2/internal/api/client"
9+
"github.com/mittwald/goharbor-client/v5/apiv2/model"
10+
11+
"github.com/go-openapi/runtime"
12+
)
13+
14+
type RESTClient struct {
15+
// Options contains optional configuration when making API calls.
16+
Options *config.Options
17+
18+
// The new client of the harbor v2 API
19+
V2Client *v2client.Harbor
20+
21+
// AuthInfo contains the auth information that is provided on API calls.
22+
AuthInfo runtime.ClientAuthInfoWriter
23+
}
24+
25+
func NewClient(v2Client *v2client.Harbor, opts *config.Options, authInfo runtime.ClientAuthInfoWriter) *RESTClient {
26+
return &RESTClient{
27+
Options: opts,
28+
V2Client: v2Client,
29+
AuthInfo: authInfo,
30+
}
31+
}
32+
33+
type Client interface {
34+
CreateImmuRule(ctx context.Context, projectNameOrID string, immutableRule *model.ImmutableRule) error
35+
UpdateImmuRule(ctx context.Context, projectNameOrID string, immutableRule *model.ImmutableRule) error
36+
DeleteImmuRule(ctx context.Context, projectNameOrID string, immutableRuleID int64) error
37+
ListImmuRules(ctx context.Context, projectNameOrID string) ([]*model.ImmutableRule, error)
38+
}
39+
40+
func (c *RESTClient) CreateImmuRule(ctx context.Context, projectNameOrID string, immutableRule *model.ImmutableRule) error {
41+
params := &immutableapi.CreateImmuRuleParams{
42+
ProjectNameOrID: projectNameOrID,
43+
ImmutableRule: immutableRule,
44+
Context: ctx,
45+
}
46+
47+
params.WithTimeout(c.Options.Timeout)
48+
49+
_, err := c.V2Client.Immutable.CreateImmuRule(params, c.AuthInfo)
50+
if err != nil {
51+
return handleSwaggerImmutableRuleErrors(err)
52+
}
53+
54+
return nil
55+
}
56+
57+
func (c *RESTClient) UpdateImmuRule(ctx context.Context, projectNameOrID string, immutableRule *model.ImmutableRule, immutableRuleID int64) error {
58+
params := &immutableapi.UpdateImmuRuleParams{
59+
ProjectNameOrID: projectNameOrID,
60+
ImmutableRule: immutableRule,
61+
ImmutableRuleID: immutableRuleID,
62+
Context: ctx,
63+
}
64+
65+
params.WithTimeout(c.Options.Timeout)
66+
67+
params.ImmutableRule.ID = immutableRuleID
68+
69+
_, err := c.V2Client.Immutable.UpdateImmuRule(params, c.AuthInfo)
70+
if err != nil {
71+
return handleSwaggerImmutableRuleErrors(err)
72+
}
73+
74+
return nil
75+
}
76+
77+
func (c *RESTClient) DeleteImmuRule(ctx context.Context, projectNameOrID string, immutableRuleID int64) error {
78+
params := &immutableapi.DeleteImmuRuleParams{
79+
ProjectNameOrID: projectNameOrID,
80+
ImmutableRuleID: immutableRuleID,
81+
Context: ctx,
82+
}
83+
84+
params.WithTimeout(c.Options.Timeout)
85+
86+
_, err := c.V2Client.Immutable.DeleteImmuRule(params, c.AuthInfo)
87+
if err != nil {
88+
return handleSwaggerImmutableRuleErrors(err)
89+
}
90+
91+
return nil
92+
}
93+
94+
func (c *RESTClient) ListImmuRules(ctx context.Context, projectNameOrID string) ([]*model.ImmutableRule, error) {
95+
var immutableRules []*model.ImmutableRule
96+
page := c.Options.Page
97+
98+
params := &immutableapi.ListImmuRulesParams{
99+
Page: &page,
100+
PageSize: &c.Options.PageSize,
101+
ProjectNameOrID: projectNameOrID,
102+
Q: &c.Options.Query,
103+
Sort: &c.Options.Sort,
104+
Context: ctx,
105+
}
106+
107+
params.WithTimeout(c.Options.Timeout)
108+
109+
for {
110+
resp, err := c.V2Client.Immutable.ListImmuRules(params, c.AuthInfo)
111+
if err != nil {
112+
return nil, handleSwaggerImmutableRuleErrors(err)
113+
}
114+
115+
if len(resp.Payload) == 0 {
116+
break
117+
}
118+
119+
totalCount := resp.XTotalCount
120+
121+
immutableRules = append(immutableRules, resp.Payload...)
122+
123+
if int64(len(immutableRules)) >= totalCount {
124+
break
125+
}
126+
127+
page++
128+
}
129+
130+
return immutableRules, nil
131+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package immutable
2+
3+
import (
4+
"net/http"
5+
6+
"github.com/go-openapi/runtime"
7+
"github.com/mittwald/goharbor-client/v5/apiv2/internal/api/client/immutable"
8+
"github.com/mittwald/goharbor-client/v5/apiv2/pkg/errors"
9+
)
10+
11+
func handleSwaggerImmutableRuleErrors(in error) error {
12+
t, ok := in.(*runtime.APIError)
13+
if ok {
14+
switch t.Code {
15+
case http.StatusOK:
16+
return nil
17+
case http.StatusCreated:
18+
return nil
19+
case http.StatusBadRequest:
20+
return &errors.ErrBadRequest{}
21+
case http.StatusUnauthorized:
22+
return &errors.ErrUnauthorized{}
23+
case http.StatusForbidden:
24+
return &errors.ErrForbidden{}
25+
case http.StatusNotFound:
26+
return &errors.ErrNotFound{}
27+
case http.StatusInternalServerError:
28+
return &errors.ErrInternalErrors{}
29+
}
30+
}
31+
32+
switch in.(type) {
33+
case *immutable.UpdateImmuRuleBadRequest:
34+
return &errors.ErrBadRequest{}
35+
case *immutable.CreateImmuRuleBadRequest:
36+
return &errors.ErrBadRequest{}
37+
case *immutable.DeleteImmuRuleBadRequest:
38+
return &errors.ErrBadRequest{}
39+
default:
40+
return in
41+
}
42+
}
Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
//go:build integration
2+
3+
package immutable
4+
5+
import (
6+
"context"
7+
"testing"
8+
"github.com/mittwald/goharbor-client/v5/apiv2/model"
9+
"github.com/mittwald/goharbor-client/v5/apiv2/pkg/clients/project"
10+
clienttesting "github.com/mittwald/goharbor-client/v5/apiv2/pkg/testing"
11+
"github.com/stretchr/testify/require"
12+
)
13+
14+
var projectName = "test-project"
15+
16+
func TestAPIImmutableListImmutableRules(t *testing.T) {
17+
ctx := context.Background()
18+
19+
c := NewClient(clienttesting.V2SwaggerClient, clienttesting.DefaultOpts, clienttesting.AuthInfo)
20+
pc := project.NewClient(clienttesting.V2SwaggerClient, clienttesting.DefaultOpts, clienttesting.AuthInfo)
21+
22+
err := pc.NewProject(ctx, &model.ProjectReq{
23+
ProjectName: projectName,
24+
})
25+
require.NoError(t, err)
26+
27+
defer pc.DeleteProject(ctx, projectName)
28+
29+
immutableRule := model.ImmutableRule{
30+
ScopeSelectors: map[string][]model.ImmutableSelector{},
31+
TagSelectors: []*model.ImmutableSelector{{
32+
Decoration: "matches",
33+
Kind: "doublestar",
34+
Pattern: "**",
35+
}},
36+
}
37+
38+
err = c.CreateImmuRule(ctx, projectName, &immutableRule)
39+
require.NoError(t, err)
40+
41+
listedImmutableRules, err := c.ListImmuRules(ctx, projectName)
42+
43+
require.NoError(t, err)
44+
45+
listedImmutableRuleTag := listedImmutableRules[0].TagSelectors
46+
47+
require.Equal(t, listedImmutableRuleTag[0], immutableRule.TagSelectors[0])
48+
49+
immuRuleID := listedImmutableRules[0].ID
50+
51+
c.DeleteImmuRule(ctx, projectName, immuRuleID)
52+
53+
checkDeletedImmuRules, err := c.ListImmuRules(ctx, projectName)
54+
55+
require.Empty(t, checkDeletedImmuRules)
56+
}
57+
58+
func TestAPIImmutableUpdateImmutableRules(t *testing.T) {
59+
ctx := context.Background()
60+
61+
c := NewClient(clienttesting.V2SwaggerClient, clienttesting.DefaultOpts, clienttesting.AuthInfo)
62+
pc := project.NewClient(clienttesting.V2SwaggerClient, clienttesting.DefaultOpts, clienttesting.AuthInfo)
63+
64+
err := pc.NewProject(ctx, &model.ProjectReq{
65+
ProjectName: projectName,
66+
})
67+
require.NoError(t, err)
68+
69+
defer pc.DeleteProject(ctx, projectName)
70+
71+
createImmutableRule := model.ImmutableRule{
72+
ScopeSelectors: map[string][]model.ImmutableSelector{},
73+
TagSelectors: []*model.ImmutableSelector{{
74+
Decoration: "matches",
75+
Kind: "doublestar",
76+
Pattern: "1.0.0",
77+
}},
78+
}
79+
80+
updateImmutableRule := model.ImmutableRule{
81+
ScopeSelectors: map[string][]model.ImmutableSelector{},
82+
TagSelectors: []*model.ImmutableSelector{{
83+
Decoration: "matches",
84+
Kind: "doublestar",
85+
Pattern: "2.0.0",
86+
}},
87+
}
88+
89+
err = c.CreateImmuRule(ctx, projectName, &createImmutableRule)
90+
require.NoError(t, err)
91+
92+
listedImmutableRules, err := c.ListImmuRules(ctx, projectName)
93+
94+
require.NoError(t, err)
95+
96+
immuRuleID := listedImmutableRules[0].ID
97+
98+
err = c.UpdateImmuRule(ctx, projectName, &updateImmutableRule, immuRuleID)
99+
100+
require.NoError(t, err)
101+
102+
listedImmutableRules, err = c.ListImmuRules(ctx, projectName)
103+
104+
require.NoError(t, err)
105+
106+
listedImmutableRuleTag := listedImmutableRules[0].TagSelectors
107+
108+
require.Equal(t, listedImmutableRuleTag[0], updateImmutableRule.TagSelectors[0])
109+
110+
111+
c.DeleteImmuRule(ctx, projectName, immuRuleID)
112+
113+
checkDeletedImmuRules, err := c.ListImmuRules(ctx, projectName)
114+
115+
require.Empty(t, checkDeletedImmuRules)
116+
}

0 commit comments

Comments
 (0)