mio-config 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (81) hide show
  1. checksums.yaml +7 -0
  2. data/#mio-config.gemspec# +23 -0
  3. data/Gemfile +16 -0
  4. data/Gemfile.lock +68 -0
  5. data/LICENCE.md +8 -0
  6. data/README.md +162 -0
  7. data/Rakefile +7 -0
  8. data/circle.yml +3 -0
  9. data/config/mio.yml +4 -0
  10. data/coverage/assets/0.10.0/application.css +799 -0
  11. data/coverage/assets/0.10.0/application.js +1707 -0
  12. data/coverage/assets/0.10.0/colorbox/border.png +0 -0
  13. data/coverage/assets/0.10.0/colorbox/controls.png +0 -0
  14. data/coverage/assets/0.10.0/colorbox/loading.gif +0 -0
  15. data/coverage/assets/0.10.0/colorbox/loading_background.png +0 -0
  16. data/coverage/assets/0.10.0/favicon_green.png +0 -0
  17. data/coverage/assets/0.10.0/favicon_red.png +0 -0
  18. data/coverage/assets/0.10.0/favicon_yellow.png +0 -0
  19. data/coverage/assets/0.10.0/loading.gif +0 -0
  20. data/coverage/assets/0.10.0/magnify.png +0 -0
  21. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_0_aaaaaa_40x100.png +0 -0
  22. data/coverage/assets/0.10.0/smoothness/images/ui-bg_flat_75_ffffff_40x100.png +0 -0
  23. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_55_fbf9ee_1x400.png +0 -0
  24. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_65_ffffff_1x400.png +0 -0
  25. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_dadada_1x400.png +0 -0
  26. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_75_e6e6e6_1x400.png +0 -0
  27. data/coverage/assets/0.10.0/smoothness/images/ui-bg_glass_95_fef1ec_1x400.png +0 -0
  28. data/coverage/assets/0.10.0/smoothness/images/ui-bg_highlight-soft_75_cccccc_1x100.png +0 -0
  29. data/coverage/assets/0.10.0/smoothness/images/ui-icons_222222_256x240.png +0 -0
  30. data/coverage/assets/0.10.0/smoothness/images/ui-icons_2e83ff_256x240.png +0 -0
  31. data/coverage/assets/0.10.0/smoothness/images/ui-icons_454545_256x240.png +0 -0
  32. data/coverage/assets/0.10.0/smoothness/images/ui-icons_888888_256x240.png +0 -0
  33. data/coverage/assets/0.10.0/smoothness/images/ui-icons_cd0a0a_256x240.png +0 -0
  34. data/coverage/index.html +4884 -0
  35. data/lib/mio.rb +24 -0
  36. data/lib/mio/#model.rb# +130 -0
  37. data/lib/mio/client.rb +106 -0
  38. data/lib/mio/config.rb +14 -0
  39. data/lib/mio/errors.rb +18 -0
  40. data/lib/mio/migrations.rb +96 -0
  41. data/lib/mio/model.rb +133 -0
  42. data/lib/mio/model/autoload.rb +7 -0
  43. data/lib/mio/model/groovy_script.rb +40 -0
  44. data/lib/mio/model/groovy_script_wait.rb +44 -0
  45. data/lib/mio/model/hotfolder.rb +56 -0
  46. data/lib/mio/model/import_action.rb +69 -0
  47. data/lib/mio/model/s3.rb +37 -0
  48. data/lib/mio/model/workflow.rb +98 -0
  49. data/lib/mio/model/workflow/node.rb +35 -0
  50. data/lib/mio/model/workflow/transition.rb +20 -0
  51. data/lib/mio/requests.rb +16 -0
  52. data/lib/mio/search.rb +29 -0
  53. data/lib/mio/tasks.rb +5 -0
  54. data/lib/mio/tasks/migrations.rb +17 -0
  55. data/lib/mio/tasks/skeletons.rb +38 -0
  56. data/migrations/20160429130853_create-an-s3-bucket-for-ingestion.rb +11 -0
  57. data/mio-config.gemspec +24 -0
  58. data/notes +1 -0
  59. data/spec/factories/client_factories.rb +41 -0
  60. data/spec/factories/mio_factories.rb +9 -0
  61. data/spec/factories/model_factories.rb +128 -0
  62. data/spec/fixtures/vcr_cassettes/client.yml +2415 -0
  63. data/spec/fixtures/vcr_cassettes/client.yml~ +2141 -0
  64. data/spec/lib/mio/client_spec.rb +79 -0
  65. data/spec/lib/mio/config_spec.rb +11 -0
  66. data/spec/lib/mio/model/groovy_script_spec.rb +13 -0
  67. data/spec/lib/mio/model/groovy_script_wait_spec.rb +13 -0
  68. data/spec/lib/mio/model/hotfolder_spec.rb +13 -0
  69. data/spec/lib/mio/model/import_action_spec.rb +13 -0
  70. data/spec/lib/mio/model/s3_spec.rb +13 -0
  71. data/spec/lib/mio/model/workflow/node_spec.rb +35 -0
  72. data/spec/lib/mio/model/workflow/transition_spec.rb +12 -0
  73. data/spec/lib/mio/model/workflow_spec.rb +38 -0
  74. data/spec/lib/mio/search_spec.rb +37 -0
  75. data/spec/lib/mio_spec.rb +30 -0
  76. data/spec/spec_helper.rb +16 -0
  77. data/spec/support/factory_girl.rb +3 -0
  78. data/spec/support/shared_examples_for_client.rb +27 -0
  79. data/spec/support/shared_examples_for_model.rb +87 -0
  80. data/spec/support/vcr.rb +12 -0
  81. metadata +195 -0
data/lib/mio.rb ADDED
@@ -0,0 +1,24 @@
1
+ require 'mio/client'
2
+ require 'mio/search'
3
+ require 'mio/errors'
4
+
5
+ require 'mio/model'
6
+ require 'mio/model/autoload'
7
+
8
+ class Mio
9
+
10
+ attr_accessor :base_uri, :username, :password
11
+ attr_reader :client
12
+ def initialize base_uri=nil, username=nil, password=nil
13
+ @base_uri = base_uri
14
+ @username = username
15
+ @password = password
16
+
17
+ if block_given?
18
+ yield self
19
+ end
20
+
21
+ @client = Mio::Client.new @base_uri, @username, @password
22
+ end
23
+
24
+ end
@@ -0,0 +1,130 @@
1
+ class Mio
2
+ class Model
3
+ class << self
4
+ attr_accessor :fields, :resource_name
5
+ def set_resource r
6
+ @resource_name = r.to_s
7
+ end
8
+
9
+ def field key, type, desc, default=nil, matcher=nil
10
+ @fields ||= []
11
+ @fields << {name: key,
12
+ type: type,
13
+ default: default,
14
+ matcher: matcher,
15
+ desc: desc,}
16
+
17
+ end
18
+
19
+ def nested val=nil
20
+ if val.nil?
21
+ @nested_value || false
22
+ else
23
+ @nested_value = val
24
+ end
25
+ end
26
+ alias_method :nested?, :nested
27
+
28
+ def mappings
29
+ m = {}
30
+ ObjectSpace.each_object(Class).each do |k|
31
+ if k < Mio::Model
32
+ m[ k.to_s.split('::').last.downcase ] = k
33
+ end
34
+ end
35
+ m
36
+ end
37
+ end
38
+
39
+ def initialize client, args
40
+ @client = client
41
+ @args = args
42
+ @search = Mio::Search.new @client
43
+ end
44
+
45
+ def go
46
+ unless look_up
47
+ @object = create
48
+ else
49
+ @object = look_up
50
+
51
+ # We can't edit a running resource
52
+ set_start :stop
53
+ end
54
+
55
+ configure if self.respond_to? :config_hash
56
+ set_enable
57
+ set_start
58
+
59
+ return @object
60
+ end
61
+
62
+ def create
63
+ @client.create self.class.resource_name, create_hash
64
+ end
65
+
66
+ def configure
67
+ @client.configure self.class.resource_name,
68
+ @object['id'],
69
+ config_hash
70
+ end
71
+
72
+ def set_enable a=nil
73
+ if a.nil?
74
+ action = @args.enable == :true ? 'enable' : 'disable'
75
+ else
76
+ action = a.to_s
77
+ end
78
+ @client.action self.class.resource_name,
79
+ @object['id'],
80
+ {action: action}
81
+ end
82
+ alias_method :disable!, :set_enable
83
+ alias_method :enable!, :set_enable
84
+
85
+ def set_start a=nil
86
+ if a.nil?
87
+ action = @args.start == :true ? 'start' : 'stop'
88
+ else
89
+ action = a.to_s
90
+ end
91
+ @client.action self.class.resource_name,
92
+ @object['id'],
93
+ {action: action}
94
+ end
95
+ alias_method :stop!, :set_start
96
+ alias_method :start!, :set_start
97
+
98
+ def validate
99
+ testable = @args.dup.to_h
100
+
101
+ self.class.fields.each do |f|
102
+ unless testable.key? f[:name]
103
+ raise Mio::Model::MissingField, "Missing field #{f[:name]} to #{self}"
104
+ end
105
+
106
+ extracted_field = testable.delete f[:name]
107
+ unless extracted_field.is_a? f[:type]
108
+ raise Mio::Model::DataTypeError, "#{f[:name]} should be of type #{f[:type]} for #{self}"
109
+ end
110
+
111
+ unless f['matcher'].nil? or extracted_field.to_s.match(f[:matcher])
112
+ raise Mio::Model::DataValueError, "#{self} #{f[:name]} value '#{extracted_field}' does not match #{f[:matcher]}"
113
+ end
114
+ end
115
+
116
+ testable.keys.each do |k|
117
+ raise Mio::Model::NoSuchField, "#{k} for #{self}"
118
+ end
119
+ true
120
+ end
121
+ alias_method :valid?, :validate
122
+
123
+ private
124
+ def look_up
125
+ r = self.class.resource_name
126
+ @client.find_all(r)[r].find{|o| o['name'] == @args.name}
127
+ end
128
+ end
129
+
130
+ end
data/lib/mio/client.rb ADDED
@@ -0,0 +1,106 @@
1
+ require 'faraday'
2
+ require 'faraday/detailed_logger'
3
+ require 'hashie/mash'
4
+ require 'net/http/persistent'
5
+ require 'json'
6
+
7
+ require 'pp'
8
+
9
+ require 'mio/requests'
10
+
11
+ class Mio
12
+ class Client
13
+
14
+ def initialize base_uri, username, password
15
+ @base_uri = base_uri
16
+ @agent = Faraday.new(url: base_uri) do |f|
17
+ f.adapter :net_http_persistent
18
+ f.response :detailed_logger if ENV.fetch('VERBOSE', 'false').to_s.downcase == 'true'
19
+ end
20
+ @agent.basic_auth(username, password)
21
+ end
22
+
23
+ def find_all resource, opts={}
24
+ url = path(resource)
25
+ response = get url, opts
26
+
27
+ unless response.success?
28
+ raise Mio::Client::LoadOfBollocks, "GET on #{url} returned #{response.status}"
29
+ end
30
+ make_object response.body
31
+ end
32
+
33
+ def create resource, payload, opts={}
34
+ url = path(resource)
35
+ response = post url, payload, opts
36
+ unless response.success?
37
+ raise Mio::Client::LoadOfBollocks, "POST on #{url}, with #{payload.inspect} returned #{response.status}"
38
+ end
39
+
40
+ make_object response.body
41
+ end
42
+
43
+ def update resource, payload, opts={}
44
+ url = path(resource)
45
+ response = put url, payload, opts
46
+ unless response.success?
47
+ raise Mio::Client::LoadOfBollocks, "PUT on #{url}, with #{payload.inspect} returned #{response.status}"
48
+ end
49
+
50
+ make_object response.body
51
+ end
52
+
53
+
54
+ def configure resource, id, payload, opts={}
55
+ url = path(resource, id, :configuration)
56
+ response = put url, payload, opts
57
+ unless response.success?
58
+ raise Mio::Client::LoadOfBollocks, "PUT on #{url}, with #{payload.inspect} returned #{response.status}"
59
+ end
60
+
61
+ make_object response.body
62
+ end
63
+
64
+ def action resource, id, payload, opts={}
65
+ url = path(resource, id, :actions)
66
+ statuses = get url, opts
67
+ unless statuses.success?
68
+ raise Mio::Client::LoadOfBollocks, "GET on #{url} returned #{statuses.status}"
69
+ end
70
+
71
+ if JSON.parse(statuses.body).find{|h| h['action'] == payload[:action]}
72
+ response = post url, payload, opts
73
+
74
+ unless response.success?
75
+ raise Mio::Client::LoadOfBollocks, "PUT on #{url}, with #{payload.inspect} returned #{response.status}"
76
+ end
77
+ return make_object response.body
78
+ end
79
+ end
80
+
81
+ private
82
+ def get url, opts
83
+ Mio::Requests.make_request :get, @agent, url, opts
84
+ end
85
+
86
+ def post url, payload, opts
87
+ Mio::Requests.make_request :post, @agent, url, opts, payload
88
+ end
89
+
90
+ def put url, payload, opts
91
+ Mio::Requests.make_request :put, @agent, url, opts, payload
92
+ end
93
+
94
+ def make_object response
95
+ JSON.parse(response)
96
+ end
97
+
98
+ def path resource, id=nil, endpoint=nil
99
+ path_string = "#{@base_uri}/#{resource.sub(/^\//, '')}"
100
+ path_string += "/#{id}" if id
101
+ path_string += "/#{endpoint.to_s}" if endpoint
102
+ path_string
103
+ end
104
+
105
+ end
106
+ end
data/lib/mio/config.rb ADDED
@@ -0,0 +1,14 @@
1
+ require 'hashie/mash'
2
+ require 'yaml'
3
+ require 'erb'
4
+
5
+ class Mio
6
+ class Config
7
+ def self.read filename
8
+ unless File.exist? filename
9
+ raise Mio::Config::FileMissing, "The config file '#{filename}' is missing"
10
+ end
11
+ OpenStruct.new YAML.load( ERB.new(File.read(filename)).result )
12
+ end
13
+ end
14
+ end
data/lib/mio/errors.rb ADDED
@@ -0,0 +1,18 @@
1
+ class Mio
2
+ class Client
3
+ class LoadOfBollocks < ArgumentError ; end
4
+ end
5
+
6
+ class Model
7
+ class NoSuchField < ArgumentError ; end
8
+ class MissingField < ArgumentError ; end
9
+ class DataTypeError < ArgumentError ; end
10
+ class DataValueError < ArgumentError ; end
11
+ class NoSuchResource < ArgumentError ; end
12
+ class EmptyField < ArgumentError ; end
13
+ end
14
+
15
+ class Config
16
+ class FileMissing < IOError ; end
17
+ end
18
+ end
@@ -0,0 +1,96 @@
1
+ require 'mio'
2
+ require 'colorize'
3
+ require 'mio/config'
4
+
5
+ class Mio
6
+ class Migrations
7
+ def initialize base_uri, username, password, base_dir='./migrations'
8
+ @mio = Mio.new do |m|
9
+ m.base_uri = base_uri
10
+ m.username = username
11
+ m.password = password
12
+ end
13
+ @base = File.expand_path(base_dir)
14
+ @migrations = Dir.glob( File.join(@base, '*.rb') ).sort
15
+ end
16
+
17
+ def create_migration_file desc
18
+ File.join(@base,
19
+ "#{Time.now.strftime('%Y%m%d%H%M%S')}_#{desc.gsub(/\W/, '-')}.rb")
20
+ end
21
+
22
+ def run_migrations
23
+ @migrations.each do |migration|
24
+ unless has_run? migration
25
+ load_migration migration
26
+ end
27
+ end
28
+ end
29
+
30
+ def has_run? migration
31
+ false
32
+ end
33
+
34
+ def load_migration migration
35
+ eval File.read(migration)
36
+ end
37
+
38
+ # Helper methods for within the migrations
39
+ def migrate desc, &block
40
+ msg desc, 'starting'
41
+ block.call
42
+
43
+ msg desc, 'completed'
44
+ end
45
+
46
+ def type_migration klass, conf
47
+ if klass.nested?
48
+ get_it klass.new(@mio.client, conf)
49
+ else
50
+ do_it klass.new(@mio.client, conf)
51
+ end
52
+ end
53
+
54
+ def method_missing method_sym, *arguments, &block
55
+ mapped = Mio::Model.mappings[method_sym.to_s]
56
+
57
+ if mapped.nil?
58
+ super
59
+ else
60
+ conf = OpenStruct.new
61
+ yield conf
62
+ type_migration mapped, conf
63
+ end
64
+ end
65
+
66
+ def respond_to? method_sym, include_private=false
67
+ if Mio::Model.mappings[method_sym.to_s].nil?
68
+ super
69
+ else
70
+ true
71
+ end
72
+ end
73
+
74
+ private
75
+ def do_it thing
76
+ if thing.valid?
77
+ obj = thing.go
78
+ end
79
+ puts "Created '#{obj['name']}' with id '#{obj['id']}'"
80
+ end
81
+
82
+ def get_it thing
83
+ if thing.valid?
84
+ return thing.create_hash
85
+ end
86
+ return nil
87
+ end
88
+
89
+
90
+ def msg desc, state
91
+ print '======> '.magenta
92
+ print "#{desc}:\t".cyan
93
+ puts "#{state.upcase}".magenta
94
+ end
95
+ end
96
+ end
data/lib/mio/model.rb ADDED
@@ -0,0 +1,133 @@
1
+ class Mio
2
+ class Model
3
+ class << self
4
+ attr_accessor :fields, :resource_name
5
+ def set_resource r
6
+ @resource_name = r.to_s
7
+ end
8
+
9
+ def field key, type, desc, default=nil, matcher=nil
10
+ @fields ||= []
11
+ @fields << {name: key,
12
+ type: type,
13
+ default: default,
14
+ matcher: matcher,
15
+ desc: desc,}
16
+
17
+ end
18
+
19
+ def nested val=nil
20
+ if val.nil?
21
+ @nested_value || false
22
+ else
23
+ @nested_value = val
24
+ end
25
+ end
26
+ alias_method :nested?, :nested
27
+
28
+ def mappings
29
+ m = {}
30
+ ObjectSpace.each_object(Class).each do |k|
31
+ if k < Mio::Model
32
+ m[ k.to_s.split('::').last.downcase ] = k
33
+ end
34
+ end
35
+ m
36
+ end
37
+ end
38
+
39
+ def initialize client, args
40
+ @client = client
41
+ @args = args
42
+ @search = Mio::Search.new @client
43
+ end
44
+
45
+ def go
46
+ unless look_up
47
+ @object = create
48
+ else
49
+ @object = look_up
50
+
51
+ # We can't edit a running resource
52
+ set_start :stop
53
+ end
54
+
55
+ configure if self.respond_to? :config_hash
56
+ set_enable
57
+ set_start
58
+
59
+ return @object
60
+ end
61
+
62
+ def create
63
+ @client.create self.class.resource_name, create_hash
64
+ end
65
+
66
+ def configure
67
+ @client.configure self.class.resource_name,
68
+ @object['id'],
69
+ config_hash
70
+ end
71
+
72
+ def set_enable a=nil
73
+ if a.nil?
74
+ action = @args.enable == :true ? 'enable' : 'disable'
75
+ else
76
+ action = a.to_s
77
+ end
78
+ @client.action self.class.resource_name,
79
+ @object['id'],
80
+ {action: action}
81
+ end
82
+ alias_method :disable!, :set_enable
83
+ alias_method :enable!, :set_enable
84
+
85
+ def set_start a=nil
86
+ if a.nil?
87
+ action = @args.start == :true ? 'start' : 'stop'
88
+ else
89
+ action = a.to_s
90
+ end
91
+ @client.action self.class.resource_name,
92
+ @object['id'],
93
+ {action: action}
94
+ end
95
+ alias_method :stop!, :set_start
96
+ alias_method :start!, :set_start
97
+
98
+ def validate
99
+ testable = @args.dup.to_h
100
+
101
+ self.class.fields.each do |f|
102
+ unless testable.key? f[:name]
103
+ raise Mio::Model::MissingField, "Missing field #{f[:name]} to #{self}"
104
+ end
105
+
106
+ extracted_field = testable.delete f[:name]
107
+ unless extracted_field.is_a? f[:type]
108
+ raise Mio::Model::DataTypeError, "#{f[:name]} should be of type #{f[:type]} for #{self}"
109
+ end
110
+
111
+ unless f['matcher'].nil? or extracted_field.to_s.match(f[:matcher])
112
+ raise Mio::Model::DataValueError, "#{self} #{f[:name]} value '#{extracted_field}' does not match #{f[:matcher]}"
113
+ end
114
+ end
115
+
116
+ testable.keys.each do |k|
117
+ raise Mio::Model::NoSuchField, "#{k} for #{self}"
118
+ end
119
+ true
120
+ end
121
+ alias_method :valid?, :validate
122
+
123
+ private
124
+ def look_up
125
+ r = self.class.resource_name
126
+ all_resources = @client.find_all(r)
127
+ return nil if all_resources['totalCount'] == 0
128
+
129
+ all_resources[r].find{|o| o['name'] == @args.name}
130
+ end
131
+ end
132
+
133
+ end