Skip to content

Commit 4e5e838

Browse files
committed
Add support for AWS STS endpoint in the Bucket API
Signed-off-by: Matheus Pimenta <[email protected]>
1 parent 218af57 commit 4e5e838

File tree

12 files changed

+617
-47
lines changed

12 files changed

+617
-47
lines changed

api/v1beta2/bucket_types.go

+26
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,8 @@ const (
4949

5050
// BucketSpec specifies the required configuration to produce an Artifact for
5151
// an object storage bucket.
52+
// +kubebuilder:validation:XValidation:rule="self.provider == 'aws' || !has(self.sts)", message="STS configuration is only supported for the 'aws' Bucket provider"
53+
// +kubebuilder:validation:XValidation:rule="self.provider != 'aws' || !has(self.sts) || self.sts.provider == 'aws'", message="'aws' is the only supported STS provider for the 'aws' Bucket provider"
5254
type BucketSpec struct {
5355
// Provider of the object storage bucket.
5456
// Defaults to 'generic', which expects an S3 (API) compatible object
@@ -66,6 +68,14 @@ type BucketSpec struct {
6668
// +required
6769
Endpoint string `json:"endpoint"`
6870

71+
// STS specifies the required configuration to use a Security Token
72+
// Service for fetching temporary credentials to authenticate in a
73+
// Bucket provider.
74+
//
75+
// This field is only supported for the `aws` provider.
76+
// +optional
77+
STS *BucketSTSSpec `json:"sts,omitempty"`
78+
6979
// Insecure allows connecting to a non-TLS HTTP Endpoint.
7080
// +optional
7181
Insecure bool `json:"insecure,omitempty"`
@@ -140,6 +150,22 @@ type BucketSpec struct {
140150
AccessFrom *acl.AccessFrom `json:"accessFrom,omitempty"`
141151
}
142152

153+
// BucketSTSSpec specifies the required configuration to use a Security Token
154+
// Service for fetching temporary credentials to authenticate in a Bucket
155+
// provider.
156+
type BucketSTSSpec struct {
157+
// Provider of the Security Token Service.
158+
// +kubebuilder:validation:Enum=aws
159+
// +required
160+
Provider string `json:"provider"`
161+
162+
// Endpoint is the HTTP/S endpoint of the Security Token Service from
163+
// where temporary credentials will be fetched.
164+
// +required
165+
// +kubebuilder:validation:Pattern="^(http|https)://.*$"
166+
Endpoint string `json:"endpoint"`
167+
}
168+
143169
// BucketStatus records the observed state of a Bucket.
144170
type BucketStatus struct {
145171
// ObservedGeneration is the last observed generation of the Bucket object.

api/v1beta2/sts_types.go

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
/*
2+
Copyright 2024 The Flux authors
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
package v1beta2
18+
19+
const (
20+
// STSProviderAmazon represents the AWS provider for Security Token Service.
21+
// Provides support for fetching temporary credentials from an AWS STS endpoint.
22+
STSProviderAmazon string = "aws"
23+
)

api/v1beta2/zz_generated.deepcopy.go

+20
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

config/crd/bases/source.toolkit.fluxcd.io_buckets.yaml

+31
Original file line numberDiff line numberDiff line change
@@ -420,6 +420,30 @@ spec:
420420
required:
421421
- name
422422
type: object
423+
sts:
424+
description: |-
425+
STS specifies the required configuration to use a Security Token
426+
Service for fetching temporary credentials to authenticate in a
427+
Bucket provider.
428+
429+
430+
This field is only supported for the `aws` provider.
431+
properties:
432+
endpoint:
433+
description: |-
434+
Endpoint is the HTTP/S endpoint of the Security Token Service from
435+
where temporary credentials will be fetched.
436+
pattern: ^(http|https)://.*$
437+
type: string
438+
provider:
439+
description: Provider of the Security Token Service.
440+
enum:
441+
- aws
442+
type: string
443+
required:
444+
- endpoint
445+
- provider
446+
type: object
423447
suspend:
424448
description: |-
425449
Suspend tells the controller to suspend the reconciliation of this
@@ -435,6 +459,13 @@ spec:
435459
- endpoint
436460
- interval
437461
type: object
462+
x-kubernetes-validations:
463+
- message: STS configuration is only supported for the 'aws' Bucket provider
464+
rule: self.provider == 'aws' || !has(self.sts)
465+
- message: '''aws'' is the only supported STS provider for the ''aws''
466+
Bucket provider'
467+
rule: self.provider != 'aws' || !has(self.sts) || self.sts.provider
468+
== 'aws'
438469
status:
439470
default:
440471
observedGeneration: -1

docs/api/v1beta2/source.md

+80
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,23 @@ string
114114
</tr>
115115
<tr>
116116
<td>
117+
<code>sts</code><br>
118+
<em>
119+
<a href="#source.toolkit.fluxcd.io/v1beta2.BucketSTSSpec">
120+
BucketSTSSpec
121+
</a>
122+
</em>
123+
</td>
124+
<td>
125+
<em>(Optional)</em>
126+
<p>STS specifies the required configuration to use a Security Token
127+
Service for fetching temporary credentials to authenticate in a
128+
Bucket provider.</p>
129+
<p>This field is only supported for the <code>aws</code> provider.</p>
130+
</td>
131+
</tr>
132+
<tr>
133+
<td>
117134
<code>insecure</code><br>
118135
<em>
119136
bool
@@ -1424,6 +1441,52 @@ map[string]string
14241441
</table>
14251442
</div>
14261443
</div>
1444+
<h3 id="source.toolkit.fluxcd.io/v1beta2.BucketSTSSpec">BucketSTSSpec
1445+
</h3>
1446+
<p>
1447+
(<em>Appears on:</em>
1448+
<a href="#source.toolkit.fluxcd.io/v1beta2.BucketSpec">BucketSpec</a>)
1449+
</p>
1450+
<p>BucketSTSSpec specifies the required configuration to use a Security Token
1451+
Service for fetching temporary credentials to authenticate in a Bucket
1452+
provider.</p>
1453+
<div class="md-typeset__scrollwrap">
1454+
<div class="md-typeset__table">
1455+
<table>
1456+
<thead>
1457+
<tr>
1458+
<th>Field</th>
1459+
<th>Description</th>
1460+
</tr>
1461+
</thead>
1462+
<tbody>
1463+
<tr>
1464+
<td>
1465+
<code>provider</code><br>
1466+
<em>
1467+
string
1468+
</em>
1469+
</td>
1470+
<td>
1471+
<p>Provider of the Security Token Service.</p>
1472+
</td>
1473+
</tr>
1474+
<tr>
1475+
<td>
1476+
<code>endpoint</code><br>
1477+
<em>
1478+
string
1479+
</em>
1480+
</td>
1481+
<td>
1482+
<p>Endpoint is the HTTP/S endpoint of the Security Token Service from
1483+
where temporary credentials will be fetched.</p>
1484+
</td>
1485+
</tr>
1486+
</tbody>
1487+
</table>
1488+
</div>
1489+
</div>
14271490
<h3 id="source.toolkit.fluxcd.io/v1beta2.BucketSpec">BucketSpec
14281491
</h3>
14291492
<p>
@@ -1480,6 +1543,23 @@ string
14801543
</tr>
14811544
<tr>
14821545
<td>
1546+
<code>sts</code><br>
1547+
<em>
1548+
<a href="#source.toolkit.fluxcd.io/v1beta2.BucketSTSSpec">
1549+
BucketSTSSpec
1550+
</a>
1551+
</em>
1552+
</td>
1553+
<td>
1554+
<em>(Optional)</em>
1555+
<p>STS specifies the required configuration to use a Security Token
1556+
Service for fetching temporary credentials to authenticate in a
1557+
Bucket provider.</p>
1558+
<p>This field is only supported for the <code>aws</code> provider.</p>
1559+
</td>
1560+
</tr>
1561+
<tr>
1562+
<td>
14831563
<code>insecure</code><br>
14841564
<em>
14851565
bool

docs/spec/v1beta2/buckets.md

+17
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,23 @@ HTTP endpoint requires enabling [`.spec.insecure`](#insecure).
749749
Some endpoints require the specification of a [`.spec.region`](#region),
750750
see [Provider](#provider) for more (provider specific) examples.
751751

752+
### STS
753+
754+
`.spec.sts` is an optional field for specifying the Security Token Service
755+
configuration. A Security Token Service (STS) is a web service that issues
756+
temporary security credentials. By adding this field, one may specify the
757+
STS endpoint from where temporary credentials will be fetched.
758+
759+
If using `.spec.sts`, the following fields are required:
760+
761+
- `.spec.sts.provider`, the Security Token Service provider. The only supported
762+
option is `aws`.
763+
- `.spec.sts.endpoint`, the HTTP/S endpoint of the Security Token Service. In
764+
the case of AWS, this can be `https://sts.amazonaws.com`, or a Regional STS
765+
Endpoint, or an Interface Endpoint created inside a VPC.
766+
767+
This field is only supported for the `aws` bucket provider.
768+
752769
### Bucket name
753770

754771
`.spec.bucketName` is a required field that specifies which object storage

internal/controller/bucket_controller.go

+5
Original file line numberDiff line numberDiff line change
@@ -463,6 +463,11 @@ func (r *BucketReconciler) reconcileSource(ctx context.Context, sp *patch.Serial
463463
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
464464
return sreconcile.ResultEmpty, e
465465
}
466+
if err = minio.ValidateSTSConfig(obj); err != nil {
467+
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)
468+
conditions.MarkTrue(obj, sourcev1.FetchFailedCondition, e.Reason, "%s", e)
469+
return sreconcile.ResultEmpty, e
470+
}
466471
tlsConfig, err := r.getTLSConfig(ctx, obj)
467472
if err != nil {
468473
e := serror.NewGeneric(err, sourcev1.AuthenticationFailedReason)

internal/controller/bucket_controller_test.go

+17
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,23 @@ func TestBucketReconciler_reconcileSource_generic(t *testing.T) {
608608
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
609609
},
610610
},
611+
{
612+
name: "Observes invalid STS configuration",
613+
bucketName: "dummy",
614+
beforeFunc: func(obj *bucketv1.Bucket) {
615+
obj.Spec.Provider = "some-provider"
616+
obj.Spec.STS = &bucketv1.BucketSTSSpec{}
617+
conditions.MarkReconciling(obj, meta.ProgressingReason, "foo")
618+
conditions.MarkUnknown(obj, meta.ReadyCondition, "foo", "bar")
619+
},
620+
wantErr: true,
621+
assertIndex: index.NewDigester(),
622+
assertConditions: []metav1.Condition{
623+
*conditions.TrueCondition(sourcev1.FetchFailedCondition, sourcev1.AuthenticationFailedReason, "STS configuration is not supported for 'some-provider' bucket provider"),
624+
*conditions.TrueCondition(meta.ReconcilingCondition, meta.ProgressingReason, "foo"),
625+
*conditions.UnknownCondition(meta.ReadyCondition, "foo", "bar"),
626+
},
627+
},
611628
{
612629
name: "Transient bucket name API failure",
613630
beforeFunc: func(obj *bucketv1.Bucket) {

0 commit comments

Comments
 (0)