Skip to content

Commit

Permalink
Feature/migrate to iam serviceaccount (#42)
Browse files Browse the repository at this point in the history
* Added serviceaccount and removed annotation for role

* Add logging for AWS authentication provider
Update go version
Replace ioutil with io

* Check the Errors field in s3.DeleteObjectsOutput

If deleting an object in s3 fail, it won't be reported in the error returned
from `svc.DeleteObjects`, instead it will be reported in the output object
returned from the same method.

* Fix snyk vuln

https://security.snyk.io/vuln/SNYK-GOLANG-GITHUBCOMPROMETHEUSCLIENTGOLANGPROMETHEUSPROMHTTP-2401819

* Use custom envvar denoting the region of the bucket used by this svc

The service access buckets which are in eu-west-1, however when the service is
deployed in us the AWS_REGION envvars is set to us-east-1(because of the IAM to
ServiceAccount feature).

Co-authored-by: mkrum001 <mkrum001@gmail.com>
Co-authored-by: Ivan Ivanov <ivan.ivanov@ft.com>
  • Loading branch information
3 people committed Dec 6, 2022
1 parent a1536a7 commit 0153966
Show file tree
Hide file tree
Showing 9 changed files with 219 additions and 93 deletions.
45 changes: 25 additions & 20 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,32 +1,37 @@
module github.com/Financial-Times/resilient-splunk-forwarder

go 1.13
go 1.19

require (
github.com/Financial-Times/go-fthealth v0.0.0-20171204124831-1b007e2b37b7
github.com/Financial-Times/go-logger/v2 v2.0.1
github.com/Financial-Times/service-status-go v0.0.0-20160323111542-3f5199736a3d
github.com/aws/aws-sdk-go v1.12.27-0.20171113235433-395e6c4c7c39
github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973 // indirect
github.com/aws/aws-sdk-go v1.33.10
github.com/jawher/mow.cli v0.0.0-20170430135212-8327d12beb75
github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c
github.com/pkg/errors v0.9.1
github.com/prometheus/client_golang v1.11.1
github.com/stretchr/testify v1.7.0
go.uber.org/multierr v1.8.0
)

require (
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-ini/ini v1.51.1 // indirect
github.com/gogo/protobuf v1.1.2-0.20180830160456-5669497fd644 // indirect
github.com/golang/protobuf v1.2.1-0.20180910224916-e344474228f5 // indirect
github.com/golang/protobuf v1.4.3 // indirect
github.com/hashicorp/go-version v0.0.0-20170202080759-03c5bf6be031 // indirect
github.com/jawher/mow.cli v0.0.0-20170430135212-8327d12beb75
github.com/jmespath/go-jmespath v0.0.0-20180206201540-c2b33e8439af // indirect
github.com/jmespath/go-jmespath v0.3.0 // indirect
github.com/konsorten/go-windows-terminal-sequences v1.0.3 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.1 // indirect
github.com/pborman/uuid v0.0.0-20170612153648-e790cca94e6c
github.com/pkg/errors v0.8.1-0.20180127015812-30136e27e2ac
github.com/prometheus/client_golang v0.9.0-pre1.0.20180907102542-7858729281ec
github.com/prometheus/client_model v0.0.0-20180712105110-5c3871d89910 // indirect
github.com/prometheus/common v0.0.0-20180801064454-c7de2306084e // indirect
github.com/prometheus/procfs v0.0.0-20180725123919-05ee40e3a273 // indirect
github.com/smartystreets/goconvey v1.6.4 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_model v0.2.0 // indirect
github.com/prometheus/common v0.26.0 // indirect
github.com/prometheus/procfs v0.6.0 // indirect
github.com/sirupsen/logrus v1.6.0 // indirect
github.com/stretchr/objx v0.1.2-0.20180129172003-8a3f7159479f // indirect
github.com/stretchr/testify v1.2.2-0.20180206082539-be8372ae8ec5
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 // indirect
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e // indirect
golang.org/x/sys v0.0.0-20200107162124-548cf772de50 // indirect
gopkg.in/ini.v1 v1.51.1 // indirect
go.uber.org/atomic v1.10.0 // indirect
golang.org/x/sys v0.2.0 // indirect
google.golang.org/protobuf v1.26.0-rc.1 // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
203 changes: 151 additions & 52 deletions go.sum

Large diffs are not rendered by default.

3 changes: 2 additions & 1 deletion helm/resilient-splunk-forwarder/templates/deployment.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ spec:
values:
- {{ .Values.service.name }}
topologyKey: "kubernetes.io/hostname"
serviceAccountName: {{ .Values.serviceAccountName }}
containers:
- name: {{ .Chart.Name }}
image: "{{ .Values.image.repository }}:{{ .Chart.Version }}"
Expand All @@ -46,7 +47,7 @@ spec:
configMapKeyRef:
name: global-config
key: splunk.forwarder.s3.bucket
- name: AWS_REGION
- name: AWS_BUCKET_REGION
valueFrom:
configMapKeyRef:
name: global-config
Expand Down
4 changes: 2 additions & 2 deletions helm/resilient-splunk-forwarder/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ metrics:
# the name of the prometheus instance, as defined in
# content-k8s-prometheus\helm\content-k8s-prometheus\app-configs\monitoring-metrics_{env}.yaml
prometheusInstance: monitoring-metrics
annotations:
iam.amazonaws.com/role: "K8sSplunkFWS3"

serviceAccountName: eksctl-resilient-splunk-forwarder-serviceaccount
12 changes: 6 additions & 6 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ type appConfig struct {
chanBuffer int
token string
bucket string
awsRegion string
bucketRegion string
UPPLogger *logger.UPPLogger
}

Expand Down Expand Up @@ -112,11 +112,11 @@ func initApp() *cli.Cli {
Desc: "S3 bucket for caching failed events",
EnvVar: "BUCKET_NAME",
})
awsRegion := app.String(cli.StringOpt{
Name: "awsRegion",
awsBucketRegion := app.String(cli.StringOpt{
Name: "awsBucketRegion",
Value: "",
Desc: "AWS region for S3",
EnvVar: "AWS_REGION",
EnvVar: "AWS_BUCKET_REGION",
})

logLevel := app.String(cli.StringOpt{
Expand All @@ -138,7 +138,7 @@ func initApp() *cli.Cli {
chanBuffer: *chanBuffer,
token: *token,
bucket: *bucket,
awsRegion: *awsRegion,
bucketRegion: *awsBucketRegion,
UPPLogger: logger.NewUPPLogger(*appSystemCode, *logLevel),
}

Expand All @@ -152,7 +152,7 @@ func initApp() *cli.Cli {

defer config.UPPLogger.Infof("Resilient Splunk forwarder: Stopped\n")

s3, err := NewS3Service(config.bucket, config.awsRegion, config.env)
s3, err := NewS3Service(config.bucket, config.bucketRegion, config.env, config.UPPLogger)
if err != nil {
config.UPPLogger.Fatalf(err.Error())
}
Expand Down
2 changes: 1 addition & 1 deletion main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ func TestMain(m *testing.M) {

os.Setenv("TOKEN", config.token)
os.Setenv("BUCKET_NAME", config.bucket)
os.Setenv("AWS_REGION", "eu")
os.Setenv("AWS_BUCKET_REGION", "eu")
os.Setenv("FORWARDER_URL", config.fwdURL)

app := initApp()
Expand Down
28 changes: 23 additions & 5 deletions s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,19 @@ package main

import (
"fmt"
"io/ioutil"
"io"
"net"
"net/http"
"strings"
"sync"
"time"

"github.com/Financial-Times/go-logger/v2"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/pborman/uuid"
"go.uber.org/multierr"
)

const maxKeys = int64(100)
Expand All @@ -37,7 +39,7 @@ type s3Service struct {
latestError error
}

var NewS3Service = func(bucketName string, awsRegion string, prefix string) (Cache, error) {
var NewS3Service = func(bucketName, bucketRegion, prefix string, log *logger.UPPLogger) (Cache, error) {
wrks := 8
spareWorkers := 1

Expand All @@ -57,13 +59,20 @@ var NewS3Service = func(bucketName string, awsRegion string, prefix string) (Cac
}
sess, err := session.NewSession(
&aws.Config{
Region: aws.String(awsRegion),
Region: aws.String(bucketRegion),
MaxRetries: aws.Int(1),
HTTPClient: hc,
})
if err != nil {
return nil, fmt.Errorf("Failed to create AWS session: %v", err)
}

v, err := sess.Config.Credentials.Get()
if err != nil {
return nil, fmt.Errorf("failed to obtain AWS authentication: %w", err)
}
log.WithField("ProviderName", v.ProviderName).Info("Establishing AWS session using authentication provider")

svc := s3.New(sess)
return &s3Service{bucketName: bucketName, prefix: prefix, svc: svc}, nil
}
Expand Down Expand Up @@ -108,7 +117,7 @@ func (s *s3Service) ListAndDelete() ([]string, error) {
}

if *out.KeyCount > 0 {
_, err = s.svc.DeleteObjects(&s3.DeleteObjectsInput{
delOutput, err := s.svc.DeleteObjects(&s3.DeleteObjectsInput{
Bucket: aws.String(s.bucketName),
Delete: &s3.Delete{
Objects: ids,
Expand All @@ -118,6 +127,15 @@ func (s *s3Service) ListAndDelete() ([]string, error) {
// don't capture latest error in case another instance has deleted them first
return nil, err
}
if delOutput != nil && len(delOutput.Errors) > 0 {
var merr error
for _, e := range delOutput.Errors {
merr = multierr.Append(merr, fmt.Errorf("deleting %q: %s", *e.Key, *e.Code))
}

return nil, err
}

s.latestError = err
return vals, nil
}
Expand Down Expand Up @@ -145,7 +163,7 @@ func (s *s3Service) Get(key string) (string, error) {
}

defer val.Body.Close()
buf, err := ioutil.ReadAll(val.Body)
buf, err := io.ReadAll(val.Body)
return string(buf), err
}

Expand Down
12 changes: 8 additions & 4 deletions s3_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package main
import (
"bytes"
"errors"
"io"
"testing"

"github.com/Financial-Times/go-logger/v2"
"github.com/aws/aws-sdk-go/service/s3"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/mock"
"io/ioutil"
"testing"
)

type mockS3Interface struct {
Expand Down Expand Up @@ -78,7 +80,7 @@ func (m *mockS3Interface) GetObject(input *s3.GetObjectInput) (*s3.GetObjectOutp
}

output := &s3.GetObjectOutput{
Body: ioutil.NopCloser(bytes.NewBufferString(successResponse)),
Body: io.NopCloser(bytes.NewBufferString(successResponse)),
}

return output, nil
Expand All @@ -87,7 +89,9 @@ func (m *mockS3Interface) GetObject(input *s3.GetObjectInput) (*s3.GetObjectOutp
var _ s3Interface = (*mockS3Interface)(nil)

func Test_S3_failServiceCreation(t *testing.T) {
s3service, errServiceCreation := NewS3Service("", "no-region", "")
t.Setenv("AWS_ACCESS_KEY_ID", "MOCK_ID")
t.Setenv("AWS_SECRET_ACCESS_KEY", "MOCK_SECRET")
s3service, errServiceCreation := NewS3Service("", "no-region", "", logger.NewUnstructuredLogger())

assert.Equal(t, nil, errServiceCreation)
assert.NotEqual(t, nil, s3service)
Expand Down
3 changes: 1 addition & 2 deletions splunk.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"crypto/tls"
"errors"
"io"
"io/ioutil"
"net/http"
"strings"
"sync"
Expand Down Expand Up @@ -63,7 +62,7 @@ func (splunk *splunkClient) forward(s string, callback func(string, error)) {
splunk.config.UPPLogger.Infof(err.Error())
} else {
defer r.Body.Close()
io.Copy(ioutil.Discard, r.Body)
_, _ = io.Copy(io.Discard, r.Body)
if r.StatusCode != 200 {
errorCounter.Inc()
splunk.config.UPPLogger.Infof("Unexpected status code %v (%v) when sending %v to %v\n", r.StatusCode, r.Status, s, splunk.config.fwdURL)
Expand Down

0 comments on commit 0153966

Please sign in to comment.