mcg 0.1.2
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 +7 -0
- data/.gitignore +9 -0
- data/.travis.yml +3 -0
- data/Gemfile +4 -0
- data/README.md +86 -0
- data/Rakefile +1 -0
- data/bin/mcg +23 -0
- data/lib/mcg.rb +76 -0
- data/lib/mcg/action.rb +22 -0
- data/lib/mcg/data.rb +41 -0
- data/lib/mcg/server.rb +16 -0
- data/lib/mcg/version.rb +3 -0
- data/mcg.gemspec +26 -0
- metadata +101 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 97b5139404c248d29de4e559176937bce91edfe6
|
4
|
+
data.tar.gz: 9f9387eb45b759cdbf653abe305b30261518324e
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: e08d97de1c340d660786c494c745c5852168da79e7036a48f7f1008546e77952fff0f4dcf0e5499ccd6593ace64c0b385358fec397f145372eea0b7a42e691be
|
7
|
+
data.tar.gz: 1f92bb98dfafa445ae664ac91b8a694b8e591cfc47646c7c551f44ff81659d57714aa0971bf0193ebc1acb2069f44f7f0a44bda85468ca90a082b96ee8bbdd5c
|
data/.gitignore
ADDED
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
# MCG
|
2
|
+
|
3
|
+
MCG is a web daemon that automatically generate file from template and execute commands for web services deployed on Apache Mesos and Marathon.
|
4
|
+
|
5
|
+
## Installation
|
6
|
+
|
7
|
+
Add this line to your application's Gemfile:
|
8
|
+
|
9
|
+
```ruby
|
10
|
+
gem 'mcg'
|
11
|
+
```
|
12
|
+
|
13
|
+
And then execute:
|
14
|
+
|
15
|
+
$ bundle
|
16
|
+
|
17
|
+
Or install it yourself as:
|
18
|
+
|
19
|
+
$ gem install mcg
|
20
|
+
|
21
|
+
## Usage
|
22
|
+
|
23
|
+
Create configuration file like this exemple:
|
24
|
+
|
25
|
+
```json
|
26
|
+
{
|
27
|
+
"bind": "127.0.0.1",
|
28
|
+
"port": 8000,
|
29
|
+
"marathon": "http://localhost:8080",
|
30
|
+
"host": "http://127.0.0.1:8000/callback",
|
31
|
+
"actions": {
|
32
|
+
"apache": {
|
33
|
+
"template": "/etc/mgc/apache-template.conf.erb",
|
34
|
+
"output": "/etc/apache2/sites-enabled/all_site",
|
35
|
+
"reload_command": "apachectl -t && apachectl graceful"
|
36
|
+
}
|
37
|
+
}
|
38
|
+
}
|
39
|
+
```
|
40
|
+
|
41
|
+
and template like this exemple:
|
42
|
+
|
43
|
+
```
|
44
|
+
<% @data.tasks.each do |name, conf| %>
|
45
|
+
# Generated configuration for <%= name %>
|
46
|
+
|
47
|
+
<VirtualHost *:80>
|
48
|
+
ServerAdmin admin@foo.fr
|
49
|
+
ServerName <%= name %>
|
50
|
+
|
51
|
+
ProxyRequests Off
|
52
|
+
ProxyPreserveHost On
|
53
|
+
SetEnv proxy-sendcl 1
|
54
|
+
|
55
|
+
<Proxy balancer://<%= name.gsub(/[\.-]/, '_') %>>
|
56
|
+
<% conf.each do |c| %>
|
57
|
+
BalancerMember <%= c[:host] %>:<%= c[:port] %>
|
58
|
+
<% end %>
|
59
|
+
</Proxy>
|
60
|
+
|
61
|
+
ProxyPass / balancer://<%= name.gsub(/[\.-]/, '_') %>/
|
62
|
+
ProxyPassReverse / balancer://<%= name.gsub(/[\.-]/, '_') %>/
|
63
|
+
|
64
|
+
</VirtualHost>
|
65
|
+
<% end %>
|
66
|
+
```
|
67
|
+
|
68
|
+
and start the daemon like this:
|
69
|
+
|
70
|
+
```
|
71
|
+
mcg -f conf.json
|
72
|
+
```
|
73
|
+
|
74
|
+
## Development
|
75
|
+
|
76
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `bin/console` for an interactive prompt that will allow you to experiment.
|
77
|
+
|
78
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release` to create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
79
|
+
|
80
|
+
## Contributing
|
81
|
+
|
82
|
+
1. Fork it ( https://github.com/pojer-s/mcg/fork )
|
83
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
84
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
85
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
86
|
+
5. Create a new Pull Request
|
data/Rakefile
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
data/bin/mcg
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'mcg'
|
4
|
+
require 'optparse'
|
5
|
+
require 'json'
|
6
|
+
|
7
|
+
options = {}
|
8
|
+
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.banner = "Usage: example.rb [options]"
|
11
|
+
|
12
|
+
opts.on("-f FILE", "--config-file FILE", "Config file") do |v|
|
13
|
+
options[:config_file] = v
|
14
|
+
end
|
15
|
+
end.parse!
|
16
|
+
|
17
|
+
config = JSON.parse(IO.read(options[:config_file]))
|
18
|
+
|
19
|
+
mcg = MCG.new(config)
|
20
|
+
mcg.generate
|
21
|
+
mcg.subscribe
|
22
|
+
mcg.start
|
23
|
+
mcg.unsubscribe
|
data/lib/mcg.rb
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
require "mcg/version"
|
5
|
+
require "mcg/action"
|
6
|
+
require "mcg/data"
|
7
|
+
require "mcg/server"
|
8
|
+
|
9
|
+
class MCG
|
10
|
+
|
11
|
+
def initialize(config=nil)
|
12
|
+
@config = {
|
13
|
+
"bind" => "127.0.0.1",
|
14
|
+
"port" => 8000,
|
15
|
+
"marathon" => "http://localhost:8080",
|
16
|
+
"actions" => {}
|
17
|
+
}
|
18
|
+
@config.merge! config
|
19
|
+
@data = Data.new(@config["marathon"])
|
20
|
+
@actions = {}
|
21
|
+
@config["actions"].each do |action_name, action_value|
|
22
|
+
add_action(action_name,
|
23
|
+
action_value["template"],
|
24
|
+
action_value["output"],
|
25
|
+
action_value["reload_command"])
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def add_action(name, template, output, reload_command)
|
30
|
+
@actions[name] = Action.new(template, output, reload_command)
|
31
|
+
end
|
32
|
+
|
33
|
+
def generate
|
34
|
+
@data.get
|
35
|
+
@actions.each do |name, action|
|
36
|
+
action.render(@data)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def subscribe
|
41
|
+
uri = URI.parse(@config["marathon"] + '/v2/eventSubscriptions')
|
42
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
43
|
+
req = Net::HTTP::Get.new(uri.path, initheader = {'Accept' =>'application/json'})
|
44
|
+
resp = http.request(req)
|
45
|
+
data = JSON.parse(resp.body)
|
46
|
+
if resp.code.to_i == 200
|
47
|
+
unless data["callbackUrls"].include?(@config["host"])
|
48
|
+
request = Net::HTTP::Post.new(uri.path + "?callbackUrl=#{@config["host"]}")
|
49
|
+
request.add_field('Content-Type', 'application/json')
|
50
|
+
resp = http.request(request)
|
51
|
+
data = JSON.parse(resp.body)
|
52
|
+
unless resp.code.to_i == 200
|
53
|
+
raise "Cannot subscribe to #{@config["marathon"]}. Error: #{data["message"]}"
|
54
|
+
end
|
55
|
+
end
|
56
|
+
else
|
57
|
+
raise "Error: #{data["message"]}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def unsubscribe
|
62
|
+
uri = URI.parse(@config["marathon"] + '/v2/eventSubscriptions')
|
63
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
64
|
+
request = Net::HTTP::Delete.new(uri.path + "?callbackUrl=#{@config["host"]}")
|
65
|
+
request.add_field('Content-Type', 'application/json')
|
66
|
+
resp = http.request(request)
|
67
|
+
data = JSON.parse(resp.body)
|
68
|
+
unless resp.code.to_i == 200
|
69
|
+
raise "Cannot unsubscribe to #{@config["marathon"]}. Error: #{data["message"]}"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
def start
|
74
|
+
Server.run!({:bind => @config["bind"], :port => @config["port"], :mcg => self})
|
75
|
+
end
|
76
|
+
end
|
data/lib/mcg/action.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'erb'
|
2
|
+
|
3
|
+
class MCG
|
4
|
+
|
5
|
+
class Action
|
6
|
+
|
7
|
+
def initialize(template, output, reload_command)
|
8
|
+
@template = IO.read(template)
|
9
|
+
@output = output
|
10
|
+
@reload_command = reload_command
|
11
|
+
end
|
12
|
+
|
13
|
+
def render(data)
|
14
|
+
@data = data
|
15
|
+
b = binding
|
16
|
+
renderer = ERB.new(@template)
|
17
|
+
IO.write(@output, renderer.result(b))
|
18
|
+
`#{@reload_command}`
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
22
|
+
end
|
data/lib/mcg/data.rb
ADDED
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'json'
|
2
|
+
require 'net/http'
|
3
|
+
|
4
|
+
class MCG
|
5
|
+
|
6
|
+
class Data
|
7
|
+
|
8
|
+
attr_reader :data
|
9
|
+
attr_reader :tasks
|
10
|
+
|
11
|
+
def initialize(marathon_url)
|
12
|
+
@marathon_url = marathon_url
|
13
|
+
@data = nil
|
14
|
+
@tasks = nil
|
15
|
+
end
|
16
|
+
|
17
|
+
def get
|
18
|
+
uri = URI.parse(@marathon_url + '/v2/tasks')
|
19
|
+
http = Net::HTTP.new(uri.host, uri.port)
|
20
|
+
req = Net::HTTP::Get.new(uri.path, initheader = {'Accept' =>'application/json'})
|
21
|
+
resp = http.request(req)
|
22
|
+
@data = JSON.parse(resp.body)
|
23
|
+
order_task
|
24
|
+
end
|
25
|
+
|
26
|
+
def order_task
|
27
|
+
@tasks = Hash.new { |h, k| h[k] = [] }
|
28
|
+
|
29
|
+
@data["tasks"].each do |task|
|
30
|
+
fqdn = task["appId"][/\/([^\/]+)\//, 1]
|
31
|
+
task["ports"].each do |port|
|
32
|
+
@tasks[fqdn] << {
|
33
|
+
:host => task["host"],
|
34
|
+
:port => port
|
35
|
+
}
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
41
|
+
end
|
data/lib/mcg/server.rb
ADDED
data/lib/mcg/version.rb
ADDED
data/mcg.gemspec
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'mcg/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "mcg"
|
8
|
+
spec.version = MCG::VERSION
|
9
|
+
spec.authors = ["Steven Pojer"]
|
10
|
+
spec.email = ["steven.pojer@gmail.com"]
|
11
|
+
|
12
|
+
spec.summary = "MCG is a web daemon that automatically generate file from template and execute commands for web services deployed on Apache Mesos and Marathon."
|
13
|
+
spec.description = spec.summary
|
14
|
+
spec.homepage = "https://github.com/pojer-s/mgc"
|
15
|
+
spec.license = "Apache-2.0"
|
16
|
+
|
17
|
+
spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
18
|
+
spec.bindir = "bin"
|
19
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
20
|
+
spec.require_paths = ["lib"]
|
21
|
+
|
22
|
+
spec.add_runtime_dependency "sinatra", ">= 0"
|
23
|
+
|
24
|
+
spec.add_development_dependency "bundler", "~> 1.9"
|
25
|
+
spec.add_development_dependency "rake", "~> 10.0"
|
26
|
+
end
|
metadata
ADDED
@@ -0,0 +1,101 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mcg
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.2
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Steven Pojer
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2015-07-16 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: sinatra
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '>='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '>='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ~>
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '1.9'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ~>
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '1.9'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - ~>
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '10.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - ~>
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '10.0'
|
55
|
+
description: MCG is a web daemon that automatically generate file from template and
|
56
|
+
execute commands for web services deployed on Apache Mesos and Marathon.
|
57
|
+
email:
|
58
|
+
- steven.pojer@gmail.com
|
59
|
+
executables:
|
60
|
+
- mcg
|
61
|
+
extensions: []
|
62
|
+
extra_rdoc_files: []
|
63
|
+
files:
|
64
|
+
- .gitignore
|
65
|
+
- .travis.yml
|
66
|
+
- Gemfile
|
67
|
+
- README.md
|
68
|
+
- Rakefile
|
69
|
+
- bin/mcg
|
70
|
+
- lib/mcg.rb
|
71
|
+
- lib/mcg/action.rb
|
72
|
+
- lib/mcg/data.rb
|
73
|
+
- lib/mcg/server.rb
|
74
|
+
- lib/mcg/version.rb
|
75
|
+
- mcg.gemspec
|
76
|
+
homepage: https://github.com/pojer-s/mgc
|
77
|
+
licenses:
|
78
|
+
- Apache-2.0
|
79
|
+
metadata: {}
|
80
|
+
post_install_message:
|
81
|
+
rdoc_options: []
|
82
|
+
require_paths:
|
83
|
+
- lib
|
84
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
85
|
+
requirements:
|
86
|
+
- - '>='
|
87
|
+
- !ruby/object:Gem::Version
|
88
|
+
version: '0'
|
89
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - '>='
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '0'
|
94
|
+
requirements: []
|
95
|
+
rubyforge_project:
|
96
|
+
rubygems_version: 2.4.6
|
97
|
+
signing_key:
|
98
|
+
specification_version: 4
|
99
|
+
summary: MCG is a web daemon that automatically generate file from template and execute
|
100
|
+
commands for web services deployed on Apache Mesos and Marathon.
|
101
|
+
test_files: []
|