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
@@ -0,0 +1,50 @@
|
|
1
|
+
module Etna
|
2
|
+
module MultipartSerializableNestedHash
|
3
|
+
def self.included(cls)
|
4
|
+
cls.instance_eval do
|
5
|
+
def self.encode_multipart_pairs(value, base_key, is_root, &block)
|
6
|
+
if value.is_a? Hash
|
7
|
+
value.each do |k, v|
|
8
|
+
encode_multipart_pairs(v, is_root ? k : "#{base_key}[#{k}]", false, &block)
|
9
|
+
end
|
10
|
+
elsif value.is_a? Array
|
11
|
+
value.each_with_index do |v, i|
|
12
|
+
# This is necessary to ensure that arrays of hashes that have hetergenous keys still get parsed correctly
|
13
|
+
# Since the only way to indicate a new entry in the array of hashes is by re-using a key that existed in
|
14
|
+
# the previous hash.
|
15
|
+
if v.is_a? Hash
|
16
|
+
encode_multipart_pairs(i, "#{base_key}[][_idx]", false, &block)
|
17
|
+
end
|
18
|
+
|
19
|
+
encode_multipart_pairs(v, "#{base_key}[]", false, &block)
|
20
|
+
end
|
21
|
+
else
|
22
|
+
raise "base_key cannot be empty for a scalar value!" if base_key.length == 0
|
23
|
+
|
24
|
+
if value.respond_to?(:read)
|
25
|
+
yield [base_key, UploadIO.new(value, 'application/octet-stream'), {filename: 'blob'}]
|
26
|
+
else
|
27
|
+
yield [base_key, value.to_s]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
def self.encode_multipart_content(value, base_key = '', is_root = true)
|
34
|
+
result = []
|
35
|
+
self.encode_multipart_pairs(value, base_key, is_root) { |pair| result << pair }
|
36
|
+
result
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def encode_multipart_content(base_key = '')
|
42
|
+
value = self
|
43
|
+
if value.respond_to? :as_json
|
44
|
+
value = value.as_json
|
45
|
+
end
|
46
|
+
|
47
|
+
self.class.encode_multipart_content(value, base_key)
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
data/lib/etna/route.rb
CHANGED
@@ -118,7 +118,7 @@ module Etna
|
|
118
118
|
|
119
119
|
def hmac_authorized?(request)
|
120
120
|
# either there is no hmac requirement, or we have a valid hmac
|
121
|
-
!@auth[:hmac] || request.env['etna.hmac']
|
121
|
+
!@auth[:hmac] || request.env['etna.hmac']&.valid?
|
122
122
|
end
|
123
123
|
|
124
124
|
def route_name(options)
|
data/lib/etna/server.rb
CHANGED
@@ -0,0 +1,99 @@
|
|
1
|
+
require 'webmock/rspec'
|
2
|
+
require 'vcr'
|
3
|
+
require 'openssl'
|
4
|
+
require 'digest/sha2'
|
5
|
+
require 'base64'
|
6
|
+
|
7
|
+
def setup_base_vcr(spec_helper_dir)
|
8
|
+
VCR.configure do |c|
|
9
|
+
c.hook_into :webmock
|
10
|
+
c.cassette_serializers
|
11
|
+
c.cassette_library_dir = ::File.join(spec_helper_dir, 'fixtures', 'cassettes')
|
12
|
+
c.allow_http_connections_when_no_cassette = true
|
13
|
+
|
14
|
+
c.register_request_matcher :try_body do |request_1, request_2|
|
15
|
+
if request_1.headers['Content-Type'].first =~ /application\/json/
|
16
|
+
if request_2.headers['Content-Type'].first =~ /application\/json/
|
17
|
+
request_1_json = begin
|
18
|
+
JSON.parse(request_1.body) rescue 'not-json'
|
19
|
+
end
|
20
|
+
request_2_json = begin
|
21
|
+
JSON.parse(request_2.body) rescue 'not-json'
|
22
|
+
end
|
23
|
+
|
24
|
+
request_1_json == request_2_json
|
25
|
+
else
|
26
|
+
false
|
27
|
+
end
|
28
|
+
else
|
29
|
+
request_1.body == request_2.body
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
c.default_cassette_options = {
|
34
|
+
serialize_with: :compressed,
|
35
|
+
record: if ENV['IS_CI'] == '1'
|
36
|
+
:none
|
37
|
+
else
|
38
|
+
ENV['RERECORD'] ? :all : :once
|
39
|
+
end,
|
40
|
+
match_requests_on: [:method, :uri, :try_body]
|
41
|
+
}
|
42
|
+
|
43
|
+
# Filter the authorization headers of any request by replacing any occurrence of that request's
|
44
|
+
# Authorization value with <AUTHORIZATION>
|
45
|
+
c.filter_sensitive_data('<AUTHORIZATION>') do |interaction|
|
46
|
+
interaction.request.headers['Authorization'].first
|
47
|
+
end
|
48
|
+
|
49
|
+
c.before_record do |interaction|
|
50
|
+
key = prepare_vcr_secret
|
51
|
+
|
52
|
+
if interaction.response.body && !interaction.response.body.empty?
|
53
|
+
cipher = OpenSSL::Cipher.new("AES-256-CBC")
|
54
|
+
iv = cipher.random_iv
|
55
|
+
|
56
|
+
cipher.encrypt
|
57
|
+
cipher.key = key
|
58
|
+
cipher.iv = iv
|
59
|
+
|
60
|
+
encrypted = cipher.update(interaction.response.body)
|
61
|
+
encrypted << cipher.final
|
62
|
+
|
63
|
+
interaction.response.body = [iv, encrypted].pack('mm')
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
c.before_playback do |interaction|
|
68
|
+
key = prepare_vcr_secret
|
69
|
+
|
70
|
+
if interaction.response.body && !interaction.response.body.empty?
|
71
|
+
iv, encrypted = interaction.response.body.unpack('mm')
|
72
|
+
|
73
|
+
cipher = OpenSSL::Cipher.new("AES-256-CBC")
|
74
|
+
cipher.decrypt
|
75
|
+
cipher.key = key
|
76
|
+
cipher.iv = iv
|
77
|
+
|
78
|
+
plain = cipher.update(encrypted)
|
79
|
+
plain << cipher.final
|
80
|
+
|
81
|
+
interaction.response.body = plain
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
def prepare_vcr_secret
|
88
|
+
secret = ENV["CI_SECRET"]
|
89
|
+
|
90
|
+
if (secret.nil? || secret.empty?) && ENV['IS_CI'] != '1'
|
91
|
+
current_example = RSpec.current_example
|
92
|
+
RSpec::Core::Pending.mark_pending! current_example, 'CI_SECRET must be set to run this test'
|
93
|
+
raise "CI_SECRET must be set to run this test"
|
94
|
+
end
|
95
|
+
|
96
|
+
digest = Digest::SHA256.new
|
97
|
+
digest.update(secret)
|
98
|
+
digest.digest
|
99
|
+
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
// Make sure to remove all comments before using -- JSON doesn't allow comments!
|
2
|
+
[
|
3
|
+
// Attribute actions can be "add_attribute", "update_attribute", "rename_attribute", or "add_link".
|
4
|
+
// These are all executed at the same time -- so you can't "update" an attribute that you "add"
|
5
|
+
// in the same file -- everything must already exist on the server."
|
6
|
+
{
|
7
|
+
"action_name": "add_attribute",
|
8
|
+
"model_name": "assay_name", // Each action must include a model_name that it applies to.
|
9
|
+
"attribute_type": "string", // When adding, you must include attribute_type, attribute_name, desc, and display_name.
|
10
|
+
"attribute_name": "notes",
|
11
|
+
"display_name": "Notes",
|
12
|
+
"desc": "for notes that you have."
|
13
|
+
},
|
14
|
+
{
|
15
|
+
"action_name": "update_attribute",
|
16
|
+
"model_name": "document",
|
17
|
+
"attribute_name": "version", // When updating, you must include model_name and attribute_name, but any additional values are optional.
|
18
|
+
"read_only": true
|
19
|
+
},
|
20
|
+
{
|
21
|
+
"action_name": "rename_attribute",
|
22
|
+
"model_name": "assay_name",
|
23
|
+
"attribute_name": "vendor",
|
24
|
+
"new_attribute_name": "e_vendor" // When renaming an attribute, you need to include a "new_attribute_name" value.
|
25
|
+
},
|
26
|
+
{
|
27
|
+
// Links require two hashes inside of a "links" attribute.
|
28
|
+
"action_name": "add_link",
|
29
|
+
"links": [
|
30
|
+
{
|
31
|
+
"model_name": "assay_name",
|
32
|
+
"attribute_name": "document",
|
33
|
+
"attribute_type": "link" // One link must be of type "link". This has a one-to-one relationship with the other model.
|
34
|
+
// In this case, each assay_name has one document record, but document records can point to zero-or-more assay_name records.
|
35
|
+
},
|
36
|
+
{
|
37
|
+
"model_name": "document",
|
38
|
+
"attribute_name": "assay_name",
|
39
|
+
"attribute_type": "collection" // The other link must be of type "collection". This is a one-to-many relationship with the other model.
|
40
|
+
}
|
41
|
+
]
|
42
|
+
}
|
43
|
+
]
|
data/lib/etna/test_auth.rb
CHANGED
@@ -43,7 +43,9 @@ module Etna
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def approve_hmac(request)
|
46
|
-
hmac_signature = etna_param(request, :signature)
|
46
|
+
hmac_signature = etna_param(request, :signature)
|
47
|
+
|
48
|
+
return false unless hmac_signature
|
47
49
|
|
48
50
|
headers = (etna_param(request, :headers)&.split(/,/) || []).map do |header|
|
49
51
|
[ header.to_sym, etna_param(request, header) ]
|
data/lib/etna/user.rb
CHANGED
@@ -7,7 +7,9 @@ module Etna
|
|
7
7
|
}
|
8
8
|
|
9
9
|
def initialize params, token=nil
|
10
|
-
@first, @last, @email, @encoded_permissions = params.values_at(:first, :last, :email, :perm)
|
10
|
+
@first, @last, @email, @encoded_permissions, encoded_flags = params.values_at(:first, :last, :email, :perm, :flags)
|
11
|
+
|
12
|
+
@flags = encoded_flags&.split(/;/) || []
|
11
13
|
@token = token unless !token
|
12
14
|
raise ArgumentError, "No email given!" unless @email
|
13
15
|
end
|
@@ -30,6 +32,10 @@ module Etna
|
|
30
32
|
end.inject([],:+).to_h
|
31
33
|
end
|
32
34
|
|
35
|
+
def has_flag?(flag)
|
36
|
+
@flags.include?(flag)
|
37
|
+
end
|
38
|
+
|
33
39
|
def name
|
34
40
|
"#{first} #{last}"
|
35
41
|
end
|
@@ -75,5 +81,9 @@ module Etna
|
|
75
81
|
def is_admin? project
|
76
82
|
is_superuser? || has_roles(project, :admin)
|
77
83
|
end
|
84
|
+
|
85
|
+
def active? project=nil
|
86
|
+
permissions.keys.length > 0
|
87
|
+
end
|
78
88
|
end
|
79
89
|
end
|
data/lib/helpers.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require_relative './etna/clients'
|
2
|
+
require_relative './etna/environment_scoped'
|
3
|
+
|
4
|
+
module WithEtnaClients
|
5
|
+
def environment
|
6
|
+
EtnaApp.instance.environment
|
7
|
+
end
|
8
|
+
|
9
|
+
def token(ignore_environment: false)
|
10
|
+
unless ignore_environment
|
11
|
+
if environment == :many
|
12
|
+
raise "You have multiple environments configured, please specify your environment by adding --environment <staging|production|development>"
|
13
|
+
elsif environment == :none
|
14
|
+
raise "You do not have a successfully configured environment, please run #{program_name} config set https://polyphemus.ucsf.edu"
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
env_token = ENV['TOKEN']
|
19
|
+
if !env_token
|
20
|
+
puts "No environment variable TOKEN is set. You should set your token with `export TOKEN=<your.janus.token>` before running."
|
21
|
+
redirect = EtnaApp.instance.config(:auth_redirect)
|
22
|
+
|
23
|
+
if redirect.nil? && EtnaApp.instance.environment == :production
|
24
|
+
redirect = 'https://janus.ucsf.edu/'
|
25
|
+
end
|
26
|
+
|
27
|
+
unless redirect.nil?
|
28
|
+
puts "Open your browser to #{redirect} to complete login and copy your token."
|
29
|
+
end
|
30
|
+
|
31
|
+
exit
|
32
|
+
end
|
33
|
+
|
34
|
+
env_token
|
35
|
+
end
|
36
|
+
|
37
|
+
def magma_client
|
38
|
+
@magma_client ||= Etna::Clients::Magma.new(
|
39
|
+
token: token,
|
40
|
+
ignore_ssl: EtnaApp.instance.config(:ignore_ssl),
|
41
|
+
# Persistent connections cause problem with magma restarts, until we can fix that we should force them
|
42
|
+
# to close + reopen each request.
|
43
|
+
persistent: false,
|
44
|
+
**EtnaApp.instance.config(:magma, environment) || {})
|
45
|
+
end
|
46
|
+
|
47
|
+
def metis_client
|
48
|
+
@metis_client ||= Etna::Clients::Metis.new(
|
49
|
+
token: token,
|
50
|
+
ignore_ssl: EtnaApp.instance.config(:ignore_ssl),
|
51
|
+
**EtnaApp.instance.config(:metis, environment) || {})
|
52
|
+
end
|
53
|
+
|
54
|
+
def janus_client
|
55
|
+
@janus_client ||= Etna::Clients::Janus.new(
|
56
|
+
token: token,
|
57
|
+
ignore_ssl: EtnaApp.instance.config(:ignore_ssl),
|
58
|
+
**EtnaApp.instance.config(:janus, environment) || {})
|
59
|
+
end
|
60
|
+
|
61
|
+
def polyphemus_client
|
62
|
+
@polyphemus_client ||= Etna::Clients::Polyphemus.new(
|
63
|
+
token: token,
|
64
|
+
ignore_ssl: EtnaApp.instance.config(:ignore_ssl),
|
65
|
+
**EtnaApp.instance.config(:polyphemus, environment) || {})
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
module WithLogger
|
70
|
+
def logger
|
71
|
+
EtnaApp.instance.logger
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
module StrongConfirmation
|
76
|
+
def confirm
|
77
|
+
puts "Confirm Y/n:"
|
78
|
+
input = STDIN.gets.chomp
|
79
|
+
if input.downcase != "y"
|
80
|
+
puts "Bailing..."
|
81
|
+
return false
|
82
|
+
end
|
83
|
+
|
84
|
+
true
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
WithEtnaClientsByEnvironment = EnvironmentScoped.new do
|
89
|
+
include WithEtnaClients
|
90
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: etna
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.20
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Saurabh Asthana
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-12-14 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -66,37 +66,102 @@ dependencies:
|
|
66
66
|
- - ">="
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rollbar
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - ">="
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '0'
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
69
83
|
description: See summary
|
70
84
|
email: Saurabh.Asthana@ucsf.edu
|
71
|
-
executables:
|
72
|
-
|
85
|
+
executables:
|
86
|
+
- etna
|
87
|
+
extensions:
|
88
|
+
- ext/completions/extconf.rb
|
73
89
|
extra_rdoc_files: []
|
74
90
|
files:
|
91
|
+
- bin/etna
|
92
|
+
- etna.completion
|
93
|
+
- etna_app.completion
|
94
|
+
- ext/completions/extconf.rb
|
95
|
+
- lib/commands.rb
|
75
96
|
- lib/etna.rb
|
76
97
|
- lib/etna/application.rb
|
77
98
|
- lib/etna/auth.rb
|
78
99
|
- lib/etna/client.rb
|
100
|
+
- lib/etna/clients.rb
|
101
|
+
- lib/etna/clients/enum.rb
|
102
|
+
- lib/etna/clients/janus.rb
|
103
|
+
- lib/etna/clients/janus/client.rb
|
104
|
+
- lib/etna/clients/janus/models.rb
|
105
|
+
- lib/etna/clients/magma.rb
|
106
|
+
- lib/etna/clients/magma/client.rb
|
107
|
+
- lib/etna/clients/magma/formatting.rb
|
108
|
+
- lib/etna/clients/magma/formatting/models_csv.rb
|
109
|
+
- lib/etna/clients/magma/models.rb
|
110
|
+
- lib/etna/clients/magma/workflows.rb
|
111
|
+
- lib/etna/clients/magma/workflows/add_project_models_workflow.rb
|
112
|
+
- lib/etna/clients/magma/workflows/attribute_actions_from_json_workflow.rb
|
113
|
+
- lib/etna/clients/magma/workflows/create_project_workflow.rb
|
114
|
+
- lib/etna/clients/magma/workflows/crud_workflow.rb
|
115
|
+
- lib/etna/clients/magma/workflows/ensure_containing_record_workflow.rb
|
116
|
+
- lib/etna/clients/magma/workflows/file_attributes_blank_workflow.rb
|
117
|
+
- lib/etna/clients/magma/workflows/file_linking_workflow.rb
|
118
|
+
- lib/etna/clients/magma/workflows/json_converters.rb
|
119
|
+
- lib/etna/clients/magma/workflows/json_validators.rb
|
120
|
+
- lib/etna/clients/magma/workflows/model_synchronization_workflow.rb
|
121
|
+
- lib/etna/clients/magma/workflows/record_synchronization_workflow.rb
|
122
|
+
- lib/etna/clients/magma/workflows/update_attributes_from_csv_workflow.rb
|
123
|
+
- lib/etna/clients/metis.rb
|
124
|
+
- lib/etna/clients/metis/client.rb
|
125
|
+
- lib/etna/clients/metis/models.rb
|
126
|
+
- lib/etna/clients/metis/workflows.rb
|
127
|
+
- lib/etna/clients/metis/workflows/metis_download_workflow.rb
|
128
|
+
- lib/etna/clients/metis/workflows/metis_upload_workflow.rb
|
129
|
+
- lib/etna/clients/polyphemus.rb
|
130
|
+
- lib/etna/clients/polyphemus/client.rb
|
131
|
+
- lib/etna/clients/polyphemus/models.rb
|
132
|
+
- lib/etna/clients/polyphemus/workflows.rb
|
133
|
+
- lib/etna/clients/polyphemus/workflows/set_configuration_workflow.rb
|
79
134
|
- lib/etna/command.rb
|
80
135
|
- lib/etna/controller.rb
|
81
136
|
- lib/etna/cross_origin.rb
|
137
|
+
- lib/etna/csvs.rb
|
82
138
|
- lib/etna/describe_routes.rb
|
139
|
+
- lib/etna/directed_graph.rb
|
140
|
+
- lib/etna/environment_scoped.rb
|
83
141
|
- lib/etna/errors.rb
|
84
142
|
- lib/etna/ext.rb
|
143
|
+
- lib/etna/generate_autocompletion_script.rb
|
85
144
|
- lib/etna/hmac.rb
|
145
|
+
- lib/etna/json_serializable_struct.rb
|
86
146
|
- lib/etna/logger.rb
|
147
|
+
- lib/etna/multipart_serializable_nested_hash.rb
|
87
148
|
- lib/etna/parse_body.rb
|
88
149
|
- lib/etna/route.rb
|
89
150
|
- lib/etna/server.rb
|
90
151
|
- lib/etna/sign_service.rb
|
91
152
|
- lib/etna/spec.rb
|
92
153
|
- lib/etna/spec/auth.rb
|
154
|
+
- lib/etna/spec/vcr.rb
|
93
155
|
- lib/etna/symbolize_params.rb
|
156
|
+
- lib/etna/templates/attribute_actions_template.json
|
94
157
|
- lib/etna/test_auth.rb
|
95
158
|
- lib/etna/user.rb
|
159
|
+
- lib/helpers.rb
|
96
160
|
homepage: http://github.com/mountetna/etna
|
97
161
|
licenses: []
|
98
162
|
metadata: {}
|
99
|
-
post_install_message:
|
163
|
+
post_install_message: "\n\n\e[1;31mAdd 'source ~/etna.completion' to your .bashrc
|
164
|
+
to get etna command line completions!\e[0m\n\n"
|
100
165
|
rdoc_options: []
|
101
166
|
require_paths:
|
102
167
|
- lib
|