Skip to content

Commit 9304b85

Browse files
authored
Merge pull request #116 from gympass/PE1-3200/prefix-bucket
[PE1-3200] feat: optionally send logs to specific directory in S3 Bucket
2 parents a3da2fe + f51341b commit 9304b85

File tree

8 files changed

+66
-3
lines changed

8 files changed

+66
-3
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ CF_CUSTOM_SSL_CERT="arn:aws:acm:us-east-1:123456789012:certificate/473e64fd-78bc
99
CF_SECURITY_POLICY="TLSv1.2_2021"
1010
CF_ENABLE_LOGGING="true"
1111
CF_S3_BUCKET_LOG="mys3bucket.s3.amazonaws.com"
12+
CF_S3_BUCKET_LOG_PREFIX="cloudfront"
1213
CF_ENABLE_IPV6="true"
1314
CF_DESCRIPTION_TEMPLATE="Serve contents for {{group}} group."
1415
CF_ROUTE53_CREATE_ALIAS="true"

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -338,6 +338,7 @@ Use the following environment variables to change the controller's behavior:
338338
| CF_ENABLE_LOGGING | No | If set to true enables sending logs to CloudWatch; `CF_S3_BUCKET_LOG` must be set as well. | "false" |
339339
| CF_PRICE_CLASS | Yes | The distribution price class. Possible values are: "PriceClass_All", "PriceClass_200", "PriceClass_100". [Official reference](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/PriceClass.html). | "PriceClass_All" |
340340
| CF_S3_BUCKET_LOG | No | The domain of the S3 bucket CloudWatch logs should be sent to. Each distribution will have its own directory inside the bucket with the same as the distribution's group. For example, if the group is "foo", the logs will be stored as `foo/<ID>.<timestamp and hash>.gz`.<br><br> If `CF_ENABLE_LOGGING` is not set to "true" then this value is ignored. | "" |
341+
| CF_S3_BUCKET_LOG_PREFIX | No | The directory within the S3 bucket informed in `CF_S3_BUCKET_LOG` logs should be created in. For example, if set to `"foo/bar"`, logs from a group called "group" will be stored in `foo/bar/group` in the S3 bucket. Trailing slash is ignore on the value, if informed (eg, "foo/bar/" ends up as "foo/bar"). | "" |
341342
| CF_SECURITY_POLICY | No | The TLS/SSL security policy to be used when serving requests. [Official reference](https://docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/secure-connections-supported-viewer-protocols-ciphers.html). <br><br> Must also inform a valid `CF_CUSTOM_SSL_CERT` if set. | "" |
342343
| DEV_MODE | No | When set to "true" logs in unstructured text instead of JSON. Also overrides LOG_LEVEL to "debug". | "false" |
343344
| LOG_LEVEL | No | Represents log level of verbosity. Can be "debug", "info", "warn", "error", "dpanic", "panic" and "fatal" (sorted with decreasing verbosity). | "info" |

internal/cloudfront/repository.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ func (r DistRepository) waitUntilDeployed(id string) (*string, error) {
282282
defer cancel()
283283

284284
var eTag *string
285-
condition := func(ctx context.Context) (done bool, err error) {
285+
condition := func(context.Context) (done bool, err error) {
286286
out, err := r.distributionByID(id)
287287
if err != nil {
288288
if cdnaws.IsErrorCode(err, awscloudfront.ErrCodeNoSuchDistribution) {

internal/cloudfront/service.go

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ func (s *Service) newDistribution(ingresses []k8s.CDNIngress, group string, shar
239239
}
240240

241241
if s.Config.CloudFrontEnableLogging && len(s.Config.CloudFrontS3BucketLog) > 0 {
242-
b = b.WithLogging(s.Config.CloudFrontS3BucketLog, group)
242+
b = b.WithLogging(s.Config.CloudFrontS3BucketLog, s.s3Prefix(group))
243243
}
244244

245245
if len(s.Config.CloudFrontCustomTags) > 0 {
@@ -272,6 +272,13 @@ func (s *Service) discoverCert(ingresses []k8s.CDNIngress) (certificate.Certific
272272
return certificate.Certificate{}, errs.ErrorOrNil()
273273
}
274274

275+
func (s *Service) s3Prefix(group string) string {
276+
if len(s.Config.CloudFrontS3BucketLogPrefix) == 0 {
277+
return group
278+
}
279+
return fmt.Sprintf("%s/%s", s.Config.CloudFrontS3BucketLogPrefix, group)
280+
}
281+
275282
func (s *Service) syncDist(ctx context.Context, desiredDist Distribution, cdnStatus *v1alpha1.CDNStatus, ing client.Object) (Distribution, error) {
276283
if desiredDist.IsEmpty() {
277284
return desiredDist, s.deleteDistribution(ctx, desiredDist)

internal/cloudfront/service_test.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,19 @@ func (s *CloudFrontServiceTestSuite) Test_validateCreation_ExistingDistributions
114114

115115
s.NoError(svc.validateCreation(dist, ing))
116116
}
117+
118+
func (s *CloudFrontServiceTestSuite) Test_s3Prefix_NoPrefixShouldJustUseGroup() {
119+
svc := Service{Config: config.Config{
120+
CloudFrontS3BucketLogPrefix: "",
121+
}}
122+
123+
s.Equal("group", svc.s3Prefix("group"))
124+
}
125+
126+
func (s *CloudFrontServiceTestSuite) Test_s3Prefix_PrefixSetShouldConcatenateWithGroup() {
127+
svc := Service{Config: config.Config{
128+
CloudFrontS3BucketLogPrefix: "foo/bar",
129+
}}
130+
131+
s.Equal("foo/bar/group", svc.s3Prefix("group"))
132+
}

internal/config/config.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ const (
3939
cfSecurityPolicyKey = "cf_security_policy"
4040
cfEnableLoggingKey = "cf_enable_logging"
4141
cfS3BucketLogKey = "cf_s3_bucket_log"
42+
cfS3BucketLogPrefixKey = "cf_s3_bucket_log_prefix"
4243
cfEnableIPV6Key = "cf_enable_ipv6"
4344
cfDescriptionTemplateKey = "cf_description_template"
4445
cfCustomTagsKey = "cf_custom_tags"
@@ -64,6 +65,7 @@ func initDefaults() {
6465
viper.SetDefault(cfSecurityPolicyKey, "")
6566
viper.SetDefault(cfEnableLoggingKey, "false")
6667
viper.SetDefault(cfS3BucketLogKey, "")
68+
viper.SetDefault(cfS3BucketLogPrefixKey, "")
6769
viper.SetDefault(cfEnableIPV6Key, "true")
6870
viper.SetDefault(cfDescriptionTemplateKey, "Serve contents for {{group}} group.")
6971
viper.SetDefault(cfCustomTagsKey, "")
@@ -106,6 +108,9 @@ type Config struct {
106108
CloudFrontEnableLogging bool
107109
// CloudFrontS3BucketLog if logging enabled represents the S3 Bucket URL to persists, for example myawslogbucket.s3.amazonaws.com.
108110
CloudFrontS3BucketLog string
111+
// CloudFrontS3BucketLogPrefix is the prefix that should be added to the S3 path when sending logs. The directory on which logs should be stored.
112+
// Trailing slashes are ignored ("foo/bar/" is the same as "foo/bar").
113+
CloudFrontS3BucketLogPrefix string
109114
// CloudFrontEnableIPV6 if should enable ipv6 for distribution responses.
110115
CloudFrontEnableIPV6 bool
111116
// CloudFrontDescriptionTemplate the description template for distribution.
@@ -174,6 +179,7 @@ func Parse() (Config, error) {
174179
CloudFrontSecurityPolicy: viper.GetString(cfSecurityPolicyKey),
175180
CloudFrontEnableLogging: viper.GetBool(cfEnableLoggingKey),
176181
CloudFrontS3BucketLog: viper.GetString(cfS3BucketLogKey),
182+
CloudFrontS3BucketLogPrefix: removeTrailingSlash(viper.GetString(cfS3BucketLogPrefixKey)),
177183
CloudFrontEnableIPV6: viper.GetBool(cfEnableIPV6Key),
178184
CloudFrontDescriptionTemplate: viper.GetString(cfDescriptionTemplateKey),
179185
CloudFrontCustomTags: extractTags(viper.GetString(cfCustomTagsKey)),
@@ -186,6 +192,13 @@ func Parse() (Config, error) {
186192
}, nil
187193
}
188194

195+
func removeTrailingSlash(getString string) string {
196+
if strings.HasSuffix(getString, "/") {
197+
return getString[:len(getString)-1]
198+
}
199+
return getString
200+
}
201+
189202
func parseNamespacedNames(names []string) ([]types.NamespacedName, error) {
190203
var result []types.NamespacedName
191204
for _, n := range names {

internal/config/config_test.go

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,31 @@ func (s *ConfigTestSuite) TestParse_DefaultToBlockCreationIsFalse() {
7474
s.False(cfg.IsCreateBlocked)
7575
}
7676

77+
func (s *ConfigTestSuite) TestParse_BucketPrefixIsSet() {
78+
testCases := []struct {
79+
name string
80+
prefix string
81+
}{
82+
{
83+
name: "No trailing slash",
84+
prefix: "foo/bar",
85+
},
86+
{
87+
name: "With trailing slash",
88+
prefix: "foo/bar/",
89+
},
90+
}
91+
92+
for _, tc := range testCases {
93+
viper.Set("cf_s3_bucket_log_prefix", tc.prefix)
94+
95+
cfg, err := Parse()
96+
97+
s.NoErrorf(err, "test case: %s", tc.name)
98+
s.Equalf("foo/bar", cfg.CloudFrontS3BucketLogPrefix, "test case: %s", tc.name)
99+
}
100+
}
101+
77102
func (s *ConfigTestSuite) TestIsCreationAllowed_UnblockedCreationReturnsTrue() {
78103
viper.Set(createBlockedKey, "false")
79104

internal/k8s/ingress_fetcher_v1_test.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -257,7 +257,7 @@ func (s *IngressFetcherV1TestSuite) TestFetchBy_FailureWithUserOrigins() {
257257
Build()
258258

259259
fetcher := NewIngressFetcherV1(client)
260-
predicate := func(ing CDNIngress) bool { return true }
260+
predicate := func(CDNIngress) bool { return true }
261261

262262
got, err := fetcher.FetchBy(context.Background(), s.CDNClass, predicate)
263263
s.Error(err, "test: %s", tc.name)

0 commit comments

Comments
 (0)