-
Notifications
You must be signed in to change notification settings - Fork 33
/
client_organizations.go
138 lines (115 loc) · 4.54 KB
/
client_organizations.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*
Copyright 2021 The Flux authors
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package stash
import (
"context"
"fmt"
"github.com/fluxcd/go-git-providers/gitprovider"
"github.com/fluxcd/go-git-providers/validation"
"github.com/hashicorp/go-multierror"
)
// OrganizationsClient implements the gitprovider.OrganizationsClient interface.
var _ gitprovider.OrganizationsClient = &OrganizationsClient{}
// OrganizationsClient operates on the projects the user has access to.
type OrganizationsClient struct {
*clientContext
}
// Get a specific organization the user has access to.
// ErrNotFound is returned if the resource does not exist.
func (c *OrganizationsClient) Get(ctx context.Context, ref gitprovider.OrganizationRef) (gitprovider.Organization, error) {
// Make sure the OrganizationRef is valid
if err := validateOrganizationRef(ref, c.host); err != nil {
return nil, err
}
apiObj, err := c.client.Projects.Get(ctx, ref.Organization)
if err != nil {
return nil, fmt.Errorf("failed to get organization %q: %w", ref.Organization, err)
}
// Validate the API objects
if err := validateProjectAPI(apiObj); err != nil {
return nil, err
}
ref.SetKey(apiObj.Key)
return newOrganization(c.clientContext, apiObj, ref), nil
}
// List all the organizations the specific user has access to.
// List returns all available organizations, using multiple paginated requests if needed.
func (c *OrganizationsClient) List(ctx context.Context) ([]gitprovider.Organization, error) {
// Retrieve all projects
apiObjs, err := c.client.Projects.All(ctx)
if err != nil {
return nil, fmt.Errorf("failed to list organizations: %w", err)
}
// Validate the API objects
var errs error
for _, apiObj := range apiObjs {
if err := validateProjectAPI(apiObj); err != nil {
errs = multierror.Append(errs, err)
}
}
if errs != nil {
return nil, errs
}
projects := make([]gitprovider.Organization, len(apiObjs))
for i, apiObj := range apiObjs {
ref := gitprovider.OrganizationRef{
Domain: c.host,
Organization: apiObj.Name,
}
ref.SetKey(apiObj.Key)
projects[i] = newOrganization(c.clientContext, apiObj, ref)
}
return projects, nil
}
// Children returns the immediate child-organizations for the specific OrganizationRef o.
// The OrganizationRef may point to any existing sub-organization.
// Children returns all available organizations, using multiple paginated requests if needed.
func (c *OrganizationsClient) Children(_ context.Context, _ gitprovider.OrganizationRef) ([]gitprovider.Organization, error) {
return nil, gitprovider.ErrNoProviderSupport
}
// validateOrganizationRef makes sure the OrganizationRef is valid for stash usage.
func validateOrganizationRef(ref gitprovider.OrganizationRef, expectedDomain string) error {
// Make sure the OrganizationRef fields are valid
if err := validation.ValidateTargets("OrganizationRef", ref); err != nil {
return err
}
// Make sure the type is valid, and domain is expected
return validateIdentityFields(ref, expectedDomain)
}
// validateIdentityFields makes sure the type of the IdentityRef is supported, and the domain is as expected.
func validateIdentityFields(ref gitprovider.IdentityRef, expectedDomain string) error {
// Make sure the expected domain is used
if ref.GetDomain() != expectedDomain {
return fmt.Errorf("domain %q not supported by this client: %w", ref.GetDomain(), gitprovider.ErrDomainUnsupported)
}
// Make sure the right type of identityref is used
switch ref.GetType() {
case gitprovider.IdentityTypeOrganization, gitprovider.IdentityTypeUser:
return nil
case gitprovider.IdentityTypeSuborganization:
return fmt.Errorf("stash doesn't support sub-organizations: %w", gitprovider.ErrNoProviderSupport)
}
return fmt.Errorf("invalid identity type: %v: %w", ref.GetType(), gitprovider.ErrInvalidArgument)
}
func validateProjectAPI(apiObj *Project) error {
return validateAPIObject("Stash.Project", func(validator validation.Validator) {
// Make sure name is set
if apiObj.Name == "" {
validator.Required("Name")
}
// Make sure key is set
if apiObj.Key == "" {
validator.Required("Key")
}
})
}