codepipeline 0.1.0 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +16 -11
- data/.gitmodules +9 -0
- data/.rspec +1 -1
- data/CHANGELOG.md +16 -0
- data/Gemfile +3 -1
- data/Gemfile.lock +111 -0
- data/Guardfile +19 -0
- data/LICENSE.txt +18 -17
- data/README.md +44 -20
- data/Rakefile +10 -2
- data/codepipe.gemspec +38 -0
- data/docs/.gitignore +4 -0
- data/docs/CNAME +1 -0
- data/docs/Gemfile +3 -0
- data/docs/LICENSE +21 -0
- data/docs/README.md +25 -0
- data/docs/_config.yml +73 -0
- data/docs/_docs/contributing.md +99 -0
- data/docs/_docs/conventions.md +43 -0
- data/docs/_docs/deploy.md +72 -0
- data/docs/_docs/dsl.md +13 -0
- data/docs/_docs/dsl/approve.md +62 -0
- data/docs/_docs/dsl/pipeline.md +56 -0
- data/docs/_docs/dsl/pipeline/action.md +28 -0
- data/docs/_docs/dsl/pipeline/codebuild.md +62 -0
- data/docs/_docs/dsl/pipeline/prefix-and-suffix.md +57 -0
- data/docs/_docs/dsl/role.md +79 -0
- data/docs/_docs/dsl/schedule.md +29 -0
- data/docs/_docs/dsl/sns.md +27 -0
- data/docs/_docs/dsl/webhook.md +31 -0
- data/docs/_docs/ecs-deploy.md +24 -0
- data/docs/_docs/examples/different-branches.md +50 -0
- data/docs/_docs/install.md +14 -0
- data/docs/_docs/next-steps.md +16 -0
- data/docs/_docs/settings.md +34 -0
- data/docs/_docs/start.md +31 -0
- data/docs/_includes/commands.html +92 -0
- data/docs/_includes/content.html +25 -0
- data/docs/_includes/edit-on-github.html +9 -0
- data/docs/_includes/footer.html +41 -0
- data/docs/_includes/google_analytics.html +10 -0
- data/docs/_includes/head.html +45 -0
- data/docs/_includes/js.html +15 -0
- data/docs/_includes/nav.html +17 -0
- data/docs/_includes/prev_next.md +19 -0
- data/docs/_includes/reference.md +1 -0
- data/docs/_includes/subnav.html +46 -0
- data/docs/_includes/tutorials.md +38 -0
- data/docs/_layouts/default.html +12 -0
- data/docs/_reference/pipe-completion.md +44 -0
- data/docs/_reference/pipe-completion_script.md +25 -0
- data/docs/_reference/pipe-delete.md +25 -0
- data/docs/_reference/pipe-deploy.md +26 -0
- data/docs/_reference/pipe-init.md +25 -0
- data/docs/_reference/pipe-start.md +25 -0
- data/docs/_reference/pipe-version.md +21 -0
- data/docs/_sass/_bootstrap-overrides.scss +40 -0
- data/docs/_sass/_contact.scss +49 -0
- data/docs/_sass/_cta.scss +37 -0
- data/docs/_sass/_download.scss +31 -0
- data/docs/_sass/_features.scss +47 -0
- data/docs/_sass/_footer.scss +49 -0
- data/docs/_sass/_global.scss +102 -0
- data/docs/_sass/_main.scss +364 -0
- data/docs/_sass/_masthead.scss +70 -0
- data/docs/_sass/_mixins.scss +79 -0
- data/docs/_sass/_navbar.scss +92 -0
- data/docs/_sass/_syntax.scss +65 -0
- data/docs/_sass/_table.scss +34 -0
- data/docs/_sass/_timeline.scss +207 -0
- data/docs/_sass/_variables.scss +24 -0
- data/docs/bin/web +8 -0
- data/docs/docs.md +24 -0
- data/docs/dsl/pipeline.md +76 -0
- data/docs/dsl/role.md +66 -0
- data/docs/dsl/schedule.md +20 -0
- data/docs/img/docs/codepipeline-output.png +0 -0
- data/docs/img/logos/boltops-logo-full.png +0 -0
- data/docs/img/logos/boltops-logo.png +0 -0
- data/docs/img/logos/project-logo.png +0 -0
- data/docs/index.html +35 -0
- data/docs/js/nav.js +39 -0
- data/docs/js/new-age.js +38 -0
- data/docs/js/new-age.min.js +6 -0
- data/docs/new-age.scss +20 -0
- data/docs/quick-start.md +73 -0
- data/docs/reference.md +12 -0
- data/docs/support.md +22 -0
- data/docs/vendor/bootstrap/css/bootstrap-grid.css +1339 -0
- data/docs/vendor/bootstrap/css/bootstrap-grid.css.map +1 -0
- data/docs/vendor/bootstrap/css/bootstrap-grid.min.css +1 -0
- data/docs/vendor/bootstrap/css/bootstrap-grid.min.css.map +1 -0
- data/docs/vendor/bootstrap/css/bootstrap-reboot.css +459 -0
- data/docs/vendor/bootstrap/css/bootstrap-reboot.css.map +1 -0
- data/docs/vendor/bootstrap/css/bootstrap-reboot.min.css +1 -0
- data/docs/vendor/bootstrap/css/bootstrap-reboot.min.css.map +1 -0
- data/docs/vendor/bootstrap/css/bootstrap.css +9320 -0
- data/docs/vendor/bootstrap/css/bootstrap.css.map +1 -0
- data/docs/vendor/bootstrap/css/bootstrap.min.css +6 -0
- data/docs/vendor/bootstrap/css/bootstrap.min.css.map +1 -0
- data/docs/vendor/bootstrap/js/bootstrap.js +3535 -0
- data/docs/vendor/bootstrap/js/bootstrap.min.js +7 -0
- data/docs/vendor/font-awesome/css/font-awesome.css +2337 -0
- data/docs/vendor/font-awesome/css/font-awesome.min.css +4 -0
- data/docs/vendor/font-awesome/fonts/FontAwesome.otf +0 -0
- data/docs/vendor/font-awesome/fonts/fontawesome-webfont.eot +0 -0
- data/docs/vendor/font-awesome/fonts/fontawesome-webfont.svg +2671 -0
- data/docs/vendor/font-awesome/fonts/fontawesome-webfont.ttf +0 -0
- data/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff +0 -0
- data/docs/vendor/font-awesome/fonts/fontawesome-webfont.woff2 +0 -0
- data/docs/vendor/font-awesome/less/animated.less +34 -0
- data/docs/vendor/font-awesome/less/bordered-pulled.less +25 -0
- data/docs/vendor/font-awesome/less/core.less +12 -0
- data/docs/vendor/font-awesome/less/fixed-width.less +6 -0
- data/docs/vendor/font-awesome/less/font-awesome.less +18 -0
- data/docs/vendor/font-awesome/less/icons.less +789 -0
- data/docs/vendor/font-awesome/less/larger.less +13 -0
- data/docs/vendor/font-awesome/less/list.less +19 -0
- data/docs/vendor/font-awesome/less/mixins.less +60 -0
- data/docs/vendor/font-awesome/less/path.less +15 -0
- data/docs/vendor/font-awesome/less/rotated-flipped.less +20 -0
- data/docs/vendor/font-awesome/less/screen-reader.less +5 -0
- data/docs/vendor/font-awesome/less/stacked.less +20 -0
- data/docs/vendor/font-awesome/less/variables.less +799 -0
- data/docs/vendor/font-awesome/scss/_animated.scss +34 -0
- data/docs/vendor/font-awesome/scss/_bordered-pulled.scss +25 -0
- data/docs/vendor/font-awesome/scss/_core.scss +12 -0
- data/docs/vendor/font-awesome/scss/_fixed-width.scss +6 -0
- data/docs/vendor/font-awesome/scss/_icons.scss +789 -0
- data/docs/vendor/font-awesome/scss/_larger.scss +13 -0
- data/docs/vendor/font-awesome/scss/_list.scss +19 -0
- data/docs/vendor/font-awesome/scss/_mixins.scss +60 -0
- data/docs/vendor/font-awesome/scss/_path.scss +15 -0
- data/docs/vendor/font-awesome/scss/_rotated-flipped.scss +20 -0
- data/docs/vendor/font-awesome/scss/_screen-reader.scss +5 -0
- data/docs/vendor/font-awesome/scss/_stacked.scss +20 -0
- data/docs/vendor/font-awesome/scss/_variables.scss +799 -0
- data/docs/vendor/font-awesome/scss/font-awesome.scss +18 -0
- data/docs/vendor/jquery-easing/jquery.easing.compatibility.js +59 -0
- data/docs/vendor/jquery-easing/jquery.easing.js +166 -0
- data/docs/vendor/jquery-easing/jquery.easing.min.js +1 -0
- data/docs/vendor/jquery/jquery.js +10253 -0
- data/docs/vendor/jquery/jquery.min.js +4 -0
- data/docs/vendor/simple-line-icons/css/simple-line-icons.css +778 -0
- data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.eot +0 -0
- data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.svg +200 -0
- data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.ttf +0 -0
- data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff +0 -0
- data/docs/vendor/simple-line-icons/fonts/Simple-Line-Icons.woff2 +0 -0
- data/docs/vendor/simple-line-icons/less/simple-line-icons.less +982 -0
- data/docs/vendor/simple-line-icons/scss/simple-line-icons.scss +979 -0
- data/docs/vendor/tether/tether.js +1811 -0
- data/docs/vendor/tether/tether.min.js +1 -0
- data/exe/codepipeline +14 -0
- data/exe/pipe +14 -0
- data/lib/codepipe.rb +23 -0
- data/lib/codepipe/autoloader.rb +21 -0
- data/lib/codepipe/aws_services.rb +20 -0
- data/lib/codepipe/aws_services/helpers.rb +71 -0
- data/lib/codepipe/build.rb +13 -0
- data/lib/codepipe/cli.rb +60 -0
- data/lib/codepipe/command.rb +82 -0
- data/lib/codepipe/completer.rb +159 -0
- data/lib/codepipe/completer/script.rb +6 -0
- data/lib/codepipe/completer/script.sh +10 -0
- data/lib/codepipe/core.rb +63 -0
- data/lib/codepipe/create.rb +12 -0
- data/lib/codepipe/delete.rb +27 -0
- data/lib/codepipe/deploy.rb +40 -0
- data/lib/codepipe/dsl/pipeline.rb +37 -0
- data/lib/codepipe/dsl/pipeline/approve.rb +34 -0
- data/lib/codepipe/dsl/pipeline/codebuild.rb +57 -0
- data/lib/codepipe/dsl/pipeline/github.rb +36 -0
- data/lib/codepipe/dsl/role.rb +50 -0
- data/lib/codepipe/dsl/schedule.rb +30 -0
- data/lib/codepipe/dsl/sns.rb +15 -0
- data/lib/codepipe/dsl/ssm.rb +22 -0
- data/lib/codepipe/dsl/webhook.rb +27 -0
- data/lib/codepipe/evaluate.rb +47 -0
- data/lib/codepipe/help.rb +9 -0
- data/lib/codepipe/help/completion.md +22 -0
- data/lib/codepipe/help/completion_script.md +3 -0
- data/lib/codepipe/help/hello.md +5 -0
- data/lib/codepipe/init.rb +57 -0
- data/lib/codepipe/pipeline.rb +61 -0
- data/lib/codepipe/pipeline/s3_bucket.rb +88 -0
- data/lib/codepipe/role.rb +181 -0
- data/lib/codepipe/schedule.rb +99 -0
- data/lib/codepipe/sequence.rb +66 -0
- data/lib/codepipe/setting.rb +79 -0
- data/lib/codepipe/sns.rb +43 -0
- data/lib/codepipe/stack.rb +95 -0
- data/lib/codepipe/start.rb +83 -0
- data/lib/codepipe/update.rb +12 -0
- data/lib/codepipe/version.rb +3 -0
- data/lib/codepipe/webhook.rb +60 -0
- data/lib/codepipeline.rb +1 -6
- data/lib/template/.codepipeline/pipeline.rb.tt +33 -0
- data/lib/template/.codepipeline/schedule.rb +3 -0
- data/lib/template/.codepipeline/settings.yml +9 -0
- data/lib/template/.codepipeline/sns.rb +14 -0
- data/spec/fixtures/app/.codepipeline/pipeline.rb +12 -0
- data/spec/fixtures/app/.codepipeline/schedule.rb +1 -0
- data/spec/fixtures/app/.codepipeline/webhook.rb +1 -0
- data/spec/fixtures/pipelines/approve.rb +22 -0
- data/spec/fixtures/pipelines/approve_existing_sns.rb +24 -0
- data/spec/lib/cli_spec.rb +18 -0
- data/spec/lib/pipeline/approve_spec.rb +32 -0
- data/spec/lib/pipeline_spec.rb +12 -0
- data/spec/lib/role_spec.rb +12 -0
- data/spec/lib/schedule_spec.rb +12 -0
- data/spec/lib/webhook_spec.rb +12 -0
- data/spec/spec_helper.rb +35 -0
- metadata +419 -22
- data/.travis.yml +0 -7
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/codepipeline.gemspec +0 -27
- data/lib/codepipeline/version.rb +0 -3
@@ -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,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
|