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,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,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,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
|