renuo-cli 0.0.12 → 0.0.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 27278c4ab97231d81b003ac7d91333dbd83fffa8
4
- data.tar.gz: 520f7e82b52a3f55731ed9cfa7aafac53ccd2a50
2
+ SHA256:
3
+ metadata.gz: adca29c33ee3aac89d50a5caf15553d14e4ae8e5bc42c141077d4ee6871218e8
4
+ data.tar.gz: 6ab51df5e5254b1d3662bb1623fdfe2bf57a4dde522559c7a91397e904ab9782
5
5
  SHA512:
6
- metadata.gz: 2041015650a4337d286a78e9a2d2fec528ecff9c60f9e73c78101ae038f5e65dc2df8d36cd4c2da9ce7054e6f7e7c6167a3a6e749ae18d4e11baf14b7c5e116a
7
- data.tar.gz: 8f339ba792311283bbdb68e3a0d72936127a352f77794bd07a1481fcbfc3e283208cfa776c6dc11416b78bdd38ee6c58e186f72e7179ce31f6ace3ae00149335
6
+ metadata.gz: b7ad94fe437809b62be431f1862c7f6d02baa55a85deeca1f855e9ce378c4c17461c7cfc91514d283a3f2417c9167a37d44f404bc32e40c00c5a5e3ecc68118f
7
+ data.tar.gz: 6b6b7c62cdeba54b28abff6e57e30a3ee26299c7becea5ca05784f8220f7d78fbaebdadcb25cdefca76d2b9c422854da439ec3a1293420e0fd3218efcb6952b9
@@ -85,19 +85,24 @@ module Renuo
85
85
 
86
86
  command 'create-aws-project' do |c|
87
87
  c.syntax = 'renuo create-aws-project'
88
- c.summary = 'Generates necessary commands for our project setup on AWS.'
88
+ c.summary = 'Generates necessary commands for our project setup on AWS incl. necessary installations.'
89
89
  c.description = <<-DESCRIPTION
90
- This creates commands for creating AWS users, buckets an versioning policies.
90
+ This creates commands for creating AWS users, buckets an versioning policies and CloudFront.
91
+ It also guides you to set up the necessary environment.
91
92
 
92
93
  You will be asked for:
94
+ (- installation of aws-cli, if not yet done)
95
+ (- setting up aws user `renuo-app-setup`, if not yet done)
93
96
  - project name and suffix so that the script can respect our naming conventions
94
97
  - the Redmine project name to tag buckets for AWS billing references
98
+ - whether you want to setup CloudFront to deliver assets via S3
95
99
 
96
100
  The generated commands do the following:
97
101
  - create an IAM user for each environment (master, develop, testing) and add it to the renuo apps group.
98
102
  - create S3 buckets for each user who owns it
99
103
  - tag the buckets
100
104
  - enable versioning for master buckets
105
+ (- set up a CloudFront distribution for each environment with the default config or plus alias if configured)
101
106
  DESCRIPTION
102
107
  c.example 'Setup a project (you will be asked for details)', 'renuo create-aws-project'
103
108
  c.action do |_args, _options|
@@ -1,46 +1,109 @@
1
+ require 'renuo/cli/app/services/cloudfront_config_service'
2
+
1
3
  class CreateAwsProject
2
4
  def initialize
3
- unless agree('Did you set up AWSCLI and the IAM profile (renuo-app-setup) yet?')
4
- abort('You can find setup instructions here: https://redmine.renuo.ch/projects/internal/wiki/Amazon_S3#Setup-AWS-CLI')
5
+ ensure_aws_setup?
6
+ ensure_aws_profile_existing?
7
+ collect_project_information
8
+ end
9
+
10
+ def run
11
+ %w[master develop testing].each do |branch|
12
+ print_setup_commands branch
5
13
  end
14
+ end
15
+
16
+ private
6
17
 
18
+ def collect_project_information
19
+ say 'We need now some informations to create your s3-bucket:'.colorize :green
20
+ collect_general_information
21
+ collect_s3_information
22
+ collect_cloudfront_information
23
+ end
24
+
25
+ def collect_general_information
7
26
  @project_name = ask('Project name (eg: renuo-cli): ') { |q| q.validate = /.+/ }
27
+ end
28
+
29
+ def collect_s3_information
8
30
  @project_purpose = ask('Suffix describing purpose (eg: assets): ') { |q| q.default = 'none' }
9
31
  @project_purpose = nil if @project_purpose.empty? || @project_purpose == 'none'
10
- @redmine_project = ask('Redmine project name for billing (eg: internal): ') { |q| q.validate = /.+/ }
32
+ @redmine_project = ask('Redmine project name for billing (eg: internal): ') do |q|
33
+ q.default = @project_name
34
+ q.validate = /.+/
35
+ end
11
36
  @aws_profile = 'renuo-app-setup'
12
37
  @aws_region = ask('AWS bucket region: ') { |q| q.default = 'eu-central-1' }
13
38
  @aws_app_group = 'renuo-apps-v2'
14
39
  end
15
40
 
16
- def run
17
- say "\n# master:\n"
18
- print_common_setup 'master'
19
- print_versioning_setup 'master'
41
+ def collect_cloudfront_information
42
+ @setup_cloudfront = agree('Would you like to setup also AWS CloudFront? '\
43
+ '(Default: yes, if you want to deliver assets/images from S3)')
44
+ return unless @setup_cloudfront
45
+ @cloudfront_alias = {}
46
+ return unless agree('Would you like to use an alias to call your assets/images on S3? (Default: no)')
47
+
48
+ %i[master develop testing].each do |branch|
49
+ cloudfront_alias_for branch
50
+ end
51
+ end
20
52
 
21
- say "\n# develop:\n"
22
- print_common_setup 'develop'
53
+ def cloudfront_alias_for(branch)
54
+ @cloudfront_alias[branch] = ask("What CF-Alias do you want to use for #{branch}?") { |q| q.validate = /.+/ }
55
+ end
23
56
 
24
- say "\n# testing:\n"
25
- print_common_setup 'testing'
57
+ def ensure_aws_setup?
58
+ ensure_is_setup?('aws --version > /dev/null',
59
+ 'brew install awscli',
60
+ 'Would you like to install aws-cli via `brew install awscli`?')
26
61
  end
27
62
 
28
- private
63
+ def ensure_aws_profile_existing?
64
+ ensure_is_setup?('aws configure --profile renuo-app-setup list > /dev/null',
65
+ 'aws configure --profile renuo-app-setup',
66
+ 'Would you like set up a profile for AWS '\
67
+ '`aws configure --profile renuo-app-setup`? (User/Password in keystore)')
68
+ end
29
69
 
30
- def print_common_setup(branch)
31
- say common_setup(@aws_profile, @aws_region, aws_user(branch), @aws_app_group)
32
- say tag_setup(@aws_profile, aws_user(branch), @redmine_project)
70
+ def ensure_is_setup?(installation_check_command, installation_command, agree_text)
71
+ (system(installation_command) if agree(agree_text)) until system(installation_check_command)
33
72
  end
34
73
 
35
- def print_versioning_setup(branch)
36
- say versioning_setup(@aws_profile, aws_user(branch))
74
+ def print_setup_commands(branch)
75
+ say "\n# AWS #{branch} \n".colorize :green
76
+ # wrap_at inserts newlines, after that, the command is no longer copyable
77
+ # rubocop:disable Style/GlobalVars
78
+ $terminal.wrap_at = nil
79
+ say aws_iam_setup(@aws_profile, @aws_region, aws_user(branch), @aws_app_group)
80
+ say tag_setup(aws_user(branch), @redmine_project)
81
+ say versioning_setup(@aws_profile, aws_user('master')) if branch == 'master'
82
+ cloudfront_setup(branch)
83
+ $terminal.wrap_at = :auto
84
+ # rubocop:enable Style/GlobalVars
85
+ end
86
+
87
+ def cloudfront_setup(branch)
88
+ return unless @setup_cloudfront
89
+ say setup_cloudfront(@aws_profile, branch)
90
+ if @cloudfront_alias[branch.to_sym]
91
+ say "\nWarning: Don't forget to set up `#{cloudfront_alias(branch)}` on the DNS if not yet done".colorize :yellow
92
+ else
93
+ say "\nHint: The domain name for your S3 files, can be found after running the" \
94
+ ' commands on https://console.aws.amazon.com/cloudfront/home'.colorize :yellow
95
+ end
37
96
  end
38
97
 
39
98
  def aws_user(branch)
40
99
  [@project_name, branch, @project_purpose].compact.join('-')
41
100
  end
42
101
 
43
- def common_setup(profile, region, user, app_group)
102
+ def cloudfront_alias(branch)
103
+ @cloudfront_alias[branch.to_sym]
104
+ end
105
+
106
+ def aws_iam_setup(profile, region, user, app_group)
44
107
  <<-SETUP_COMMANDS
45
108
  aws --profile #{profile} iam create-user --user-name #{user}
46
109
  aws --profile #{profile} iam add-user-to-group --user-name #{user} --group-name #{app_group}
@@ -49,15 +112,26 @@ class CreateAwsProject
49
112
  SETUP_COMMANDS
50
113
  end
51
114
 
115
+ def setup_cloudfront(profile, branch)
116
+ <<-SETUP_COMMANDS
117
+ aws cloudfront create-distribution --profile #{profile} --cli-input-json '#{cloudfront_config_string(aws_user(branch), branch)}'
118
+ SETUP_COMMANDS
119
+ end
120
+
52
121
  def versioning_setup(profile, bucket)
53
122
  <<-VERSIONING_COMMANDS
54
123
  aws --profile #{profile} s3api put-bucket-versioning --bucket #{bucket} --versioning-configuration Status=Enabled
55
124
  VERSIONING_COMMANDS
56
125
  end
57
126
 
58
- def tag_setup(profile, bucket, redmine_project)
127
+ def tag_setup(bucket, redmine_project)
128
+ tag_set = "[{Key=redmine_project,Value=#{redmine_project}}]"
59
129
  <<-TAGGING_COMMANDS
60
- aws --profile #{profile} s3api put-bucket-tagging --bucket #{bucket} --tagging "TagSet=[{Key=redmine_project,Value=#{redmine_project}}]"
130
+ aws --profile #{@aws_profile} s3api put-bucket-tagging --bucket #{bucket} --tagging "TagSet=#{tag_set}"
61
131
  TAGGING_COMMANDS
62
132
  end
133
+
134
+ def cloudfront_config_string(bucket, branch)
135
+ CloudfrontConfigService.new(bucket, cloudfront_alias(branch)).to_s
136
+ end
63
137
  end
@@ -0,0 +1,121 @@
1
+ class CloudfrontConfigService
2
+ def initialize(bucket, bucket_alias)
3
+ @bucket = bucket
4
+ @bucket_alias = bucket_alias
5
+ end
6
+
7
+ def to_s
8
+ bucket_config.to_json.strip
9
+ end
10
+
11
+ private
12
+
13
+ # rubocop:disable Metrics/MethodLength
14
+ def bucket_config
15
+ {
16
+ "DistributionConfig": {
17
+ "CallerReference": unique_caller_reference,
18
+ "Aliases": bucket_aliases,
19
+ "Origins": {
20
+ "Quantity": 1,
21
+ "Items": [
22
+ {
23
+ "Id": "S3-#{@bucket}",
24
+ "DomainName": "#{@bucket}.s3.amazonaws.com",
25
+ "OriginPath": '',
26
+ "CustomHeaders": {
27
+ "Quantity": 0
28
+ },
29
+ "S3OriginConfig": {
30
+ "OriginAccessIdentity": ''
31
+ }
32
+ }
33
+ ]
34
+ },
35
+ "DefaultCacheBehavior": {
36
+ "TargetOriginId": "S3-#{@bucket}",
37
+ "ForwardedValues": {
38
+ "QueryString": false,
39
+ "Cookies": {
40
+ "Forward": 'none'
41
+ },
42
+ "Headers": {
43
+ "Quantity": 0
44
+ },
45
+ "QueryStringCacheKeys": {
46
+ "Quantity": 0
47
+ }
48
+ },
49
+ "TrustedSigners": {
50
+ "Enabled": false,
51
+ "Quantity": 0
52
+ },
53
+ "ViewerProtocolPolicy": 'redirect-to-https',
54
+ "MinTTL": 0,
55
+ "AllowedMethods": {
56
+ "Quantity": 2,
57
+ "Items": %w[
58
+ HEAD
59
+ GET
60
+ ],
61
+ "CachedMethods": {
62
+ "Quantity": 2,
63
+ "Items": %w[
64
+ HEAD
65
+ GET
66
+ ]
67
+ }
68
+ },
69
+ "SmoothStreaming": false,
70
+ "DefaultTTL": 86_400,
71
+ "MaxTTL": 31_536_000,
72
+ "Compress": true,
73
+ "LambdaFunctionAssociations": {
74
+ "Quantity": 0
75
+ }
76
+ },
77
+ "CacheBehaviors": {
78
+ "Quantity": 0
79
+ },
80
+ "CustomErrorResponses": {
81
+ "Quantity": 0
82
+ },
83
+ "Comment": '',
84
+ "Logging": {
85
+ "Enabled": false,
86
+ "IncludeCookies": false,
87
+ "Bucket": '',
88
+ "Prefix": ''
89
+ },
90
+ "PriceClass": 'PriceClass_100',
91
+ "Enabled": true,
92
+ "ViewerCertificate": {
93
+ "CloudFrontDefaultCertificate": true,
94
+ "MinimumProtocolVersion": 'TLSv1.2_2018',
95
+ "CertificateSource": 'cloudfront'
96
+ },
97
+ "Restrictions": {
98
+ "GeoRestriction": {
99
+ "RestrictionType": 'none',
100
+ "Quantity": 0
101
+ }
102
+ },
103
+ "WebACLId": '',
104
+ "HttpVersion": 'http2',
105
+ "IsIPV6Enabled": true
106
+ }
107
+ }
108
+ end
109
+ # rubocop:enable Metrics/MethodLength
110
+
111
+ def unique_caller_reference
112
+ "#{Time.now.getutc.to_i}-#{@bucket}"
113
+ end
114
+
115
+ def bucket_aliases
116
+ {
117
+ "Quantity": @bucket_alias ? 1 : 0,
118
+ "Items": @bucket_alias ? [@bucket_alias] : []
119
+ }
120
+ end
121
+ end
@@ -1,5 +1,5 @@
1
1
  module Renuo
2
2
  module Cli
3
- VERSION = '0.0.12'.freeze
3
+ VERSION = '0.0.13'.freeze
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: renuo-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.12
4
+ version: 0.0.13
5
5
  platform: ruby
6
6
  authors:
7
7
  - Lukas Elmer
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2018-01-05 00:00:00.000000000 Z
11
+ date: 2018-02-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: colorize
@@ -230,6 +230,7 @@ files:
230
230
  - lib/renuo/cli/app/local_storage.rb
231
231
  - lib/renuo/cli/app/name_display.rb
232
232
  - lib/renuo/cli/app/release_project.rb
233
+ - lib/renuo/cli/app/services/cloudfront_config_service.rb
233
234
  - lib/renuo/cli/app/services/markdown_parser_service.rb
234
235
  - lib/renuo/cli/app/upgrade_laptop.rb
235
236
  - lib/renuo/cli/app/upgrade_laptop/run_command.rb
@@ -257,7 +258,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
257
258
  version: '0'
258
259
  requirements: []
259
260
  rubyforge_project:
260
- rubygems_version: 2.6.12
261
+ rubygems_version: 2.7.5
261
262
  signing_key:
262
263
  specification_version: 4
263
264
  summary: The Renuo CLI automates some commonly used workflows by providing a command