-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathclient.go
More file actions
123 lines (116 loc) · 3.94 KB
/
Copy pathclient.go
File metadata and controls
123 lines (116 loc) · 3.94 KB
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
package cinc
import (
"crypto/rsa"
"crypto/tls"
"fmt"
"net/http"
"net/url"
"strings"
"time"
)
// Client is a Chef/CINC Server API client. It is safe for concurrent use.
type Client struct {
baseURL *url.URL
baseURLStr string // cached baseURL.String() for the request hot path
org string
clientName string
key *rsa.PrivateKey
httpClient *http.Client
opts options
clock func() time.Time
// Services.
Nodes *NodesService
Roles *RolesService
Environments *EnvironmentsService
Clients *ClientsService
DataBags *DataBagsService
Search *SearchService
Cookbooks *CookbooksService
CookbookArtifacts *CookbookArtifactsService
Keys *KeysService
Groups *GroupsService
Status *StatusService
License *LicenseService
Policies *PoliciesService
PolicyGroups *PolicyGroupsService
Orgs *OrgsService
Users *UsersService
Containers *ContainersService
ACLs *ACLsService
RequiredRecipe *RequiredRecipeService
Associations *AssociationsService
Principals *PrincipalsService
Universe *UniverseService
Stats *StatsService
}
// NewClient builds a Client from cfg and optional Options.
func NewClient(cfg Config, opts ...Option) (*Client, error) {
if err := cfg.validate(); err != nil {
return nil, err
}
base, err := url.Parse(strings.TrimRight(cfg.ServerURL, "/"))
if err != nil || base.Host == "" {
return nil, fmt.Errorf("cinc: invalid ServerURL %q", cfg.ServerURL)
}
o := defaultOptions()
for _, opt := range opts {
opt(&o)
}
hc := o.httpClient
if o.skipTLSVerify {
hc = &http.Client{Timeout: hc.Timeout, Transport: cloneTransportSkipVerify(hc.Transport)}
}
c := &Client{
baseURL: base, baseURLStr: base.String(), org: cfg.Org, clientName: cfg.ClientName,
key: cfg.Key, httpClient: hc, opts: o, clock: time.Now,
}
c.Nodes = &NodesService{client: c}
c.Roles = &RolesService{client: c}
c.Environments = &EnvironmentsService{client: c}
c.Clients = &ClientsService{client: c}
c.DataBags = &DataBagsService{client: c}
c.Search = &SearchService{client: c}
c.Cookbooks = &CookbooksService{client: c}
c.CookbookArtifacts = &CookbookArtifactsService{client: c}
c.Keys = &KeysService{client: c}
c.Groups = &GroupsService{client: c}
c.Status = &StatusService{client: c}
c.License = &LicenseService{client: c}
c.Policies = &PoliciesService{client: c}
c.PolicyGroups = &PolicyGroupsService{client: c}
c.Orgs = &OrgsService{client: c}
c.Users = &UsersService{client: c}
c.Containers = &ContainersService{client: c}
c.ACLs = &ACLsService{client: c}
c.RequiredRecipe = &RequiredRecipeService{client: c}
c.Associations = &AssociationsService{client: c}
c.Principals = &PrincipalsService{client: c}
c.Universe = &UniverseService{client: c}
c.Stats = &StatsService{client: c}
return c, nil
}
// cloneTransportSkipVerify returns a transport that mirrors base but skips TLS
// verification. When base is a caller-supplied *http.Transport its tuning is
// preserved; otherwise (nil, as with the default client, or a non-Transport
// RoundTripper) http.DefaultTransport is cloned so HTTP/2, proxy support, and
// connection pooling are retained. Only InsecureSkipVerify is flipped on.
func cloneTransportSkipVerify(base http.RoundTripper) *http.Transport {
tr, ok := base.(*http.Transport)
if !ok || tr == nil {
tr = http.DefaultTransport.(*http.Transport)
}
clone := tr.Clone()
if clone.TLSClientConfig == nil {
clone.TLSClientConfig = &tls.Config{}
}
clone.TLSClientConfig.InsecureSkipVerify = true
return clone
}
// orgPath prefixes p with /organizations/<org>.
func (c *Client) orgPath(p string) string {
return "/organizations/" + c.org + "/" + strings.TrimLeft(p, "/")
}
// timestamp returns the current time as an ISO-8601 UTC string.
func (c *Client) timestamp() string {
return c.clock().UTC().Format("2006-01-02T15:04:05Z")
}