codepipeline 0.1.0 → 0.2.0

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.
Files changed (220) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +16 -11
  3. data/.gitmodules +9 -0
  4. data/.rspec +1 -1
  5. data/CHANGELOG.md +16 -0
  6. data/Gemfile +3 -1
  7. data/Gemfile.lock +111 -0
  8. data/Guardfile +19 -0
  9. data/LICENSE.txt +18 -17
  10. data/README.md +44 -20
  11. data/Rakefile +10 -2
  12. data/codepipe.gemspec +38 -0
  13. data/docs/.gitignore +4 -0
  14. data/docs/CNAME +1 -0
  15. data/docs/Gemfile +3 -0
  16. data/docs/LICENSE +21 -0
  17. data/docs/README.md +25 -0
  18. data/docs/_config.yml +73 -0
  19. data/docs/_docs/contributing.md +99 -0
  20. data/docs/_docs/conventions.md +43 -0
  21. data/docs/_docs/deploy.md +72 -0
  22. data/docs/_docs/dsl.md +13 -0
  23. data/docs/_docs/dsl/approve.md +62 -0
  24. data/docs/_docs/dsl/pipeline.md +56 -0
  25. data/docs/_docs/dsl/pipeline/action.md +28 -0
  26. data/docs/_docs/dsl/pipeline/codebuild.md +62 -0
  27. data/docs/_docs/dsl/pipeline/prefix-and-suffix.md +57 -0
  28. data/docs/_docs/dsl/role.md +79 -0
  29. data/docs/_docs/dsl/schedule.md +29 -0
  30. data/docs/_docs/dsl/sns.md +27 -0
  31. data/docs/_docs/dsl/webhook.md +31 -0
  32. data/docs/_docs/ecs-deploy.md +24 -0
  33. data/docs/_docs/examples/different-branches.md +50 -0
  34. data/docs/_docs/install.md +14 -0
  35. data/docs/_docs/next-steps.md +16 -0
  36. data/docs/_docs/settings.md +34 -0
  37. data/docs/_docs/start.md +31 -0
  38. data/docs/_includes/commands.html +92 -0
  39. data/docs/_includes/content.html +25 -0
  40. data/docs/_includes/edit-on-github.html +9 -0
  41. data/docs/_includes/footer.html +41 -0
  42. data/docs/_includes/google_analytics.html +10 -0
  43. data/docs/_includes/head.html +45 -0
  44. data/docs/_includes/js.html +15 -0
  45. data/docs/_includes/nav.html +17 -0
  46. data/docs/_includes/prev_next.md +19 -0
  47. data/docs/_includes/reference.md +1 -0
  48. data/docs/_includes/subnav.html +46 -0
  49. data/docs/_includes/tutorials.md +38 -0
  50. data/docs/_layouts/default.html +12 -0
  51. data/docs/_reference/pipe-completion.md +44 -0
  52. data/docs/_reference/pipe-completion_script.md +25 -0
  53. data/docs/_reference/pipe-delete.md +25 -0
  54. data/docs/_reference/pipe-deploy.md +26 -0
  55. data/docs/_reference/pipe-init.md +25 -0
  56. data/docs/_reference/pipe-start.md +25 -0
  57. data/docs/_reference/pipe-version.md +21 -0
  58. data/docs/_sass/_bootstrap-overrides.scss +40 -0
  59. data/docs/_sass/_contact.scss +49 -0
  60. data/docs/_sass/_cta.scss +37 -0
  61. data/docs/_sass/_download.scss +31 -0
  62. data/docs/_sass/_features.scss +47 -0
  63. data/docs/_sass/_footer.scss +49 -0
  64. data/docs/_sass/_global.scss +102 -0
  65. data/docs/_sass/_main.scss +364 -0
  66. data/docs/_sass/_masthead.scss +70 -0
  67. data/docs/_sass/_mixins.scss +79 -0
  68. data/docs/_sass/_navbar.scss +92 -0
  69. data/docs/_sass/_syntax.scss +65 -0
  70. data/docs/_sass/_table.scss +34 -0
  71. data/docs/_sass/_timeline.scss +207 -0
  72. data/docs/_sass/_variables.scss +24 -0
  73. data/docs/bin/web +8 -0
  74. data/docs/docs.md +24 -0
  75. data/docs/dsl/pipeline.md +76 -0
  76. data/docs/dsl/role.md +66 -0
  77. data/docs/dsl/schedule.md +20 -0
  78. data/docs/img/docs/codepipeline-output.png +0 -0
  79. data/docs/img/logos/boltops-logo-full.png +0 -0
  80. data/docs/img/logos/boltops-logo.png +0 -0
  81. data/docs/img/logos/project-logo.png +0 -0
  82. data/docs/index.html +35 -0
  83. data/docs/js/nav.js +39 -0
  84. data/docs/js/new-age.js +38 -0
  85. data/docs/js/new-age.min.js +6 -0
  86. data/docs/new-age.scss +20 -0
  87. data/docs/quick-start.md +73 -0
  88. data/docs/reference.md +12 -0
  89. data/docs/support.md +22 -0
  90. data/docs/vendor/bootstrap/css/bootstrap-grid.css +1339 -0
  91. data/docs/vendor/bootstrap/css/bootstrap-grid.css.map +1 -0
  92. data/docs/vendor/bootstrap/css/bootstrap-grid.min.css +1 -0
  93. data/docs/vendor/bootstrap/css/bootstrap-grid.min.css.map +1 -0
  94. data/docs/vendor/bootstrap/css/bootstrap-reboot.css +459 -0
  95. data/docs/vendor/bootstrap/css/bootstrap-reboot.css.map +1 -0
  96. data/docs/vendor/bootstrap/css/bootstrap-reboot.min.css +1 -0
  97. data/docs/vendor/bootstrap/css/bootstrap-reboot.min.css.map +1 -0
  98. data/docs/vendor/bootstrap/css/bootstrap.css +9320 -0
  99. data/docs/vendor/bootstrap/css/bootstrap.css.map +1 -0
  100. data/docs/vendor/bootstrap/css/bootstrap.min.css +6 -0
  101. data/docs/vendor/bootstrap/css/bootstrap.min.css.map +1 -0
  102. data/docs/vendor/bootstrap/js/bootstrap.js +3535 -0
  103. data/docs/vendor/bootstrap/js/bootstrap.min.js +7 -0
  104. data/docs/vendor/font-awesome/css/font-awesome.css +2337 -0
  105. data/docs/vendor/font-awesome/css/font-awesome.min.css +4 -0
  106. data/docs/vendor/font-awesome/fonts/FontAwesome.otf +0 -0
  107. data/docs/vendor/font-awesome/fonts/fontawesome-webfont.eot +0 -0
  108. data/docs/vendor/font-awesome/fonts/fontawesome-webfont.svg +2671 -0
  109. data/docs/vendor/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
  110. data/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff +0 -0
  111. data/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
  112. data/docs/vendor/font-awesome/less/animated.less +34 -0
  113. data/docs/vendor/font-awesome/less/bordered-pulled.less +25 -0
  114. data/docs/vendor/font-awesome/less/core.less +12 -0
  115. data/docs/vendor/font-awesome/less/fixed-width.less +6 -0
  116. data/docs/vendor/font-awesome/less/font-awesome.less +18 -0
  117. data/docs/vendor/font-awesome/less/icons.less +789 -0
  118. data/docs/vendor/font-awesome/less/larger.less +13 -0
  119. data/docs/vendor/font-awesome/less/list.less +19 -0
  120. data/docs/vendor/font-awesome/less/mixins.less +60 -0
  121. data/docs/vendor/font-awesome/less/path.less +15 -0
  122. data/docs/vendor/font-awesome/less/rotated-flipped.less +20 -0
  123. data/docs/vendor/font-awesome/less/screen-reader.less +5 -0
  124. data/docs/vendor/font-awesome/less/stacked.less +20 -0
  125. data/docs/vendor/font-awesome/less/variables.less +799 -0
  126. data/docs/vendor/font-awesome/scss/_animated.scss +34 -0
  127. data/docs/vendor/font-awesome/scss/_bordered-pulled.scss +25 -0
  128. data/docs/vendor/font-awesome/scss/_core.scss +12 -0
  129. data/docs/vendor/font-awesome/scss/_fixed-width.scss +6 -0
  130. data/docs/vendor/font-awesome/scss/_icons.scss +789 -0
  131. data/docs/vendor/font-awesome/scss/_larger.scss +13 -0
  132. data/docs/vendor/font-awesome/scss/_list.scss +19 -0
  133. data/docs/vendor/font-awesome/scss/_mixins.scss +60 -0
  134. data/docs/vendor/font-awesome/scss/_path.scss +15 -0
  135. data/docs/vendor/font-awesome/scss/_rotated-flipped.scss +20 -0
  136. data/docs/vendor/font-awesome/scss/_screen-reader.scss +5 -0
  137. data/docs/vendor/font-awesome/scss/_stacked.scss +20 -0
  138. data/docs/vendor/font-awesome/scss/_variables.scss +799 -0
  139. data/docs/vendor/font-awesome/scss/font-awesome.scss +18 -0
  140. data/docs/vendor/jquery-easing/jquery.easing.compatibility.js +59 -0
  141. data/docs/vendor/jquery-easing/jquery.easing.js +166 -0
  142. data/docs/vendor/jquery-easing/jquery.easing.min.js +1 -0
  143. data/docs/vendor/jquery/jquery.js +10253 -0
  144. data/docs/vendor/jquery/jquery.min.js +4 -0
  145. data/docs/vendor/simple-line-icons/css/simple-line-icons.css +778 -0
  146. data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot +0 -0
  147. data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.svg +200 -0
  148. data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf +0 -0
  149. data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff +0 -0
  150. data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2 +0 -0
  151. data/docs/vendor/simple-line-icons/less/simple-line-icons.less +982 -0
  152. data/docs/vendor/simple-line-icons/scss/simple-line-icons.scss +979 -0
  153. data/docs/vendor/tether/tether.js +1811 -0
  154. data/docs/vendor/tether/tether.min.js +1 -0
  155. data/exe/codepipeline +14 -0
  156. data/exe/pipe +14 -0
  157. data/lib/codepipe.rb +23 -0
  158. data/lib/codepipe/autoloader.rb +21 -0
  159. data/lib/codepipe/aws_services.rb +20 -0
  160. data/lib/codepipe/aws_services/helpers.rb +71 -0
  161. data/lib/codepipe/build.rb +13 -0
  162. data/lib/codepipe/cli.rb +60 -0
  163. data/lib/codepipe/command.rb +82 -0
  164. data/lib/codepipe/completer.rb +159 -0
  165. data/lib/codepipe/completer/script.rb +6 -0
  166. data/lib/codepipe/completer/script.sh +10 -0
  167. data/lib/codepipe/core.rb +63 -0
  168. data/lib/codepipe/create.rb +12 -0
  169. data/lib/codepipe/delete.rb +27 -0
  170. data/lib/codepipe/deploy.rb +40 -0
  171. data/lib/codepipe/dsl/pipeline.rb +37 -0
  172. data/lib/codepipe/dsl/pipeline/approve.rb +34 -0
  173. data/lib/codepipe/dsl/pipeline/codebuild.rb +57 -0
  174. data/lib/codepipe/dsl/pipeline/github.rb +36 -0
  175. data/lib/codepipe/dsl/role.rb +50 -0
  176. data/lib/codepipe/dsl/schedule.rb +30 -0
  177. data/lib/codepipe/dsl/sns.rb +15 -0
  178. data/lib/codepipe/dsl/ssm.rb +22 -0
  179. data/lib/codepipe/dsl/webhook.rb +27 -0
  180. data/lib/codepipe/evaluate.rb +47 -0
  181. data/lib/codepipe/help.rb +9 -0
  182. data/lib/codepipe/help/completion.md +22 -0
  183. data/lib/codepipe/help/completion_script.md +3 -0
  184. data/lib/codepipe/help/hello.md +5 -0
  185. data/lib/codepipe/init.rb +57 -0
  186. data/lib/codepipe/pipeline.rb +61 -0
  187. data/lib/codepipe/pipeline/s3_bucket.rb +88 -0
  188. data/lib/codepipe/role.rb +181 -0
  189. data/lib/codepipe/schedule.rb +99 -0
  190. data/lib/codepipe/sequence.rb +66 -0
  191. data/lib/codepipe/setting.rb +79 -0
  192. data/lib/codepipe/sns.rb +43 -0
  193. data/lib/codepipe/stack.rb +95 -0
  194. data/lib/codepipe/start.rb +83 -0
  195. data/lib/codepipe/update.rb +12 -0
  196. data/lib/codepipe/version.rb +3 -0
  197. data/lib/codepipe/webhook.rb +60 -0
  198. data/lib/codepipeline.rb +1 -6
  199. data/lib/template/.codepipeline/pipeline.rb.tt +33 -0
  200. data/lib/template/.codepipeline/schedule.rb +3 -0
  201. data/lib/template/.codepipeline/settings.yml +9 -0
  202. data/lib/template/.codepipeline/sns.rb +14 -0
  203. data/spec/fixtures/app/.codepipeline/pipeline.rb +12 -0
  204. data/spec/fixtures/app/.codepipeline/schedule.rb +1 -0
  205. data/spec/fixtures/app/.codepipeline/webhook.rb +1 -0
  206. data/spec/fixtures/pipelines/approve.rb +22 -0
  207. data/spec/fixtures/pipelines/approve_existing_sns.rb +24 -0
  208. data/spec/lib/cli_spec.rb +18 -0
  209. data/spec/lib/pipeline/approve_spec.rb +32 -0
  210. data/spec/lib/pipeline_spec.rb +12 -0
  211. data/spec/lib/role_spec.rb +12 -0
  212. data/spec/lib/schedule_spec.rb +12 -0
  213. data/spec/lib/webhook_spec.rb +12 -0
  214. data/spec/spec_helper.rb +35 -0
  215. metadata +419 -22
  216. data/.travis.yml +0 -7
  217. data/bin/console +0 -14
  218. data/bin/setup +0 -8
  219. data/codepipeline.gemspec +0 -27
  220. data/lib/codepipeline/version.rb +0 -3
@@ -0,0 +1,27 @@
1
+ module Codepipe::Dsl
2
+ module Webhook
3
+ include Ssm
4
+
5
+ # https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-codepipeline-webhook.html
6
+ PROPERTIES = %w[
7
+ authentication
8
+ authentication_configuration
9
+ filters
10
+ name
11
+ register_with_third_party
12
+ target_action
13
+ target_pipeline
14
+ target_pipeline_version
15
+ ]
16
+ PROPERTIES.each do |prop|
17
+ define_method(prop) do |v|
18
+ @properties[prop.to_sym] = v
19
+ end
20
+ end
21
+
22
+ def secret_token(v)
23
+ @secret_token = v
24
+ end
25
+ alias_method :github_token, :secret_token
26
+ end
27
+ end
@@ -0,0 +1,47 @@
1
+ module Codepipe
2
+ module Evaluate
3
+ def evaluate(path)
4
+ source_code = IO.read(path)
5
+ begin
6
+ instance_eval(source_code, path)
7
+ rescue Exception => e
8
+ if e.class == SystemExit # allow exit to happen normally
9
+ raise
10
+ else
11
+ task_definition_error(e)
12
+ puts "\nFull error:"
13
+ raise
14
+ end
15
+ end
16
+ end
17
+
18
+ private
19
+ # Prints out a user friendly task_definition error message
20
+ def task_definition_error(e)
21
+ error_info = e.backtrace.first
22
+ path, line_no, _ = error_info.split(':')
23
+ line_no = line_no.to_i
24
+ puts "Error evaluating #{path}:".color(:red)
25
+ puts e.message
26
+ puts "Here's the line in #{path} with the error:\n\n"
27
+
28
+ contents = IO.read(path)
29
+ content_lines = contents.split("\n")
30
+ context = 5 # lines of context
31
+ top, bottom = [line_no-context-1, 0].max, line_no+context-1
32
+ spacing = content_lines.size.to_s.size
33
+ content_lines[top..bottom].each_with_index do |line_content, index|
34
+ line_number = top+index+1
35
+ if line_number == line_no
36
+ printf("%#{spacing}d %s\n".color(:red), line_number, line_content)
37
+ else
38
+ printf("%#{spacing}d %s\n", line_number, line_content)
39
+ end
40
+ end
41
+ end
42
+
43
+ def lookup_codepipeline_file(name)
44
+ [".codepipeline", @options[:type], name].compact.join("/")
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,9 @@
1
+ module Codepipe::Help
2
+ class << self
3
+ def text(namespaced_command)
4
+ path = namespaced_command.to_s.gsub(':','/')
5
+ path = File.expand_path("../help/#{path}.md", __FILE__)
6
+ IO.read(path) if File.exist?(path)
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,22 @@
1
+ Example:
2
+
3
+ codepipe completion
4
+
5
+ Prints words for TAB auto-completion.
6
+
7
+ Examples:
8
+
9
+ codepipe completion
10
+ codepipe completion hello
11
+ codepipe completion hello name
12
+
13
+ To enable, TAB auto-completion add the following to your profile:
14
+
15
+ eval $(codepipe completion_script)
16
+
17
+ Auto-completion example usage:
18
+
19
+ codepipe [TAB]
20
+ codepipe hello [TAB]
21
+ codepipe hello name [TAB]
22
+ codepipe hello name --[TAB]
@@ -0,0 +1,3 @@
1
+ To use, add the following to your `~/.bashrc` or `~/.profile`
2
+
3
+ eval $(codepipe completion_script)
@@ -0,0 +1,5 @@
1
+ Examples:
2
+
3
+ codepipe hello
4
+ codepipe hello NAME
5
+ codepipe hello NAME --from me
@@ -0,0 +1,57 @@
1
+ module Codepipe
2
+ class Init < Sequence
3
+ # Ugly, this is how I can get the options from to match with this Thor::Group
4
+ def self.cli_options
5
+ [
6
+ [:name, desc: "CodePipeline project name."],
7
+ [:force, type: :boolean, desc: "Bypass overwrite are you sure prompt for existing files."],
8
+ [:template, desc: "Custom template to use."],
9
+ [:template_mode, desc: "Template mode: replace or additive."],
10
+ ]
11
+ end
12
+ cli_options.each { |o| class_option(*o) }
13
+
14
+ def setup_template_repo
15
+ return unless @options[:template]&.include?('/')
16
+
17
+ sync_template_repo
18
+ end
19
+
20
+ def set_source_path
21
+ return unless @options[:template]
22
+
23
+ custom_template = "#{ENV['HOME']}/.codepipeline/templates/#{full_repo_name}"
24
+
25
+ if @options[:template_mode] == "replace" # replace the template entirely
26
+ override_source_paths(custom_template)
27
+ else # additive: modify on top of default template
28
+ default_template = File.expand_path("../../template", __FILE__)
29
+ override_source_paths([custom_template, default_template])
30
+ end
31
+ end
32
+
33
+ def copy_project
34
+ puts "Initialize codepipeline project in .codepipeline"
35
+ if @options[:template]
36
+ directory ".", ".codepipeline", exclude_pattern: /.git/
37
+ else
38
+ directory ".", exclude_pattern: /.git/
39
+ end
40
+ end
41
+
42
+ private
43
+ def project_name
44
+ inferred_name = File.basename(Dir.pwd).gsub('_','-').gsub(/[^0-9a-zA-Z,-]/, '')
45
+ @options[:name] || inferred_name
46
+ end
47
+
48
+ def project_github_repo
49
+ default = "user/repo"
50
+ return default unless File.exist?(".git/config") && git_installed?
51
+
52
+ url = `git config --get remote.origin.url`.strip
53
+ repo = url.sub('git@github.com:','').sub(/\.git$/,'')
54
+ repo == '' ? default : repo
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,61 @@
1
+ module Codepipe
2
+ class Pipeline
3
+ extend Memoist
4
+ include Dsl::Pipeline
5
+ include Evaluate
6
+
7
+ def initialize(options={})
8
+ @options = options
9
+ @pipeline_path = options[:pipeline_path] || get_pipeline_path
10
+ @properties = default_properties # defaults make pipeline.rb simpler
11
+ @stages = []
12
+ end
13
+
14
+ def run
15
+ evaluate(@pipeline_path)
16
+ @properties[:stages] ||= @stages
17
+ set_source_branch!
18
+
19
+ resource = {
20
+ pipeline: {
21
+ type: "AWS::CodePipeline::Pipeline",
22
+ properties: @properties
23
+ }
24
+ }
25
+ CfnCamelizer.transform(resource)
26
+ end
27
+
28
+ def default_properties
29
+ {
30
+ name: @options[:full_pipeline_name],
31
+ role_arn: { "Fn::GetAtt": "IamRole.Arn" },
32
+ artifact_store: {
33
+ type: "S3",
34
+ location: s3_bucket, # auto creates s3 bucket
35
+ }
36
+ }
37
+ end
38
+
39
+ # cli branch option always takes highest precedence
40
+ def set_source_branch!
41
+ return unless @options[:branch]
42
+
43
+ source_stage = @properties[:stages].first
44
+ action = source_stage[:actions].first
45
+ action[:configuration][:branch] = @options[:branch]
46
+ end
47
+
48
+ def exist?
49
+ File.exist?(@pipeline_path)
50
+ end
51
+
52
+ def s3_bucket
53
+ S3Bucket.name
54
+ end
55
+
56
+ private
57
+ def get_pipeline_path
58
+ lookup_codepipeline_file "pipeline.rb"
59
+ end
60
+ end
61
+ end
@@ -0,0 +1,88 @@
1
+ require "aws-sdk-s3"
2
+
3
+ class Codepipe::Pipeline
4
+ class S3Bucket
5
+ extend Memoist
6
+ include Codepipe::AwsServices
7
+
8
+ class << self
9
+ extend Memoist
10
+ def name
11
+ new.name
12
+ end
13
+ memoize :name
14
+ end
15
+
16
+ def name
17
+ ensure_exists(bucket_name)
18
+ bucket_name
19
+ end
20
+ memoize :name
21
+
22
+ def bucket_name
23
+ "codepipeline-#{aws.region}-#{aws.account}"
24
+ end
25
+
26
+ def ensure_exists(name)
27
+ return if exists?(name) || ENV['TEST']
28
+ s3.create_bucket(bucket: name)
29
+ policy = {
30
+ "Version": "2012-10-17",
31
+ "Id": "SSEAndSSLPolicy",
32
+ "Statement": [
33
+ {
34
+ "Sid": "DenyUnEncryptedObjectUploads",
35
+ "Effect": "Deny",
36
+ "Principal": "*",
37
+ "Action": "s3:PutObject",
38
+ "Resource": "arn:aws:s3:::#{name}/*",
39
+ "Condition": {
40
+ "StringNotEquals": {
41
+ "s3:x-amz-server-side-encryption": "aws:kms"
42
+ }
43
+ }
44
+ },
45
+ {
46
+ "Sid": "DenyInsecureConnections",
47
+ "Effect": "Deny",
48
+ "Principal": "*",
49
+ "Action": "s3:*",
50
+ "Resource": "arn:aws:s3:::#{name}/*",
51
+ "Condition": {
52
+ "Bool": {
53
+ "aws:SecureTransport": "false"
54
+ }
55
+ }
56
+ }
57
+ ]
58
+ }
59
+ s3.put_bucket_policy(
60
+ bucket: name,
61
+ policy: JSON.dump(policy),
62
+ )
63
+ rescue Aws::S3::Errors::BucketAlreadyExists => e
64
+ puts "ERROR #{e.class}: #{e.message}".color(:red)
65
+ puts "Bucket name: #{name}"
66
+ exit 1
67
+ end
68
+
69
+ def exists?(name)
70
+ begin
71
+ s3.head_bucket(bucket: name)
72
+ true
73
+ rescue Aws::S3::Errors::BucketAlreadyOwnedByYou, Aws::S3::Errors::Http301Error
74
+ # These exceptions indicate bucket already exists
75
+ # Aws::S3::Errors::Http301Error could be inaccurate but compromising for simplicity
76
+ true
77
+ rescue
78
+ false
79
+ end
80
+ end
81
+
82
+ private
83
+ def aws
84
+ AwsData.new
85
+ end
86
+ memoize :aws
87
+ end
88
+ end
@@ -0,0 +1,181 @@
1
+ require "yaml"
2
+
3
+ module Codepipe
4
+ class Role
5
+ include Codepipe::Dsl::Role
6
+ include Evaluate
7
+
8
+ def initialize(options={})
9
+ @options = options
10
+ @role_path = options[:role_path] || get_role_path
11
+ @properties = default_properties
12
+ end
13
+
14
+ def run
15
+ evaluate(@role_path) if File.exist?(@role_path)
16
+ @properties[:policies] = [{
17
+ policy_name: "CodePipelineAccess",
18
+ policy_document: {
19
+ version: "2012-10-17",
20
+ statement: derived_iam_statements
21
+ }
22
+ }]
23
+
24
+ @properties[:managed_policy_arns] = @managed_policy_arns if @managed_policy_arns && !@managed_policy_arns.empty?
25
+
26
+ resource = {
27
+ logical_id => {
28
+ type: "AWS::IAM::Role",
29
+ properties: @properties
30
+ }
31
+ }
32
+ CfnCamelizer.transform(resource)
33
+ end
34
+
35
+ def logical_id
36
+ "IamRole"
37
+ end
38
+
39
+ private
40
+ def get_role_path
41
+ lookup_codepipeline_file("role.rb")
42
+ end
43
+
44
+ def default_properties
45
+ {
46
+ assume_role_policy_document: {
47
+ statement: [{
48
+ action: ["sts:AssumeRole"],
49
+ effect: "Allow",
50
+ principal: {
51
+ service: principal_services
52
+ }
53
+ }],
54
+ version: "2012-10-17"
55
+ },
56
+ path: "/"
57
+ }
58
+ end
59
+
60
+ def principal_services
61
+ ["codepipeline.amazonaws.com"]
62
+ end
63
+
64
+ def derived_iam_statements
65
+ @iam_statements || default_iam_statements
66
+ end
67
+
68
+ def default_iam_statements
69
+ # Based on the one created by CodePipeline Console
70
+ [{
71
+ "action"=>["iam:PassRole"],
72
+ "resource"=>"*",
73
+ "effect"=>"Allow",
74
+ "condition"=>
75
+ {"string_equals_if_exists"=>
76
+ {"iam:passed_to_service"=>
77
+ ["cloudformation.amazonaws.com",
78
+ "elasticbeanstalk.amazonaws.com",
79
+ "ec2.amazonaws.com",
80
+ "ecs-tasks.amazonaws.com"]
81
+ }
82
+ }
83
+ },{
84
+ "action"=>
85
+ ["codecommit:CancelUploadArchive",
86
+ "codecommit:GetBranch",
87
+ "codecommit:GetCommit",
88
+ "codecommit:GetUploadArchiveStatus",
89
+ "codecommit:UploadArchive"],
90
+ "resource"=>"*",
91
+ "effect"=>"Allow"
92
+ },{
93
+ "action"=>
94
+ ["codedeploy:CreateDeployment",
95
+ "codedeploy:GetApplication",
96
+ "codedeploy:GetApplicationRevision",
97
+ "codedeploy:GetDeployment",
98
+ "codedeploy:GetDeploymentConfig",
99
+ "codedeploy:RegisterApplicationRevision"],
100
+ "resource"=>"*",
101
+ "effect"=>"Allow"
102
+ },{
103
+ "action"=>
104
+ ["elasticbeanstalk:*",
105
+ "ec2:*",
106
+ "elasticloadbalancing:*",
107
+ "autoscaling:*",
108
+ "cloudwatch:*",
109
+ "s3:*",
110
+ "sns:*",
111
+ "cloudformation:*",
112
+ "rds:*",
113
+ "sqs:*",
114
+ "ecs:*"],
115
+ "resource"=>"*",
116
+ "effect"=>"Allow"
117
+ },{
118
+ "action"=>["lambda:InvokeFunction", "lambda:ListFunctions"],
119
+ "resource"=>"*",
120
+ "effect"=>"Allow"
121
+ },{
122
+ "action"=>
123
+ ["opsworks:CreateDeployment",
124
+ "opsworks:DescribeApps",
125
+ "opsworks:DescribeCommands",
126
+ "opsworks:DescribeDeployments",
127
+ "opsworks:DescribeInstances",
128
+ "opsworks:DescribeStacks",
129
+ "opsworks:UpdateApp",
130
+ "opsworks:UpdateStack"],
131
+ "resource"=>"*",
132
+ "effect"=>"Allow"
133
+ },{
134
+ "action"=>
135
+ ["cloudformation:CreateStack",
136
+ "cloudformation:DeleteStack",
137
+ "cloudformation:DescribeStacks",
138
+ "cloudformation:UpdateStack",
139
+ "cloudformation:CreateChangeSet",
140
+ "cloudformation:DeleteChangeSet",
141
+ "cloudformation:DescribeChangeSet",
142
+ "cloudformation:ExecuteChangeSet",
143
+ "cloudformation:SetStackPolicy",
144
+ "cloudformation:ValidateTemplate"],
145
+ "resource"=>"*",
146
+ "effect"=>"Allow"
147
+ },{
148
+ "action"=>["codebuild:BatchGetBuilds", "codebuild:StartBuild"],
149
+ "resource"=>"*",
150
+ "effect"=>"Allow"
151
+ },{
152
+ "action"=>
153
+ ["devicefarm:ListProjects",
154
+ "devicefarm:ListDevicePools",
155
+ "devicefarm:GetRun",
156
+ "devicefarm:GetUpload",
157
+ "devicefarm:CreateUpload",
158
+ "devicefarm:ScheduleRun"],
159
+ "resource"=>"*",
160
+ "effect"=>"Allow",
161
+ },{
162
+ "action"=>
163
+ ["servicecatalog:ListProvisioningArtifacts",
164
+ "servicecatalog:CreateProvisioningArtifact",
165
+ "servicecatalog:DescribeProvisioningArtifact",
166
+ "servicecatalog:DeleteProvisioningArtifact",
167
+ "servicecatalog:UpdateProduct"],
168
+ "resource"=>"*",
169
+ "effect"=>"Allow",
170
+ },{
171
+ "action"=>["cloudformation:ValidateTemplate"],
172
+ "resource"=>"*",
173
+ "effect"=>"Allow",
174
+ },{
175
+ "action"=>["ecr:DescribeImages"],
176
+ "resource"=>"*",
177
+ "effect"=>"Allow",
178
+ }]
179
+ end
180
+ end
181
+ end