codepipeline 0.1.0 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
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