pipedream 0.1.0 → 0.4.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 (106) hide show
  1. checksums.yaml +4 -4
  2. data/.cody/buildspec.yml +9 -0
  3. data/.cody/project.rb +4 -0
  4. data/.gitignore +16 -11
  5. data/.gitmodules +9 -0
  6. data/.rspec +1 -1
  7. data/CHANGELOG.md +34 -0
  8. data/Gemfile +3 -1
  9. data/Gemfile.lock +112 -0
  10. data/Guardfile +19 -0
  11. data/LICENSE.txt +18 -17
  12. data/README.md +55 -21
  13. data/Rakefile +10 -2
  14. data/exe/pipe +14 -0
  15. data/exe/pipedream +14 -0
  16. data/lib/pipedream/autoloader.rb +21 -0
  17. data/lib/pipedream/aws_services/helpers.rb +71 -0
  18. data/lib/pipedream/aws_services.rb +20 -0
  19. data/lib/pipedream/build.rb +13 -0
  20. data/lib/pipedream/cli.rb +60 -0
  21. data/lib/pipedream/command.rb +82 -0
  22. data/lib/pipedream/completer/script.rb +6 -0
  23. data/lib/pipedream/completer/script.sh +10 -0
  24. data/lib/pipedream/completer.rb +159 -0
  25. data/lib/pipedream/core.rb +63 -0
  26. data/lib/pipedream/create.rb +12 -0
  27. data/lib/pipedream/delete.rb +27 -0
  28. data/lib/pipedream/deploy.rb +40 -0
  29. data/lib/pipedream/dsl/pipeline/approve.rb +34 -0
  30. data/lib/pipedream/dsl/pipeline/codebuild.rb +57 -0
  31. data/lib/pipedream/dsl/pipeline/github.rb +42 -0
  32. data/lib/pipedream/dsl/pipeline.rb +37 -0
  33. data/lib/pipedream/dsl/role.rb +50 -0
  34. data/lib/pipedream/dsl/schedule.rb +30 -0
  35. data/lib/pipedream/dsl/sns.rb +15 -0
  36. data/lib/pipedream/dsl/ssm.rb +22 -0
  37. data/lib/pipedream/dsl/webhook.rb +27 -0
  38. data/lib/pipedream/evaluate.rb +47 -0
  39. data/lib/pipedream/help/completion.md +22 -0
  40. data/lib/pipedream/help/completion_script.md +3 -0
  41. data/lib/pipedream/help/deploy.md +54 -0
  42. data/lib/pipedream/help/start.md +20 -0
  43. data/lib/pipedream/help.rb +9 -0
  44. data/lib/pipedream/init.rb +68 -0
  45. data/lib/pipedream/pipeline/s3_bucket.rb +88 -0
  46. data/lib/pipedream/pipeline.rb +61 -0
  47. data/lib/pipedream/role.rb +181 -0
  48. data/lib/pipedream/schedule.rb +99 -0
  49. data/lib/pipedream/sequence.rb +66 -0
  50. data/lib/pipedream/setting.rb +82 -0
  51. data/lib/pipedream/sns.rb +43 -0
  52. data/lib/pipedream/stack.rb +95 -0
  53. data/lib/pipedream/start.rb +84 -0
  54. data/lib/pipedream/update.rb +12 -0
  55. data/lib/pipedream/version.rb +1 -1
  56. data/lib/pipedream/webhook.rb +60 -0
  57. data/lib/pipedream.rb +18 -1
  58. data/lib/template/.pipedream/pipeline.rb.tt +40 -0
  59. data/lib/template/.pipedream/schedule.rb +3 -0
  60. data/lib/template/.pipedream/settings.yml +9 -0
  61. data/lib/template/.pipedream/sns.rb +14 -0
  62. data/pipedream.gemspec +25 -14
  63. data/vendor/aws_data/CHANGELOG.md +7 -0
  64. data/vendor/aws_data/Gemfile +4 -0
  65. data/vendor/aws_data/Gemfile.lock +48 -0
  66. data/vendor/aws_data/LICENSE.txt +21 -0
  67. data/vendor/aws_data/README.md +42 -0
  68. data/vendor/aws_data/Rakefile +6 -0
  69. data/vendor/aws_data/aws_data.gemspec +30 -0
  70. data/{bin → vendor/aws_data/bin}/console +1 -1
  71. data/{bin → vendor/aws_data/bin}/setup +0 -0
  72. data/vendor/aws_data/lib/aws_data/version.rb +3 -0
  73. data/vendor/aws_data/lib/aws_data.rb +91 -0
  74. data/vendor/aws_data/spec/aws_data_spec.rb +5 -0
  75. data/vendor/aws_data/spec/spec_helper.rb +14 -0
  76. data/vendor/cfn-status/Gemfile +4 -0
  77. data/vendor/cfn-status/Gemfile.lock +49 -0
  78. data/vendor/cfn-status/LICENSE.txt +21 -0
  79. data/vendor/cfn-status/README.md +56 -0
  80. data/vendor/cfn-status/Rakefile +6 -0
  81. data/vendor/cfn-status/bin/console +14 -0
  82. data/vendor/cfn-status/bin/setup +8 -0
  83. data/vendor/cfn-status/cfn-status.gemspec +30 -0
  84. data/vendor/cfn-status/lib/cfn/aws_service.rb +56 -0
  85. data/vendor/cfn-status/lib/cfn/status/version.rb +5 -0
  86. data/vendor/cfn-status/lib/cfn/status.rb +220 -0
  87. data/vendor/cfn-status/spec/cfn/status_spec.rb +81 -0
  88. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-complete.json +1080 -0
  89. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-in-progress.json +1080 -0
  90. data/vendor/cfn-status/spec/fixtures/cfn/stack-events-update-rollback-complete.json +1086 -0
  91. data/vendor/cfn-status/spec/spec_helper.rb +14 -0
  92. data/vendor/cfn_camelizer/CHANGELOG.md +10 -0
  93. data/vendor/cfn_camelizer/Gemfile +4 -0
  94. data/vendor/cfn_camelizer/LICENSE.txt +21 -0
  95. data/vendor/cfn_camelizer/README.md +40 -0
  96. data/vendor/cfn_camelizer/Rakefile +6 -0
  97. data/vendor/cfn_camelizer/bin/console +14 -0
  98. data/vendor/cfn_camelizer/bin/setup +8 -0
  99. data/vendor/cfn_camelizer/cfn_camelizer.gemspec +32 -0
  100. data/vendor/cfn_camelizer/lib/camelizer.yml +27 -0
  101. data/vendor/cfn_camelizer/lib/cfn_camelizer/version.rb +3 -0
  102. data/vendor/cfn_camelizer/lib/cfn_camelizer.rb +92 -0
  103. data/vendor/cfn_camelizer/spec/cfn_camelizer_spec.rb +79 -0
  104. data/vendor/cfn_camelizer/spec/spec_helper.rb +14 -0
  105. metadata +295 -23
  106. data/.travis.yml +0 -7
@@ -0,0 +1,82 @@
1
+ require "thor"
2
+
3
+ # Override thor's long_desc identation behavior
4
+ # https://github.com/erikhuda/thor/issues/398
5
+ class Thor
6
+ module Shell
7
+ class Basic
8
+ def print_wrapped(message, options = {})
9
+ message = "\n#{message}" unless message[0] == "\n"
10
+ stdout.puts message
11
+ end
12
+ end
13
+ end
14
+ end
15
+
16
+ module Pipedream
17
+ class Command < Thor
18
+ class << self
19
+ def dispatch(m, args, options, config)
20
+ # Allow calling for help via:
21
+ # codepipe command help
22
+ # codepipe command -h
23
+ # codepipe command --help
24
+ # codepipe command -D
25
+ #
26
+ # as well thor's normal way:
27
+ #
28
+ # codepipe help command
29
+ help_flags = Thor::HELP_MAPPINGS + ["help"]
30
+ if args.length > 1 && !(args & help_flags).empty?
31
+ args -= help_flags
32
+ args.insert(-2, "help")
33
+ end
34
+
35
+ # codepipe version
36
+ # codepipe --version
37
+ # codepipe -v
38
+ version_flags = ["--version", "-v"]
39
+ if args.length == 1 && !(args & version_flags).empty?
40
+ args = ["version"]
41
+ end
42
+
43
+ super
44
+ end
45
+
46
+ # Override command_help to include the description at the top of the
47
+ # long_description.
48
+ def command_help(shell, command_name)
49
+ meth = normalize_command_name(command_name)
50
+ command = all_commands[meth]
51
+ alter_command_description(command)
52
+ super
53
+ end
54
+
55
+ def alter_command_description(command)
56
+ return unless command
57
+
58
+ # Add description to beginning of long_description
59
+ long_desc = if command.long_description
60
+ "#{command.description}\n\n#{command.long_description}"
61
+ else
62
+ command.description
63
+ end
64
+
65
+ # add reference url to end of the long_description
66
+ unless website.empty?
67
+ full_command = [command.ancestor_name, command.name].compact.join('-')
68
+ url = "#{website}/reference/codepipe-#{full_command}"
69
+ long_desc += "\n\nHelp also available at: #{url}"
70
+ end
71
+
72
+ command.long_description = long_desc
73
+ end
74
+ private :alter_command_description
75
+
76
+ # meant to be overriden
77
+ def website
78
+ ""
79
+ end
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,6 @@
1
+ class Pipedream::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,159 @@
1
+ =begin
2
+ Code Explanation:
3
+
4
+ There are 3 types of things to auto-complete:
5
+
6
+ 1. command: the command itself
7
+ 2. parameters: command parameters.
8
+ 3. options: command options
9
+
10
+ Here's an example:
11
+
12
+ mycli hello name --from me
13
+
14
+ * command: hello
15
+ * parameters: name
16
+ * option: --from
17
+
18
+ When command parameters are done processing, the remaining completion words will be options. We can tell that the command params are completed based on the method arity.
19
+
20
+ ## Arity
21
+
22
+ For example, say you had a method for a CLI command with the following form:
23
+
24
+ ufo scale service count --cluster development
25
+
26
+ It's equivalent ruby method:
27
+
28
+ scale(service, count) = has an arity of 2
29
+
30
+ So typing:
31
+
32
+ ufo scale service count [TAB] # there are 3 parameters including the "scale" command according to Thor's CLI processing.
33
+
34
+ So the completion should only show options, something like this:
35
+
36
+ --noop --verbose --cluster
37
+
38
+ ## Splat Arguments
39
+
40
+ When the ruby method has a splat argument, it's arity is negative. Here are some example methods and their arities.
41
+
42
+ ship(service) = 1
43
+ scale(service, count) = 2
44
+ ships(*services) = -1
45
+ foo(example, *rest) = -2
46
+
47
+ Fortunately, negative and positive arity values are processed the same way. So we take simply take the absolute value of the arity and process it the same.
48
+
49
+ Here are some test cases, hit TAB after typing the command:
50
+
51
+ codepipe completion
52
+ codepipe completion hello
53
+ codepipe completion hello name
54
+ codepipe completion hello name --
55
+ codepipe completion hello name --noop
56
+
57
+ codepipe completion
58
+ codepipe completion sub:goodbye
59
+ codepipe completion sub:goodbye name
60
+
61
+ ## Subcommands and Thor::Group Registered Commands
62
+
63
+ Sometimes the commands are not simple thor commands but are subcommands or Thor::Group commands. A good specific example is the ufo tool.
64
+
65
+ * regular command: ufo ship
66
+ * subcommand: ufo docker
67
+ * Thor::Group command: ufo init
68
+
69
+ Auto-completion accounts for each of these type of commands.
70
+ =end
71
+ module Pipedream
72
+ class Completer
73
+ def initialize(command_class, *params)
74
+ @params = params
75
+ @current_command = @params[0]
76
+ @command_class = command_class # CLI initiall
77
+ end
78
+
79
+ def run
80
+ if subcommand?(@current_command)
81
+ subcommand_class = @command_class.subcommand_classes[@current_command]
82
+ @params.shift # destructive
83
+ Completer.new(subcommand_class, *@params).run # recursively use subcommand
84
+ return
85
+ end
86
+
87
+ # full command has been found!
88
+ unless found?(@current_command)
89
+ puts all_commands
90
+ return
91
+ end
92
+
93
+ # will only get to here if command aws found (above)
94
+ arity = @command_class.instance_method(@current_command).arity.abs
95
+ if @params.size > arity or thor_group_command?
96
+ puts options_completion
97
+ else
98
+ puts params_completion
99
+ end
100
+ end
101
+
102
+ def subcommand?(command)
103
+ @command_class.subcommands.include?(command)
104
+ end
105
+
106
+ # hacky way to detect that command is a registered Thor::Group command
107
+ def thor_group_command?
108
+ command_params(raw=true) == [[:rest, :args]]
109
+ end
110
+
111
+ def found?(command)
112
+ public_methods = @command_class.public_instance_methods(false)
113
+ command && public_methods.include?(command.to_sym)
114
+ end
115
+
116
+ # all top-level commands
117
+ def all_commands
118
+ commands = @command_class.all_commands.reject do |k,v|
119
+ v.is_a?(Thor::HiddenCommand)
120
+ end
121
+ commands.keys
122
+ end
123
+
124
+ def command_params(raw=false)
125
+ params = @command_class.instance_method(@current_command).parameters
126
+ # Example:
127
+ # >> Sub.instance_method(:goodbye).parameters
128
+ # => [[:req, :name]]
129
+ # >>
130
+ raw ? params : params.map!(&:last)
131
+ end
132
+
133
+ def params_completion
134
+ offset = @params.size - 1
135
+ offset_params = command_params[offset..-1]
136
+ command_params[offset..-1].first
137
+ end
138
+
139
+ def options_completion
140
+ used = ARGV.select { |a| a.include?('--') } # so we can remove used options
141
+
142
+ method_options = @command_class.all_commands[@current_command].options.keys
143
+ class_options = @command_class.class_options.keys
144
+
145
+ all_options = method_options + class_options + ['help']
146
+
147
+ all_options.map! { |o| "--#{o.to_s.gsub('_','-')}" }
148
+ filtered_options = all_options - used
149
+ filtered_options.uniq
150
+ end
151
+
152
+ # Useful for debugging. Using puts messes up completion.
153
+ def log(msg)
154
+ File.open("/tmp/complete.log", "a") do |file|
155
+ file.puts(msg)
156
+ end
157
+ end
158
+ end
159
+ end
@@ -0,0 +1,63 @@
1
+ require 'pathname'
2
+ require 'yaml'
3
+ require 'active_support/core_ext/string'
4
+
5
+ module Pipedream
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 Pipedream.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?("#{Pipedream.root}/.pipedream/settings.yml") # for rake docs
34
+ return unless settings # Only load if within Pipedream 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=#{Pipedream.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 = "#{Pipedream.root}/.pipedream"
50
+ unless File.exist?(check_path)
51
+ puts "ERROR: No .pipedream 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
+ Pipedream::Setting.new.pipe_env
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,12 @@
1
+ module Pipedream
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 Pipedream
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 Pipedream
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,34 @@
1
+ module Pipedream::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 Pipedream::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,42 @@
1
+ module Pipedream::Dsl::Pipeline
2
+ module Github
3
+ def github(props)
4
+ # nice shorthands
5
+ source = props.delete(:source)
6
+ source = extract_repo_source(source)
7
+ owner,repo = source.split("/")
8
+
9
+ # cli option can override this in codepipe/pipeline.rb set_source!
10
+ # so cli option always gets the highest precendence
11
+ branch = props.delete(:branch) || "master" # always delete branch prop
12
+
13
+ o_auth_token = props.delete(:auth_token)
14
+ poll_for_source_changes = props.delete(:poll_for_source_changes) || "false"
15
+
16
+ default = {
17
+ name: "Source",
18
+ action_type_id: {
19
+ category: "Source",
20
+ owner: "ThirdParty",
21
+ provider: "GitHub",
22
+ version: "1",
23
+ },
24
+ run_order: @run_order,
25
+ configuration: {
26
+ branch: branch,
27
+ o_auth_token: o_auth_token,
28
+ owner: owner,
29
+ poll_for_source_changes: poll_for_source_changes,
30
+ repo: repo,
31
+ },
32
+ output_artifacts: [name: "SourceArtifact"]
33
+ }
34
+ action(props.reverse_merge(default))
35
+ end
36
+
37
+ def extract_repo_source(url)
38
+ url.sub('git@github.com:','').sub('https://github.com/','').sub(/\.git$/,'')
39
+ end
40
+ extend self # mainly for extract_repo_source
41
+ end
42
+ end
@@ -0,0 +1,37 @@
1
+ module Pipedream::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,50 @@
1
+ module Pipedream::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 Pipedream::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 Pipedream::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 Pipedream::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