lmc 0.4.0
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 +13 -0
- data/.idea/inspectionProfiles/Project_Default.xml +13 -0
- data/.idea/lmc.iml +31 -0
- data/.idea/misc.xml +4 -0
- data/.idea/modules.xml +8 -0
- data/.idea/vcs.xml +6 -0
- data/.ruby-version +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +6 -0
- data/README.md +41 -0
- data/Rakefile +10 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/coverage/.gitignore +3 -0
- data/coverage/.last_run.json +5 -0
- data/lib/lmc.rb +16 -0
- data/lib/lmc/Account.rb +175 -0
- data/lib/lmc/Cloud.rb +230 -0
- data/lib/lmc/Configstates.rb +14 -0
- data/lib/lmc/Device.rb +72 -0
- data/lib/lmc/Response.rb +53 -0
- data/lib/lmc/Site.rb +37 -0
- data/lib/lmc/User.rb +40 -0
- data/lib/lmc/account_manager.rb +83 -0
- data/lib/lmc/device_config_state.rb +6 -0
- data/lib/lmc/entity.rb +17 -0
- data/lib/lmc/exceptions/lmc_outdated_terms_of_use_exception.rb +21 -0
- data/lib/lmc/membership.rb +15 -0
- data/lib/lmc/principal.rb +34 -0
- data/lib/lmc/version.rb +3 -0
- data/lmc.gemspec +42 -0
- metadata +201 -0
checksums.yaml
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
---
|
|
2
|
+
SHA1:
|
|
3
|
+
metadata.gz: b3a6cc095210c99890c8ebb6b1c24f18fdee5ace
|
|
4
|
+
data.tar.gz: c32528dfb1a87d9238db2c96f23297dbdd75660f
|
|
5
|
+
SHA512:
|
|
6
|
+
metadata.gz: 32ff5ff2362f3534b20e8dab058cc0faccf9f754fa7858b89e5693f26be5c7d2adab48af988660df597242323bcb58f39f46440ba75efd938d8517f7dbaf468c
|
|
7
|
+
data.tar.gz: b9c2259efdb008fca13912c5066a966d66b65f25a92843413d2447bc0ee20011365869f1514f0f1c265b73f0ea64fd2176892b475bdf481e6e9115c13b9f958a
|
data/.gitignore
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
<component name="InspectionProjectProfileManager">
|
|
2
|
+
<profile version="1.0">
|
|
3
|
+
<option name="myName" value="Project Default" />
|
|
4
|
+
<inspection_tool class="RubyInstanceMethodNamingConvention" enabled="true" level="WARNING" enabled_by_default="true">
|
|
5
|
+
<scope name="Tests" level="WARNING" enabled="false" />
|
|
6
|
+
</inspection_tool>
|
|
7
|
+
<inspection_tool class="SpellCheckingInspection" enabled="false" level="TYPO" enabled_by_default="false">
|
|
8
|
+
<option name="processCode" value="true" />
|
|
9
|
+
<option name="processLiterals" value="true" />
|
|
10
|
+
<option name="processComments" value="true" />
|
|
11
|
+
</inspection_tool>
|
|
12
|
+
</profile>
|
|
13
|
+
</component>
|
data/.idea/lmc.iml
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<module type="RUBY_MODULE" version="4">
|
|
3
|
+
<component name="ModuleRunConfigurationManager">
|
|
4
|
+
<shared />
|
|
5
|
+
</component>
|
|
6
|
+
<component name="NewModuleRootManager">
|
|
7
|
+
<content url="file://$MODULE_DIR$" />
|
|
8
|
+
<orderEntry type="jdk" jdkName="rbenv: 2.4.1" jdkType="RUBY_SDK" />
|
|
9
|
+
<orderEntry type="sourceFolder" forTests="false" />
|
|
10
|
+
<orderEntry type="library" scope="PROVIDED" name="ansi (v1.5.0, rbenv: 2.4.1) [gem]" level="application" />
|
|
11
|
+
<orderEntry type="library" scope="PROVIDED" name="builder (v3.2.3, rbenv: 2.4.1) [gem]" level="application" />
|
|
12
|
+
<orderEntry type="library" scope="PROVIDED" name="bundler (v1.16.1, rbenv: 2.4.1) [gem]" level="application" />
|
|
13
|
+
<orderEntry type="library" scope="PROVIDED" name="docile (v1.1.5, rbenv: 2.4.1) [gem]" level="application" />
|
|
14
|
+
<orderEntry type="library" scope="PROVIDED" name="domain_name (v0.5.20170404, rbenv: 2.4.1) [gem]" level="application" />
|
|
15
|
+
<orderEntry type="library" scope="PROVIDED" name="http-cookie (v1.0.3, rbenv: 2.4.1) [gem]" level="application" />
|
|
16
|
+
<orderEntry type="library" scope="PROVIDED" name="json (v2.1.0, rbenv: 2.4.1) [gem]" level="application" />
|
|
17
|
+
<orderEntry type="library" scope="PROVIDED" name="mime-types (v3.1, rbenv: 2.4.1) [gem]" level="application" />
|
|
18
|
+
<orderEntry type="library" scope="PROVIDED" name="mime-types-data (v3.2016.0521, rbenv: 2.4.1) [gem]" level="application" />
|
|
19
|
+
<orderEntry type="library" scope="PROVIDED" name="minitest (v5.11.3, rbenv: 2.4.1) [gem]" level="application" />
|
|
20
|
+
<orderEntry type="library" scope="PROVIDED" name="minitest-reporters (v1.1.19, rbenv: 2.4.1) [gem]" level="application" />
|
|
21
|
+
<orderEntry type="library" scope="PROVIDED" name="netrc (v0.11.0, rbenv: 2.4.1) [gem]" level="application" />
|
|
22
|
+
<orderEntry type="library" scope="PROVIDED" name="rake (v10.5.0, rbenv: 2.4.1) [gem]" level="application" />
|
|
23
|
+
<orderEntry type="library" scope="PROVIDED" name="recursive-open-struct (v1.1.0, rbenv: 2.4.1) [gem]" level="application" />
|
|
24
|
+
<orderEntry type="library" scope="PROVIDED" name="rest-client (v2.0.2, rbenv: 2.4.1) [gem]" level="application" />
|
|
25
|
+
<orderEntry type="library" scope="PROVIDED" name="ruby-progressbar (v1.9.0, rbenv: 2.4.1) [gem]" level="application" />
|
|
26
|
+
<orderEntry type="library" scope="PROVIDED" name="simplecov (v0.15.1, rbenv: 2.4.1) [gem]" level="application" />
|
|
27
|
+
<orderEntry type="library" scope="PROVIDED" name="simplecov-html (v0.10.2, rbenv: 2.4.1) [gem]" level="application" />
|
|
28
|
+
<orderEntry type="library" scope="PROVIDED" name="unf (v0.1.4, rbenv: 2.4.1) [gem]" level="application" />
|
|
29
|
+
<orderEntry type="library" scope="PROVIDED" name="unf_ext (v0.0.7.5, rbenv: 2.4.1) [gem]" level="application" />
|
|
30
|
+
</component>
|
|
31
|
+
</module>
|
data/.idea/misc.xml
ADDED
data/.idea/modules.xml
ADDED
data/.idea/vcs.xml
ADDED
data/.ruby-version
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
2.4.1
|
data/.travis.yml
ADDED
data/Gemfile
ADDED
data/README.md
ADDED
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
# Lmc
|
|
2
|
+
|
|
3
|
+
Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/lmc`. To experiment with that code, run `bin/console` for an interactive prompt.
|
|
4
|
+
|
|
5
|
+
TODO: Delete this and the text above, and describe your gem
|
|
6
|
+
|
|
7
|
+
## Installation
|
|
8
|
+
|
|
9
|
+
Add this line to your application's Gemfile:
|
|
10
|
+
|
|
11
|
+
```ruby
|
|
12
|
+
gem 'lmc'
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
And then execute:
|
|
16
|
+
|
|
17
|
+
$ bundle
|
|
18
|
+
|
|
19
|
+
Or install it yourself as:
|
|
20
|
+
|
|
21
|
+
$ gem install lmc
|
|
22
|
+
|
|
23
|
+
## Usage
|
|
24
|
+
|
|
25
|
+
TODO: Write usage instructions here
|
|
26
|
+
|
|
27
|
+
## Development
|
|
28
|
+
|
|
29
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
|
30
|
+
|
|
31
|
+
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`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
|
32
|
+
|
|
33
|
+
### Tests against real LMC instances
|
|
34
|
+
|
|
35
|
+
#### credentials file
|
|
36
|
+
email: testuser@foocorp.example
|
|
37
|
+
password: Foobar1+
|
|
38
|
+
lmc_url: https://my.lmc.example
|
|
39
|
+
## Contributing
|
|
40
|
+
|
|
41
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/[USERNAME]/lmc.
|
data/Rakefile
ADDED
data/bin/console
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
#!/usr/bin/env ruby
|
|
2
|
+
|
|
3
|
+
require "bundler/setup"
|
|
4
|
+
require "lmc"
|
|
5
|
+
|
|
6
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
|
7
|
+
# with your gem easier. You can also use a different console, if you like.
|
|
8
|
+
|
|
9
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
|
10
|
+
# require "pry"
|
|
11
|
+
# Pry.start
|
|
12
|
+
|
|
13
|
+
require "irb"
|
|
14
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/coverage/.gitignore
ADDED
data/lib/lmc.rb
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
require 'json'
|
|
2
|
+
require 'restclient'
|
|
3
|
+
|
|
4
|
+
Dir.glob(File.expand_path("../lmc/*.rb", __FILE__)).each do |file|
|
|
5
|
+
require file
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
Dir.glob(File.expand_path("../lmc/exceptions/*.rb", __FILE__)).each do |file|
|
|
9
|
+
require file
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
module LMC
|
|
13
|
+
def self.useful
|
|
14
|
+
return true
|
|
15
|
+
end
|
|
16
|
+
end
|
data/lib/lmc/Account.rb
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
require_relative 'account_manager.rb'
|
|
2
|
+
require_relative 'entity'
|
|
3
|
+
module LMC
|
|
4
|
+
class Account < Entity
|
|
5
|
+
ROOT_ACCOUNT_UUID = '9ec458c2-d05f-3004-96f0-ebe73fa20de8'
|
|
6
|
+
attr_accessor :name
|
|
7
|
+
attr_reader :id, :state, :type
|
|
8
|
+
|
|
9
|
+
def self.get(id)
|
|
10
|
+
cloud = Cloud.instance
|
|
11
|
+
result = cloud.get ["cloud-service-auth", "accounts", id.to_s]
|
|
12
|
+
return Account.new(result.body)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def self.get_by_uuid uuid
|
|
16
|
+
raise "Missing argument" if uuid.nil?
|
|
17
|
+
return self.get uuid
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def self.get_by_name(name, type = nil)
|
|
21
|
+
raise "Missing argument" if name.nil?
|
|
22
|
+
accounts = Cloud.instance.get_accounts_objects.select do |a|
|
|
23
|
+
(name.nil? || a.name == name) && (type.nil? || a.type == type)
|
|
24
|
+
end
|
|
25
|
+
if accounts.length == 1
|
|
26
|
+
return accounts[0]
|
|
27
|
+
elsif accounts.length == 0
|
|
28
|
+
raise 'Did not find account'
|
|
29
|
+
else
|
|
30
|
+
raise 'Account name not unique'
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
def initialize(data)
|
|
36
|
+
@cloud = LMC::Cloud.instance
|
|
37
|
+
apply_data(data)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
#returns itself, allows chaining
|
|
41
|
+
def save
|
|
42
|
+
response = if @id.nil?
|
|
43
|
+
@cloud.auth_for_accounts [@parent]
|
|
44
|
+
@cloud.post ["cloud-service-auth", "accounts"], self
|
|
45
|
+
else
|
|
46
|
+
@cloud.post path, self
|
|
47
|
+
end
|
|
48
|
+
apply_data(response.body)
|
|
49
|
+
return self
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def delete
|
|
53
|
+
if @id != nil
|
|
54
|
+
@cloud.auth_for_accounts [@id]
|
|
55
|
+
deleted = @cloud.delete ["cloud-service-auth", "accounts", @id]
|
|
56
|
+
if deleted.code == 200
|
|
57
|
+
@id = nil
|
|
58
|
+
return true
|
|
59
|
+
else
|
|
60
|
+
raise "unable to delete account: #{deleted.body.message}"
|
|
61
|
+
end
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def exists?
|
|
66
|
+
# noch ungelöst: woran mache ich fest, ob das objekt in der DB schon da ist.
|
|
67
|
+
# Bleibt wohl nix außer manuell auf @id != nil zu checken.
|
|
68
|
+
@id != nil
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def members
|
|
72
|
+
ids = Cloud.instance.get ["cloud-service-auth", "accounts", @id, 'members'], {"select" => "id"}
|
|
73
|
+
puts ids.inspect if Cloud.debug
|
|
74
|
+
principals = ids.map do |principal_id|
|
|
75
|
+
response = Cloud.instance.get ["cloud-service-auth", "accounts", @id, 'members', principal_id]
|
|
76
|
+
if response.code == 200
|
|
77
|
+
principal = response.body
|
|
78
|
+
else
|
|
79
|
+
raise "ERROR: #{response.code} #{response.body.message}"
|
|
80
|
+
end
|
|
81
|
+
puts principal.inspect if Cloud.debug
|
|
82
|
+
principal
|
|
83
|
+
end
|
|
84
|
+
return principals
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
def find_member_by_name name
|
|
88
|
+
members.find {|m| m.name == name}
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
#def update_member(principal_id, data)
|
|
92
|
+
# response = @cloud.post ["cloud-service-auth", "accounts", id, 'members', principal_id], data
|
|
93
|
+
# return response
|
|
94
|
+
#end
|
|
95
|
+
|
|
96
|
+
def remove_membership(member_id)
|
|
97
|
+
response = @cloud.delete ["cloud-service-auth", "accounts", id, "members", member_id]
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def remove_membership_self
|
|
101
|
+
response = @cloud.delete ["cloud-service-auth", "accounts", id, "members", "self"]
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
def authorities
|
|
105
|
+
response = @cloud.get ['cloud-service-auth', 'accounts', id, 'authorities']
|
|
106
|
+
if response.code == 200
|
|
107
|
+
return response.body
|
|
108
|
+
else
|
|
109
|
+
raise 'Unable to get authorities'
|
|
110
|
+
end
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
def children
|
|
114
|
+
@cloud.auth_for_account self
|
|
115
|
+
response = @cloud.get ['cloud-service-auth', 'accounts', id, 'children']
|
|
116
|
+
response.map {|child| Account.new child}
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
def logs
|
|
120
|
+
# https://lmctest/cloud-service-logging/accounts/6392b234-b11c-498a-a077-a5f5b23c54a0/logs?lang=DE
|
|
121
|
+
cloud = Cloud.instance
|
|
122
|
+
cloud.auth_for_accounts [id]
|
|
123
|
+
cloud.get(["cloud-service-logging", "accounts", id, "logs?lang=DE"]).body
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def sites
|
|
127
|
+
# private clouds can not have sites
|
|
128
|
+
return [] if @type == "PRIVATE_CLOUD"
|
|
129
|
+
@cloud.auth_for_accounts([id])
|
|
130
|
+
response = @cloud.get ["cloud-service-devices", "accounts", id, "sites"]
|
|
131
|
+
if response.code == 200
|
|
132
|
+
return response.body.map {|data|
|
|
133
|
+
Site.new(data, self)
|
|
134
|
+
}
|
|
135
|
+
elsif response.code == 404
|
|
136
|
+
return []
|
|
137
|
+
end
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def config_updatestates
|
|
141
|
+
@cloud.auth_for_accounts([id])
|
|
142
|
+
response = @cloud.get ["cloud-service-config", "configdevice", "accounts", id, "updatestates"]
|
|
143
|
+
return LMC::Configstates.new response.body
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def to_json(*a)
|
|
147
|
+
{
|
|
148
|
+
"name" => @name,
|
|
149
|
+
"state" => @state,
|
|
150
|
+
"type" => @type,
|
|
151
|
+
"parent" => @parent
|
|
152
|
+
}.to_json(*a)
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def to_s
|
|
156
|
+
"#{name}"
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
private
|
|
160
|
+
|
|
161
|
+
## should be put into entity or such
|
|
162
|
+
def path
|
|
163
|
+
["cloud-service-auth", "accounts", @id].join("/")
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
def apply_data(data)
|
|
167
|
+
@id = data["id"]
|
|
168
|
+
@parent = data["parent"]
|
|
169
|
+
@name = data["name"]
|
|
170
|
+
@state = data["state"]
|
|
171
|
+
@type = data["type"]
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
end
|
|
175
|
+
end
|
data/lib/lmc/Cloud.rb
ADDED
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
require 'base64'
|
|
2
|
+
require 'json'
|
|
3
|
+
require 'restclient'
|
|
4
|
+
|
|
5
|
+
module LMC
|
|
6
|
+
class Cloud
|
|
7
|
+
#include ActionView::Helpers::DateHelper
|
|
8
|
+
|
|
9
|
+
class << self
|
|
10
|
+
attr_writer :cloud_host, :user, :password
|
|
11
|
+
attr_accessor :verbose, :debug, :verify_tls, :use_tls
|
|
12
|
+
Cloud.use_tls = true
|
|
13
|
+
Cloud.verify_tls = true
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# def self.cloud_host=(cloud_host)
|
|
17
|
+
# @@cloud_host = cloud_host
|
|
18
|
+
# end
|
|
19
|
+
|
|
20
|
+
def self.instance(opts = {authorize: true})
|
|
21
|
+
@@inst ||= self.new(@cloud_host, @user, @password, opts[:authorize])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
attr_reader :auth_ok, :cloud_host
|
|
26
|
+
|
|
27
|
+
def initialize(cloud_host, user, pass, auth=true)
|
|
28
|
+
@auth_ok = false
|
|
29
|
+
@cloud_host = cloud_host
|
|
30
|
+
@user = user
|
|
31
|
+
@password = pass
|
|
32
|
+
@verify_tls = Cloud.verify_tls
|
|
33
|
+
authorize if auth
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# hide password from dumps
|
|
37
|
+
def inspect
|
|
38
|
+
"#<Cloud:#{object_id}, #{build_url}>"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
def get_backstage_serviceinfos
|
|
42
|
+
get "cloud-service-backstage/serviceinfos"
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def get_accounts
|
|
46
|
+
get "cloud-service-auth/accounts"
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def get_accounts_objects
|
|
50
|
+
result = get ["cloud-service-auth", "accounts"]
|
|
51
|
+
if result.code == 200
|
|
52
|
+
accounts = result.map do |aj|
|
|
53
|
+
Account.new(aj)
|
|
54
|
+
end
|
|
55
|
+
else
|
|
56
|
+
raise "Unable to fetch accounts: #{result.body.message}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
return accounts
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
# functionality should be moved to Account class
|
|
63
|
+
#def get_account(name, type = nil)
|
|
64
|
+
# accounts = get_accounts_objects.select do |a|
|
|
65
|
+
# (name.nil? || a.name == name) && (type.nil? || a.type == type)
|
|
66
|
+
# end
|
|
67
|
+
# if accounts.length == 1
|
|
68
|
+
# return accounts[0]
|
|
69
|
+
# else
|
|
70
|
+
# raise "Did not specify exactly one account"
|
|
71
|
+
# end
|
|
72
|
+
#end
|
|
73
|
+
|
|
74
|
+
def invite_user_to_account(email, account_id, type, authorities = [])
|
|
75
|
+
body = {name: email, state: "ACTIVE", type: type}
|
|
76
|
+
body["authorities"] = authorities
|
|
77
|
+
post ["cloud-service-auth", "accounts", account_id, 'members'], body
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
def get(path, params = nil)
|
|
81
|
+
RestClient.log = ("stdout") if Cloud.debug
|
|
82
|
+
begin
|
|
83
|
+
prepared_headers = headers
|
|
84
|
+
prepared_headers[:params] = params
|
|
85
|
+
args = {
|
|
86
|
+
:method => :get,
|
|
87
|
+
:url => build_url(path),
|
|
88
|
+
:headers => prepared_headers,
|
|
89
|
+
}
|
|
90
|
+
args.merge!(rest_options)
|
|
91
|
+
resp = RestClient::Request.execute args
|
|
92
|
+
return LMCResponse.new(resp)
|
|
93
|
+
rescue RestClient::ExceptionWithResponse => e
|
|
94
|
+
puts "EXCEPTION: " + e.to_s if Cloud.debug
|
|
95
|
+
puts "EX.response: " + e.response.to_s if Cloud.debug
|
|
96
|
+
puts JSON.parse(e.response)["message"] if Cloud.debug
|
|
97
|
+
raise e
|
|
98
|
+
#return LMCResponse.new(e.response)
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def put(path, body_object)
|
|
103
|
+
RestClient.log = ("stdout") if Cloud.debug
|
|
104
|
+
begin
|
|
105
|
+
args = {
|
|
106
|
+
:method => :put,
|
|
107
|
+
:url => build_url(path),
|
|
108
|
+
:payload => body_object.to_json,
|
|
109
|
+
:headers => headers
|
|
110
|
+
|
|
111
|
+
}
|
|
112
|
+
args.merge!(rest_options)
|
|
113
|
+
resp = RestClient::Request.execute args
|
|
114
|
+
return LMCResponse.new(resp)
|
|
115
|
+
rescue RestClient::ExceptionWithResponse => e
|
|
116
|
+
puts "EXCEPTION: " + e.to_s if Cloud.debug
|
|
117
|
+
puts "EX.response: " + e.response.to_s if Cloud.debug
|
|
118
|
+
puts JSON.parse(e.response)["message"] if Cloud.debug
|
|
119
|
+
return LMCResponse.new(e.response)
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
def post(path, body_object)
|
|
124
|
+
RestClient.log = ("stdout") if Cloud.debug
|
|
125
|
+
begin
|
|
126
|
+
args = {
|
|
127
|
+
:method => :post,
|
|
128
|
+
:url => build_url(path),
|
|
129
|
+
:payload => body_object.to_json,
|
|
130
|
+
:headers => headers
|
|
131
|
+
|
|
132
|
+
}
|
|
133
|
+
args.merge!(rest_options)
|
|
134
|
+
resp = RestClient::Request.execute args
|
|
135
|
+
return LMCResponse.new(resp)
|
|
136
|
+
rescue RestClient::ExceptionWithResponse => e
|
|
137
|
+
puts "EXCEPTION: " + e.to_s if Cloud.debug
|
|
138
|
+
puts "EX.response: " + e.response.to_s if Cloud.debug
|
|
139
|
+
puts JSON.parse(e.response)["message"] if Cloud.debug
|
|
140
|
+
raise e
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def delete(path, body_object = nil)
|
|
145
|
+
RestClient.log = ("stdout") if Cloud.debug
|
|
146
|
+
begin
|
|
147
|
+
args = {
|
|
148
|
+
:method => :delete,
|
|
149
|
+
:url => build_url(path),
|
|
150
|
+
:payload => body_object.to_json,
|
|
151
|
+
:headers => headers
|
|
152
|
+
}
|
|
153
|
+
args.merge!(rest_options)
|
|
154
|
+
resp = RestClient::Request.execute args
|
|
155
|
+
return LMCResponse.new(resp)
|
|
156
|
+
rescue RestClient::ExceptionWithResponse => e
|
|
157
|
+
puts "EXCEPTION: " + e.to_s if Cloud.debug
|
|
158
|
+
puts "EX.response: " + e.response.to_s if Cloud.debug
|
|
159
|
+
puts JSON.parse(e.response)["message"] if Cloud.debug
|
|
160
|
+
return LMCResponse.new(e.response)
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
|
|
164
|
+
##
|
|
165
|
+
# public accessors
|
|
166
|
+
##
|
|
167
|
+
def session_token
|
|
168
|
+
@auth_token["value"]
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def build_url(*path_components)
|
|
172
|
+
protocol = "https"
|
|
173
|
+
if !Cloud.use_tls
|
|
174
|
+
protocol = "http"
|
|
175
|
+
end
|
|
176
|
+
["#{protocol}://#{@cloud_host}", path_components].flatten.compact.join("/")
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
def auth_for_accounts(account_ids)
|
|
180
|
+
puts "Authorizing for accounts: " + account_ids.to_s if Cloud.debug
|
|
181
|
+
authorize(account_ids)
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
def auth_for_account(account)
|
|
185
|
+
auth_for_accounts([account.id])
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
def accept_tos(tos)
|
|
189
|
+
authorize([], tos)
|
|
190
|
+
end
|
|
191
|
+
|
|
192
|
+
|
|
193
|
+
private
|
|
194
|
+
def authorize(account_ids = [], tos = [])
|
|
195
|
+
begin
|
|
196
|
+
reply = post(["cloud-service-auth", "auth"], {name: @user, password: @password, accountIds: account_ids, termsOfUse: tos})
|
|
197
|
+
puts "authorize reply " + reply.inspect if Cloud.debug
|
|
198
|
+
@auth_token = reply
|
|
199
|
+
@auth_ok = true
|
|
200
|
+
rescue ::RestClient::ExceptionWithResponse => e
|
|
201
|
+
response = JSON.parse(e.response.body)
|
|
202
|
+
if response['code'] == 100
|
|
203
|
+
raise LMC::OutdatedTermsOfUseException.new(response)
|
|
204
|
+
end
|
|
205
|
+
end
|
|
206
|
+
end
|
|
207
|
+
|
|
208
|
+
def auth_bearer
|
|
209
|
+
"Bearer " + session_token
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
def headers
|
|
213
|
+
headers = {}
|
|
214
|
+
headers[:content_type] = 'application/json'
|
|
215
|
+
if @auth_ok
|
|
216
|
+
headers[:Authorization] = auth_bearer
|
|
217
|
+
end
|
|
218
|
+
return headers
|
|
219
|
+
end
|
|
220
|
+
|
|
221
|
+
def rest_options
|
|
222
|
+
options = {}
|
|
223
|
+
if !@verify_tls
|
|
224
|
+
options[:verify_ssl] = false
|
|
225
|
+
end
|
|
226
|
+
return options
|
|
227
|
+
end
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
end
|
data/lib/lmc/Device.rb
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
module LMC
|
|
2
|
+
class Device
|
|
3
|
+
attr_reader :id, :name, :model, :serial, :heartbeatstate
|
|
4
|
+
|
|
5
|
+
def initialize(data)
|
|
6
|
+
@cloud = Cloud.instance
|
|
7
|
+
@id = data["id"]
|
|
8
|
+
@comment = data["comment"]
|
|
9
|
+
@name = data["status"]["name"]
|
|
10
|
+
@serial = data["status"]["serial"]
|
|
11
|
+
@model = data["status"]["model"]
|
|
12
|
+
@heartbeatstate = data["status"]["heartbeatState"]
|
|
13
|
+
@status = data["status"]
|
|
14
|
+
@account = data["account"]
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def get_config_for_account(account)
|
|
18
|
+
response = @cloud.get ["cloud-service-config", "configbuilder", "accounts", account.id, "devices", @id, "ui"]
|
|
19
|
+
JSON.parse(JSON.generate(response.body.to_h)) #terrible hack to get it to work for now. needs way to get more raw body_object from Response
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def set_config_for_account(config, account)
|
|
23
|
+
@cloud.put ["cloud-service-config", "configbuilder", "accounts", account.id, "devices", @id, "ui"], config
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def get_monitor_widgets(widget_item_ids)
|
|
27
|
+
@cloud.get ["cloud-service-monitoring", @account.id, "devices", @id, "monitordata"], {:widgetItemIds => widget_item_ids.join(",")}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.get_for_account(account)
|
|
31
|
+
cloud = Cloud.instance
|
|
32
|
+
cloud.auth_for_accounts [account.id]
|
|
33
|
+
list = cloud.get ["cloud-service-devices", "accounts", account.id, "devices"]
|
|
34
|
+
if list.code != 200
|
|
35
|
+
puts "Error getting devices: #{list.body.message}"
|
|
36
|
+
exit 1
|
|
37
|
+
end
|
|
38
|
+
devices = list.map do |data|
|
|
39
|
+
data["account"] = account
|
|
40
|
+
LMC::Device.new(data)
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def self.get_for_account_id(account_id)
|
|
45
|
+
self.get_for_account Account.get(account_id)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def config_state
|
|
49
|
+
@config_state ||= get_config_state
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def logs
|
|
53
|
+
# https://lmctest/#/project/6392b234-b11c-498a-a077-a5f5b23c54a0/devices/compact/eaafa152-62cf-48a1-be65-b222886daa6d/logging
|
|
54
|
+
#cloud = Cloud.instance
|
|
55
|
+
##cloud.auth_for_accounts [id]
|
|
56
|
+
#cloud.get ["cloud-service-logging", "accounts", id, "logs?lang=DE"]
|
|
57
|
+
raise "device logs not supported"
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
private
|
|
61
|
+
def get_config_state
|
|
62
|
+
reply = @cloud.get ["cloud-service-config", "configdevice", "accounts", @account.id, "state"], {"deviceIds" => @id}
|
|
63
|
+
if reply.code == 200
|
|
64
|
+
# binding.pry
|
|
65
|
+
DeviceConfigState.new reply.body[@id]
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
end
|
data/lib/lmc/Response.rb
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
require 'ostruct'
|
|
2
|
+
module LMC
|
|
3
|
+
class LMCResponse
|
|
4
|
+
|
|
5
|
+
attr_reader :body, :code, :headers
|
|
6
|
+
|
|
7
|
+
def initialize(response)
|
|
8
|
+
@body_object = {}
|
|
9
|
+
if response.bytesize > 0
|
|
10
|
+
@body_object = JSON.parse response.body
|
|
11
|
+
end
|
|
12
|
+
if @body_object.class == Array
|
|
13
|
+
@body = @body_object.map {|elem|
|
|
14
|
+
if elem.is_a? Hash then
|
|
15
|
+
OpenStruct.new(elem)
|
|
16
|
+
else
|
|
17
|
+
elem
|
|
18
|
+
end}
|
|
19
|
+
elsif @body_object.class == Hash
|
|
20
|
+
@body = OpenStruct.new(@body_object)
|
|
21
|
+
elsif @body_object.class == TrueClass || @body_object.class == FalseClass
|
|
22
|
+
@body = @body_object
|
|
23
|
+
else
|
|
24
|
+
raise "Unknown json parse result"
|
|
25
|
+
end
|
|
26
|
+
@code = response.code
|
|
27
|
+
@headers = response.headers
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# body_object and these methods allow to use LMCResponse objects in place
|
|
31
|
+
# of the old response which was just the body parsed to a hash or array
|
|
32
|
+
def [](key)
|
|
33
|
+
@body_object[key]
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def map(&block)
|
|
37
|
+
@body_object.map &block
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def each(&block)
|
|
41
|
+
@body_object.each &block
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def to_s
|
|
45
|
+
"Response: Code: #{@code}, Body: #{@body_object.to_s}"
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def empty?
|
|
49
|
+
@body_object.empty?
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
end
|
data/lib/lmc/Site.rb
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
module LMC
|
|
2
|
+
class Site
|
|
3
|
+
attr_accessor :name
|
|
4
|
+
attr_reader :id, :account
|
|
5
|
+
|
|
6
|
+
def initialize(data, account)
|
|
7
|
+
@cloud = Cloud.instance
|
|
8
|
+
@id = data["id"]
|
|
9
|
+
@name = data["name"]
|
|
10
|
+
@subnet_group_id = data["subnetGroupId"]
|
|
11
|
+
@account = account
|
|
12
|
+
|
|
13
|
+
if @account
|
|
14
|
+
@cloud.auth_for_account @account
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def to_s
|
|
19
|
+
"#{@name}"
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def account=(account)
|
|
23
|
+
if @account == nil
|
|
24
|
+
@account = account
|
|
25
|
+
return true
|
|
26
|
+
else
|
|
27
|
+
raise "Cannot replace account for site"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def configstates
|
|
32
|
+
response = @cloud.get ["cloud-service-config", "configsubnetgroup", "accounts", @account.id, "subnetgroups", @subnet_group_id, "updatestates"]
|
|
33
|
+
states = LMC::Configstates.new response.body
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
end
|
data/lib/lmc/User.rb
ADDED
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
module LMC
|
|
2
|
+
class User
|
|
3
|
+
#todo: look into hiding password
|
|
4
|
+
attr_reader :email
|
|
5
|
+
|
|
6
|
+
def initialize(data)
|
|
7
|
+
@email = data["email"]
|
|
8
|
+
@password = data["password"]
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# current registration process unclear and likely to have changed
|
|
12
|
+
# since this code was written.
|
|
13
|
+
#def register()
|
|
14
|
+
# # cloud instance by default authenticates.
|
|
15
|
+
# # for registration specifically, no authentication is required
|
|
16
|
+
# # should be possible without email and password for "admin" user
|
|
17
|
+
# cloud = Cloud.instance
|
|
18
|
+
# cloud.post ["cloud-service-auth", "users"], {"password" => @password, "email" => @email}
|
|
19
|
+
#end
|
|
20
|
+
|
|
21
|
+
def update(old_pw)
|
|
22
|
+
cloud = Cloud.instance
|
|
23
|
+
begin
|
|
24
|
+
cloud.post ["cloud-service-auth", "users", "self", "password"], {"password" => @password, 'verification' => old_pw}
|
|
25
|
+
rescue RestClient::BadRequest => e
|
|
26
|
+
response_body = JSON.parse(e.response)
|
|
27
|
+
raise "#{e.message} - #{response_body['message']}"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def request_pw_reset
|
|
32
|
+
#https://beta.cloud.lancom.de/cloud-service-auth/actions
|
|
33
|
+
cloud = Cloud.instance
|
|
34
|
+
post_data = {"type" => "PASSWORD_RESET", "name" => @email}
|
|
35
|
+
cloud.post ["cloud-service-auth", "actions"], post_data
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
end
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
module LMC
|
|
2
|
+
class AccountManager
|
|
3
|
+
@options
|
|
4
|
+
@global_options
|
|
5
|
+
@errors
|
|
6
|
+
attr_reader :errors
|
|
7
|
+
|
|
8
|
+
def initialize(options, global_options)
|
|
9
|
+
@options = options
|
|
10
|
+
@global_options = global_options
|
|
11
|
+
@errors = []
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
# returns nil if invite did not work
|
|
15
|
+
def invite(lmcen, distro, line, type, authority_name)
|
|
16
|
+
lmcen.auth_for_accounts([distro["id"]])
|
|
17
|
+
line = line.strip.downcase
|
|
18
|
+
begin
|
|
19
|
+
account = Account.get(distro["id"])
|
|
20
|
+
account_authorities = account.authorities
|
|
21
|
+
#puts account_authorities.inspect if @global_options[:debug]
|
|
22
|
+
if @global_options[:debug]
|
|
23
|
+
account_authorities.each do |a|
|
|
24
|
+
puts a["name"]
|
|
25
|
+
puts a.inspect
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
authority = account_authorities.find {|auth| auth["name"] == authority_name}
|
|
29
|
+
#puts "account authorities: #{account_authorities}" if @global_options[:debug]
|
|
30
|
+
puts authority if @global_options[:debug]
|
|
31
|
+
if !@options[:dry]
|
|
32
|
+
# TODO wenn der default authority nicht gibt geht das ding kaputt
|
|
33
|
+
invited = lmcen.invite_user_to_account(line, distro["id"], type, [authority["id"]])
|
|
34
|
+
puts "Invite response:" + invited.inspect if @global_options[:debug]
|
|
35
|
+
puts "Invited " + invited["name"].to_s + " to account #{distro["name"]}(#{invited.code})." if @global_options[:v]
|
|
36
|
+
if invited.code != 200
|
|
37
|
+
@errors << {:line => line, :result => invited.body}
|
|
38
|
+
return nil
|
|
39
|
+
end
|
|
40
|
+
else
|
|
41
|
+
invited = {"name" => line}
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
invite_url = lmcen.build_url("#", "register", Base64.encode64(invited["name"]))
|
|
45
|
+
if @options["show-csv"]
|
|
46
|
+
puts "\n" + invited["name"] + ", " + invite_url
|
|
47
|
+
end
|
|
48
|
+
if @options["send-mail"] && invited
|
|
49
|
+
mailbody = <<END
|
|
50
|
+
Hallo,
|
|
51
|
+
auf #{lmcen.cloud_host} wurde eine Einladung zu dem Account #{distro["name"]} für den Nutzer #{invited["name"]} erstellt.
|
|
52
|
+
|
|
53
|
+
Falls der Account noch nicht existiert, kann dieser Link zur Registrierung genutzt werden:
|
|
54
|
+
END
|
|
55
|
+
mail = Mail.new do
|
|
56
|
+
from "Philipp Erbelding <philipp.erbelding@lancom.de>"
|
|
57
|
+
to invited["name"]
|
|
58
|
+
subject "Einladung auf " + lmcen.cloud_host
|
|
59
|
+
body mailbody + invite_url
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
puts invite_url
|
|
63
|
+
if !@options[:dry]
|
|
64
|
+
puts "sending mail to " + invited["name"]
|
|
65
|
+
mail.delivery_method :smtp, address: "lcs-mail"
|
|
66
|
+
mail.deliver
|
|
67
|
+
else
|
|
68
|
+
puts "[DRY RUN] would send mail to " + invited["name"]
|
|
69
|
+
end
|
|
70
|
+
puts mail.to_s if @global_options[:v]
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
rescue RestClient::ExceptionWithResponse => e
|
|
74
|
+
puts e.to_s
|
|
75
|
+
puts invited.inspect
|
|
76
|
+
resp = JSON.parse(e.response)
|
|
77
|
+
puts resp.inspect
|
|
78
|
+
puts resp["message"]
|
|
79
|
+
end
|
|
80
|
+
return true
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
data/lib/lmc/entity.rb
ADDED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
module LMC
|
|
2
|
+
class Entity
|
|
3
|
+
def self.get_by_uuid_or_name term
|
|
4
|
+
raise "Missing argument" if term.nil?
|
|
5
|
+
begin
|
|
6
|
+
return self.get_by_uuid term
|
|
7
|
+
rescue RestClient::BadRequest, URI::InvalidURIError
|
|
8
|
+
return self.get_by_name term
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def [] key
|
|
13
|
+
self.send(key)
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
end
|
|
17
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module LMC
|
|
2
|
+
class OutdatedTermsOfUseException < Exception
|
|
3
|
+
def initialize(response = {})
|
|
4
|
+
@response = response
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
def response
|
|
8
|
+
r = "Terms of use must be accepted before using this LMC instance:\n"
|
|
9
|
+
missing.each do |tos|
|
|
10
|
+
r += "Name: #{tos['name']}, Date #{tos['acceptance']}\n"
|
|
11
|
+
|
|
12
|
+
end
|
|
13
|
+
return r
|
|
14
|
+
end
|
|
15
|
+
def missing
|
|
16
|
+
@response['details']['missing']
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
end
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
module LMC
|
|
2
|
+
class Principal
|
|
3
|
+
def initialize(data)
|
|
4
|
+
apply_data(data)
|
|
5
|
+
end
|
|
6
|
+
|
|
7
|
+
#returns itself, allows chaining
|
|
8
|
+
def save
|
|
9
|
+
response = if @id.nil?
|
|
10
|
+
Cloud.instance.post ["cloud-service-auth", "principals"], self
|
|
11
|
+
else
|
|
12
|
+
raise "editing principals not supported"
|
|
13
|
+
#@cloud.put ["cloud-service-auth", "principals", @id], self
|
|
14
|
+
end
|
|
15
|
+
apply_data(response.body)
|
|
16
|
+
return self
|
|
17
|
+
end
|
|
18
|
+
def to_json(*a)
|
|
19
|
+
{
|
|
20
|
+
"name" => @name,
|
|
21
|
+
"type" => @type,
|
|
22
|
+
"password" => @password
|
|
23
|
+
}.to_json(*a)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
private
|
|
27
|
+
def apply_data(data)
|
|
28
|
+
@id = data['id']
|
|
29
|
+
@name = data['name']
|
|
30
|
+
@password = data['password']
|
|
31
|
+
@type = data['type']
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
data/lib/lmc/version.rb
ADDED
data/lmc.gemspec
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
lib = File.expand_path("../lib", __FILE__)
|
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
|
4
|
+
require "lmc/version"
|
|
5
|
+
|
|
6
|
+
Gem::Specification.new do |spec|
|
|
7
|
+
spec.name = "lmc"
|
|
8
|
+
spec.version = LMC::VERSION
|
|
9
|
+
spec.authors = ["erpel"]
|
|
10
|
+
spec.email = ["philipp@copythat.de"]
|
|
11
|
+
|
|
12
|
+
spec.summary = %q{Library for interacting with LMC cloud instances}
|
|
13
|
+
# spec.homepage = "https://copythat.de"
|
|
14
|
+
spec.license = 'BSD-3-Clause'
|
|
15
|
+
|
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
|
18
|
+
if spec.respond_to?(:metadata)
|
|
19
|
+
#spec.metadata["allowed_push_host"] = "TODO: Set to 'http://mygemserver.com'"
|
|
20
|
+
else
|
|
21
|
+
raise "RubyGems 2.0 or newer is required to protect against " \
|
|
22
|
+
"public gem pushes."
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
spec.files = `git ls-files -z`.split("\x0").reject do |f|
|
|
26
|
+
f.match(%r{^(test|spec|features)/})
|
|
27
|
+
end
|
|
28
|
+
spec.bindir = "exe"
|
|
29
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
|
30
|
+
spec.require_paths = ["lib"]
|
|
31
|
+
|
|
32
|
+
spec.add_development_dependency 'bundler', '~> 1.16'
|
|
33
|
+
spec.add_development_dependency 'minitest', '~> 5.0'
|
|
34
|
+
spec.add_development_dependency 'minitest-reporters', '~> 1.1'
|
|
35
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
|
36
|
+
spec.add_development_dependency 'recursive-open-struct', '~> 1.1'
|
|
37
|
+
spec.add_development_dependency 'simplecov', '~> 0.15'
|
|
38
|
+
spec.add_development_dependency 'pry-nav', '~> 0.2.4'
|
|
39
|
+
|
|
40
|
+
spec.add_runtime_dependency 'json', '~> 2.0'
|
|
41
|
+
spec.add_runtime_dependency 'rest-client', '~> 2.0'
|
|
42
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: lmc
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.4.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- erpel
|
|
8
|
+
autorequire:
|
|
9
|
+
bindir: exe
|
|
10
|
+
cert_chain: []
|
|
11
|
+
date: 2018-07-06 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.16'
|
|
20
|
+
type: :development
|
|
21
|
+
prerelease: false
|
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
23
|
+
requirements:
|
|
24
|
+
- - "~>"
|
|
25
|
+
- !ruby/object:Gem::Version
|
|
26
|
+
version: '1.16'
|
|
27
|
+
- !ruby/object:Gem::Dependency
|
|
28
|
+
name: minitest
|
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
|
30
|
+
requirements:
|
|
31
|
+
- - "~>"
|
|
32
|
+
- !ruby/object:Gem::Version
|
|
33
|
+
version: '5.0'
|
|
34
|
+
type: :development
|
|
35
|
+
prerelease: false
|
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
37
|
+
requirements:
|
|
38
|
+
- - "~>"
|
|
39
|
+
- !ruby/object:Gem::Version
|
|
40
|
+
version: '5.0'
|
|
41
|
+
- !ruby/object:Gem::Dependency
|
|
42
|
+
name: minitest-reporters
|
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
|
44
|
+
requirements:
|
|
45
|
+
- - "~>"
|
|
46
|
+
- !ruby/object:Gem::Version
|
|
47
|
+
version: '1.1'
|
|
48
|
+
type: :development
|
|
49
|
+
prerelease: false
|
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
51
|
+
requirements:
|
|
52
|
+
- - "~>"
|
|
53
|
+
- !ruby/object:Gem::Version
|
|
54
|
+
version: '1.1'
|
|
55
|
+
- !ruby/object:Gem::Dependency
|
|
56
|
+
name: rake
|
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
|
58
|
+
requirements:
|
|
59
|
+
- - "~>"
|
|
60
|
+
- !ruby/object:Gem::Version
|
|
61
|
+
version: '10.0'
|
|
62
|
+
type: :development
|
|
63
|
+
prerelease: false
|
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
65
|
+
requirements:
|
|
66
|
+
- - "~>"
|
|
67
|
+
- !ruby/object:Gem::Version
|
|
68
|
+
version: '10.0'
|
|
69
|
+
- !ruby/object:Gem::Dependency
|
|
70
|
+
name: recursive-open-struct
|
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
|
72
|
+
requirements:
|
|
73
|
+
- - "~>"
|
|
74
|
+
- !ruby/object:Gem::Version
|
|
75
|
+
version: '1.1'
|
|
76
|
+
type: :development
|
|
77
|
+
prerelease: false
|
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
79
|
+
requirements:
|
|
80
|
+
- - "~>"
|
|
81
|
+
- !ruby/object:Gem::Version
|
|
82
|
+
version: '1.1'
|
|
83
|
+
- !ruby/object:Gem::Dependency
|
|
84
|
+
name: simplecov
|
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
|
86
|
+
requirements:
|
|
87
|
+
- - "~>"
|
|
88
|
+
- !ruby/object:Gem::Version
|
|
89
|
+
version: '0.15'
|
|
90
|
+
type: :development
|
|
91
|
+
prerelease: false
|
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
93
|
+
requirements:
|
|
94
|
+
- - "~>"
|
|
95
|
+
- !ruby/object:Gem::Version
|
|
96
|
+
version: '0.15'
|
|
97
|
+
- !ruby/object:Gem::Dependency
|
|
98
|
+
name: pry-nav
|
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
|
100
|
+
requirements:
|
|
101
|
+
- - "~>"
|
|
102
|
+
- !ruby/object:Gem::Version
|
|
103
|
+
version: 0.2.4
|
|
104
|
+
type: :development
|
|
105
|
+
prerelease: false
|
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
107
|
+
requirements:
|
|
108
|
+
- - "~>"
|
|
109
|
+
- !ruby/object:Gem::Version
|
|
110
|
+
version: 0.2.4
|
|
111
|
+
- !ruby/object:Gem::Dependency
|
|
112
|
+
name: json
|
|
113
|
+
requirement: !ruby/object:Gem::Requirement
|
|
114
|
+
requirements:
|
|
115
|
+
- - "~>"
|
|
116
|
+
- !ruby/object:Gem::Version
|
|
117
|
+
version: '2.0'
|
|
118
|
+
type: :runtime
|
|
119
|
+
prerelease: false
|
|
120
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
121
|
+
requirements:
|
|
122
|
+
- - "~>"
|
|
123
|
+
- !ruby/object:Gem::Version
|
|
124
|
+
version: '2.0'
|
|
125
|
+
- !ruby/object:Gem::Dependency
|
|
126
|
+
name: rest-client
|
|
127
|
+
requirement: !ruby/object:Gem::Requirement
|
|
128
|
+
requirements:
|
|
129
|
+
- - "~>"
|
|
130
|
+
- !ruby/object:Gem::Version
|
|
131
|
+
version: '2.0'
|
|
132
|
+
type: :runtime
|
|
133
|
+
prerelease: false
|
|
134
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
135
|
+
requirements:
|
|
136
|
+
- - "~>"
|
|
137
|
+
- !ruby/object:Gem::Version
|
|
138
|
+
version: '2.0'
|
|
139
|
+
description:
|
|
140
|
+
email:
|
|
141
|
+
- philipp@copythat.de
|
|
142
|
+
executables: []
|
|
143
|
+
extensions: []
|
|
144
|
+
extra_rdoc_files: []
|
|
145
|
+
files:
|
|
146
|
+
- ".gitignore"
|
|
147
|
+
- ".idea/inspectionProfiles/Project_Default.xml"
|
|
148
|
+
- ".idea/lmc.iml"
|
|
149
|
+
- ".idea/misc.xml"
|
|
150
|
+
- ".idea/modules.xml"
|
|
151
|
+
- ".idea/vcs.xml"
|
|
152
|
+
- ".ruby-version"
|
|
153
|
+
- ".travis.yml"
|
|
154
|
+
- Gemfile
|
|
155
|
+
- README.md
|
|
156
|
+
- Rakefile
|
|
157
|
+
- bin/console
|
|
158
|
+
- bin/setup
|
|
159
|
+
- coverage/.gitignore
|
|
160
|
+
- coverage/.last_run.json
|
|
161
|
+
- lib/lmc.rb
|
|
162
|
+
- lib/lmc/Account.rb
|
|
163
|
+
- lib/lmc/Cloud.rb
|
|
164
|
+
- lib/lmc/Configstates.rb
|
|
165
|
+
- lib/lmc/Device.rb
|
|
166
|
+
- lib/lmc/Response.rb
|
|
167
|
+
- lib/lmc/Site.rb
|
|
168
|
+
- lib/lmc/User.rb
|
|
169
|
+
- lib/lmc/account_manager.rb
|
|
170
|
+
- lib/lmc/device_config_state.rb
|
|
171
|
+
- lib/lmc/entity.rb
|
|
172
|
+
- lib/lmc/exceptions/lmc_outdated_terms_of_use_exception.rb
|
|
173
|
+
- lib/lmc/membership.rb
|
|
174
|
+
- lib/lmc/principal.rb
|
|
175
|
+
- lib/lmc/version.rb
|
|
176
|
+
- lmc.gemspec
|
|
177
|
+
homepage:
|
|
178
|
+
licenses:
|
|
179
|
+
- BSD-3-Clause
|
|
180
|
+
metadata: {}
|
|
181
|
+
post_install_message:
|
|
182
|
+
rdoc_options: []
|
|
183
|
+
require_paths:
|
|
184
|
+
- lib
|
|
185
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
186
|
+
requirements:
|
|
187
|
+
- - ">="
|
|
188
|
+
- !ruby/object:Gem::Version
|
|
189
|
+
version: '0'
|
|
190
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
191
|
+
requirements:
|
|
192
|
+
- - ">="
|
|
193
|
+
- !ruby/object:Gem::Version
|
|
194
|
+
version: '0'
|
|
195
|
+
requirements: []
|
|
196
|
+
rubyforge_project:
|
|
197
|
+
rubygems_version: 2.6.11
|
|
198
|
+
signing_key:
|
|
199
|
+
specification_version: 4
|
|
200
|
+
summary: Library for interacting with LMC cloud instances
|
|
201
|
+
test_files: []
|