Skip to content

Commit b8481b7

Browse files
committed
Add Archs field to AdminOPAVersion and AdminSentinelVersion
1 parent dd8f6c7 commit b8481b7

7 files changed

+325
-89
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
* Updates team token `Description` to be a pointer, allowing for both nil descriptions and empty string descriptions. Team token descriptions and the ability to create multiple team tokens is in BETA, which is EXPERIMENTAL, SUBJECT TO CHANGE, and may not be available to all users, by @mkam [#1088](https://github.com/hashicorp/go-tfe/pull/1088)
66

7+
## Enhancements
8+
9+
* Add BETA support for use of OPA and Sentinel with Linux arm64 agents, which is EXPERIMENTAL, SUBJECT TO CHANGE, and may not be available to all users @natalie-todd [#1090](https://github.com/hashicorp/go-tfe/pull/1090)
10+
711
# v1.78.0
812

913
## Enhancements

admin_opa_version.go

Lines changed: 45 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"context"
88
"fmt"
99
"net/url"
10+
"reflect"
1011
"time"
1112
)
1213

@@ -42,17 +43,18 @@ type adminOPAVersions struct {
4243

4344
// AdminOPAVersion represents a OPA Version
4445
type AdminOPAVersion struct {
45-
ID string `jsonapi:"primary,opa-versions"`
46-
Version string `jsonapi:"attr,version"`
47-
URL string `jsonapi:"attr,url"`
48-
SHA string `jsonapi:"attr,sha"`
49-
Deprecated bool `jsonapi:"attr,deprecated"`
50-
DeprecatedReason *string `jsonapi:"attr,deprecated-reason,omitempty"`
51-
Official bool `jsonapi:"attr,official"`
52-
Enabled bool `jsonapi:"attr,enabled"`
53-
Beta bool `jsonapi:"attr,beta"`
54-
Usage int `jsonapi:"attr,usage"`
55-
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
46+
ID string `jsonapi:"primary,opa-versions"`
47+
Version string `jsonapi:"attr,version"`
48+
URL string `jsonapi:"attr,url,omitempty"`
49+
SHA string `jsonapi:"attr,sha,omitempty"`
50+
Deprecated bool `jsonapi:"attr,deprecated"`
51+
DeprecatedReason *string `jsonapi:"attr,deprecated-reason,omitempty"`
52+
Official bool `jsonapi:"attr,official"`
53+
Enabled bool `jsonapi:"attr,enabled"`
54+
Beta bool `jsonapi:"attr,beta"`
55+
Usage int `jsonapi:"attr,usage"`
56+
CreatedAt time.Time `jsonapi:"attr,created-at,iso8601"`
57+
Archs []*ToolVersionArchitecture `jsonapi:"attr,archs,omitempty"`
5658
}
5759

5860
// AdminOPAVersionsListOptions represents the options for listing
@@ -69,28 +71,30 @@ type AdminOPAVersionsListOptions struct {
6971

7072
// AdminOPAVersionCreateOptions for creating an OPA version.
7173
type AdminOPAVersionCreateOptions struct {
72-
Type string `jsonapi:"primary,opa-versions"`
73-
Version string `jsonapi:"attr,version"` // Required
74-
URL string `jsonapi:"attr,url"` // Required
75-
SHA string `jsonapi:"attr,sha"` // Required
76-
Official *bool `jsonapi:"attr,official,omitempty"`
77-
Deprecated *bool `jsonapi:"attr,deprecated,omitempty"`
78-
DeprecatedReason *string `jsonapi:"attr,deprecated-reason,omitempty"`
79-
Enabled *bool `jsonapi:"attr,enabled,omitempty"`
80-
Beta *bool `jsonapi:"attr,beta,omitempty"`
74+
Type string `jsonapi:"primary,opa-versions"`
75+
Version string `jsonapi:"attr,version"` // Required
76+
URL string `jsonapi:"attr,url,omitempty"` // Required w/ SHA unless Archs are provided
77+
SHA string `jsonapi:"attr,sha,omitempty"` // Required w/ URL unless Archs are provided
78+
Official *bool `jsonapi:"attr,official,omitempty"`
79+
Deprecated *bool `jsonapi:"attr,deprecated,omitempty"`
80+
DeprecatedReason *string `jsonapi:"attr,deprecated-reason,omitempty"`
81+
Enabled *bool `jsonapi:"attr,enabled,omitempty"`
82+
Beta *bool `jsonapi:"attr,beta,omitempty"`
83+
Archs []*ToolVersionArchitecture `jsonapi:"attr,archs,omitempty"` // Required unless URL and SHA are provided
8184
}
8285

8386
// AdminOPAVersionUpdateOptions for updating OPA version.
8487
type AdminOPAVersionUpdateOptions struct {
85-
Type string `jsonapi:"primary,opa-versions"`
86-
Version *string `jsonapi:"attr,version,omitempty"`
87-
URL *string `jsonapi:"attr,url,omitempty"`
88-
SHA *string `jsonapi:"attr,sha,omitempty"`
89-
Official *bool `jsonapi:"attr,official,omitempty"`
90-
Deprecated *bool `jsonapi:"attr,deprecated,omitempty"`
91-
DeprecatedReason *string `jsonapi:"attr,deprecated-reason,omitempty"`
92-
Enabled *bool `jsonapi:"attr,enabled,omitempty"`
93-
Beta *bool `jsonapi:"attr,beta,omitempty"`
88+
Type string `jsonapi:"primary,opa-versions"`
89+
Version *string `jsonapi:"attr,version,omitempty"`
90+
URL *string `jsonapi:"attr,url,omitempty"`
91+
SHA *string `jsonapi:"attr,sha,omitempty"`
92+
Official *bool `jsonapi:"attr,official,omitempty"`
93+
Deprecated *bool `jsonapi:"attr,deprecated,omitempty"`
94+
DeprecatedReason *string `jsonapi:"attr,deprecated-reason,omitempty"`
95+
Enabled *bool `jsonapi:"attr,enabled,omitempty"`
96+
Beta *bool `jsonapi:"attr,beta,omitempty"`
97+
Archs []*ToolVersionArchitecture `jsonapi:"attr,archs,omitempty"`
9498
}
9599

96100
// AdminOPAVersionsList represents a list of OPA versions.
@@ -192,18 +196,23 @@ func (a *adminOPAVersions) Delete(ctx context.Context, id string) error {
192196
}
193197

194198
func (o AdminOPAVersionCreateOptions) valid() error {
195-
if (o == AdminOPAVersionCreateOptions{}) {
199+
if (reflect.DeepEqual(o, AdminOPAVersionCreateOptions{})) {
196200
return ErrRequiredOPAVerCreateOps
197201
}
198202
if o.Version == "" {
199203
return ErrRequiredVersion
200204
}
201-
if o.URL == "" {
202-
return ErrRequiredURL
205+
if !o.validArch() && (o.URL == "" || o.SHA == "") {
206+
return ErrRequiredArchOrURLAndSha
203207
}
204-
if o.SHA == "" {
205-
return ErrRequiredSha
206-
}
207-
208208
return nil
209209
}
210+
211+
func (o AdminOPAVersionCreateOptions) validArch() bool {
212+
for _, a := range o.Archs {
213+
if a.URL != "" && a.Sha != "" && a.OS == linux && (a.Arch == amd64 || a.Arch == arm64) {
214+
return true
215+
}
216+
}
217+
return false
218+
}

admin_opa_version_integration_test.go

Lines changed: 113 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,46 @@ func TestAdminOPAVersions_CreateDelete(t *testing.T) {
102102
ctx := context.Background()
103103
version := createAdminOPAVersion()
104104

105-
t.Run("with valid options", func(t *testing.T) {
105+
t.Run("with valid options including archs", func(t *testing.T) {
106+
opts := AdminOPAVersionCreateOptions{
107+
Version: version,
108+
Deprecated: Bool(true),
109+
DeprecatedReason: String("Test Reason"),
110+
Official: Bool(false),
111+
Enabled: Bool(false),
112+
Beta: Bool(false),
113+
Archs: []*ToolVersionArchitecture{
114+
{
115+
URL: "https://www.hashicorp.com",
116+
Sha: *String(genSha(t)),
117+
OS: linux,
118+
Arch: amd64,
119+
},
120+
{
121+
URL: "https://www.hashicorp.com",
122+
Sha: *String(genSha(t)),
123+
OS: linux,
124+
Arch: arm64,
125+
}},
126+
}
127+
ov, err := client.Admin.OPAVersions.Create(ctx, opts)
128+
require.NoError(t, err)
129+
130+
defer func() {
131+
deleteErr := client.Admin.OPAVersions.Delete(ctx, ov.ID)
132+
require.NoError(t, deleteErr)
133+
}()
134+
135+
assert.Equal(t, opts.Version, ov.Version)
136+
assert.ElementsMatch(t, opts.Archs, ov.Archs)
137+
assert.Equal(t, *opts.Official, ov.Official)
138+
assert.Equal(t, *opts.Deprecated, ov.Deprecated)
139+
assert.Equal(t, *opts.DeprecatedReason, *ov.DeprecatedReason)
140+
assert.Equal(t, *opts.Enabled, ov.Enabled)
141+
assert.Equal(t, *opts.Beta, ov.Beta)
142+
})
143+
144+
t.Run("with valid options including, url, and sha", func(t *testing.T) {
106145
opts := AdminOPAVersionCreateOptions{
107146
Version: version,
108147
URL: "https://www.hashicorp.com",
@@ -131,8 +170,8 @@ func TestAdminOPAVersions_CreateDelete(t *testing.T) {
131170
assert.Equal(t, *opts.Beta, ov.Beta)
132171
})
133172

134-
t.Run("with only required options", func(t *testing.T) {
135-
version := createAdminOPAVersion()
173+
t.Run("with only required options including tool version url and sha", func(t *testing.T) {
174+
version = createAdminOPAVersion()
136175
opts := AdminOPAVersionCreateOptions{
137176
Version: version,
138177
URL: "https://www.hashicorp.com",
@@ -156,6 +195,41 @@ func TestAdminOPAVersions_CreateDelete(t *testing.T) {
156195
assert.Equal(t, false, ov.Beta)
157196
})
158197

198+
t.Run("with only required options including archs", func(t *testing.T) {
199+
version = createAdminOPAVersion()
200+
opts := AdminOPAVersionCreateOptions{
201+
Version: version,
202+
Archs: []*ToolVersionArchitecture{
203+
{
204+
URL: "https://www.hashicorp.com",
205+
Sha: *String(genSha(t)),
206+
OS: linux,
207+
Arch: amd64,
208+
},
209+
{
210+
URL: "https://www.hashicorp.com",
211+
Sha: *String(genSha(t)),
212+
OS: linux,
213+
Arch: arm64,
214+
}},
215+
}
216+
ov, err := client.Admin.OPAVersions.Create(ctx, opts)
217+
require.NoError(t, err)
218+
219+
defer func() {
220+
deleteErr := client.Admin.OPAVersions.Delete(ctx, ov.ID)
221+
require.NoError(t, deleteErr)
222+
}()
223+
224+
assert.Equal(t, opts.Version, ov.Version)
225+
assert.ElementsMatch(t, opts.Archs, ov.Archs)
226+
assert.Equal(t, false, ov.Official)
227+
assert.Equal(t, false, ov.Deprecated)
228+
assert.Nil(t, ov.DeprecatedReason)
229+
assert.Equal(t, true, ov.Enabled)
230+
assert.Equal(t, false, ov.Beta)
231+
})
232+
159233
t.Run("with empty options", func(t *testing.T) {
160234
_, err := client.Admin.OPAVersions.Create(ctx, AdminOPAVersionCreateOptions{})
161235
require.Equal(t, err, ErrRequiredOPAVerCreateOps)
@@ -170,6 +244,7 @@ func TestAdminOPAVersions_ReadUpdate(t *testing.T) {
170244

171245
t.Run("reads and updates", func(t *testing.T) {
172246
version := createAdminOPAVersion()
247+
sha := String(genSha(t))
173248
opts := AdminOPAVersionCreateOptions{
174249
Version: version,
175250
URL: "https://www.hashicorp.com",
@@ -179,6 +254,12 @@ func TestAdminOPAVersions_ReadUpdate(t *testing.T) {
179254
DeprecatedReason: String("Test Reason"),
180255
Enabled: Bool(false),
181256
Beta: Bool(false),
257+
Archs: []*ToolVersionArchitecture{{
258+
URL: "https://www.hashicorp.com",
259+
Sha: *sha,
260+
OS: linux,
261+
Arch: amd64,
262+
}},
182263
}
183264
ov, err := client.Admin.OPAVersions.Create(ctx, opts)
184265
require.NoError(t, err)
@@ -193,8 +274,9 @@ func TestAdminOPAVersions_ReadUpdate(t *testing.T) {
193274
require.NoError(t, err)
194275

195276
assert.Equal(t, opts.Version, ov.Version)
196-
assert.Equal(t, opts.URL, ov.URL)
197-
assert.Equal(t, opts.SHA, ov.SHA)
277+
assert.Equal(t, opts.Archs[0].URL, ov.URL)
278+
assert.Equal(t, opts.Archs[0].Sha, ov.SHA)
279+
assert.ElementsMatch(t, opts.Archs, ov.Archs)
198280
assert.Equal(t, *opts.Official, ov.Official)
199281
assert.Equal(t, *opts.Deprecated, ov.Deprecated)
200282
assert.Equal(t, *opts.DeprecatedReason, *ov.DeprecatedReason)
@@ -215,10 +297,36 @@ func TestAdminOPAVersions_ReadUpdate(t *testing.T) {
215297
assert.Equal(t, updateVersion, ov.Version)
216298
assert.Equal(t, updateURL, ov.URL)
217299
assert.Equal(t, opts.SHA, ov.SHA)
300+
assert.Equal(t, updateURL, ov.Archs[0].URL)
301+
assert.Equal(t, opts.SHA, ov.Archs[0].Sha)
218302
assert.Equal(t, *opts.Official, ov.Official)
219303
assert.Equal(t, *updateOpts.Deprecated, ov.Deprecated)
220304
assert.Equal(t, *opts.Enabled, ov.Enabled)
221305
assert.Equal(t, *opts.Beta, ov.Beta)
306+
307+
updateOpts = AdminOPAVersionUpdateOptions{
308+
Archs: []*ToolVersionArchitecture{
309+
{
310+
URL: "https://www.hashicorp.com/update",
311+
Sha: *sha,
312+
OS: linux,
313+
Arch: amd64,
314+
},
315+
{
316+
URL: "https://www.hashicorp.com/update/arm64",
317+
Sha: *sha,
318+
OS: linux,
319+
Arch: arm64,
320+
},
321+
},
322+
}
323+
324+
ov, err = client.Admin.OPAVersions.Update(ctx, id, updateOpts)
325+
require.NoError(t, err)
326+
327+
assert.Equal(t, "https://www.hashicorp.com/update", ov.URL)
328+
assert.Equal(t, opts.SHA, ov.SHA)
329+
assert.ElementsMatch(t, updateOpts.Archs, ov.Archs)
222330
})
223331

224332
t.Run("with non-existent OPA version", func(t *testing.T) {

0 commit comments

Comments
 (0)