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,6 @@
1
+ class Codepipe::Completer::Script
2
+ def self.generate
3
+ bash_script = File.expand_path("script.sh", File.dirname(__FILE__))
4
+ puts "source #{bash_script}"
5
+ end
6
+ end
@@ -0,0 +1,10 @@
1
+ _codepipe() {
2
+ COMPREPLY=()
3
+ local word="${COMP_WORDS[COMP_CWORD]}"
4
+ local words=("${COMP_WORDS[@]}")
5
+ unset words[0]
6
+ local completion=$(codepipe completion ${words[@]})
7
+ COMPREPLY=( $(compgen -W "$completion" -- "$word") )
8
+ }
9
+
10
+ complete -F _codepipe codepipe
@@ -0,0 +1,63 @@
1
+ require 'pathname'
2
+ require 'yaml'
3
+ require 'active_support/core_ext/string'
4
+
5
+ module Codepipe
6
+ module Core
7
+ extend Memoist
8
+
9
+ def root
10
+ path = ENV['PIPE_ROOT'] || '.'
11
+ Pathname.new(path)
12
+ end
13
+
14
+ def env
15
+ # 2-way binding
16
+ pipe_env = env_from_profile || 'development'
17
+ pipe_env = ENV['PIPE_ENV'] if ENV['PIPE_ENV'] # highest precedence
18
+ ActiveSupport::StringInquirer.new(pipe_env)
19
+ end
20
+ memoize :env
21
+
22
+ def env_extra
23
+ env_extra = ENV['PIPE_ENV_EXTRA'] if ENV['PIPE_ENV_EXTRA'] # highest precedence
24
+ return if env_extra&.empty?
25
+ env_extra
26
+ end
27
+ memoize :env_extra
28
+
29
+ # Overrides AWS_PROFILE based on the Codepipe.env if set in configs/settings.yml
30
+ # 2-way binding.
31
+ def set_aws_profile!
32
+ return if ENV['TEST']
33
+ return unless File.exist?("#{Codepipe.root}/.codepipeline/settings.yml") # for rake docs
34
+ return unless settings # Only load if within Codepipe project and there's a settings.yml
35
+
36
+ data = settings || {}
37
+ if data[:aws_profile]
38
+ puts "Using AWS_PROFILE=#{data[:aws_profile]} from PIPE_ENV=#{Codepipe.env} in config/settings.yml"
39
+ ENV['AWS_PROFILE'] = data[:aws_profile]
40
+ end
41
+ end
42
+
43
+ def settings
44
+ Setting.new.data
45
+ end
46
+ memoize :settings
47
+
48
+ def check_codepipeline_project!
49
+ check_path = "#{Codepipe.root}/.codepipeline"
50
+ unless File.exist?(check_path)
51
+ puts "ERROR: No .codepipeline folder found. Are you sure you are in a project with codepipeline setup?".color(:red)
52
+ puts "Current directory: #{Dir.pwd}"
53
+ puts "If you want to set up codepipeline for this prjoect, please create a settings file via: codepipeline init"
54
+ exit 1 unless ENV['TEST']
55
+ end
56
+ end
57
+
58
+ private
59
+ def env_from_profile
60
+ Codepipe::Setting.new.pipe_env
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,12 @@
1
+ module Codepipe
2
+ class Create < Stack
3
+ def perform
4
+ cfn.create_stack(
5
+ stack_name: @stack_name,
6
+ template_body: YAML.dump(@template),
7
+ capabilities: ["CAPABILITY_IAM"]
8
+ )
9
+ puts "Creating stack #{@stack_name}. Check CloudFormation console for status."
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,27 @@
1
+ module Codepipe
2
+ class Delete
3
+ include AwsServices
4
+
5
+ def initialize(options)
6
+ @options = options
7
+ @pipeline_name = options[:pipeline_name] || inferred_pipeline_name
8
+ @stack_name = options[:stack_name] || inferred_stack_name(@pipeline_name)
9
+ end
10
+
11
+ def run
12
+ message = "Deleted #{@stack_name} stack."
13
+ if @options[:noop]
14
+ puts "NOOP #{message}"
15
+ else
16
+ are_you_sure?(@stack_name, :delete)
17
+
18
+ if stack_exists?(@stack_name)
19
+ cfn.delete_stack(stack_name: @stack_name)
20
+ puts message
21
+ else
22
+ puts "#{@stack_name.inspect} stack does not exist".color(:red)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,40 @@
1
+ module Codepipe
2
+ class Deploy < Stack
3
+ def run
4
+ handle_rollback_completed!
5
+ if stack_exists?(@stack_name)
6
+ Update.new(@options).run
7
+ else
8
+ Create.new(@options).run
9
+ end
10
+ end
11
+
12
+ def handle_rollback_completed!
13
+ @stack = find_stack(@stack_name)
14
+ if @stack && rollback_complete?(@stack)
15
+ puts "Existing stack in ROLLBACK_COMPLETE state. Deleting stack before continuing."
16
+ cfn.delete_stack(stack_name: @stack_name)
17
+ status.wait
18
+ status.reset
19
+ @stack = nil # at this point stack has been deleted
20
+ end
21
+ end
22
+
23
+ def rollback_complete?(stack)
24
+ stack.stack_status == 'ROLLBACK_COMPLETE'
25
+ end
26
+
27
+ def find_stack(stack_name)
28
+ return if ENV['TEST']
29
+ resp = cfn.describe_stacks(stack_name: stack_name)
30
+ resp.stacks.first
31
+ rescue Aws::CloudFormation::Errors::ValidationError => e
32
+ # example: Stack with id demo-web does not exist
33
+ if e.message =~ /Stack with/ && e.message =~ /does not exist/
34
+ nil
35
+ else
36
+ raise
37
+ end
38
+ end
39
+ end
40
+ end
@@ -0,0 +1,37 @@
1
+ module Codepipe::Dsl
2
+ module Pipeline
3
+ include Approve
4
+ include Codebuild
5
+ include Github
6
+ include Ssm
7
+
8
+ PROPERTIES = %w[
9
+ artifact_store
10
+ artifact_stores
11
+ disable_inboundstage_transitions
12
+ name
13
+ restart_execution_on_update
14
+ role_arn
15
+ stages
16
+ ]
17
+ PROPERTIES.each do |prop|
18
+ define_method(prop) do |v|
19
+ @properties[prop.to_sym] = v
20
+ end
21
+ end
22
+
23
+ def stage(name, &block)
24
+ # Reset values for each stage declaraion
25
+ @run_order = 1
26
+
27
+ @current_stage = {name: name, actions: []}
28
+ @stages << @current_stage
29
+ block.call
30
+ end
31
+
32
+ def action(*props)
33
+ @current_stage[:actions] += props
34
+ @run_order += 1
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,34 @@
1
+ module Codepipe::Dsl::Pipeline
2
+ module Approve
3
+ def approve(props)
4
+ default = {
5
+ name: "approve",
6
+ action_type_id: {
7
+ category: "Approval",
8
+ owner: "AWS",
9
+ provider: "Manual",
10
+ version: "1",
11
+ },
12
+ run_order: @run_order,
13
+ configuration: { # required: will be set
14
+ notification_arn: {ref: "SnsTopic"}, # defaults to generated SNS topic
15
+ },
16
+ }
17
+
18
+ # Normalize special options. Simple approach of setting the default
19
+ case props
20
+ when String, Symbol
21
+ default[:configuration][:custom_data] = props
22
+ props = {}
23
+ when Hash
24
+ default[:configuration][:notification_arn] = props.delete(:notification_arn) if props.key?(:notification_arn)
25
+ default[:configuration][:custom_data] = props.delete(:custom_data) if props.key?(:custom_data)
26
+ else
27
+ raise "Invalid props type: #{props.class}"
28
+ end
29
+
30
+ options = default.merge(props)
31
+ action(options)
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,57 @@
1
+ module Codepipe::Dsl::Pipeline
2
+ module Codebuild
3
+ def codebuild(*projects)
4
+ default = {
5
+ # name: '', # will be set
6
+ action_type_id: {
7
+ category: "Build",
8
+ owner: "AWS",
9
+ provider: "CodeBuild",
10
+ version: "1",
11
+ },
12
+ run_order: @run_order,
13
+ # configuration: { project_name: '' }, # will be set
14
+ # output_artifacts: [name: "BuildArtifact#{name}"], # TODO: maybe make this configurable with a setting
15
+ input_artifacts: [name: "SourceArtifact"],
16
+ }
17
+
18
+ actions = projects.map do |item|
19
+ if item.is_a?(String)
20
+ name = item.underscore.camelize
21
+ project_name = adjusted_project_name(item) # add prefix and suffix
22
+ default.deep_merge(
23
+ name: name,
24
+ configuration: { project_name: project_name },
25
+ )
26
+ else # Hash
27
+ # With the hash, the user needs to set: name and configuration.project_name
28
+
29
+ # Handy shorthands
30
+ # The project name will allow this syntax
31
+ # codebuild(name: "action-name", project_name: "codebuild-project-names")
32
+ project_name = item.delete(:project_name)
33
+ if project_name
34
+ item[:configuration] = { project_name: project_name }
35
+ end
36
+
37
+ item.reverse_merge(default)
38
+ end
39
+ end
40
+
41
+ action(*actions)
42
+ end
43
+
44
+ def codebuild_prefix(v)
45
+ @codebuild_prefix = v
46
+ end
47
+
48
+ def codebuild_suffix(v)
49
+ @codebuild_suffix = v
50
+ end
51
+
52
+ private
53
+ def adjusted_project_name(name)
54
+ [@codebuild_prefix, name, @codebuild_suffix].compact.join
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,36 @@
1
+ module Codepipe::Dsl::Pipeline
2
+ module Github
3
+ def github(props)
4
+ # nice shorthands
5
+ source = props.delete(:source)
6
+ owner,repo = source.split("/")
7
+
8
+ # cli option can override this in codepipe/pipeline.rb set_source!
9
+ # so cli option always gets the highest precendence
10
+ branch = props.delete(:branch) || "master" # always delete branch prop
11
+
12
+ o_auth_token = props.delete(:auth_token)
13
+ poll_for_source_changes = props.delete(:poll_for_source_changes) || "false"
14
+
15
+ default = {
16
+ name: "Source",
17
+ action_type_id: {
18
+ category: "Source",
19
+ owner: "ThirdParty",
20
+ provider: "GitHub",
21
+ version: "1",
22
+ },
23
+ run_order: @run_order,
24
+ configuration: {
25
+ branch: branch,
26
+ o_auth_token: o_auth_token,
27
+ owner: owner,
28
+ poll_for_source_changes: poll_for_source_changes,
29
+ repo: repo,
30
+ },
31
+ output_artifacts: [name: "SourceArtifact"]
32
+ }
33
+ action(props.reverse_merge(default))
34
+ end
35
+ end
36
+ end
@@ -0,0 +1,50 @@
1
+ module Codepipe::Dsl
2
+ module Role
3
+ PROPERTIES = %w[
4
+ assume_role_policy_document
5
+ managed_policy_arns
6
+ max_session_duration
7
+ path
8
+ permissions_boundary
9
+ policies
10
+ role_name
11
+ ]
12
+ PROPERTIES.each do |prop|
13
+ define_method(prop) do |v|
14
+ @properties[prop.to_sym] = v
15
+ end
16
+ end
17
+
18
+ # convenience wrapper methods
19
+ def iam_policy(*definitions)
20
+ @iam_statements = definitions.map { |definition| standardize_iam_policy(definition) }
21
+ end
22
+
23
+ # Returns standarized IAM statement
24
+ def standardize_iam_policy(definition)
25
+ case definition
26
+ when String
27
+ # Expands simple string from: logs => logs:*
28
+ definition = "#{definition}:*" unless definition.include?(':')
29
+ {
30
+ action: [definition],
31
+ effect: "Allow",
32
+ resource: "*",
33
+ }
34
+ when Hash
35
+ definition
36
+ end
37
+ end
38
+
39
+ def managed_iam_policy(*definitions)
40
+ @managed_policy_arns = definitions.map { |definition| standardize_managed_iam_policy(definition) }
41
+ end
42
+
43
+ # AmazonEC2ReadOnlyAccess => arn:aws:iam::aws:policy/AmazonEC2ReadOnlyAccess
44
+ def standardize_managed_iam_policy(definition)
45
+ return definition if definition.include?('iam::aws:policy')
46
+
47
+ "arn:aws:iam::aws:policy/#{definition}"
48
+ end
49
+ end
50
+ end
@@ -0,0 +1,30 @@
1
+ module Codepipe::Dsl
2
+ module Schedule
3
+ PROPERTIES = %w[
4
+ description
5
+ event_pattern
6
+ name
7
+ role_arn
8
+ schedule_expression
9
+ state
10
+ targets
11
+ ]
12
+ PROPERTIES.each do |prop|
13
+ define_method(prop) do |v|
14
+ @properties[prop.to_sym] = v
15
+ end
16
+ end
17
+
18
+ def rate(period)
19
+ @schedule_expression = "rate(#{period})"
20
+ end
21
+
22
+ def cron(expression)
23
+ @schedule_expression = "cron(#{expression})"
24
+ end
25
+
26
+ def rule_event(props={})
27
+ @rule_event_props = props
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,15 @@
1
+ module Codepipe::Dsl
2
+ module Sns
3
+ PROPERTIES = %w[
4
+ display_name
5
+ kms_master_key_id
6
+ subscription
7
+ topic_name
8
+ ]
9
+ PROPERTIES.each do |prop|
10
+ define_method(prop) do |v|
11
+ @properties[prop.to_sym] = v
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,22 @@
1
+ require "aws-sdk-ssm"
2
+
3
+ module Codepipe::Dsl
4
+ module Ssm
5
+ # This method grabs the ssm parameter store value at "compile" time vs
6
+ # CloudFormation run time. In case we need it as part of the DSL compile phase.
7
+ def ssm(name)
8
+ resp = ssm_client.get_parameter(name: name)
9
+ if resp.parameter.type == "SecureString"
10
+ resp = ssm_client.get_parameter(name: name, with_decryption: true)
11
+ end
12
+
13
+ resp.parameter.value
14
+ rescue Aws::SSM::Errors::ParameterNotFound
15
+ puts "WARN: #{name} found on AWS SSM.".color(:yellow)
16
+ end
17
+
18
+ def ssm_client
19
+ @ssm_client ||= Aws::SSM::Client.new
20
+ end
21
+ end
22
+ end