orch 0.0.1

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.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 2f67ca3214ddbc6302dde59fc294da08fd0dbd2b
4
+ data.tar.gz: 572ce735ddf78eebbd1ace4c6d0b33a05892d37f
5
+ SHA512:
6
+ metadata.gz: e890d242ed98f9986b2a2eced37f4798aa85baba10192ac3bc5baeae214611c84043fef017163388267fdd5f8807241eb2efda216e284849546acb205154af43
7
+ data.tar.gz: 876005978425fba1769c54227c1473dddae4e83e5f210d98fcb5e5aa5e49f10d2d56454f31ff763841f7d83e0e771432405a81c1b15d45ee608f29e249fdeef1
data/.gitignore ADDED
@@ -0,0 +1,22 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ *.bundle
19
+ *.so
20
+ *.o
21
+ *.a
22
+ mkmf.log
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in orch.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2015 Ray Johnson
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,44 @@
1
+ # Orch
2
+
3
+ orch - uses a Yaml file to specify jobs that can be delpoyed to Mesos' Marathon and Chronos frameworks.
4
+
5
+ ## Installing this tool
6
+
7
+ Run the following command:
8
+ ```
9
+ $> gem install orch
10
+ ```
11
+ (you might need to sudo)
12
+
13
+ Once the gem is installed, the command orch will be in your $PATH
14
+
15
+ ## Usage
16
+
17
+ Type "orch help" to get the list of commands and "orch help <command>" to get list of options for a given command.
18
+
19
+ The general usecase is to run "orch deploy <job_spec>" to deploy a configuration to to Marathon or Chronos. A given job_spec can contain specifications for many jobs and for multiple environments. Various options to the deploy command gives control to exactly what is deployed.
20
+
21
+ ## Job spec format
22
+
23
+ TODO: describe the file
24
+
25
+ ## Configuration Options
26
+
27
+ Run the following command to interactively create a config file.
28
+ ```
29
+ $> orch config
30
+ ```
31
+
32
+ The file ~/.orch/config.yaml would contain values for "chronos_url" and "marathon_url". You can also pass --chronos_url or --marathon_url options to the "orch deploy" command to override what is in the config file.
33
+
34
+ ## Examples
35
+
36
+ TODO: show some examples
37
+
38
+ ## Contributing
39
+
40
+ 1. Fork it ( https://github.com/[my-github-username]/orch/fork )
41
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
42
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
43
+ 4. Push to the branch (`git push origin my-new-feature`)
44
+ 5. Create a new Pull Request
data/Rakefile ADDED
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
data/bin/orch ADDED
@@ -0,0 +1,5 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'orch'
4
+
5
+ Orch::Application.start(ARGV)
@@ -0,0 +1,46 @@
1
+
2
+ default_job: &DEFAULT_JOB
3
+ kind: Chronos
4
+ environment: override me
5
+ cronos_spec: &DEFAULT_SPEC
6
+ name: "ray-test-{{ENV}}"
7
+ schedule: "R/2015-01-25T21:00/PT24H"
8
+ scheduleTimeZone: "PST"
9
+ owner: "rjohnson@yp.com"
10
+ container: &DEFAULT_CONTAINER
11
+ type: "DOCKER"
12
+ image: "busybox"
13
+ network: "BRIDGE"
14
+ cpus: "0.5"
15
+ mem: "512"
16
+ uris: []
17
+ environmentVariables:
18
+ -
19
+ name: "LOG_LOCATION"
20
+ value: "/var/{{ENV}}"
21
+ forcePullImage: false
22
+ command: "echo \"log here: $LOG_LOCATION\"; echo \"ENV: $DEPLOY_ENV\";sleep 10; echo bye"
23
+
24
+ version: alpha1
25
+ environments_var: DEPLOY_ENV
26
+ environments:
27
+ - dev
28
+ - test
29
+ - prod
30
+ applications:
31
+ - <<: *DEFAULT_JOB
32
+ environment: dev
33
+ cronos_spec:
34
+ <<: *DEFAULT_SPEC
35
+ schedule: "R/2015-08-01T21:00/PT24H"
36
+ forcePullImage: true
37
+ - <<: *DEFAULT_JOB
38
+ environment: test
39
+ cronos_spec:
40
+ <<: *DEFAULT_SPEC
41
+ schedule: "R/2015-08-01T21:10/PT24H"
42
+ - <<: *DEFAULT_JOB
43
+ environment: prod
44
+ cronos_spec:
45
+ <<: *DEFAULT_SPEC
46
+ schedule: "R/2015-08-01T21:30/PT24H"
@@ -0,0 +1,17 @@
1
+ version: alpha1
2
+ applications:
3
+ - kind: Chronos
4
+ cronos_spec:
5
+ name: "ray-test"
6
+ schedule: "R/2015-01-25T21:00/PT24H"
7
+ scheduleTimeZone: "PST"
8
+ owner: "rjohnson@yp.com"
9
+ container:
10
+ type: "DOCKER"
11
+ image: "busybox"
12
+ network: "BRIDGE"
13
+ cpus: "0.5"
14
+ mem: "512"
15
+ uris: []
16
+ forcePullImage: true
17
+ command: "echo hello; sleep 10; echo bye"
@@ -0,0 +1,28 @@
1
+ version: alpha1
2
+ environments_var: DEPLOY_ENV
3
+ environments:
4
+ - dev
5
+ - test
6
+ - prod
7
+ applications:
8
+ - kind: Marathon
9
+ environment: dev
10
+ marathon_spec:
11
+ id: "ray-web-{{ENV}}"
12
+ cpus: 0.1
13
+ mem: 300
14
+ instances: 10
15
+ env:
16
+ FOO: "bar"
17
+ container:
18
+ type: "DOCKER"
19
+ docker:
20
+ image: "nginx"
21
+ network: "BRIDGE"
22
+ portMappings:
23
+ -
24
+ containerPort: 80
25
+ hostPort: 0
26
+ protocol: "tcp"
27
+ forcePullImage: true
28
+
data/lib/config.rb ADDED
@@ -0,0 +1,63 @@
1
+ # config
2
+
3
+ require 'json'
4
+ require 'yaml'
5
+
6
+ module Orch
7
+ class Config
8
+ def initialize(options)
9
+ @options = options
10
+
11
+ @config_path = "#{Dir.home}/.orch/config.yml"
12
+ if File.file?(@config_path)
13
+ @APP_CONFIG = YAML.load_file(@config_path)
14
+ else
15
+ @APP_CONFIG = nil
16
+ end
17
+ end
18
+
19
+ def chronos_url
20
+ if @options.has_key?("chronos_url")
21
+ # If passed in on command line override what is in config file
22
+ url = @options["chronos_url"]
23
+ return url
24
+ end
25
+
26
+ if @APP_CONFIG.nil? || @APP_CONFIG["chronos_url"].nil?
27
+ puts "chronos_url not specified, use --chronos_url or set in ~/.orch/config.yml"
28
+ exit 1
29
+ end
30
+
31
+ return @APP_CONFIG["chronos_url"]
32
+ end
33
+
34
+ def marathon_url
35
+ if @options.has_key?("marathon_url")
36
+ # If passed in on command line override what is in config file
37
+ url = @options["marathon_url"]
38
+ return url
39
+ end
40
+
41
+ if @APP_CONFIG.nil? || @APP_CONFIG["marathon_url"].nil?
42
+ puts "marathon_url not specified, use --marathon_url or set in ~/.orch/config.yml"
43
+ exit 1
44
+ end
45
+
46
+ return @APP_CONFIG["marathon_url"]
47
+ end
48
+
49
+ def setup_config(marathon_url, chronos_url)
50
+
51
+ if @APP_CONFIG.nil?
52
+ @APP_CONFIG = {}
53
+ end
54
+ @APP_CONFIG['marathon_url'] = marathon_url
55
+ @APP_CONFIG['chronos_url'] = chronos_url
56
+
57
+ if ! File.directory?("#{Dir.home}/.orch")
58
+ Dir.mkdir("#{Dir.home}/.orch")
59
+ end
60
+ File.open(@config_path, 'w') {|f| f.write @APP_CONFIG.to_yaml}
61
+ end
62
+ end
63
+ end
data/lib/deploy.rb ADDED
@@ -0,0 +1,121 @@
1
+ require 'json'
2
+ require 'net/http'
3
+ require 'uri'
4
+
5
+ require 'config'
6
+
7
+ class String
8
+ def numeric?
9
+ Float(self) != nil rescue false
10
+ end
11
+ end
12
+
13
+ module Orch
14
+ class Deploy
15
+ def initialize(options)
16
+ # TODO: get chronos and marathon urls from diffferent ways: param, env, .config
17
+ @config = Orch::Config.new(options)
18
+ end
19
+
20
+ def deploy_chronos(json_payload)
21
+ uri = URI(@config.chronos_url)
22
+ json_headers = {"Content-Type" => "application/json",
23
+ "Accept" => "application/json"}
24
+
25
+ # curl -L -H 'Content-Type: application/json' -X POST -d @$schedule_file $CHRONOS_URL/scheduler/iso8601
26
+ http = Net::HTTP.new(uri.host, uri.port)
27
+ response = http.post("/scheduler/iso8601", json_payload, json_headers)
28
+
29
+ if response.code != 204.to_s
30
+ puts "Response #{response.code} #{response.message}: #{response.body}"
31
+ end
32
+
33
+ # TODO: handle error codes better?
34
+
35
+ return response
36
+ end
37
+
38
+ def verify_chronos(json_payload)
39
+ spec = Hashie::Mash.new(JSON.parse(json_payload))
40
+
41
+ uri = URI(@config.chronos_url)
42
+ json_headers = {"Content-Type" => "application/json",
43
+ "Accept" => "application/json"}
44
+
45
+ # curl -L -H 'Content-Type: application/json' -X POST -d @$schedule_file $CHRONOS_URL/scheduler/iso8601
46
+ http = Net::HTTP.new(uri.host, uri.port)
47
+ response = http.get("/scheduler/jobs", json_headers)
48
+
49
+ if response.code != 200.to_s
50
+ puts "Response #{response.code} #{response.message}: #{response.body}"
51
+ end
52
+
53
+ array = JSON.parse(response.body).map { |hash| Hashie::Mash.new(hash) }
54
+
55
+ jobFound = false
56
+ array.each do |job|
57
+ if job.name == spec.name
58
+ jobFound = true
59
+ foundDiffs = find_diffs(spec, job)
60
+ end
61
+ end
62
+
63
+ if !jobFound
64
+ puts "job \"#{spec.name}\" not currently deployed"
65
+ end
66
+
67
+ # TODO: handle error codes better?
68
+
69
+ return response
70
+ end
71
+
72
+ def find_diffs(spec, job)
73
+ foundDiff = false
74
+
75
+ spec.each_key do |key|
76
+ if spec[key].is_a?(Hash)
77
+ if find_diffs(spec[key], job[key]) == true
78
+ foundDiff = true
79
+ end
80
+ next
81
+ end
82
+ specVal = spec[key]
83
+ jobVal = job[key]
84
+ if spec[key].to_s.numeric?
85
+ specVal = Float(spec[key])
86
+ jobVal = Float(job[key])
87
+ else
88
+ specVal = spec[key]
89
+ jobVal = job[key]
90
+ end
91
+ if specVal != jobVal
92
+ puts "#{key}= spec:#{spec[key]}, server:#{job[key]}"
93
+ foundDiff = true
94
+ end
95
+ end
96
+
97
+ return foundDiff
98
+ end
99
+
100
+ def deploy_marathon(json_payload)
101
+ uri = URI(@config.marathon_url)
102
+ json_headers = {"Content-Type" => "application/json",
103
+ "Accept" => "application/json"}
104
+
105
+ # curl -L -H 'Content-Type: application/json' -X POST -d @$schedule_file $CHRONOS_URL/scheduler/iso8601
106
+ puts uri
107
+ http = Net::HTTP.new(uri.host, uri.port)
108
+ response = http.put("/v2/apps/#{json_payload["id"]}", json_payload, json_headers)
109
+
110
+ puts "Response #{response.code} #{response.message}: #{response.body}"
111
+
112
+ if response.code == 204.to_s
113
+ puts "success"
114
+ end
115
+
116
+ # TODO: handle error codes
117
+
118
+ return response
119
+ end
120
+ end
121
+ end
@@ -0,0 +1,3 @@
1
+ module Orch
2
+ VERSION = "0.0.1"
3
+ end
data/lib/orch.rb ADDED
@@ -0,0 +1,97 @@
1
+ require "orch/version"
2
+ require 'hashie'
3
+ require 'json'
4
+ require 'thor'
5
+ require "yaml"
6
+ require "parse"
7
+ require "deploy"
8
+
9
+ module Orch
10
+ class Application < Thor
11
+
12
+ desc 'config', 'Interactive way to build ~/.orch/config.yml file'
13
+ def config
14
+ config = Orch::Config.new(options)
15
+
16
+ if File.file?("#{Dir.home}/.orch/config.yml")
17
+ say "This will over-write your existing ~/.orch/config.yaml file", :yellow
18
+ answer = yes? "Proceed?", :yellow
19
+ if answer == false
20
+ exit 0
21
+ end
22
+ end
23
+ say("Enter values to construct a ~/.orch/config.yaml file")
24
+ marathon_url = ask("Marathon URL: ")
25
+ chronos_url = ask("Chronos URL: ")
26
+
27
+ config.setup_config(marathon_url, chronos_url)
28
+ end
29
+
30
+ option :deploy_type, :default => 'all',
31
+ :desc => 'chronos, marathon, all'
32
+ option :env_type, :default => 'all',
33
+ :desc => 'a valid environment defined in your config or all to deploy to all environments'
34
+ option :subst,
35
+ :desc => 'KEY=VALUE substitute KEY with VALUE globaly in your config'
36
+ option :show_json, :default => false,
37
+ :desc => 'show the json result that would be sent to Chronos or Marathon'
38
+ desc 'verify PATH', 'Checks basic syntax and does not deploy'
39
+ def verify(file_name)
40
+ parser = Orch::Parse.new(file_name, options)
41
+ result = parser.parse(true)
42
+ puts "Number of configs found: #{result.length}"
43
+ deploy = Orch::Deploy.new(options)
44
+ result.each do |app|
45
+ if parser.hasEnvironments
46
+ puts "Name: #{app[:name]}, Type: #{app[:type]}, Would deploy: #{app[:deploy]}, Environment: #{app[:environment]}"
47
+ else
48
+ puts "Name: #{app[:name]}, Type: #{app[:type]}, Would deploy: #{app[:deploy]}"
49
+ end
50
+ if options[:show_json]
51
+ pretty = JSON.pretty_generate(app[:json])
52
+ puts "JSON: #{pretty}"
53
+ end
54
+ if app[:type] == "Chronos"
55
+ deploy.verify_chronos(app[:json].to_json)
56
+ end
57
+ end
58
+ end
59
+
60
+ option :deploy_type, :default => 'all',
61
+ :desc => 'chronos, marathon, all'
62
+ option :env_type, :default => 'all',
63
+ :desc => 'a valid environment defined in your config or all to deploy to all environments'
64
+ option :chronos_url,
65
+ :desc => 'url to chronos master'
66
+ option :marathon_url,
67
+ :desc => 'url to marathon master'
68
+ option :subst,
69
+ :desc => 'KEY=VALUE substitute KEY with VALUE globaly in your config'
70
+ desc 'deploy PATH', 'Deploys config to mesos frameworks.'
71
+ def deploy(file_name)
72
+ parser = Orch::Parse.new(file_name, options)
73
+ result = parser.parse(false)
74
+
75
+ if result.length == 0
76
+ puts "nothing found to deploy"
77
+ end
78
+
79
+ deploy = Orch::Deploy.new(options)
80
+ result.each do |app|
81
+ if !app[:deploy]
82
+ puts "skipping app: #{app[:name]}"
83
+ next
84
+ end
85
+ puts "deploying #{app[:name]} to #{app[:type]}"
86
+ #puts "#{app[:json]}" - should I support show_json here as well?
87
+ if app[:type] == "Chronos"
88
+ deploy.deploy_chronos(app[:json].to_json)
89
+ end
90
+ if app[:type] == "Marathon"
91
+ deploy.deploy_marathon(app[:json].to_json)
92
+ end
93
+ end
94
+ end
95
+
96
+ end
97
+ end
data/lib/parse.rb ADDED
@@ -0,0 +1,209 @@
1
+ require 'yaml'
2
+ require 'json'
3
+
4
+ module Orch
5
+ class Parse
6
+ attr_reader :hasEnvironments
7
+
8
+ def initialize(path, options)
9
+ if ! File.file?(path)
10
+ puts "file does not exist: #{path}"
11
+ exit 1
12
+ end
13
+ # TODO: try resecue for any syntax issues in yaml file
14
+ yaml = ::YAML.load_file(path)
15
+ #puts yaml.to_json
16
+
17
+ @options = options
18
+
19
+ @spec = Hashie::Mash.new(yaml)
20
+ end
21
+
22
+ def parse(dry_run)
23
+ @dry_run = dry_run
24
+ check_option_syntax
25
+ spec = @spec
26
+
27
+ # Check for valid version paramter
28
+ if spec.version.nil?
29
+ puts "required field version was not found"
30
+ exit 1
31
+ end
32
+ if spec.version != "alpha1"
33
+ puts "unsupported orch version specified: #{spec.version}"
34
+ puts "application only understands version alpha1"
35
+ exit 1
36
+ end
37
+
38
+ # Does this config support environments
39
+ @hasEnvironments = false
40
+ defined_environments = {}
41
+ if (! spec.environments.nil?)
42
+ @hasEnvironments = true
43
+ spec.environments.each do |e|
44
+ defined_environments[e] = e
45
+ end
46
+ end
47
+
48
+ if (! spec.environments_var.nil?)
49
+ @environments_var = spec.environments_var
50
+ end
51
+
52
+ if spec.applications.nil?
53
+ puts "required section applications: must have at least one application defined"
54
+ exit 1
55
+ end
56
+
57
+ results = []
58
+ spec.applications.each do |app|
59
+ # Check for valid kind paramter
60
+ if app.kind.nil?
61
+ puts "required field kind was not found"
62
+ exit 1
63
+ end
64
+
65
+
66
+ if !(app.kind == "Chronos" || app.kind == "Marathon")
67
+ puts "unsupported kind specified: #{app.kind} - must be: Chronos | Marathon"
68
+ exit 1
69
+ end
70
+
71
+ if @hasEnvironments
72
+ if !defined_environments.has_key?(app.environment)
73
+ puts "environment \"#{app.environment}\" not defined in environments"
74
+ exit 1
75
+ end
76
+ end
77
+
78
+ if (app.kind == "Chronos")
79
+ chronos_spec = parse_chronos(app)
80
+
81
+ result = {:name => chronos_spec["name"], :type => app.kind, :deploy => should_deploy?(app), :json => chronos_spec}
82
+ if @hasEnvironments
83
+ result[:environment] = app.environment
84
+ end
85
+ results << result
86
+ end
87
+
88
+ if (app.kind == "Marathon")
89
+ marathon_spec = parse_marathon(app)
90
+
91
+ result = {:name => marathon_spec["id"], :type => app.kind, :deploy => should_deploy?(app), :json => marathon_spec}
92
+ if @hasEnvironments
93
+ result[:environment] = app.environment
94
+ end
95
+ results << result
96
+ end
97
+ end
98
+
99
+ return results
100
+ end
101
+
102
+ def parse_chronos(app)
103
+ # TODO: check if it exists
104
+ cronos_spec = app.cronos_spec
105
+
106
+ # This adds environment vaiables to the spec that conform to our docker-wrapper security hack
107
+ if ! app.vault.nil?
108
+ # TODO: check that an environment was defined
109
+ if (! @hasEnvironments) || app.environment.nil?
110
+ puts "the vault feature requires an environment to be set"
111
+ exit 1
112
+ end
113
+
114
+ count = 1
115
+ cronos_spec.environmentVariables ||= []
116
+ app.vault.each do |vault_key|
117
+ # Add an environment
118
+ pair = {"name" => "VAULT_KEY_#{count}", "value" => vault_key}
119
+ count += 1
120
+ cronos_spec.environmentVariables << pair
121
+ end
122
+ end
123
+
124
+ if (! @environments_var.nil?)
125
+ pair = {"name" => @environments_var, "value" => app.environment}
126
+ cronos_spec.environmentVariables << pair
127
+ end
128
+
129
+ # Do subst processing
130
+ spec_str = do_subst(cronos_spec, app)
131
+ cronos_spec = JSON.parse(spec_str)
132
+
133
+ return cronos_spec
134
+ end
135
+
136
+ def parse_marathon(app)
137
+ # TODO: check if it exists
138
+ marathon_spec = app.marathon_spec
139
+
140
+ # This adds environment vaiables to the spec that conform to our docker-wrapper security hack
141
+ if ! app.vault.nil?
142
+ # TODO: check that an environment was defined
143
+ if (! @hasEnvironments) || app.environment.nil?
144
+ puts "the vault feature requires an environment to be set"
145
+ exit 1
146
+ end
147
+
148
+ count = 1
149
+ marathon_spec.env ||= {}
150
+ app.vault.each do |vault_key|
151
+ # Add an environment
152
+ marathon_spec.env["VAULT_KEY_#{count}"] = vault_key
153
+ count += 1
154
+ end
155
+ end
156
+
157
+ if (! @environments_var.nil?)
158
+ marathon_spec.env[@environments_var] = app.environment
159
+ end
160
+
161
+ spec_str = do_subst(marathon_spec, app)
162
+ marathon_spec = JSON.parse(spec_str)
163
+
164
+ return marathon_spec
165
+ end
166
+
167
+ def should_deploy?(app)
168
+ result = true
169
+ if (app.kind == "Marathon") && @options[:deploy_type] == 'chronos'
170
+ result = false
171
+ end
172
+ if (app.kind == "Chronos") && @options[:deploy_type] == 'marathon'
173
+ result = false
174
+ end
175
+ if @options[:env_type] != 'all'
176
+ if @options[:env_type] != app.environment
177
+ result = false
178
+ end
179
+ end
180
+
181
+ return result
182
+ end
183
+
184
+ def do_subst(spec, app)
185
+ # {{ENV}} is a special value
186
+ spec_str = spec.to_json.to_s.gsub(/{{ENV}}/, app.environment)
187
+
188
+ if ! @options[:subst].nil?
189
+ @options[:subst].split(",").each do |x|
190
+ pair = x.split("=")
191
+ spec_str = spec_str.gsub(/{{#{pair[0]}}}/, pair[1])
192
+ end
193
+ end
194
+
195
+ return spec_str
196
+ end
197
+
198
+ def check_option_syntax
199
+ if @dry_run
200
+ return
201
+ end
202
+
203
+ if ! ['chronos', 'marathon', 'all'].include?(@options[:deploy_type])
204
+ puts "value of --deploy-type was #{@options[:deploy_type]}, must be chronos, marathon or all"
205
+ exit 1
206
+ end
207
+ end
208
+ end
209
+ end
data/orch.gemspec ADDED
@@ -0,0 +1,27 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'orch/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "orch"
8
+ spec.version = Orch::VERSION
9
+ spec.authors = ["Ray Johnson"]
10
+ spec.email = ["rjohnson@yp.com"]
11
+ spec.summary = %q{orch uses yaml to deploy to Mesos' Marathon and Chronos frameworks}
12
+ spec.description = %q{orch uses yaml to deploy to Mesos' Marathon and Chronos frameworks}
13
+ spec.homepage = "https://github.com/rayjohnson/orch"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.6"
22
+ spec.add_development_dependency "rake"
23
+
24
+ spec.add_dependency 'thor', '~> 0.18'
25
+ spec.add_dependency 'hashie'
26
+
27
+ end
metadata ADDED
@@ -0,0 +1,116 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: orch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Ray Johnson
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-08-21 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: '1.6'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: '1.6'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: thor
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '0.18'
48
+ type: :runtime
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '0.18'
55
+ - !ruby/object:Gem::Dependency
56
+ name: hashie
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :runtime
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ description: orch uses yaml to deploy to Mesos' Marathon and Chronos frameworks
70
+ email:
71
+ - rjohnson@yp.com
72
+ executables:
73
+ - orch
74
+ extensions: []
75
+ extra_rdoc_files: []
76
+ files:
77
+ - .gitignore
78
+ - Gemfile
79
+ - LICENSE.txt
80
+ - README.md
81
+ - Rakefile
82
+ - bin/orch
83
+ - examples/env-chronos.yml
84
+ - examples/simple-chronos.yml
85
+ - examples/simple-marathon.yml
86
+ - lib/config.rb
87
+ - lib/deploy.rb
88
+ - lib/orch.rb
89
+ - lib/orch/version.rb
90
+ - lib/parse.rb
91
+ - orch.gemspec
92
+ homepage: https://github.com/rayjohnson/orch
93
+ licenses:
94
+ - MIT
95
+ metadata: {}
96
+ post_install_message:
97
+ rdoc_options: []
98
+ require_paths:
99
+ - lib
100
+ required_ruby_version: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - '>='
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ required_rubygems_version: !ruby/object:Gem::Requirement
106
+ requirements:
107
+ - - '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ requirements: []
111
+ rubyforge_project:
112
+ rubygems_version: 2.4.6
113
+ signing_key:
114
+ specification_version: 4
115
+ summary: orch uses yaml to deploy to Mesos' Marathon and Chronos frameworks
116
+ test_files: []