1/* Copyright 2017 WALLIX
2
3Licensed under the Apache License, Version 2.0 (the "License");
4you may not use this file except in compliance with the License.
5You may obtain a copy of the License at
6
7    http://www.apache.org/licenses/LICENSE-2.0
8
9Unless required by applicable law or agreed to in writing, software
10distributed under the License is distributed on an "AS IS" BASIS,
11WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12See the License for the specific language governing permissions and
13limitations under the License.
14*/
15
16package awsspec
17
18import (
19	"time"
20
21	"github.com/wallix/awless/cloud"
22	"github.com/wallix/awless/template/env"
23	"github.com/wallix/awless/template/params"
24
25	"github.com/aws/aws-sdk-go/aws"
26	"github.com/aws/aws-sdk-go/service/s3"
27	"github.com/aws/aws-sdk-go/service/s3/s3iface"
28	"github.com/wallix/awless/logger"
29)
30
31type CreateBucket struct {
32	_      string `action:"create" entity:"bucket" awsAPI:"s3" awsCall:"CreateBucket" awsInput:"s3.CreateBucketInput" awsOutput:"s3.CreateBucketOutput"`
33	logger *logger.Logger
34	graph  cloud.GraphAPI
35	api    s3iface.S3API
36	Name   *string `awsName:"Bucket" awsType:"awsstr" templateName:"name"`
37	Acl    *string `awsName:"ACL" awsType:"awsstr" templateName:"acl"`
38}
39
40func (cmd *CreateBucket) ParamsSpec() params.Spec {
41	return params.NewSpec(params.AllOf(params.Key("name"),
42		params.Opt("acl"),
43	))
44}
45
46func (cmd *CreateBucket) ExtractResult(i interface{}) string {
47	return StringValue(cmd.Name)
48}
49
50type UpdateBucket struct {
51	_                string `action:"update" entity:"bucket" awsAPI:"s3"`
52	logger           *logger.Logger
53	graph            cloud.GraphAPI
54	api              s3iface.S3API
55	Name             *string `templateName:"name"`
56	Acl              *string `templateName:"acl"`
57	PublicWebsite    *bool   `templateName:"public-website"`
58	RedirectHostname *string `templateName:"redirect-hostname"`
59	IndexSuffix      *string `templateName:"index-suffix"`
60	EnforceHttps     *bool   `templateName:"enforce-https"`
61}
62
63func (cmd *UpdateBucket) ParamsSpec() params.Spec {
64	return params.NewSpec(params.AllOf(params.Key("name"),
65		params.Opt("acl", "enforce-https", "index-suffix", "public-website", "redirect-hostname"),
66	))
67}
68
69func (cmd *UpdateBucket) ManualRun(renv env.Running) (interface{}, error) {
70	start := time.Now()
71
72	if cmd.Acl != nil { // Update the canned ACL to apply to the bucket
73		input := &s3.PutBucketAclInput{
74			Bucket: cmd.Name,
75		}
76
77		if err := setFieldWithType(cmd.Acl, input, "ACL", awsstr); err != nil {
78			return nil, err
79		}
80
81		if _, err := cmd.api.PutBucketAcl(input); err != nil {
82			return nil, err
83		}
84
85		cmd.logger.ExtraVerbosef("s3.PutBucketAcl call took %s", time.Since(start))
86		return nil, nil
87	}
88
89	if cmd.PublicWebsite != nil { // Set/Unset this bucket as a public website
90		if BoolValue(cmd.PublicWebsite) {
91			input := &s3.PutBucketWebsiteInput{
92				Bucket:               cmd.Name,
93				WebsiteConfiguration: &s3.WebsiteConfiguration{},
94			}
95			if cmd.RedirectHostname != nil {
96				input.WebsiteConfiguration.RedirectAllRequestsTo = &s3.RedirectAllRequestsTo{HostName: cmd.RedirectHostname}
97				if BoolValue(cmd.EnforceHttps) {
98					input.WebsiteConfiguration.RedirectAllRequestsTo.Protocol = aws.String("https")
99				}
100			} else if cmd.IndexSuffix != nil {
101				input.WebsiteConfiguration.IndexDocument = &s3.IndexDocument{Suffix: cmd.IndexSuffix}
102			} else {
103				input.WebsiteConfiguration.IndexDocument = &s3.IndexDocument{Suffix: aws.String("index.html")}
104			}
105
106			if _, err := cmd.api.PutBucketWebsite(input); err != nil {
107				return nil, err
108			}
109		} else {
110			if _, err := cmd.api.DeleteBucketWebsite(&s3.DeleteBucketWebsiteInput{Bucket: cmd.Name}); err != nil {
111				return nil, err
112			}
113		}
114		cmd.logger.ExtraVerbosef("s3.PutBucketWebsite call took %s", time.Since(start))
115	}
116	return nil, nil
117}
118
119type DeleteBucket struct {
120	_      string `action:"delete" entity:"bucket" awsAPI:"s3" awsCall:"DeleteBucket" awsInput:"s3.DeleteBucketInput" awsOutput:"s3.DeleteBucketOutput"`
121	logger *logger.Logger
122	graph  cloud.GraphAPI
123	api    s3iface.S3API
124	Name   *string `awsName:"Bucket" awsType:"awsstr" templateName:"name"`
125}
126
127func (cmd *DeleteBucket) ParamsSpec() params.Spec {
128	return params.NewSpec(params.AllOf(params.Key("name")))
129}
130