etna 0.1.14 → 0.1.20
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 +4 -4
- data/bin/etna +18 -0
- data/etna.completion +1001 -0
- data/etna_app.completion +133 -0
- data/ext/completions/extconf.rb +20 -0
- data/lib/commands.rb +395 -0
- data/lib/etna.rb +7 -0
- data/lib/etna/application.rb +46 -22
- data/lib/etna/client.rb +82 -48
- data/lib/etna/clients.rb +4 -0
- data/lib/etna/clients/enum.rb +9 -0
- data/lib/etna/clients/janus.rb +2 -0
- data/lib/etna/clients/janus/client.rb +73 -0
- data/lib/etna/clients/janus/models.rb +78 -0
- data/lib/etna/clients/magma.rb +4 -0
- data/lib/etna/clients/magma/client.rb +80 -0
- data/lib/etna/clients/magma/formatting.rb +1 -0
- data/lib/etna/clients/magma/formatting/models_csv.rb +354 -0
- data/lib/etna/clients/magma/models.rb +630 -0
- data/lib/etna/clients/magma/workflows.rb +10 -0
- data/lib/etna/clients/magma/workflows/add_project_models_workflow.rb +67 -0
- data/lib/etna/clients/magma/workflows/attribute_actions_from_json_workflow.rb +62 -0
- data/lib/etna/clients/magma/workflows/create_project_workflow.rb +123 -0
- data/lib/etna/clients/magma/workflows/crud_workflow.rb +85 -0
- data/lib/etna/clients/magma/workflows/ensure_containing_record_workflow.rb +44 -0
- data/lib/etna/clients/magma/workflows/file_attributes_blank_workflow.rb +68 -0
- data/lib/etna/clients/magma/workflows/file_linking_workflow.rb +115 -0
- data/lib/etna/clients/magma/workflows/json_converters.rb +81 -0
- data/lib/etna/clients/magma/workflows/json_validators.rb +452 -0
- data/lib/etna/clients/magma/workflows/model_synchronization_workflow.rb +306 -0
- data/lib/etna/clients/magma/workflows/record_synchronization_workflow.rb +63 -0
- data/lib/etna/clients/magma/workflows/update_attributes_from_csv_workflow.rb +246 -0
- data/lib/etna/clients/metis.rb +3 -0
- data/lib/etna/clients/metis/client.rb +239 -0
- data/lib/etna/clients/metis/models.rb +313 -0
- data/lib/etna/clients/metis/workflows.rb +2 -0
- data/lib/etna/clients/metis/workflows/metis_download_workflow.rb +37 -0
- data/lib/etna/clients/metis/workflows/metis_upload_workflow.rb +137 -0
- data/lib/etna/clients/polyphemus.rb +3 -0
- data/lib/etna/clients/polyphemus/client.rb +33 -0
- data/lib/etna/clients/polyphemus/models.rb +68 -0
- data/lib/etna/clients/polyphemus/workflows.rb +1 -0
- data/lib/etna/clients/polyphemus/workflows/set_configuration_workflow.rb +47 -0
- data/lib/etna/command.rb +243 -5
- data/lib/etna/controller.rb +4 -0
- data/lib/etna/csvs.rb +159 -0
- data/lib/etna/directed_graph.rb +56 -0
- data/lib/etna/environment_scoped.rb +19 -0
- data/lib/etna/errors.rb +6 -0
- data/lib/etna/generate_autocompletion_script.rb +131 -0
- data/lib/etna/json_serializable_struct.rb +37 -0
- data/lib/etna/logger.rb +24 -2
- data/lib/etna/multipart_serializable_nested_hash.rb +50 -0
- data/lib/etna/route.rb +1 -1
- data/lib/etna/server.rb +3 -0
- data/lib/etna/spec/vcr.rb +99 -0
- data/lib/etna/templates/attribute_actions_template.json +43 -0
- data/lib/etna/test_auth.rb +3 -1
- data/lib/etna/user.rb +11 -1
- data/lib/helpers.rb +90 -0
- metadata +70 -5
data/lib/etna.rb
CHANGED
@@ -15,3 +15,10 @@ require_relative './etna/describe_routes'
|
|
15
15
|
require_relative './etna/client'
|
16
16
|
require_relative './etna/symbolize_params'
|
17
17
|
require_relative './etna/spec'
|
18
|
+
require_relative './etna/clients'
|
19
|
+
require_relative './etna/csvs'
|
20
|
+
require_relative './etna/environment_scoped'
|
21
|
+
|
22
|
+
class EtnaApp
|
23
|
+
include Etna::Application
|
24
|
+
end
|
data/lib/etna/application.rb
CHANGED
@@ -4,17 +4,31 @@
|
|
4
4
|
# whenever we want to use it as a container
|
5
5
|
|
6
6
|
require_relative './sign_service'
|
7
|
+
require_relative './command'
|
8
|
+
require_relative './generate_autocompletion_script'
|
7
9
|
require 'singleton'
|
10
|
+
require 'rollbar'
|
8
11
|
|
9
12
|
module Etna::Application
|
10
13
|
def self.included(other)
|
11
14
|
other.include Singleton
|
15
|
+
other.include Etna::CommandExecutor
|
16
|
+
@@application = other
|
17
|
+
|
18
|
+
other.const_set(:GenerateCompletionScript, Class.new(Etna::GenerateCompletionScript))
|
12
19
|
end
|
13
20
|
|
14
21
|
def self.find(klass)
|
15
|
-
|
16
|
-
|
17
|
-
|
22
|
+
namespace = klass.name.split('::').first
|
23
|
+
if (namespace_klass = Kernel.const_get(namespace)) && (namespace_klass.respond_to? :instance)
|
24
|
+
return namespace_klass.instance
|
25
|
+
end
|
26
|
+
|
27
|
+
if @@application
|
28
|
+
return @@application.instance
|
29
|
+
end
|
30
|
+
|
31
|
+
raise "Could not find application instance from #{namespace}, and not subclass of Application found."
|
18
32
|
end
|
19
33
|
|
20
34
|
def self.register(app)
|
@@ -31,6 +45,12 @@ module Etna::Application
|
|
31
45
|
|
32
46
|
def configure(opts)
|
33
47
|
@config = opts
|
48
|
+
|
49
|
+
if (rollbar_config = config(:rollbar)) && rollbar_config[:access_token]
|
50
|
+
Rollbar.configure do |config|
|
51
|
+
config.access_token = rollbar_config[:access_token]
|
52
|
+
end
|
53
|
+
end
|
34
54
|
end
|
35
55
|
|
36
56
|
def setup_logger
|
@@ -40,18 +60,27 @@ module Etna::Application
|
|
40
60
|
# Number of old copies of the log to keep.
|
41
61
|
config(:log_copies) || 5,
|
42
62
|
# How large the log can get before overturning.
|
43
|
-
config(:log_size) || 1048576
|
63
|
+
config(:log_size) || 1048576,
|
44
64
|
)
|
45
65
|
log_level = (config(:log_level) || 'warn').upcase.to_sym
|
46
|
-
|
47
66
|
@logger.level = Logger.const_defined?(log_level) ? Logger.const_get(log_level) : Logger::WARN
|
48
67
|
end
|
49
68
|
|
50
69
|
# the application logger is available globally
|
51
70
|
attr_reader :logger
|
52
71
|
|
53
|
-
def config(type)
|
54
|
-
@config
|
72
|
+
def config(type, env = environment)
|
73
|
+
return nil if @config.nil?
|
74
|
+
return nil if @config[env].nil?
|
75
|
+
return nil unless @config[env].is_a?(Hash)
|
76
|
+
@config[env][type]
|
77
|
+
end
|
78
|
+
|
79
|
+
def env_config(env = environment)
|
80
|
+
return nil if @config.nil?
|
81
|
+
return nil if @config[env].nil?
|
82
|
+
return nil unless @config[env].is_a?(Hash)
|
83
|
+
@config[env]
|
55
84
|
end
|
56
85
|
|
57
86
|
def sign
|
@@ -68,23 +97,18 @@ module Etna::Application
|
|
68
97
|
end
|
69
98
|
end
|
70
99
|
|
71
|
-
def run_command(config,
|
72
|
-
cmd =
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
commands[:help].execute
|
100
|
+
def run_command(config, *args, &block)
|
101
|
+
cmd, cmd_args, cmd_kwds = find_command(*args)
|
102
|
+
cmd.setup(config)
|
103
|
+
|
104
|
+
if block_given?
|
105
|
+
return unless yield [cmd, cmd_args]
|
78
106
|
end
|
79
|
-
end
|
80
107
|
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
[ cmd.name, cmd ]
|
86
|
-
end
|
87
|
-
]
|
108
|
+
cmd.execute(*cmd.fill_in_missing_params(cmd_args), **cmd_kwds)
|
109
|
+
rescue => e
|
110
|
+
Rollbar.error(e)
|
111
|
+
raise
|
88
112
|
end
|
89
113
|
end
|
90
114
|
|
data/lib/etna/client.rb
CHANGED
@@ -1,16 +1,20 @@
|
|
1
1
|
require 'net/http/persistent'
|
2
2
|
require 'net/http/post/multipart'
|
3
3
|
require 'singleton'
|
4
|
+
require 'rack/utils'
|
4
5
|
|
5
6
|
module Etna
|
6
7
|
class Client
|
7
|
-
def initialize(host, token)
|
8
|
-
@host = host.sub(%r!/$!,'')
|
8
|
+
def initialize(host, token, routes_available: true, persistent: true, ignore_ssl: false)
|
9
|
+
@host = host.sub(%r!/$!, '')
|
9
10
|
@token = token
|
11
|
+
@persistent = persistent
|
12
|
+
@ignore_ssl = ignore_ssl
|
10
13
|
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
+
if routes_available
|
15
|
+
set_routes
|
16
|
+
define_route_helpers
|
17
|
+
end
|
14
18
|
end
|
15
19
|
|
16
20
|
attr_reader :routes
|
@@ -19,6 +23,29 @@ module Etna
|
|
19
23
|
Etna::Route.path(route[:route], params)
|
20
24
|
end
|
21
25
|
|
26
|
+
def multipart_post(endpoint, content, &block)
|
27
|
+
uri = request_uri(endpoint)
|
28
|
+
multipart = Net::HTTP::Post::Multipart.new uri.request_uri, content
|
29
|
+
multipart.add_field('Authorization', "Etna #{@token}")
|
30
|
+
request(uri, multipart, &block)
|
31
|
+
end
|
32
|
+
|
33
|
+
def post(endpoint, params = {}, &block)
|
34
|
+
body_request(Net::HTTP::Post, endpoint, params, &block)
|
35
|
+
end
|
36
|
+
|
37
|
+
def get(endpoint, params = {}, &block)
|
38
|
+
query_request(Net::HTTP::Get, endpoint, params, &block)
|
39
|
+
end
|
40
|
+
|
41
|
+
def options(endpoint, params = {}, &block)
|
42
|
+
query_request(Net::HTTP::Options, endpoint, params, &block)
|
43
|
+
end
|
44
|
+
|
45
|
+
def delete(endpoint, params = {}, &block)
|
46
|
+
body_request(Net::HTTP::Delete, endpoint, params, &block)
|
47
|
+
end
|
48
|
+
|
22
49
|
private
|
23
50
|
|
24
51
|
def set_routes
|
@@ -30,12 +57,12 @@ module Etna
|
|
30
57
|
def define_route_helpers
|
31
58
|
@routes.each do |route|
|
32
59
|
next unless route[:name]
|
33
|
-
self.define_singleton_method(route[:name]) do |params={}|
|
60
|
+
self.define_singleton_method(route[:name]) do |params = {}|
|
34
61
|
|
35
62
|
missing_params = (route[:params] - params.keys.map(&:to_s))
|
36
63
|
unless missing_params.empty?
|
37
64
|
raise ArgumentError, "Missing required #{missing_params.size > 1 ?
|
38
|
-
|
65
|
+
'params' : 'param'} #{missing_params.join(', ')}"
|
39
66
|
end
|
40
67
|
|
41
68
|
response = send(route[:method].downcase, route_path(route, params), params)
|
@@ -54,45 +81,29 @@ module Etna
|
|
54
81
|
|
55
82
|
def persistent_connection
|
56
83
|
@http ||= begin
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
def multipart_post(endpoint, content, &block)
|
64
|
-
uri = request_uri(endpoint)
|
65
|
-
multipart = Net::HTTP::Post::Multipart.new uri.path, content
|
66
|
-
multipart.add_field('Authorization', "Etna #{@token}")
|
67
|
-
request(uri, multipart, &block)
|
68
|
-
end
|
69
|
-
|
70
|
-
def post(endpoint, params={}, &block)
|
71
|
-
body_request(Net::HTTP::Post, endpoint, params, &block)
|
72
|
-
end
|
73
|
-
|
74
|
-
def get(endpoint, params={}, &block)
|
75
|
-
query_request(Net::HTTP::Get, endpoint, params, &block)
|
76
|
-
end
|
77
|
-
|
78
|
-
def options(endpoint, params={}, &block)
|
79
|
-
query_request(Net::HTTP::Options, endpoint, params, &block)
|
84
|
+
http = Net::HTTP::Persistent.new
|
85
|
+
http.read_timeout = 3600
|
86
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @ignore_ssl
|
87
|
+
http
|
88
|
+
end
|
80
89
|
end
|
81
90
|
|
82
|
-
def delete(endpoint, params={}, &block)
|
83
|
-
body_request(Net::HTTP::Delete, endpoint, params, &block)
|
84
|
-
end
|
85
91
|
|
86
|
-
def body_request(type, endpoint, params={}, &block)
|
92
|
+
def body_request(type, endpoint, params = {}, &block)
|
87
93
|
uri = request_uri(endpoint)
|
88
|
-
req = type.new(uri.request_uri,request_params)
|
94
|
+
req = type.new(uri.request_uri, request_params)
|
89
95
|
req.body = params.to_json
|
90
96
|
request(uri, req, &block)
|
91
97
|
end
|
92
98
|
|
93
|
-
def query_request(type, endpoint, params={}, &block)
|
99
|
+
def query_request(type, endpoint, params = {}, &block)
|
94
100
|
uri = request_uri(endpoint)
|
95
|
-
|
101
|
+
|
102
|
+
if uri.query
|
103
|
+
uri.query += "&" + URI.encode_www_form(params)
|
104
|
+
else
|
105
|
+
uri.query = URI.encode_www_form(params)
|
106
|
+
end
|
96
107
|
req = type.new(uri.request_uri, request_params)
|
97
108
|
request(uri, req, &block)
|
98
109
|
end
|
@@ -103,9 +114,9 @@ module Etna
|
|
103
114
|
|
104
115
|
def request_params
|
105
116
|
{
|
106
|
-
|
107
|
-
|
108
|
-
|
117
|
+
'Content-Type' => 'application/json',
|
118
|
+
'Accept' => 'application/json, text/*',
|
119
|
+
'Authorization' => "Etna #{@token}"
|
109
120
|
}
|
110
121
|
end
|
111
122
|
|
@@ -113,8 +124,8 @@ module Etna
|
|
113
124
|
status = response.code.to_i
|
114
125
|
if status >= 400
|
115
126
|
msg = response.content_type == 'application/json' ?
|
116
|
-
|
117
|
-
|
127
|
+
json_error(response.body) :
|
128
|
+
response.body
|
118
129
|
raise Etna::Error.new(msg, status)
|
119
130
|
end
|
120
131
|
end
|
@@ -130,14 +141,37 @@ module Etna
|
|
130
141
|
|
131
142
|
def request(uri, data)
|
132
143
|
if block_given?
|
133
|
-
|
134
|
-
|
135
|
-
|
144
|
+
if @persistent
|
145
|
+
persistent_connection.request(uri, data) do |response|
|
146
|
+
status_check!(response)
|
147
|
+
yield response
|
148
|
+
end
|
149
|
+
else
|
150
|
+
verify_mode = @ignore_ssl ?
|
151
|
+
OpenSSL::SSL::VERIFY_NONE :
|
152
|
+
OpenSSL::SSL::VERIFY_PEER
|
153
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true, verify_mode: verify_mode) do |http|
|
154
|
+
http.request(data) do |response|
|
155
|
+
status_check!(response)
|
156
|
+
yield response
|
157
|
+
end
|
158
|
+
end
|
136
159
|
end
|
137
160
|
else
|
138
|
-
|
139
|
-
|
140
|
-
|
161
|
+
if @persistent
|
162
|
+
response = persistent_connection.request(uri, data)
|
163
|
+
status_check!(response)
|
164
|
+
return response
|
165
|
+
else
|
166
|
+
verify_mode = @ignore_ssl ?
|
167
|
+
OpenSSL::SSL::VERIFY_NONE :
|
168
|
+
OpenSSL::SSL::VERIFY_PEER
|
169
|
+
Net::HTTP.start(uri.host, uri.port, use_ssl: true, verify_mode: verify_mode) do |http|
|
170
|
+
response = http.request(data)
|
171
|
+
status_check!(response)
|
172
|
+
return response
|
173
|
+
end
|
174
|
+
end
|
141
175
|
end
|
142
176
|
end
|
143
177
|
end
|
data/lib/etna/clients.rb
ADDED
@@ -0,0 +1,73 @@
|
|
1
|
+
require 'net/http/persistent'
|
2
|
+
require 'net/http/post/multipart'
|
3
|
+
require 'singleton'
|
4
|
+
require_relative '../../client'
|
5
|
+
require_relative './models'
|
6
|
+
|
7
|
+
module Etna
|
8
|
+
module Clients
|
9
|
+
class Janus
|
10
|
+
def initialize(host:, token:, persistent: true, ignore_ssl: false)
|
11
|
+
raise 'Janus client configuration is missing host.' unless host
|
12
|
+
raise 'Janus client configuration is missing token.' unless token
|
13
|
+
@etna_client = ::Etna::Client.new(
|
14
|
+
host,
|
15
|
+
token,
|
16
|
+
routes_available: false,
|
17
|
+
persistent: persistent,
|
18
|
+
ignore_ssl: ignore_ssl)
|
19
|
+
end
|
20
|
+
|
21
|
+
def get_project(get_project_request = GetProjectRequest.new)
|
22
|
+
html = nil
|
23
|
+
@etna_client.get(
|
24
|
+
"/project/#{get_project_request.project_name}",
|
25
|
+
get_project_request) do |res|
|
26
|
+
html = res.body
|
27
|
+
end
|
28
|
+
|
29
|
+
HtmlResponse.new(html)
|
30
|
+
end
|
31
|
+
|
32
|
+
def add_project(add_project_request = AddProjectRequest.new)
|
33
|
+
@etna_client.post('/add_project', add_project_request) do |res|
|
34
|
+
# Redirect, no response data
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def add_user(add_user_request = AddUserRequest.new)
|
39
|
+
@etna_client.post(
|
40
|
+
"/add_user/#{add_user_request.project_name}",
|
41
|
+
add_user_request) do |res|
|
42
|
+
# Redirect, no response data
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
def update_permission(update_permission_request = UpdatePermissionRequest.new)
|
47
|
+
@etna_client.post(
|
48
|
+
"/update_permission/#{update_permission_request.project_name}",
|
49
|
+
update_permission_request) do |res|
|
50
|
+
# Redirect, no response data
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def refresh_token(refresh_token_request = RefreshTokenRequest.new)
|
55
|
+
token = nil
|
56
|
+
@etna_client.get('/refresh_token', refresh_token_request) do |res|
|
57
|
+
token = res.body
|
58
|
+
end
|
59
|
+
|
60
|
+
TokenResponse.new(token)
|
61
|
+
end
|
62
|
+
|
63
|
+
def viewer_token(viewer_token_request = ViewerTokenRequest.new)
|
64
|
+
token = nil
|
65
|
+
@etna_client.get('/viewer_token', viewer_token_request) do |res|
|
66
|
+
token = res.body
|
67
|
+
end
|
68
|
+
|
69
|
+
TokenResponse.new(token)
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'ostruct'
|
2
|
+
require_relative '../../json_serializable_struct'
|
3
|
+
|
4
|
+
# TODO: In the near future, I'd like to transition to specifying apis via SWAGGER and generating model stubs from the
|
5
|
+
# common definitions. For nowe I've written them out by hand here.
|
6
|
+
module Etna
|
7
|
+
module Clients
|
8
|
+
class Janus
|
9
|
+
class GetProjectRequest < Struct.new(:project_name, keyword_init: true)
|
10
|
+
include JsonSerializableStruct
|
11
|
+
|
12
|
+
def initialize(**params)
|
13
|
+
super({}.update(params))
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
class AddProjectRequest < Struct.new(:project_name, :project_name_full, keyword_init: true)
|
18
|
+
include JsonSerializableStruct
|
19
|
+
|
20
|
+
def initialize(**params)
|
21
|
+
super({}.update(params))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class AddUserRequest < Struct.new(:project_name, :email, :name, :role, :privileged, :affiliation, keyword_init: true)
|
26
|
+
include JsonSerializableStruct
|
27
|
+
|
28
|
+
def initialize(**params)
|
29
|
+
super({privileged: false, affiliation: ''}.update(params))
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
class UpdatePermissionRequest < Struct.new(:project_name, :email, :role, :privileged, :affiliation, keyword_init: true)
|
34
|
+
include JsonSerializableStruct
|
35
|
+
|
36
|
+
def initialize(**params)
|
37
|
+
super({privileged: false, affiliation: ''}.update(params))
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
class RefreshTokenRequest
|
42
|
+
def map
|
43
|
+
[]
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
class ViewerTokenRequest
|
48
|
+
def map
|
49
|
+
[]
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
class HtmlResponse
|
54
|
+
attr_reader :raw
|
55
|
+
|
56
|
+
def initialize(raw = '')
|
57
|
+
@raw = raw
|
58
|
+
end
|
59
|
+
|
60
|
+
def html
|
61
|
+
@raw
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class TokenResponse
|
66
|
+
attr_reader :raw
|
67
|
+
|
68
|
+
def initialize(raw = '')
|
69
|
+
@raw = raw
|
70
|
+
end
|
71
|
+
|
72
|
+
def token
|
73
|
+
@raw
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|