soar-registry-staff 0.0.1
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/README.md +132 -0
- data/lib/soar/registry/staff/directory/dynamo_db/base.rb +86 -0
- data/lib/soar/registry/staff/directory/dynamo_db/identity.rb +83 -0
- data/lib/soar/registry/staff/directory/error.rb +19 -0
- data/lib/soar/registry/staff/identity.rb +90 -0
- data/lib/soar/registry/staff/translator/dynamo_db.rb +34 -0
- metadata +123 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: d667963b213a8c1f8bfac707cd214818eb33e591
|
4
|
+
data.tar.gz: 3ce77a63e9ec45a7e84ecbef40891526c2557d3d
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 40202401ddea924599085587392e84cdfb10263a640e3980ddd6347cd4729d9bffac46013c9a5bbd502a405eacd9f07c5f7a388708a8a0a18aa42876c8f26643
|
7
|
+
data.tar.gz: b345267177081bba7e8b69d3b7cf1c79b3ee5ec9853617e9b62bf94b84f6c0a8a6a5f5cf18fe05f1ffa378af30cf08ba0ff13ba320a913b00d7ec48a573dfa1b
|
data/README.md
ADDED
@@ -0,0 +1,132 @@
|
|
1
|
+
# Registry of staff identities
|
2
|
+
Allows you to query staff identities using the idm api.
|
3
|
+
|
4
|
+
*Please note:* Querying staff entities requires a different idr just for entities.
|
5
|
+
|
6
|
+
## Quickstart
|
7
|
+
|
8
|
+
### Required configuration
|
9
|
+
See config/config.yml
|
10
|
+
```yaml
|
11
|
+
rule_set:
|
12
|
+
adaptor: 'Soar::Registry::Staff::Translator::DynamoDb'
|
13
|
+
provider:
|
14
|
+
adaptor: 'Soar::Registry::Staff::Directory::DynamoDb::Identity'
|
15
|
+
config:
|
16
|
+
table: 'identities'
|
17
|
+
region: 'us-west-2'
|
18
|
+
endpoint: 'http://localhost:8000'
|
19
|
+
credentials:
|
20
|
+
username: 'username'
|
21
|
+
password: 'secret'
|
22
|
+
```
|
23
|
+
|
24
|
+
### Create an instance of the staff identity registry
|
25
|
+
```ruby
|
26
|
+
@idr = Soar::Registry::Staff::Identity.new(configuration)
|
27
|
+
```
|
28
|
+
|
29
|
+
### Getting a list of identifiers
|
30
|
+
```ruby
|
31
|
+
> identifiers = @idr.get_identifiers( {"email" => "admin@hetzner.co.za"} )
|
32
|
+
> identifiers = @idr.get_identifiers( {"identity_id" => "identity-820d5660-2204-4f7d-8c04-746313439b81"} )
|
33
|
+
> puts identifiers.inspect
|
34
|
+
["admin@hetzner.co.za", "identity-820d5660-2204-4f7d-8c04-746313439b81"]
|
35
|
+
```
|
36
|
+
|
37
|
+
### Getting a list of roles
|
38
|
+
```ruby
|
39
|
+
> roles = @idr.get_roles( {"email" => "admin@hetzner.co.za"} )
|
40
|
+
> roles = @idr.get_roles( {"identity_id" => "identity-820d5660-2204-4f7d-8c04-746313439b81"} )
|
41
|
+
> puts roles.inspect
|
42
|
+
["staff", "configuration_publisher", "configuration_consumer"]
|
43
|
+
```
|
44
|
+
|
45
|
+
### Getting a hash of attributes for a role
|
46
|
+
```ruby
|
47
|
+
> role = 'staff'
|
48
|
+
> attributes = @idr.get_attributes( {"email" => "admin@hetzner.co.za"}, role)
|
49
|
+
> attributes = @idr.get_attributes( {"identity_id" => "identity-820d5660-2204-4f7d-8c04-746313439b81"}, role )
|
50
|
+
> puts attributes.inspect
|
51
|
+
{
|
52
|
+
"staff": {
|
53
|
+
"department": "technical"
|
54
|
+
}
|
55
|
+
}
|
56
|
+
|
57
|
+
```
|
58
|
+
|
59
|
+
### Getting a hash of all attributes
|
60
|
+
```ruby
|
61
|
+
> attributes = @idr.get_attributes( {"email" => "admin@hetzner.co.za"} )
|
62
|
+
> attributes = @idr.get_attributes( {"identity_id" => "identity-820d5660-2204-4f7d-8c04-746313439b81"} )
|
63
|
+
> puts attributes.inspect
|
64
|
+
{
|
65
|
+
"identity_id" => "identity-820d5660-2204-4f7d-8c04-746313439b81",
|
66
|
+
"entity_id"=> "entity-bad85eb9-0713-4da7-8d36-07a8e4b00eab",
|
67
|
+
"email"=> "admin@hetzner.co.za",
|
68
|
+
"roles"=> {
|
69
|
+
"staff"=> {},
|
70
|
+
"configuration_publisher"=> {
|
71
|
+
"configuration_identifiers"=> ["*"]
|
72
|
+
},
|
73
|
+
"configuration_consumer"=> {
|
74
|
+
"configuration_identifiers"=> ["*"]
|
75
|
+
}
|
76
|
+
},
|
77
|
+
"address"=> {
|
78
|
+
"detail"=> "Belvedere Office Park, Unit F",
|
79
|
+
"street"=> "Bella Rosa Street",
|
80
|
+
"suburb"=> "Tygervalley",
|
81
|
+
"city"=> "Durbanville",
|
82
|
+
"postal"=> "7550"
|
83
|
+
}
|
84
|
+
}
|
85
|
+
```
|
86
|
+
|
87
|
+
## Tests
|
88
|
+
|
89
|
+
### Quicktest
|
90
|
+
```
|
91
|
+
$ docker-compose --file docker-compose.test.yml up --abort-on-container-exit --remove-orphans
|
92
|
+
```
|
93
|
+
|
94
|
+
### CI
|
95
|
+
*NB:* container_name in docker-compose.ci.yml corresponds with name parameter of docker ps command in below bash script.
|
96
|
+
```bash
|
97
|
+
#!/bin/bash
|
98
|
+
docker-compose --file docker-compose.test.yml up --build --abort-on-container-exit --remove-orphans --force-recreate;
|
99
|
+
EXIT_CODE=$(docker ps -a -f "name=soar-registry-staff" -q | xargs docker inspect -f "{{ .State.ExitCode }}");
|
100
|
+
exit $EXIT_CODE;
|
101
|
+
```
|
102
|
+
|
103
|
+
### Unit tests
|
104
|
+
|
105
|
+
#### Run dynamodb
|
106
|
+
```
|
107
|
+
$ docker-compose up
|
108
|
+
```
|
109
|
+
|
110
|
+
#### Open another terminal and run:
|
111
|
+
```
|
112
|
+
$ sudo -H pip install awscli
|
113
|
+
$ aws configure
|
114
|
+
$ bundle
|
115
|
+
$ rspec
|
116
|
+
```
|
117
|
+
|
118
|
+
### Useful commands:
|
119
|
+
```
|
120
|
+
$ aws dynamodb list-tables --endpoint-url http://localhost:8000
|
121
|
+
$ aws dynamodb delete-table --table-name identities --endpoint-url http://localhost:8000
|
122
|
+
```
|
123
|
+
|
124
|
+
## Resources
|
125
|
+
* [DynamoDBLocal](http://docs.aws.amazon.com/amazondynamodb/latest/developerguide/DynamoDBLocal.html)
|
126
|
+
* [Multiple AWS Credentials](https://blogs.aws.amazon.com/security/post/Tx3D6U6WSFGOK2H/A-New-and-Standardized-Way-to-Manage-Credentials-in-the-AWS-SDKs)
|
127
|
+
* [AWS SDK for Ruby](http://docs.aws.amazon.com/amazondynamodb/latest/gettingstartedguide/GettingStarted.Ruby.html)
|
128
|
+
|
129
|
+
## References
|
130
|
+
* [soar idm](https://github.hetzner.co.za/hetznerZA/soar_idm/blob/master/lib/soar_idm/soar_idm.rb)
|
131
|
+
* [Domain analysis](https://docs.google.com/a/hetzner.co.za/drawings/d/1vGdzjKPD3gzn1e0bsC4liFCyxY31Qjjxe3y41beVBzw/edit?usp=sharing)
|
132
|
+
* [staff idr](https://github.hetzner.co.za/hetznerZA/idr_staff/blob/master/idr_staff/lib/idr_staff/staff_idr.rb)
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'soar_idm/directory_provider'
|
2
|
+
require 'aws-sdk'
|
3
|
+
require 'hashie'
|
4
|
+
require 'soar/registry/staff/directory/error'
|
5
|
+
|
6
|
+
module Soar
|
7
|
+
module Registry
|
8
|
+
module Staff
|
9
|
+
module Directory
|
10
|
+
module DynamoDb
|
11
|
+
class Base < SoarIdm::DirectoryProvider
|
12
|
+
|
13
|
+
attr_reader :configuration, :credentials, :client
|
14
|
+
|
15
|
+
##
|
16
|
+
# @param [Hash] configuration for the directory provider
|
17
|
+
# @return [Nil]
|
18
|
+
# @raise [Soar::Registry::Staff::Directory::Error::BootstrapError] if required configuration is missing
|
19
|
+
##
|
20
|
+
def bootstrap(configuration)
|
21
|
+
@configuration = Hashie.stringify_keys(configuration)
|
22
|
+
raise Soar::Registry::Staff::Directory::Error::BootstrapError, 'Missing region' if not @configuration.has_key?('region')
|
23
|
+
raise Soar::Registry::Staff::Directory::Error::BootstrapError, 'Missing endpoint' if not @configuration.has_key?('endpoint')
|
24
|
+
@table_name = @configuration.delete('table')
|
25
|
+
raise Soar::Registry::Staff::Directory::Error::BootstrapError, 'Missing table name' if not @table_name
|
26
|
+
end
|
27
|
+
|
28
|
+
##
|
29
|
+
# @return [Bool] whether directory provider received minimum required configuration
|
30
|
+
##
|
31
|
+
def bootstrapped?
|
32
|
+
@configuration.has_key?('region') and @configuration.has_key?('endpoint')
|
33
|
+
end
|
34
|
+
|
35
|
+
def uri
|
36
|
+
@configuration['endpoint']
|
37
|
+
end
|
38
|
+
|
39
|
+
def authenticate(credentials)
|
40
|
+
raise Soar::Registry::Staff::Directory::Error::AuthenticationError, 'missing username' if not credentials.key?('username')
|
41
|
+
raise Soar::Registry::Staff::Directory::Error::AuthenticationError, 'missing password' if not credentials.key?('password')
|
42
|
+
@credentials = {
|
43
|
+
"access_key_id" => credentials['username'],
|
44
|
+
"secret_access_key" => credentials['password']
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
def connect
|
49
|
+
begin
|
50
|
+
options = @configuration.dup
|
51
|
+
options['credentials'] = Aws::Credentials.new(@credentials['access_key_id'], @credentials['secret_access_key'])
|
52
|
+
@client = Aws::DynamoDB::Client.new(Hashie.symbolize_keys(options))
|
53
|
+
@client
|
54
|
+
rescue ArgumentError => e
|
55
|
+
raise Soar::Registry::Staff::Directory::Error::ConnectionError, e.message
|
56
|
+
rescue
|
57
|
+
raise Soar::Registry::Staff::Directory::Error::ConnectionError, 'error creating client'
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
|
62
|
+
def connected?
|
63
|
+
return @client.class.name == 'Aws::DynamoDB::Client'
|
64
|
+
end
|
65
|
+
|
66
|
+
def ready?
|
67
|
+
begin
|
68
|
+
return @client.list_tables.table_names.class.name == 'Array'
|
69
|
+
rescue Seahorse::Client::NetworkingError
|
70
|
+
return false
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def put_identity(entity)
|
75
|
+
@client.put_item({
|
76
|
+
table_name: @table_name,
|
77
|
+
item: Hashie.symbolize_keys(entity)
|
78
|
+
})
|
79
|
+
end
|
80
|
+
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,83 @@
|
|
1
|
+
require 'soar_idm/directory_provider'
|
2
|
+
require 'soar/registry/staff/directory/dynamo_db/base'
|
3
|
+
require 'aws-sdk'
|
4
|
+
require 'hashie'
|
5
|
+
|
6
|
+
module Soar
|
7
|
+
module Registry
|
8
|
+
module Staff
|
9
|
+
module Directory
|
10
|
+
module DynamoDb
|
11
|
+
class Identity < Base
|
12
|
+
|
13
|
+
LIMIT = 10
|
14
|
+
INDEXED_ATTRIBUTES = ['email', 'entity_id']
|
15
|
+
|
16
|
+
##
|
17
|
+
# @param [String] identity_id primary key of the identity
|
18
|
+
# @return [Hash] the identity
|
19
|
+
# @raise [Soar::Registry::Staff::Directory::DynamoDb::Error::UniqueIdentifierNotFoundError] if primary key not found
|
20
|
+
##
|
21
|
+
def fetch_identity(identifier)
|
22
|
+
options = {
|
23
|
+
table_name: @table_name,
|
24
|
+
key: {
|
25
|
+
identity_id: identifier
|
26
|
+
}
|
27
|
+
}
|
28
|
+
identity = @client.get_item(options)
|
29
|
+
raise Soar::Registry::Staff::Directory::Error::UniqueIdentifierNotFoundError, 'Unable to find identity' if identity.item.nil?
|
30
|
+
identity.item
|
31
|
+
end
|
32
|
+
|
33
|
+
##
|
34
|
+
# @param [String] identifier_attribute
|
35
|
+
# @param [String] identifier_value
|
36
|
+
# @return [Array] list of identities
|
37
|
+
# @raise [ArgumentError] if query or index is not specified
|
38
|
+
##
|
39
|
+
def search_identities(identifier_attribute, identifier_value)
|
40
|
+
raise ArgumentError, "Attribute is required" if identifier_attribute.nil?
|
41
|
+
raise ArgumentError, 'Value is required' if identifier_value.nil?
|
42
|
+
options = {
|
43
|
+
table_name: @table_name,
|
44
|
+
select: 'ALL_ATTRIBUTES',
|
45
|
+
limit: LIMIT,
|
46
|
+
key_condition_expression: "#{identifier_attribute} = :value",
|
47
|
+
expression_attribute_values: {
|
48
|
+
":value": identifier_value
|
49
|
+
}
|
50
|
+
}
|
51
|
+
|
52
|
+
options.merge!({index_name: "#{identifier_attribute}_index"}) if INDEXED_ATTRIBUTES.include?(identifier_attribute)
|
53
|
+
identity = @client.query(options)
|
54
|
+
identity.items.map { |item|
|
55
|
+
Hashie.stringify_keys(item)
|
56
|
+
}
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# @return [Array] a list of primary keys and global secondary indexes
|
61
|
+
##
|
62
|
+
def indexed_attributes
|
63
|
+
resp = @client.describe_table({
|
64
|
+
table_name: @table_name
|
65
|
+
})
|
66
|
+
indexed_attributes = []
|
67
|
+
resp['table']['key_schema'].each { |key_schema|
|
68
|
+
indexed_attributes << key_schema['attribute_name']
|
69
|
+
}
|
70
|
+
resp['table']['global_secondary_indexes'].each { |index|
|
71
|
+
index['key_schema'].each { |key_schema|
|
72
|
+
indexed_attributes << key_schema['attribute_name']
|
73
|
+
}
|
74
|
+
}
|
75
|
+
indexed_attributes
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Soar
|
2
|
+
module Registry
|
3
|
+
module Staff
|
4
|
+
module Directory
|
5
|
+
module Error
|
6
|
+
class BootstrapError < StandardError; end;
|
7
|
+
class AuthenticationError < StandardError; end;
|
8
|
+
class CommunicationError < StandardError; end;
|
9
|
+
class ConnectionError < StandardError; end;
|
10
|
+
class NotReadyError < StandardError; end;
|
11
|
+
class UniqueIdentifierNotFoundError < StandardError; end;
|
12
|
+
class MissingIndexError < StandardError; end;
|
13
|
+
class MissingQueryError < StandardError; end;
|
14
|
+
class UniqueIdentifierNotFound < StandardError; end;
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'soar_idm/soar_idm'
|
2
|
+
require 'soar/registry/staff/translator/dynamo_db'
|
3
|
+
require 'soar/registry/staff/directory/dynamo_db/identity'
|
4
|
+
|
5
|
+
module Soar
|
6
|
+
module Registry
|
7
|
+
module Staff
|
8
|
+
|
9
|
+
class Identity < SoarIdm::IdmApi
|
10
|
+
|
11
|
+
attr_reader :directory
|
12
|
+
attr_reader :translator
|
13
|
+
attr_reader :client
|
14
|
+
|
15
|
+
##
|
16
|
+
# @param [Hash] configuration
|
17
|
+
# for example see config/config.yml
|
18
|
+
##
|
19
|
+
def initialize(configuration)
|
20
|
+
@translator = Object.const_get(configuration['rule_set']['adaptor']).new
|
21
|
+
@directory = Object::const_get(configuration['provider']['adaptor']).new
|
22
|
+
@directory.bootstrap(configuration['provider']['config'])
|
23
|
+
@directory.authenticate(configuration['provider']['credentials'])
|
24
|
+
@client = @directory.connect
|
25
|
+
raise Soar::Registry::Staff::Directory::Error::BootstrapError if not @directory.bootstrapped?
|
26
|
+
raise Soar::Registry::Staff::Directory::Error::ConnectionError if not @directory.connected?
|
27
|
+
raise Soar::Registry::Staff::Directory::Error::NotReadyError if not @directory.ready?
|
28
|
+
end
|
29
|
+
|
30
|
+
##
|
31
|
+
# @param [String] identity_id
|
32
|
+
# @return [Array] list of roles
|
33
|
+
def calculate_roles(identity_id)
|
34
|
+
entry = @directory.fetch_identity(identity_id)
|
35
|
+
return nil if not entry
|
36
|
+
identity = @translator.get_identity(entry)
|
37
|
+
roles = []
|
38
|
+
identity['roles'].each do |role, attributes|
|
39
|
+
roles << role
|
40
|
+
end
|
41
|
+
roles
|
42
|
+
end
|
43
|
+
|
44
|
+
##
|
45
|
+
# @param [String] identity_id
|
46
|
+
# @return [Array] list of identifiers
|
47
|
+
##
|
48
|
+
def calculate_identifiers(identity_id)
|
49
|
+
indexes = @directory.indexed_attributes
|
50
|
+
entry = @directory.fetch_identity(identity_id)
|
51
|
+
identity = @translator.get_identity(entry)
|
52
|
+
identifiers = []
|
53
|
+
indexes.each { |index|
|
54
|
+
identifiers << identity[index]
|
55
|
+
}
|
56
|
+
identifiers
|
57
|
+
end
|
58
|
+
|
59
|
+
##
|
60
|
+
# @param [String] identity_id
|
61
|
+
# @param [String] role
|
62
|
+
# @return [Hash] A hash of attributes
|
63
|
+
def calculate_attributes(identity_id, role)
|
64
|
+
entry = @directory.fetch_identity(identity_id)
|
65
|
+
return nil if not entry
|
66
|
+
identity = @translator.get_identity(entry)
|
67
|
+
{ role => identity['roles'][role] }
|
68
|
+
end
|
69
|
+
|
70
|
+
##
|
71
|
+
# @param [String] identity_id
|
72
|
+
# @return [Hash] Hash of attributes keyed by role
|
73
|
+
def calculate_all_attributes(identity_id)
|
74
|
+
entry = @directory.fetch_identity(identity_id)
|
75
|
+
@translator.get_identity(entry)
|
76
|
+
end
|
77
|
+
|
78
|
+
##
|
79
|
+
# @param [Hash] identifier containing attribute name and attribute value
|
80
|
+
# @return [Array]
|
81
|
+
def calculate_identities(identifier)
|
82
|
+
identifier = @translator.get_identifier(identifier)
|
83
|
+
entries = @directory.search_identities(identifier.keys[0], identifier[identifier.keys[0]] )
|
84
|
+
[@translator.get_identity(entries)[0]['identity_id']]
|
85
|
+
end
|
86
|
+
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
module Soar
|
2
|
+
module Registry
|
3
|
+
module Staff
|
4
|
+
module Translator
|
5
|
+
class DynamoDb
|
6
|
+
|
7
|
+
##
|
8
|
+
# @param [Hash] entry a single entry from datasource
|
9
|
+
# @returns [Hash] identity a single identity
|
10
|
+
##
|
11
|
+
def get_identity(entry)
|
12
|
+
return entry
|
13
|
+
end
|
14
|
+
|
15
|
+
##
|
16
|
+
# @param [Array] entries a list of entries from data source
|
17
|
+
# @return [Array] identities a list of identities
|
18
|
+
##
|
19
|
+
def get_identities(entries)
|
20
|
+
return entries
|
21
|
+
end
|
22
|
+
|
23
|
+
##
|
24
|
+
# @param [String|Hash] identifier could be a json string or a ruby hash
|
25
|
+
# @return [Hash] identifier with identifying attribute key and attribute value
|
26
|
+
##
|
27
|
+
def get_identifier(identifier)
|
28
|
+
identifier.is_a?(Hash) ? identifier : JSON.parse(identifier)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
metadata
ADDED
@@ -0,0 +1,123 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: soar-registry-staff
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Charles Mulder
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2016-10-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: soar_idm
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.2
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.2
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: aws-sdk
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '2.6'
|
34
|
+
- - ">="
|
35
|
+
- !ruby/object:Gem::Version
|
36
|
+
version: 2.6.6
|
37
|
+
type: :runtime
|
38
|
+
prerelease: false
|
39
|
+
version_requirements: !ruby/object:Gem::Requirement
|
40
|
+
requirements:
|
41
|
+
- - "~>"
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: '2.6'
|
44
|
+
- - ">="
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 2.6.6
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: aws-sdk-core
|
49
|
+
requirement: !ruby/object:Gem::Requirement
|
50
|
+
requirements:
|
51
|
+
- - "~>"
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '2.6'
|
54
|
+
- - ">="
|
55
|
+
- !ruby/object:Gem::Version
|
56
|
+
version: 2.6.11
|
57
|
+
type: :runtime
|
58
|
+
prerelease: false
|
59
|
+
version_requirements: !ruby/object:Gem::Requirement
|
60
|
+
requirements:
|
61
|
+
- - "~>"
|
62
|
+
- !ruby/object:Gem::Version
|
63
|
+
version: '2.6'
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: 2.6.11
|
67
|
+
- !ruby/object:Gem::Dependency
|
68
|
+
name: hashie
|
69
|
+
requirement: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - "~>"
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '3.4'
|
74
|
+
- - ">="
|
75
|
+
- !ruby/object:Gem::Version
|
76
|
+
version: 3.4.6
|
77
|
+
type: :runtime
|
78
|
+
prerelease: false
|
79
|
+
version_requirements: !ruby/object:Gem::Requirement
|
80
|
+
requirements:
|
81
|
+
- - "~>"
|
82
|
+
- !ruby/object:Gem::Version
|
83
|
+
version: '3.4'
|
84
|
+
- - ">="
|
85
|
+
- !ruby/object:Gem::Version
|
86
|
+
version: 3.4.6
|
87
|
+
description: Registry of staff identities and entities
|
88
|
+
email: charles.mulder@hetzner.co.za
|
89
|
+
executables: []
|
90
|
+
extensions: []
|
91
|
+
extra_rdoc_files: []
|
92
|
+
files:
|
93
|
+
- README.md
|
94
|
+
- lib/soar/registry/staff/directory/dynamo_db/base.rb
|
95
|
+
- lib/soar/registry/staff/directory/dynamo_db/identity.rb
|
96
|
+
- lib/soar/registry/staff/directory/error.rb
|
97
|
+
- lib/soar/registry/staff/identity.rb
|
98
|
+
- lib/soar/registry/staff/translator/dynamo_db.rb
|
99
|
+
homepage: https://gitlab.host-h.net/registries/staff
|
100
|
+
licenses:
|
101
|
+
- MIT
|
102
|
+
metadata: {}
|
103
|
+
post_install_message:
|
104
|
+
rdoc_options: []
|
105
|
+
require_paths:
|
106
|
+
- lib
|
107
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
108
|
+
requirements:
|
109
|
+
- - ">="
|
110
|
+
- !ruby/object:Gem::Version
|
111
|
+
version: '0'
|
112
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
113
|
+
requirements:
|
114
|
+
- - ">="
|
115
|
+
- !ruby/object:Gem::Version
|
116
|
+
version: '0'
|
117
|
+
requirements: []
|
118
|
+
rubyforge_project:
|
119
|
+
rubygems_version: 2.5.1
|
120
|
+
signing_key:
|
121
|
+
specification_version: 4
|
122
|
+
summary: Staff Registry
|
123
|
+
test_files: []
|