1package tfe
2
3import (
4	"context"
5	"errors"
6	"fmt"
7	"net/url"
8)
9
10// Compile-time proof of interface implementation.
11var _ PolicySetParameters = (*policySetParameters)(nil)
12
13// PolicySetParameters describes all the parameter related methods that the Terraform
14// Enterprise API supports.
15//
16// TFE API docs: https://www.terraform.io/docs/enterprise/api/policy-set-params.html
17type PolicySetParameters interface {
18	// List all the parameters associated with the given policy-set.
19	List(ctx context.Context, policySetID string, options PolicySetParameterListOptions) (*PolicySetParameterList, error)
20
21	// Create is used to create a new parameter.
22	Create(ctx context.Context, policySetID string, options PolicySetParameterCreateOptions) (*PolicySetParameter, error)
23
24	// Read a parameter by its ID.
25	Read(ctx context.Context, policySetID string, parameterID string) (*PolicySetParameter, error)
26
27	// Update values of an existing parameter.
28	Update(ctx context.Context, policySetID string, parameterID string, options PolicySetParameterUpdateOptions) (*PolicySetParameter, error)
29
30	// Delete a parameter by its ID.
31	Delete(ctx context.Context, policySetID string, parameterID string) error
32}
33
34// policySetParameters implements Parameters.
35type policySetParameters struct {
36	client *Client
37}
38
39// PolicySetParameterList represents a list of parameters.
40type PolicySetParameterList struct {
41	*Pagination
42	Items []*PolicySetParameter
43}
44
45// PolicySetParameter represents a Policy Set parameter
46type PolicySetParameter struct {
47	ID        string       `jsonapi:"primary,vars"`
48	Key       string       `jsonapi:"attr,key"`
49	Value     string       `jsonapi:"attr,value"`
50	Category  CategoryType `jsonapi:"attr,category"`
51	Sensitive bool         `jsonapi:"attr,sensitive"`
52
53	// Relations
54	PolicySet *PolicySet `jsonapi:"relation,configurable"`
55}
56
57// PolicySetParameterListOptions represents the options for listing parameters.
58type PolicySetParameterListOptions struct {
59	ListOptions
60}
61
62func (o PolicySetParameterListOptions) valid() error {
63	return nil
64}
65
66// List all the parameters associated with the given policy-set.
67func (s *policySetParameters) List(ctx context.Context, policySetID string, options PolicySetParameterListOptions) (*PolicySetParameterList, error) {
68	if !validStringID(&policySetID) {
69		return nil, errors.New("invalid value for policy set ID")
70	}
71	if err := options.valid(); err != nil {
72		return nil, err
73	}
74
75	u := fmt.Sprintf("policy-sets/%s/parameters", policySetID)
76	req, err := s.client.newRequest("GET", u, &options)
77	if err != nil {
78		return nil, err
79	}
80
81	vl := &PolicySetParameterList{}
82	err = s.client.do(ctx, req, vl)
83	if err != nil {
84		return nil, err
85	}
86
87	return vl, nil
88}
89
90// PolicySetParameterCreateOptions represents the options for creating a new parameter.
91type PolicySetParameterCreateOptions struct {
92	// For internal use only!
93	ID string `jsonapi:"primary,vars"`
94
95	// The name of the parameter.
96	Key *string `jsonapi:"attr,key"`
97
98	// The value of the parameter.
99	Value *string `jsonapi:"attr,value,omitempty"`
100
101	// The Category of the parameter, should always be "policy-set"
102	Category *CategoryType `jsonapi:"attr,category"`
103
104	// Whether the value is sensitive.
105	Sensitive *bool `jsonapi:"attr,sensitive,omitempty"`
106}
107
108func (o PolicySetParameterCreateOptions) valid() error {
109	if !validString(o.Key) {
110		return errors.New("key is required")
111	}
112	if o.Category == nil {
113		return errors.New("category is required")
114	}
115	if *o.Category != CategoryPolicySet {
116		return errors.New("category must be policy-set")
117	}
118	return nil
119}
120
121// Create is used to create a new parameter.
122func (s *policySetParameters) Create(ctx context.Context, policySetID string, options PolicySetParameterCreateOptions) (*PolicySetParameter, error) {
123	if !validStringID(&policySetID) {
124		return nil, errors.New("invalid value for policy set ID")
125	}
126	if err := options.valid(); err != nil {
127		return nil, err
128	}
129
130	// Make sure we don't send a user provided ID.
131	options.ID = ""
132
133	u := fmt.Sprintf("policy-sets/%s/parameters", url.QueryEscape(policySetID))
134	req, err := s.client.newRequest("POST", u, &options)
135	if err != nil {
136		return nil, err
137	}
138
139	p := &PolicySetParameter{}
140	err = s.client.do(ctx, req, p)
141	if err != nil {
142		return nil, err
143	}
144
145	return p, nil
146}
147
148// Read a parameter by its ID.
149func (s *policySetParameters) Read(ctx context.Context, policySetID string, parameterID string) (*PolicySetParameter, error) {
150	if !validStringID(&policySetID) {
151		return nil, errors.New("invalid value for policy set ID")
152	}
153	if !validStringID(&parameterID) {
154		return nil, errors.New("invalid value for parameter ID")
155	}
156
157	u := fmt.Sprintf("policy-sets/%s/parameters/%s", url.QueryEscape(policySetID), url.QueryEscape(parameterID))
158	req, err := s.client.newRequest("GET", u, nil)
159	if err != nil {
160		return nil, err
161	}
162
163	p := &PolicySetParameter{}
164	err = s.client.do(ctx, req, p)
165	if err != nil {
166		return nil, err
167	}
168
169	return p, err
170}
171
172// PolicySetParameterUpdateOptions represents the options for updating a parameter.
173type PolicySetParameterUpdateOptions struct {
174	// For internal use only!
175	ID string `jsonapi:"primary,vars"`
176
177	// The name of the parameter.
178	Key *string `jsonapi:"attr,key,omitempty"`
179
180	// The value of the parameter.
181	Value *string `jsonapi:"attr,value,omitempty"`
182
183	// Whether the value is sensitive.
184	Sensitive *bool `jsonapi:"attr,sensitive,omitempty"`
185}
186
187// Update values of an existing parameter.
188func (s *policySetParameters) Update(ctx context.Context, policySetID string, parameterID string, options PolicySetParameterUpdateOptions) (*PolicySetParameter, error) {
189	if !validStringID(&policySetID) {
190		return nil, errors.New("invalid value for policy set ID")
191	}
192	if !validStringID(&parameterID) {
193		return nil, errors.New("invalid value for parameter ID")
194	}
195
196	// Make sure we don't send a user provided ID.
197	options.ID = parameterID
198
199	u := fmt.Sprintf("policy-sets/%s/parameters/%s", url.QueryEscape(policySetID), url.QueryEscape(parameterID))
200	req, err := s.client.newRequest("PATCH", u, &options)
201	if err != nil {
202		return nil, err
203	}
204
205	p := &PolicySetParameter{}
206	err = s.client.do(ctx, req, p)
207	if err != nil {
208		return nil, err
209	}
210
211	return p, nil
212}
213
214// Delete a parameter by its ID.
215func (s *policySetParameters) Delete(ctx context.Context, policySetID string, parameterID string) error {
216	if !validStringID(&policySetID) {
217		return errors.New("invalid value for policy set ID")
218	}
219	if !validStringID(&parameterID) {
220		return errors.New("invalid value for parameter ID")
221	}
222
223	u := fmt.Sprintf("policy-sets/%s/parameters/%s", url.QueryEscape(policySetID), url.QueryEscape(parameterID))
224	req, err := s.client.newRequest("DELETE", u, nil)
225	if err != nil {
226		return err
227	}
228
229	return s.client.do(ctx, req, nil)
230}
231