Skip to content

Commit f60ea33

Browse files
authored
Create loggroup and bucket in go instead of bash (#898)
1 parent cc8272e commit f60ea33

File tree

6 files changed

+145
-38
lines changed

6 files changed

+145
-38
lines changed

cli/cmd/cluster.go

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import (
2323
"os"
2424
"time"
2525

26+
"github.com/cortexlabs/cortex/pkg/lib/aws"
2627
cr "github.com/cortexlabs/cortex/pkg/lib/configreader"
2728
"github.com/cortexlabs/cortex/pkg/lib/errors"
2829
"github.com/cortexlabs/cortex/pkg/lib/exit"
@@ -110,6 +111,17 @@ var _upCmd = &cobra.Command{
110111
if err != nil {
111112
exit.Error(err)
112113
}
114+
115+
err = CreateBucketIfNotFound(awsClient, clusterConfig.Bucket)
116+
if err != nil {
117+
exit.Error(err)
118+
}
119+
120+
err = CreateLogGroupIfNotFound(awsClient, clusterConfig.LogGroup)
121+
if err != nil {
122+
exit.Error(err)
123+
}
124+
113125
out, exitCode, err := runManagerUpdateCommand("/root/install.sh", clusterConfig, awsCreds)
114126
if err != nil {
115127
exit.Error(err)
@@ -452,3 +464,40 @@ func assertClusterStatus(accessConfig *clusterconfig.AccessConfig, status cluste
452464
func getCloudFormationURLWithAccessConfig(accessConfig *clusterconfig.AccessConfig) string {
453465
return getCloudFormationURL(*accessConfig.ClusterName, *accessConfig.Region)
454466
}
467+
468+
func CreateBucketIfNotFound(awsClient *aws.Client, bucket string) error {
469+
bucketFound, err := awsClient.DoesBucketExist(bucket)
470+
if err != nil {
471+
return err
472+
}
473+
if !bucketFound {
474+
fmt.Print("○ creating a new s3 bucket: ", bucket)
475+
err = awsClient.CreateBucket(bucket)
476+
if err != nil {
477+
return err
478+
}
479+
fmt.Println(" ✓")
480+
} else {
481+
fmt.Println("○ using existing s3 bucket:", bucket, "✓")
482+
}
483+
return nil
484+
}
485+
486+
func CreateLogGroupIfNotFound(awsClient *aws.Client, logGroup string) error {
487+
logGroupFound, err := awsClient.DoesLogGroupExist(logGroup)
488+
if err != nil {
489+
return err
490+
}
491+
if !logGroupFound {
492+
fmt.Print("○ creating a new cloudwatch log group: ", logGroup)
493+
err = awsClient.CreateLogGroup(logGroup)
494+
if err != nil {
495+
return err
496+
}
497+
fmt.Println(" ✓")
498+
} else {
499+
fmt.Println("○ using existing cloudwatch log group:", logGroup, "✓")
500+
}
501+
502+
return nil
503+
}

cli/cmd/lib_cluster_config.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,11 @@ func getClusterUpdateConfig(cachedClusterConfig clusterconfig.Config, awsCreds A
199199
}
200200
userClusterConfig.Bucket = cachedClusterConfig.Bucket
201201

202+
if userClusterConfig.LogGroup != "" && userClusterConfig.LogGroup != cachedClusterConfig.LogGroup {
203+
return nil, clusterconfig.ErrorConfigCannotBeChangedOnUpdate(clusterconfig.LogGroupKey, cachedClusterConfig.LogGroup)
204+
}
205+
userClusterConfig.LogGroup = cachedClusterConfig.LogGroup
206+
202207
if userClusterConfig.InstanceType != nil && *userClusterConfig.InstanceType != *cachedClusterConfig.InstanceType {
203208
return nil, clusterconfig.ErrorConfigCannotBeChangedOnUpdate(clusterconfig.InstanceTypeKey, *cachedClusterConfig.InstanceType)
204209
}

manager/install.sh

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -131,9 +131,6 @@ function ensure_eks() {
131131
function main() {
132132
mkdir -p $CORTEX_CLUSTER_WORKSPACE
133133

134-
setup_bucket
135-
setup_cloudwatch_logs
136-
137134
ensure_eks
138135

139136
eksctl utils write-kubeconfig --cluster=$CORTEX_CLUSTER_NAME --region=$CORTEX_REGION | grep -v "saved kubeconfig as" | grep -v "using region" | grep -v "eksctl version" || true
@@ -211,40 +208,6 @@ function main() {
211208
echo -e "\ncortex is ready!"
212209
}
213210

214-
function setup_bucket() {
215-
if ! aws s3api head-bucket --bucket $CORTEX_BUCKET --output json 2>/dev/null; then
216-
if aws s3 ls "s3://$CORTEX_BUCKET" --output json 2>&1 | grep -q 'NoSuchBucket'; then
217-
echo -n "○ creating s3 bucket: $CORTEX_BUCKET "
218-
if [ "$CORTEX_REGION" == "us-east-1" ]; then
219-
aws s3api create-bucket --bucket $CORTEX_BUCKET \
220-
--region $CORTEX_REGION \
221-
>/dev/null
222-
else
223-
aws s3api create-bucket --bucket $CORTEX_BUCKET \
224-
--region $CORTEX_REGION \
225-
--create-bucket-configuration LocationConstraint=$CORTEX_REGION \
226-
>/dev/null
227-
fi
228-
echo ""
229-
else
230-
echo "error: a bucket named \"${CORTEX_BUCKET}\" already exists, but you do not have access to it"
231-
exit 1
232-
fi
233-
else
234-
echo "○ using existing s3 bucket: $CORTEX_BUCKET"
235-
fi
236-
}
237-
238-
function setup_cloudwatch_logs() {
239-
if ! aws logs list-tags-log-group --log-group-name $CORTEX_LOG_GROUP --region $CORTEX_REGION --output json 2>&1 | grep -q "\"tags\":"; then
240-
echo -n "○ creating cloudwatch log group: $CORTEX_LOG_GROUP "
241-
aws logs create-log-group --log-group-name $CORTEX_LOG_GROUP --region $CORTEX_REGION
242-
echo ""
243-
else
244-
echo "○ using existing cloudwatch log group: $CORTEX_LOG_GROUP"
245-
fi
246-
}
247-
248211
function setup_configmap() {
249212
kubectl -n=default create configmap 'cluster-config' \
250213
--from-file='cluster.yaml'=$CORTEX_CLUSTER_CONFIG_FILE \

pkg/lib/aws/cloudwatch.go

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
Copyright 2020 Cortex Labs, Inc.
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 aws
18+
19+
import (
20+
"github.com/aws/aws-sdk-go/aws"
21+
"github.com/aws/aws-sdk-go/service/cloudwatchlogs"
22+
"github.com/cortexlabs/cortex/pkg/lib/errors"
23+
)
24+
25+
func (c *Client) DoesLogGroupExist(logGroup string) (bool, error) {
26+
_, err := c.CloudWatchLogs().ListTagsLogGroup(&cloudwatchlogs.ListTagsLogGroupInput{
27+
LogGroupName: aws.String(logGroup),
28+
})
29+
if err != nil {
30+
if CheckErrCode(err, "ResourceNotFoundException") {
31+
return false, nil
32+
}
33+
return false, errors.Wrap(err, "log group "+logGroup)
34+
}
35+
36+
return true, nil
37+
}
38+
39+
func (c *Client) CreateLogGroup(logGroup string) error {
40+
_, err := c.CloudWatchLogs().CreateLogGroup(&cloudwatchlogs.CreateLogGroupInput{
41+
LogGroupName: aws.String(logGroup),
42+
})
43+
if err != nil {
44+
return errors.Wrap(err, "creating log group "+logGroup)
45+
}
46+
47+
return nil
48+
}

pkg/lib/aws/errors.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ func IsNoSuchBucketErr(err error) bool {
4848
return CheckErrCode(err, "NoSuchBucket")
4949
}
5050

51+
func IsForbiddenErr(err error) bool {
52+
return CheckErrCode(err, "Forbidden")
53+
}
54+
5155
func IsGenericNotFoundErr(err error) bool {
5256
return IsNotFoundErr(err) || IsNoSuchKeyErr(err) || IsNoSuchBucketErr(err)
5357
}
@@ -94,7 +98,7 @@ func ErrorAuth() error {
9498
func ErrorBucketInaccessible(bucket string) error {
9599
return errors.WithStack(&errors.Error{
96100
Kind: ErrBucketInaccessible,
97-
Message: fmt.Sprintf("bucket \"%s\" not found or insufficient permissions", bucket),
101+
Message: fmt.Sprintf("bucket \"%s\" is not accessible with the specified AWS credentials", bucket),
98102
})
99103
}
100104

pkg/lib/aws/s3.go

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"strings"
2323

2424
"github.com/aws/aws-sdk-go/aws"
25+
"github.com/aws/aws-sdk-go/aws/awserr"
2526
"github.com/aws/aws-sdk-go/aws/endpoints"
2627
"github.com/aws/aws-sdk-go/aws/session"
2728
"github.com/aws/aws-sdk-go/service/s3"
@@ -429,6 +430,43 @@ func (c *Client) DeletePrefix(bucket string, prefix string, continueIfFailure bo
429430
return nil
430431
}
431432

433+
func (c *Client) CreateBucket(bucket string) error {
434+
var bucketConfiguration *s3.CreateBucketConfiguration
435+
if c.Region != "us-east-1" {
436+
bucketConfiguration = &s3.CreateBucketConfiguration{
437+
LocationConstraint: aws.String(c.Region),
438+
}
439+
}
440+
_, err := c.S3().CreateBucket(&s3.CreateBucketInput{
441+
Bucket: aws.String(bucket),
442+
CreateBucketConfiguration: bucketConfiguration,
443+
})
444+
if err != nil {
445+
return errors.Wrap(err, "creating bucket "+bucket)
446+
}
447+
return nil
448+
}
449+
450+
// Checks bucket existence and accessibility with credentials
451+
func (c *Client) DoesBucketExist(bucket string) (bool, error) {
452+
_, err := c.S3().HeadBucket(&s3.HeadBucketInput{
453+
Bucket: aws.String(bucket),
454+
})
455+
if err != nil {
456+
if aerr, ok := err.(awserr.Error); ok {
457+
switch aerr.Code() {
458+
case "NotFound":
459+
return false, nil
460+
case "Forbidden":
461+
return false, ErrorBucketInaccessible(bucket)
462+
}
463+
}
464+
return false, errors.Wrap(err, "bucket "+bucket)
465+
}
466+
467+
return true, nil
468+
}
469+
432470
func GetBucketRegion(bucket string) (string, error) {
433471
sess := session.Must(session.NewSession()) // credentials are not necessary for this request, and will not be used
434472
region, err := s3manager.GetBucketRegion(aws.BackgroundContext(), sess, bucket, endpoints.UsWest2RegionID)

0 commit comments

Comments
 (0)