cloudkeeper-one 1.3.1 → 2.0.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 +5 -5
- data/.circleci/config.yml +11 -9
- data/.rubocop.yml +10 -0
- data/Dockerfile +2 -2
- data/README.md +51 -43
- data/{cloudkeeper-one.gemspec → cloudkeeper_one.gemspec} +3 -3
- data/config/cloudkeeper-one.yml +1 -3
- data/config/templates/template.erb +1 -1
- data/lib/cloudkeeper/one.rb +0 -1
- data/lib/cloudkeeper/one/appliance_actions/list.rb +21 -7
- data/lib/cloudkeeper/one/appliance_actions/registration.rb +11 -18
- data/lib/cloudkeeper/one/appliance_actions/update.rb +3 -2
- data/lib/cloudkeeper/one/appliance_actions/utils/template_preparation.rb +7 -6
- data/lib/cloudkeeper/one/appliance_actions/utils/templates/attributes.erb +10 -1
- data/lib/cloudkeeper/one/cli.rb +7 -11
- data/lib/cloudkeeper/one/core_connector.rb +41 -49
- data/lib/cloudkeeper/one/opennebula/appliance_handler.rb +0 -14
- data/lib/cloudkeeper/one/opennebula/datastore_handler.rb +0 -4
- data/lib/cloudkeeper/one/opennebula/image_handler.rb +1 -4
- data/lib/cloudkeeper/one/opennebula/tags.rb +4 -1
- data/lib/cloudkeeper/one/opennebula/template_handler.rb +1 -2
- data/lib/cloudkeeper/one/version.rb +1 -1
- data/lib/cloudkeeper_grpc.rb +2 -0
- data/lib/cloudkeeper_grpc/.gitmodules +3 -3
- data/lib/cloudkeeper_grpc/README.md +6 -0
- data/lib/cloudkeeper_grpc/cloudkeeper_pb.rb +5 -2
- data/lib/cloudkeeper_grpc/cloudkeeper_services_pb.rb +2 -0
- data/lib/cloudkeeper_grpc/constants.rb +3 -5
- data/lib/cloudkeeper_grpc/protos/cloudkeeper.proto +7 -2
- data/lib/cloudkeeper_grpc/{metadata → status-codes}/CODE_OF_CONDUCT.md +0 -0
- data/lib/cloudkeeper_grpc/{metadata → status-codes}/LICENSE.txt +2 -6
- data/lib/cloudkeeper_grpc/status-codes/README.md +3 -0
- data/lib/cloudkeeper_grpc/status-codes/status-codes.yml +12 -0
- metadata +16 -23
- data/lib/cloudkeeper/one/opennebula/group_handler.rb +0 -12
- data/lib/cloudkeeper_grpc/metadata/README.md +0 -3
- data/lib/cloudkeeper_grpc/metadata/metadata.yml +0 -13
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
|
-
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
2
|
+
SHA256:
|
|
3
|
+
metadata.gz: 8b8142e76a372832f41e114c4c8857a6d3a053850a26513bc6aed57b05a50307
|
|
4
|
+
data.tar.gz: 613d777b20247367cf1bd708f7cf2360875596387b6ab871ed947aa781c9c141
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: b2850302011a4dce74a674f6fa6c680c8e1d183949f244cbd1ca94ef96e08c1f0f3a0ba03277eddde4b2553037bcd9753e4182d704ebfbe81a92f5e72b3278a7
|
|
7
|
+
data.tar.gz: b3286b1caf923a0c92547900399d950c4bf67d76a9fc5e3b54c6e7f91fdad5b9133271c2d402502e574b52dac7527702f49251b9b9a880afc1981749d65d5462
|
data/.circleci/config.yml
CHANGED
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
version: 2
|
|
2
2
|
jobs:
|
|
3
|
-
|
|
4
|
-
branches:
|
|
5
|
-
ignore:
|
|
6
|
-
- /.*/
|
|
3
|
+
build_upload:
|
|
7
4
|
docker:
|
|
8
5
|
- image: docker:stable
|
|
9
6
|
working_directory: /root/working_directory
|
|
@@ -29,8 +26,13 @@ jobs:
|
|
|
29
26
|
docker tag $DOCKERHUB_ORGANIZATION/$CIRCLE_PROJECT_REPONAME:$TAG $DOCKERHUB_ORGANIZATION/$CIRCLE_PROJECT_REPONAME:latest
|
|
30
27
|
docker push $DOCKERHUB_ORGANIZATION/$CIRCLE_PROJECT_REPONAME:latest
|
|
31
28
|
fi
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
-
|
|
29
|
+
workflows:
|
|
30
|
+
version: 2
|
|
31
|
+
release-docker-images:
|
|
32
|
+
jobs:
|
|
33
|
+
- build_upload:
|
|
34
|
+
filters:
|
|
35
|
+
tags:
|
|
36
|
+
only: /v.*/
|
|
37
|
+
branches:
|
|
38
|
+
ignore: /.*/
|
data/.rubocop.yml
CHANGED
|
@@ -11,12 +11,22 @@ Metrics/LineLength:
|
|
|
11
11
|
Exclude:
|
|
12
12
|
- 'lib/cloudkeeper/one/appliance_actions/list.rb'
|
|
13
13
|
|
|
14
|
+
Metrics/LineLength:
|
|
15
|
+
Max: 140
|
|
16
|
+
Include:
|
|
17
|
+
- 'lib/cloudkeeper/one/core_connector.rb'
|
|
18
|
+
|
|
14
19
|
Style/Documentation:
|
|
15
20
|
Enabled: false
|
|
16
21
|
|
|
17
22
|
Metrics/MethodLength:
|
|
18
23
|
Max: 15
|
|
19
24
|
|
|
25
|
+
Metrics/MethodLength:
|
|
26
|
+
Max: 20
|
|
27
|
+
Include:
|
|
28
|
+
- 'lib/cloudkeeper/one/appliance_actions/list.rb'
|
|
29
|
+
|
|
20
30
|
Metrics/AbcSize:
|
|
21
31
|
Max: 20
|
|
22
32
|
Exclude:
|
data/Dockerfile
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
FROM ubuntu:
|
|
1
|
+
FROM ubuntu:18.04
|
|
2
2
|
|
|
3
3
|
ARG branch=master
|
|
4
4
|
ARG version
|
|
@@ -10,7 +10,7 @@ ENV applDir="${spoolDir}/appliances" \
|
|
|
10
10
|
logDir="/var/log/${username}"
|
|
11
11
|
|
|
12
12
|
LABEL application=${name} \
|
|
13
|
-
description="A tool for synchronizing appliances between
|
|
13
|
+
description="A tool for synchronizing appliances between Cloudkeeper and OpenNebula" \
|
|
14
14
|
maintainer="kimle@cesnet.cz" \
|
|
15
15
|
version=${version} \
|
|
16
16
|
branch=${branch}
|
data/README.md
CHANGED
|
@@ -1,14 +1,21 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
<h1 align="center">
|
|
2
|
+
<img src="https://i.imgur.com/95iUPzX.png" alt="Logo Cloudkeeper-ONE" title="Logo Cloudkeeper-ONE" width="256"/>
|
|
3
|
+
<p>Cloudkeeper-ONE</p>
|
|
4
|
+
</h1>
|
|
3
5
|
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
<p align="center">
|
|
7
|
+
<a href="http://travis-ci.org/the-cloudkeeper-project/cloudkeeper-one"><img src="https://img.shields.io/travis/the-cloudkeeper-project/cloudkeeper-one.svg?style=flat-square" alt="Travis"></a>
|
|
8
|
+
<a href="https://depfu.com/repos/the-cloudkeeper-project/cloudkeeper-one"><img src="https://img.shields.io/depfu/the-cloudkeeper-project/cloudkeeper-one.svg?style=flat-square" alt="Depfu"></a>
|
|
9
|
+
<a href="https://rubygems.org/gems/cloudkeeper-one"><img src="https://img.shields.io/gem/v/cloudkeeper-one.svg?style=flat-square" alt="Gem"></a>
|
|
10
|
+
<a href="https://codeclimate.com/github/the-cloudkeeper-project/cloudkeeper-one"><img src="https://img.shields.io/codeclimate/maintainability/the-cloudkeeper-project/cloudkeeper-one.svg?style=flat-square" alt="Code Climate"></a>
|
|
11
|
+
<a href="https://hub.docker.com/r/cloudkeeper/cloudkeeper-one/"><img src="https://img.shields.io/badge/docker-ready-blue.svg?style=flat-square" alt="DockerHub"></a>
|
|
12
|
+
<a href="https://zenodo.org/record/1134571"><img src="https://img.shields.io/badge/dynamic/json.svg?label=DOI&colorB=0D7EBE&prefix=&suffix=&query=$.doi&uri=https%3A%2F%2Fzenodo.org%2Fapi%2Frecords%2F1134571&style=flat-square" alt="DOI"></a>
|
|
13
|
+
</p>
|
|
9
14
|
|
|
10
|
-
|
|
11
|
-
|
|
15
|
+
<h4 align="center">OpenNebula backend for <a href="https://github.com/the-cloudkeeper-project/cloudkeeper">Cloudkeeper</a></h4>
|
|
16
|
+
|
|
17
|
+
## What does Cloudkeeper-ONE do?
|
|
18
|
+
Cloudkeeper-ONE is able to manage [OpenNebula](https://opennebula.org/) CMF - upload, update and remove images and templates representing EGI AppDB appliances. Cloudkeeper-ONE runs as a server listening for [gRPC](http://www.grpc.io/) communication usually from core [cloudkeeper](https://github.com/the-cloudkeeper-project/cloudkeeper) component.
|
|
12
19
|
|
|
13
20
|
## Requirements
|
|
14
21
|
* Ruby >= 2.2.0
|
|
@@ -40,8 +47,8 @@ bundle exec rake spec
|
|
|
40
47
|
```
|
|
41
48
|
|
|
42
49
|
## Configuration
|
|
43
|
-
### Create a configuration file for
|
|
44
|
-
Configuration file can be read by
|
|
50
|
+
### Create a configuration file for Cloudkeeper-ONE
|
|
51
|
+
Configuration file can be read by Cloudkeeper-ONE from these
|
|
45
52
|
three locations:
|
|
46
53
|
|
|
47
54
|
* `~/.cloudkeeper-one/cloudkeeper-one.yml`
|
|
@@ -52,43 +59,44 @@ The default configuration file can be found at the last location
|
|
|
52
59
|
`PATH_TO_GEM_DIR/config/cloudkeeper-one.yml`.
|
|
53
60
|
|
|
54
61
|
## Usage
|
|
55
|
-
|
|
62
|
+
Cloudkeeper-ONE is run with executable `cloudkeeper-one`. For further assistance run `cloudkeeper-one help sync`:
|
|
56
63
|
```bash
|
|
57
64
|
Usage:
|
|
58
|
-
cloudkeeper-one sync --appliances-permissions=APPLIANCES-PERMISSIONS --appliances-tmp-dir=APPLIANCES-TMP-DIR --identifier=IDENTIFIER --listen-address=LISTEN-ADDRESS --opennebula-api-call-timeout=OPENNEBULA-API-CALL-TIMEOUT --opennebula-
|
|
65
|
+
cloudkeeper-one sync --appliances-permissions=APPLIANCES-PERMISSIONS --appliances-tmp-dir=APPLIANCES-TMP-DIR --identifier=IDENTIFIER --listen-address=LISTEN-ADDRESS --opennebula-api-call-timeout=OPENNEBULA-API-CALL-TIMEOUT --opennebula-datastore=OPENNEBULA-DATASTORE
|
|
59
66
|
|
|
60
67
|
Options:
|
|
61
|
-
--listen-address=LISTEN-ADDRESS
|
|
62
|
-
|
|
63
|
-
[--authentication], [--no-authentication]
|
|
64
|
-
[--certificate=CERTIFICATE]
|
|
65
|
-
|
|
66
|
-
[--key=KEY]
|
|
67
|
-
|
|
68
|
-
--identifier=IDENTIFIER
|
|
69
|
-
|
|
70
|
-
[--core-certificate=CORE-CERTIFICATE]
|
|
71
|
-
|
|
72
|
-
--appliances-tmp-dir=APPLIANCES-TMP-DIR
|
|
73
|
-
|
|
74
|
-
[--appliances-template-dir=APPLIANCES-TEMPLATE-DIR]
|
|
75
|
-
--appliances-permissions=APPLIANCES-PERMISSIONS
|
|
76
|
-
|
|
77
|
-
--opennebula-secret=OPENNEBULA-SECRET
|
|
78
|
-
|
|
79
|
-
--opennebula-endpoint=OPENNEBULA-ENDPOINT
|
|
80
|
-
|
|
81
|
-
--opennebula-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
68
|
+
--listen-address=LISTEN-ADDRESS # IP address gRPC server will listen on
|
|
69
|
+
# Default: 127.0.0.1:50051
|
|
70
|
+
[--authentication], [--no-authentication] # Client <-> server authentication
|
|
71
|
+
[--certificate=CERTIFICATE] # Backend's host certificate
|
|
72
|
+
# Default: /etc/grid-security/hostcert.pem
|
|
73
|
+
[--key=KEY] # Backend's host key
|
|
74
|
+
# Default: /etc/grid-security/hostkey.pem
|
|
75
|
+
--identifier=IDENTIFIER # Instance identifier
|
|
76
|
+
# Default: cloudkeeper-one
|
|
77
|
+
[--core-certificate=CORE-CERTIFICATE] # Core's certificate
|
|
78
|
+
# Default: /etc/grid-security/corecert.pem
|
|
79
|
+
--appliances-tmp-dir=APPLIANCES-TMP-DIR # Directory where to temporarily store appliances
|
|
80
|
+
# Default: /var/spool/cloudkeeper/appliances
|
|
81
|
+
[--appliances-template-dir=APPLIANCES-TEMPLATE-DIR] # If set, templates within this directory are used to construct images and templates in OpenNebula
|
|
82
|
+
--appliances-permissions=APPLIANCES-PERMISSIONS # UNIX-like permissions appliances will have within OpenNebula
|
|
83
|
+
# Default: 640
|
|
84
|
+
[--opennebula-secret=OPENNEBULA-SECRET] # OpenNebula authentication secret
|
|
85
|
+
# Default: oneadmin:opennebula
|
|
86
|
+
[--opennebula-endpoint=OPENNEBULA-ENDPOINT] # OpenNebula XML-RPC endpoint
|
|
87
|
+
# Default: http://localhost:2633/RPC2
|
|
88
|
+
--opennebula-datastore=OPENNEBULA-DATASTORE # OpenNebula datastore images will be uploaded to
|
|
89
|
+
# Default: default
|
|
90
|
+
--opennebula-api-call-timeout=OPENNEBULA-API-CALL-TIMEOUT # How long will cloudkeeper-one wait for image/template operations to finish in OpenNebula
|
|
91
|
+
# Default: 3h
|
|
92
|
+
[--opennebula-allow-remote-source], [--no-opennebula-allow-remote-source] # Allows OpenNebula to directly download remote image
|
|
93
|
+
# Default: true
|
|
86
94
|
--logging-level=LOGGING-LEVEL
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
[--logging-file=LOGGING-FILE]
|
|
90
|
-
|
|
91
|
-
[--debug], [--no-debug]
|
|
95
|
+
# Default: ERROR
|
|
96
|
+
# Possible values: DEBUG, INFO, WARN, ERROR, FATAL, UNKNOWN
|
|
97
|
+
[--logging-file=LOGGING-FILE] # File to write logs to
|
|
98
|
+
# Default: /var/log/cloudkeeper/cloudkeeper-one.log
|
|
99
|
+
[--debug], [--no-debug] # Runs cloudkeeper in debug mode
|
|
92
100
|
```
|
|
93
101
|
|
|
94
102
|
## Contributing
|
|
@@ -30,16 +30,16 @@ Gem::Specification.new do |spec|
|
|
|
30
30
|
spec.require_paths = ['lib']
|
|
31
31
|
|
|
32
32
|
spec.add_development_dependency 'bundler', '~> 1.14'
|
|
33
|
-
spec.add_development_dependency 'grpc-tools', '
|
|
33
|
+
spec.add_development_dependency 'grpc-tools', '~> 1.14'
|
|
34
34
|
spec.add_development_dependency 'pry', '~> 0.10'
|
|
35
35
|
spec.add_development_dependency 'pry-byebug', '~> 3.4'
|
|
36
|
-
spec.add_development_dependency 'rake', '~>
|
|
36
|
+
spec.add_development_dependency 'rake', '~> 12.3'
|
|
37
37
|
spec.add_development_dependency 'rspec', '~> 3.5'
|
|
38
38
|
spec.add_development_dependency 'rspec-collection_matchers', '~> 1.1'
|
|
39
39
|
spec.add_development_dependency 'rubocop', '~> 0.48'
|
|
40
40
|
spec.add_development_dependency 'rubocop-rspec', '~> 1.15'
|
|
41
41
|
spec.add_development_dependency 'simplecov', '~> 0.12'
|
|
42
|
-
spec.add_development_dependency 'vcr', '~>
|
|
42
|
+
spec.add_development_dependency 'vcr', '~> 4.0'
|
|
43
43
|
spec.add_development_dependency 'webmock', '~> 3.0'
|
|
44
44
|
|
|
45
45
|
spec.add_runtime_dependency 'activesupport', '>= 4.0', '< 6.0'
|
data/config/cloudkeeper-one.yml
CHANGED
|
@@ -13,9 +13,7 @@ cloudkeeper-one:
|
|
|
13
13
|
opennebula:
|
|
14
14
|
secret: oneadmin:opennebula # If not specified, looking for secret in environment variable ONE_AUTH and file ~/.one/one_auth
|
|
15
15
|
endpoint: http://localhost:2633/RPC2 # If not specified, looking for endpoint in environment variable ONE_XMLRPC and file ~/.one/one_endpoint
|
|
16
|
-
|
|
17
|
-
- default
|
|
18
|
-
users: # Handle only images/templates of specified users
|
|
16
|
+
datastore: default # OpenNebula datastore images will be uploaded to
|
|
19
17
|
api-call-timeout: 3h # How long will cloudkeeper-one wait for image/template operations to finish in OpenNebula
|
|
20
18
|
allow-remote-source: true # Allows OpenNebula to directly download remote image
|
|
21
19
|
logging:
|
|
@@ -6,7 +6,7 @@ DESCRIPTION = "<%= "#{appliance.title} - #{appliance.description}" %>"
|
|
|
6
6
|
DESCRIPTION = "<%= appliance.title %>"
|
|
7
7
|
<% end %>
|
|
8
8
|
|
|
9
|
-
MEMORY = "<%= appliance.ram != 0 ? appliance.ram : 1024 %>"
|
|
9
|
+
MEMORY = "<%= appliance.ram != 0 ? (appliance.ram / (1024**2)) : 1024 %>"
|
|
10
10
|
CPU = "<%= appliance.core != 0 ? appliance.core : 0.25 %>"
|
|
11
11
|
VCPU = "<%= appliance.core != 0 ? appliance.core : 1 %>"
|
|
12
12
|
|
data/lib/cloudkeeper/one.rb
CHANGED
|
@@ -23,8 +23,8 @@ module Cloudkeeper
|
|
|
23
23
|
templates.uniq! { |template| template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_ID}"] }
|
|
24
24
|
|
|
25
25
|
appliances = templates.map do |template|
|
|
26
|
-
|
|
27
|
-
populate_proto_appliance template
|
|
26
|
+
image = find_image_for_template template
|
|
27
|
+
populate_proto_appliance template, image
|
|
28
28
|
end
|
|
29
29
|
|
|
30
30
|
logger.debug "Appliances: #{appliances.map(&:identifier).inspect}"
|
|
@@ -33,12 +33,15 @@ module Cloudkeeper
|
|
|
33
33
|
|
|
34
34
|
private
|
|
35
35
|
|
|
36
|
-
def
|
|
36
|
+
def find_image_for_template(template)
|
|
37
|
+
image = image_handler.find_by_name template.name
|
|
37
38
|
raise Cloudkeeper::One::Errors::Actions::ListingError, "Missing coresponding image for template #{template.id.inspect}" \
|
|
38
|
-
unless
|
|
39
|
+
unless image
|
|
40
|
+
|
|
41
|
+
image
|
|
39
42
|
end
|
|
40
43
|
|
|
41
|
-
def populate_proto_appliance(template)
|
|
44
|
+
def populate_proto_appliance(template, image)
|
|
42
45
|
CloudkeeperGrpc::Appliance.new identifier: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_ID}"].to_s,
|
|
43
46
|
description: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_DESCRIPTION}"].to_s,
|
|
44
47
|
mpuri: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_MPURI}"].to_s,
|
|
@@ -50,10 +53,21 @@ module Cloudkeeper
|
|
|
50
53
|
architecture: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_ARCHITECTURE}"].to_s,
|
|
51
54
|
operating_system: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_OPERATING_SYSTEM}"].to_s,
|
|
52
55
|
vo: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_VO}"].to_s,
|
|
53
|
-
image:
|
|
56
|
+
image: populate_proto_image(image),
|
|
54
57
|
expiration_date: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_EXPIRATION_DATE}"].to_i,
|
|
55
58
|
image_list_identifier: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_IMAGE_LIST_ID}"].to_s,
|
|
56
|
-
|
|
59
|
+
base_mpuri: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_BASE_MPURI}"].to_s,
|
|
60
|
+
appid: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_APPID}"].to_s,
|
|
61
|
+
digest: template["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::APPLIANCE_DIGEST}"].to_s
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def populate_proto_image(image)
|
|
65
|
+
CloudkeeperGrpc::Image.new mode: :LOCAL, location: '',
|
|
66
|
+
format: image["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::IMAGE_FORMAT}"].upcase.to_sym,
|
|
67
|
+
checksum: image["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::IMAGE_CHECKSUM}"].to_s,
|
|
68
|
+
size: image["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::IMAGE_SIZE}"].to_i,
|
|
69
|
+
uri: image["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::IMAGE_URI}"].to_s,
|
|
70
|
+
digest: image["TEMPLATE/#{Cloudkeeper::One::Opennebula::Tags::IMAGE_DIGEST}"].to_s
|
|
57
71
|
end
|
|
58
72
|
end
|
|
59
73
|
end
|
|
@@ -10,54 +10,47 @@ module Cloudkeeper
|
|
|
10
10
|
def register_or_update_appliance(proto_appliance)
|
|
11
11
|
raise Cloudkeeper::One::Errors::ArgumentError, 'appliance cannot be nil' unless proto_appliance
|
|
12
12
|
|
|
13
|
-
group = group_handler.find_by_name proto_appliance.vo
|
|
14
|
-
raise Cloudkeeper::One::Errors::Actions::RegistrationError, "Missing group with name #{proto_appliance.vo}" unless group
|
|
15
|
-
|
|
16
13
|
discard_images :find_by_appliance_id, proto_appliance.identifier
|
|
17
14
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
register_or_update_template proto_appliance, image, group
|
|
22
|
-
end
|
|
15
|
+
datastore = datastore_handler.find_by_name Cloudkeeper::One::Settings[:'opennebula-datastore']
|
|
16
|
+
image = register_image proto_appliance, datastore
|
|
17
|
+
register_or_update_template proto_appliance, image
|
|
23
18
|
end
|
|
24
19
|
|
|
25
20
|
private
|
|
26
21
|
|
|
27
|
-
def register_or_update_template(proto_appliance, image
|
|
22
|
+
def register_or_update_template(proto_appliance, image)
|
|
28
23
|
template = template_handler.find_by_name image.name
|
|
29
24
|
if template
|
|
30
25
|
update_template template, image, proto_appliance
|
|
31
26
|
return
|
|
32
27
|
end
|
|
33
28
|
|
|
34
|
-
register_template proto_appliance, image.id, image.name
|
|
29
|
+
register_template proto_appliance, image.id, image.name
|
|
35
30
|
end
|
|
36
31
|
|
|
37
|
-
def register_image(proto_appliance, datastore
|
|
32
|
+
def register_image(proto_appliance, datastore)
|
|
38
33
|
raise Cloudkeeper::One::Errors::ArgumentError, 'appliance and image cannot be nil' \
|
|
39
34
|
unless proto_appliance && proto_appliance.image
|
|
40
35
|
|
|
41
|
-
logger.debug "Registering image for appliance #{proto_appliance.identifier}
|
|
42
|
-
"group #{group.name.inspect}"
|
|
36
|
+
logger.debug "Registering image for appliance #{proto_appliance.identifier} and datastore #{datastore.name.inspect}"
|
|
43
37
|
|
|
44
38
|
proto_image = prepare_image proto_appliance
|
|
45
39
|
name = "#{proto_appliance.identifier}@#{datastore.name}"
|
|
46
40
|
template = prepare_template 'image.erb', appliance: proto_appliance, image: proto_image, name: name
|
|
47
|
-
image_handler.register template, datastore
|
|
41
|
+
image_handler.register template, datastore
|
|
48
42
|
end
|
|
49
43
|
|
|
50
|
-
def register_template(proto_appliance, image_id, name
|
|
44
|
+
def register_template(proto_appliance, image_id, name)
|
|
51
45
|
raise Cloudkeeper::One::Errors::ArgumentError, 'appliance cannot be nil' \
|
|
52
46
|
unless proto_appliance
|
|
53
47
|
|
|
54
|
-
logger.debug "Registering template for appliance #{proto_appliance.identifier}
|
|
55
|
-
"group #{group.name.inspect}"
|
|
48
|
+
logger.debug "Registering template for appliance #{proto_appliance.identifier} and image #{image_id.inspect}"
|
|
56
49
|
|
|
57
50
|
proto_image = proto_appliance.image
|
|
58
51
|
template = prepare_template 'template.erb', appliance: proto_appliance, image: proto_image,
|
|
59
52
|
name: name, image_id: image_id
|
|
60
|
-
template_handler.register template
|
|
53
|
+
template_handler.register template
|
|
61
54
|
end
|
|
62
55
|
|
|
63
56
|
def prepare_image(proto_appliance)
|
|
@@ -4,7 +4,7 @@ module Cloudkeeper
|
|
|
4
4
|
module Update
|
|
5
5
|
include Utils::TemplatePreparation
|
|
6
6
|
|
|
7
|
-
def
|
|
7
|
+
def update_metadata(proto_appliance)
|
|
8
8
|
raise Cloudkeeper::One::Errors::ArgumentError, 'appliance cannot be nil' unless proto_appliance
|
|
9
9
|
|
|
10
10
|
templates = template_handler.find_by_appliance_id proto_appliance.identifier
|
|
@@ -12,6 +12,7 @@ module Cloudkeeper
|
|
|
12
12
|
image = image_handler.find_by_name template.name
|
|
13
13
|
raise Cloudkeeper::One::Errors::Actions::UpdateError, "Missing coresponding image for template #{template.id.inspect}"\
|
|
14
14
|
unless image
|
|
15
|
+
|
|
15
16
|
update_image image, proto_appliance
|
|
16
17
|
update_template template, image, proto_appliance
|
|
17
18
|
end
|
|
@@ -25,7 +26,7 @@ module Cloudkeeper
|
|
|
25
26
|
|
|
26
27
|
def update_template(template, image, proto_appliance)
|
|
27
28
|
logger.debug "Updating template metadata for appliance #{proto_appliance.identifier.inspect}"
|
|
28
|
-
template_template = prepare_template 'template.erb', appliance: proto_appliance, name: template.name, image_id: image.id
|
|
29
|
+
template_template = prepare_template 'template.erb', appliance: proto_appliance, image: proto_appliance.image, name: template.name, image_id: image.id
|
|
29
30
|
template_handler.update template, template_template
|
|
30
31
|
end
|
|
31
32
|
end
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
require 'stringio'
|
|
1
2
|
require 'erb'
|
|
2
3
|
require 'tilt/erb'
|
|
3
4
|
|
|
@@ -21,13 +22,13 @@ module Cloudkeeper
|
|
|
21
22
|
end
|
|
22
23
|
|
|
23
24
|
def render_templates(templates, data)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
template = Tilt::ERBTemplate.new tmp
|
|
29
|
-
template.render Object.new, data
|
|
25
|
+
template = Tilt::ERBTemplate.new do
|
|
26
|
+
io = StringIO.new
|
|
27
|
+
templates.each { |file| io.write(File.read(file)) }
|
|
28
|
+
io.string
|
|
30
29
|
end
|
|
30
|
+
|
|
31
|
+
template.render Object.new, data
|
|
31
32
|
end
|
|
32
33
|
end
|
|
33
34
|
end
|
|
@@ -12,5 +12,14 @@
|
|
|
12
12
|
<%= Cloudkeeper::One::Opennebula::Tags::APPLIANCE_VO %> = "<%= appliance.vo %>"
|
|
13
13
|
<%= Cloudkeeper::One::Opennebula::Tags::APPLIANCE_EXPIRATION_DATE %> = "<%= appliance.expiration_date %>"
|
|
14
14
|
<%= Cloudkeeper::One::Opennebula::Tags::APPLIANCE_IMAGE_LIST_ID %> = "<%= appliance.image_list_identifier %>"
|
|
15
|
+
<%= Cloudkeeper::One::Opennebula::Tags::APPLIANCE_BASE_MPURI %> = "<%= appliance.base_mpuri %>"
|
|
16
|
+
<%= Cloudkeeper::One::Opennebula::Tags::APPLIANCE_APPID %> = "<%= appliance.appid %>"
|
|
17
|
+
<%= Cloudkeeper::One::Opennebula::Tags::APPLIANCE_DIGEST %> = "<%= appliance.digest %>"
|
|
15
18
|
|
|
16
|
-
|
|
19
|
+
<% if image %>
|
|
20
|
+
<%= Cloudkeeper::One::Opennebula::Tags::IMAGE_URI %> = "<%= image.uri %>"
|
|
21
|
+
<%= Cloudkeeper::One::Opennebula::Tags::IMAGE_CHECKSUM %> = "<%= image.checksum %>"
|
|
22
|
+
<%= Cloudkeeper::One::Opennebula::Tags::IMAGE_SIZE %> = "<%= image.size %>"
|
|
23
|
+
<%= Cloudkeeper::One::Opennebula::Tags::IMAGE_FORMAT %> = "<%= image.format %>"
|
|
24
|
+
<%= Cloudkeeper::One::Opennebula::Tags::IMAGE_DIGEST %> = "<%= image.digest %>"
|
|
25
|
+
<% end %>
|
data/lib/cloudkeeper/one/cli.rb
CHANGED
|
@@ -68,25 +68,20 @@ module Cloudkeeper
|
|
|
68
68
|
type: :string,
|
|
69
69
|
desc: 'UNIX-like permissions appliances will have within OpenNebula'
|
|
70
70
|
method_option :'opennebula-secret',
|
|
71
|
-
required:
|
|
71
|
+
required: false,
|
|
72
72
|
default: Cloudkeeper::One::Settings['opennebula']['secret'],
|
|
73
73
|
type: :string,
|
|
74
74
|
desc: 'OpenNebula authentication secret'
|
|
75
75
|
method_option :'opennebula-endpoint',
|
|
76
|
-
required:
|
|
76
|
+
required: false,
|
|
77
77
|
default: Cloudkeeper::One::Settings['opennebula']['endpoint'],
|
|
78
78
|
type: :string,
|
|
79
79
|
desc: 'OpenNebula XML-RPC endpoint'
|
|
80
|
-
method_option :'opennebula-
|
|
80
|
+
method_option :'opennebula-datastore',
|
|
81
81
|
required: true,
|
|
82
|
-
default: Cloudkeeper::One::Settings['opennebula']['
|
|
83
|
-
type: :
|
|
84
|
-
desc: 'OpenNebula
|
|
85
|
-
method_option :'opennebula-users',
|
|
86
|
-
required: false,
|
|
87
|
-
default: Cloudkeeper::One::Settings['opennebula']['users'],
|
|
88
|
-
type: :array,
|
|
89
|
-
desc: 'Handle only images/templates of specified users'
|
|
82
|
+
default: Cloudkeeper::One::Settings['opennebula']['datastore'],
|
|
83
|
+
type: :string,
|
|
84
|
+
desc: 'OpenNebula datastore images will be uploaded to'
|
|
90
85
|
method_option :'opennebula-api-call-timeout',
|
|
91
86
|
required: true,
|
|
92
87
|
default: Cloudkeeper::One::Settings['opennebula']['api-call-timeout'],
|
|
@@ -106,6 +101,7 @@ module Cloudkeeper
|
|
|
106
101
|
grpc_server.run_till_terminated
|
|
107
102
|
rescue SignalException => ex
|
|
108
103
|
raise ex unless SIGNALS.include? ex.signo
|
|
104
|
+
|
|
109
105
|
grpc_server.stop
|
|
110
106
|
rescue Cloudkeeper::One::Errors::InvalidConfigurationError => ex
|
|
111
107
|
abort ex.message
|
|
@@ -1,24 +1,24 @@
|
|
|
1
1
|
module Cloudkeeper
|
|
2
2
|
module One
|
|
3
3
|
class CoreConnector < CloudkeeperGrpc::Communicator::Service
|
|
4
|
-
attr_reader :image_handler, :template_handler, :datastore_handler
|
|
4
|
+
attr_reader :image_handler, :template_handler, :datastore_handler
|
|
5
5
|
|
|
6
6
|
include Cloudkeeper::One::ApplianceActions::Registration
|
|
7
7
|
include Cloudkeeper::One::ApplianceActions::Discard
|
|
8
8
|
include Cloudkeeper::One::ApplianceActions::Update
|
|
9
9
|
include Cloudkeeper::One::ApplianceActions::List
|
|
10
10
|
|
|
11
|
-
|
|
12
|
-
Cloudkeeper::One::Errors::Actions::ListingError => CloudkeeperGrpc::Constants::
|
|
13
|
-
Cloudkeeper::One::Errors::Actions::UpdateError => CloudkeeperGrpc::Constants::
|
|
14
|
-
Cloudkeeper::One::Errors::NetworkConnectionError => CloudkeeperGrpc::Constants::
|
|
15
|
-
Cloudkeeper::One::Errors::Opennebula::AuthenticationError => CloudkeeperGrpc::Constants::
|
|
16
|
-
Cloudkeeper::One::Errors::Opennebula::UserNotAuthorizedError => CloudkeeperGrpc::Constants::
|
|
17
|
-
Cloudkeeper::One::Errors::Opennebula::ResourceNotFoundError => CloudkeeperGrpc::Constants::
|
|
18
|
-
Cloudkeeper::One::Errors::Actions::RegistrationError => CloudkeeperGrpc::Constants::
|
|
19
|
-
Cloudkeeper::One::Errors::Opennebula::ResourceRetrievalError => CloudkeeperGrpc::Constants::
|
|
20
|
-
Cloudkeeper::One::Errors::Opennebula::ResourceStateError => CloudkeeperGrpc::Constants::
|
|
21
|
-
Cloudkeeper::One::Errors::Opennebula::ApiCallTimeoutError => CloudkeeperGrpc::Constants::
|
|
11
|
+
STATUS_CODES = Hash.new(CloudkeeperGrpc::Constants::STATUS_CODE_UNKNOWN).update(
|
|
12
|
+
Cloudkeeper::One::Errors::Actions::ListingError => CloudkeeperGrpc::Constants::STATUS_CODE_APPLIANCE_NOT_FOUND,
|
|
13
|
+
Cloudkeeper::One::Errors::Actions::UpdateError => CloudkeeperGrpc::Constants::STATUS_CODE_APPLIANCE_NOT_FOUND,
|
|
14
|
+
Cloudkeeper::One::Errors::NetworkConnectionError => CloudkeeperGrpc::Constants::STATUS_CODE_FAILED_APPLIANCE_TRANSFER,
|
|
15
|
+
Cloudkeeper::One::Errors::Opennebula::AuthenticationError => CloudkeeperGrpc::Constants::STATUS_CODE_UNAUTHENTICATED,
|
|
16
|
+
Cloudkeeper::One::Errors::Opennebula::UserNotAuthorizedError => CloudkeeperGrpc::Constants::STATUS_CODE_PERMISSION_DENIED,
|
|
17
|
+
Cloudkeeper::One::Errors::Opennebula::ResourceNotFoundError => CloudkeeperGrpc::Constants::STATUS_CODE_RESOURCE_NOT_FOUND,
|
|
18
|
+
Cloudkeeper::One::Errors::Actions::RegistrationError => CloudkeeperGrpc::Constants::STATUS_CODE_RESOURCE_NOT_FOUND,
|
|
19
|
+
Cloudkeeper::One::Errors::Opennebula::ResourceRetrievalError => CloudkeeperGrpc::Constants::STATUS_CODE_FAILED_RESOURCE_RETRIEVAL,
|
|
20
|
+
Cloudkeeper::One::Errors::Opennebula::ResourceStateError => CloudkeeperGrpc::Constants::STATUS_CODE_INVALID_RESOURCE_STATE,
|
|
21
|
+
Cloudkeeper::One::Errors::Opennebula::ApiCallTimeoutError => CloudkeeperGrpc::Constants::STATUS_CODE_INVALID_RESOURCE_STATE
|
|
22
22
|
).freeze
|
|
23
23
|
|
|
24
24
|
def initialize
|
|
@@ -27,78 +27,70 @@ module Cloudkeeper
|
|
|
27
27
|
@image_handler = Cloudkeeper::One::Opennebula::ImageHandler.new
|
|
28
28
|
@template_handler = Cloudkeeper::One::Opennebula::TemplateHandler.new
|
|
29
29
|
@datastore_handler = Cloudkeeper::One::Opennebula::DatastoreHandler.new
|
|
30
|
-
@group_handler = Cloudkeeper::One::Opennebula::GroupHandler.new
|
|
31
30
|
end
|
|
32
31
|
|
|
33
|
-
def pre_action(_empty,
|
|
32
|
+
def pre_action(_empty, _call)
|
|
34
33
|
logger.debug 'Running \'pre-action\'...'
|
|
35
|
-
|
|
34
|
+
Google::Protobuf::Empty.new
|
|
36
35
|
end
|
|
37
36
|
|
|
38
|
-
def post_action(_empty,
|
|
37
|
+
def post_action(_empty, _call)
|
|
39
38
|
logger.debug 'Running \'post-action\'...'
|
|
40
|
-
call.output_metadata['status'] = 'SUCCESS'
|
|
41
39
|
Google::Protobuf::Empty.new
|
|
42
40
|
end
|
|
43
41
|
|
|
44
|
-
def add_appliance(appliance,
|
|
42
|
+
def add_appliance(appliance, _call)
|
|
45
43
|
logger.debug "Registering appliance #{appliance.identifier.inspect}"
|
|
46
|
-
call_backend
|
|
44
|
+
call_backend { register_or_update_appliance appliance }
|
|
47
45
|
end
|
|
48
46
|
|
|
49
|
-
def update_appliance(appliance,
|
|
47
|
+
def update_appliance(appliance, _call)
|
|
50
48
|
logger.debug "Updating appliance #{appliance.identifier.inspect}"
|
|
51
|
-
call_backend
|
|
49
|
+
call_backend { register_or_update_appliance appliance }
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
def update_appliance_metadata(appliance, _call)
|
|
53
|
+
logger.debug "Updating appliance metadata of #{appliance.identifier.inspect}"
|
|
54
|
+
call_backend { update_metadata appliance }
|
|
52
55
|
end
|
|
53
56
|
|
|
54
|
-
def remove_appliance(appliance,
|
|
57
|
+
def remove_appliance(appliance, _call)
|
|
55
58
|
logger.debug "Removing appliance #{appliance.identifier.inspect}"
|
|
56
|
-
call_backend
|
|
59
|
+
call_backend { discard_appliance appliance.identifier }
|
|
57
60
|
end
|
|
58
61
|
|
|
59
|
-
def remove_image_list(image_list_identifier,
|
|
62
|
+
def remove_image_list(image_list_identifier, _call)
|
|
60
63
|
logger.debug "Removing appliances from image list #{image_list_identifier.image_list_identifier.inspect}"
|
|
61
|
-
call_backend
|
|
64
|
+
call_backend { discard_image_list image_list_identifier.image_list_identifier }
|
|
62
65
|
end
|
|
63
66
|
|
|
64
|
-
def image_lists(_empty,
|
|
67
|
+
def image_lists(_empty, _call)
|
|
65
68
|
logger.debug 'Retrieving image lists registered in OpenNebula'
|
|
66
|
-
call_backend(
|
|
69
|
+
call_backend(use_return_value: true) { list_image_lists.each }
|
|
67
70
|
end
|
|
68
71
|
|
|
69
|
-
def appliances(image_list_identifier,
|
|
72
|
+
def appliances(image_list_identifier, _call)
|
|
70
73
|
logger.debug "Retrieving appliances from image list #{image_list_identifier.image_list_identifier.inspect} " \
|
|
71
74
|
'registered in OpenNebula'
|
|
72
|
-
call_backend(
|
|
73
|
-
|
|
74
|
-
|
|
75
|
+
call_backend(use_return_value: true) { list_appliances(image_list_identifier.image_list_identifier).each }
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
def remove_expired_appliances(_empty, _call)
|
|
79
|
+
logger.debug 'Removing expired appliances'
|
|
80
|
+
|
|
81
|
+
call_backend { discard_expired }
|
|
75
82
|
end
|
|
76
83
|
|
|
77
84
|
private
|
|
78
85
|
|
|
79
|
-
def call_backend(
|
|
86
|
+
def call_backend(use_return_value: false)
|
|
80
87
|
raise Cloudkeeper::One::Errors::ArgumentError, 'Error handler was called without a block!' unless block_given?
|
|
81
88
|
|
|
82
|
-
return_value = handle_errors(call) { yield }
|
|
83
|
-
finalize_return_value(return_value, default_return_value, use_return_value)
|
|
84
|
-
end
|
|
85
|
-
|
|
86
|
-
def handle_errors(call)
|
|
87
89
|
return_value = yield
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
return_value
|
|
90
|
+
use_return_value ? return_value : Google::Protobuf::Empty.new
|
|
91
91
|
rescue Cloudkeeper::One::Errors::StandardError => ex
|
|
92
92
|
logger.error "#{ex.class.inspect}: #{ex.message}"
|
|
93
|
-
|
|
94
|
-
call.output_metadata[CloudkeeperGrpc::Constants::KEY_MESSAGE] = ex.message
|
|
95
|
-
|
|
96
|
-
return_value
|
|
97
|
-
end
|
|
98
|
-
|
|
99
|
-
def finalize_return_value(return_value, default_return_value, use_return_value)
|
|
100
|
-
return return_value if return_value && use_return_value
|
|
101
|
-
default_return_value
|
|
93
|
+
raise GRPC::BadStatus.new(STATUS_CODES[ex.class], ex.message)
|
|
102
94
|
end
|
|
103
95
|
end
|
|
104
96
|
end
|
|
@@ -50,24 +50,10 @@ module Cloudkeeper
|
|
|
50
50
|
end
|
|
51
51
|
end
|
|
52
52
|
|
|
53
|
-
def chgrp(element, group)
|
|
54
|
-
raise Cloudkeeper::One::Errors::ArgumentError, 'element cannot be nil' unless element
|
|
55
|
-
|
|
56
|
-
handle_opennebula_error { element.info! }
|
|
57
|
-
return if group.id == element.gid
|
|
58
|
-
|
|
59
|
-
handle_opennebula_error do
|
|
60
|
-
element.chown(LEAVE_ID_AS_IS, group.id)
|
|
61
|
-
element.info!
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
53
|
private
|
|
66
54
|
|
|
67
55
|
def find_all_by(attributes)
|
|
68
56
|
xpaths = attributes.clone
|
|
69
|
-
xpaths['UNAME'] = Cloudkeeper::One::Settings[:'opennebula-users'] \
|
|
70
|
-
if Cloudkeeper::One::Settings[:'opennebula-users'] && !Cloudkeeper::One::Settings[:'opennebula-users'].empty?
|
|
71
57
|
|
|
72
58
|
find_all xpaths
|
|
73
59
|
end
|
|
@@ -18,8 +18,6 @@ module Cloudkeeper
|
|
|
18
18
|
|
|
19
19
|
def expired
|
|
20
20
|
xpaths = { "TEMPLATE/#{Tags::EXPIRED}" => 'yes' }
|
|
21
|
-
xpaths['UNAME'] = Cloudkeeper::One::Settings[:'opennebula-users'] \
|
|
22
|
-
if Cloudkeeper::One::Settings[:'opennebula-users'] && !Cloudkeeper::One::Settings[:'opennebula-users'].empty?
|
|
23
21
|
|
|
24
22
|
find_all xpaths
|
|
25
23
|
end
|
|
@@ -76,7 +74,7 @@ module Cloudkeeper
|
|
|
76
74
|
handle_opennebula_error { image.update(expiration_attribute, true) }
|
|
77
75
|
end
|
|
78
76
|
|
|
79
|
-
def register(image_template, datastore
|
|
77
|
+
def register(image_template, datastore)
|
|
80
78
|
image_alloc = OpenNebula::Image.build_xml
|
|
81
79
|
image = OpenNebula::Image.new(image_alloc, client)
|
|
82
80
|
|
|
@@ -93,7 +91,6 @@ module Cloudkeeper
|
|
|
93
91
|
end
|
|
94
92
|
|
|
95
93
|
chmod image, Cloudkeeper::One::Settings[:'appliances-permissions']
|
|
96
|
-
chgrp image, group
|
|
97
94
|
|
|
98
95
|
image
|
|
99
96
|
end
|
|
@@ -22,12 +22,15 @@ module Cloudkeeper
|
|
|
22
22
|
APPLIANCE_VO = "#{APPLIANCE}_VO".freeze
|
|
23
23
|
APPLIANCE_EXPIRATION_DATE = "#{APPLIANCE}_EXPIRATION_DATE".freeze
|
|
24
24
|
APPLIANCE_IMAGE_LIST_ID = "#{APPLIANCE}_IMAGE_LIST_ID".freeze
|
|
25
|
-
|
|
25
|
+
APPLIANCE_BASE_MPURI = "#{APPLIANCE}_BASE_MPURI".freeze
|
|
26
|
+
APPLIANCE_APPID = "#{APPLIANCE}_APPID".freeze
|
|
27
|
+
APPLIANCE_DIGEST = "#{APPLIANCE}_DIGEST".freeze
|
|
26
28
|
|
|
27
29
|
IMAGE_URI = "#{IMAGE}_URI".freeze
|
|
28
30
|
IMAGE_CHECKSUM = "#{IMAGE}_CHECKSUM".freeze
|
|
29
31
|
IMAGE_SIZE = "#{IMAGE}_SIZE".freeze
|
|
30
32
|
IMAGE_FORMAT = "#{IMAGE}_FORMAT".freeze
|
|
33
|
+
IMAGE_DIGEST = "#{IMAGE}_DIGEST".freeze
|
|
31
34
|
end
|
|
32
35
|
end
|
|
33
36
|
end
|
|
@@ -7,14 +7,13 @@ module Cloudkeeper
|
|
|
7
7
|
@pool = OpenNebula::TemplatePool.new client
|
|
8
8
|
end
|
|
9
9
|
|
|
10
|
-
def register(template_template
|
|
10
|
+
def register(template_template)
|
|
11
11
|
template_alloc = OpenNebula::Template.build_xml
|
|
12
12
|
template = OpenNebula::Template.new(template_alloc, client)
|
|
13
13
|
|
|
14
14
|
handle_opennebula_error { template.allocate template_template }
|
|
15
15
|
|
|
16
16
|
chmod template, Cloudkeeper::One::Settings[:'appliances-permissions']
|
|
17
|
-
chgrp template, group
|
|
18
17
|
|
|
19
18
|
template
|
|
20
19
|
end
|
data/lib/cloudkeeper_grpc.rb
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[submodule "protos"]
|
|
2
2
|
path = protos
|
|
3
3
|
url = https://github.com/the-cloudkeeper-project/cloudkeeper-proto.git
|
|
4
|
-
[submodule "
|
|
5
|
-
path =
|
|
6
|
-
url = https://github.com/the-cloudkeeper-project/cloudkeeper-
|
|
4
|
+
[submodule "status-codes"]
|
|
5
|
+
path = status-codes
|
|
6
|
+
url = https://github.com/the-cloudkeeper-project/cloudkeeper-status-codes.git
|
|
@@ -1,3 +1,9 @@
|
|
|
1
1
|
## cloudkeeper gRPC generated classes for Ruby
|
|
2
2
|
|
|
3
3
|
This repository contains Ruby classes generated for gRPC communication within the [cloudkeeper](https://github.com/the-cloudkeeper-project/cloudkeeper) project.
|
|
4
|
+
|
|
5
|
+
### Important!
|
|
6
|
+
Code expects `String` class to contain method `underscore` which can be find within [Active Support](https://guides.rubyonrails.org/active_support_core_extensions.html) gem. At least extensions for `String` class must be required:
|
|
7
|
+
```ruby
|
|
8
|
+
require 'active_support/core_ext/string'
|
|
9
|
+
```
|
|
@@ -19,8 +19,10 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
|
19
19
|
optional :vo, :string, 11
|
|
20
20
|
optional :expiration_date, :int64, 12
|
|
21
21
|
optional :image_list_identifier, :string, 13
|
|
22
|
-
optional :
|
|
23
|
-
|
|
22
|
+
optional :base_mpuri, :string, 14
|
|
23
|
+
optional :appid, :string, 15
|
|
24
|
+
optional :digest, :string, 16
|
|
25
|
+
optional :image, :message, 17, "cloudkeeper_grpc.Image"
|
|
24
26
|
end
|
|
25
27
|
add_message "cloudkeeper_grpc.Image" do
|
|
26
28
|
optional :mode, :enum, 1, "cloudkeeper_grpc.Image.Mode"
|
|
@@ -31,6 +33,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
|
|
|
31
33
|
optional :size, :int64, 6
|
|
32
34
|
optional :username, :string, 7
|
|
33
35
|
optional :password, :string, 8
|
|
36
|
+
optional :digest, :string, 9
|
|
34
37
|
end
|
|
35
38
|
add_enum "cloudkeeper_grpc.Image.Mode" do
|
|
36
39
|
value :LOCAL, 0
|
|
@@ -18,10 +18,12 @@ module CloudkeeperGrpc
|
|
|
18
18
|
rpc :PostAction, Google::Protobuf::Empty, Google::Protobuf::Empty
|
|
19
19
|
rpc :AddAppliance, Appliance, Google::Protobuf::Empty
|
|
20
20
|
rpc :UpdateAppliance, Appliance, Google::Protobuf::Empty
|
|
21
|
+
rpc :UpdateApplianceMetadata, Appliance, Google::Protobuf::Empty
|
|
21
22
|
rpc :RemoveAppliance, Appliance, Google::Protobuf::Empty
|
|
22
23
|
rpc :RemoveImageList, ImageListIdentifier, Google::Protobuf::Empty
|
|
23
24
|
rpc :ImageLists, Google::Protobuf::Empty, stream(ImageListIdentifier)
|
|
24
25
|
rpc :Appliances, ImageListIdentifier, stream(Appliance)
|
|
26
|
+
rpc :RemoveExpiredAppliances, Google::Protobuf::Empty, Google::Protobuf::Empty
|
|
25
27
|
end
|
|
26
28
|
|
|
27
29
|
Stub = Service.rpc_stub_class
|
|
@@ -2,11 +2,9 @@ require 'yaml'
|
|
|
2
2
|
|
|
3
3
|
module CloudkeeperGrpc
|
|
4
4
|
class Constants
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const_set("KEY_#{upcase_key}", key)
|
|
9
|
-
metadata[key].each { |value| const_set("#{upcase_key}_#{value.upcase}", value)} if metadata.has_key? key
|
|
5
|
+
status_codes = YAML.load_file(File.join(File.dirname(__FILE__), 'status-codes', 'status-codes.yml'))
|
|
6
|
+
status_codes.each do |key, value|
|
|
7
|
+
const_set("STATUS_CODE_#{key.underscore.upcase}", value)
|
|
10
8
|
end
|
|
11
9
|
end
|
|
12
10
|
end
|
|
@@ -18,8 +18,10 @@ message Appliance {
|
|
|
18
18
|
string vo = 11;
|
|
19
19
|
int64 expiration_date = 12;
|
|
20
20
|
string image_list_identifier = 13;
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
string base_mpuri = 14;
|
|
22
|
+
string appid = 15;
|
|
23
|
+
string digest = 16;
|
|
24
|
+
Image image = 17;
|
|
23
25
|
}
|
|
24
26
|
|
|
25
27
|
message Image {
|
|
@@ -41,6 +43,7 @@ message Image {
|
|
|
41
43
|
int64 size = 6;
|
|
42
44
|
string username = 7;
|
|
43
45
|
string password = 8;
|
|
46
|
+
string digest = 9;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
message ImageListIdentifier {
|
|
@@ -52,8 +55,10 @@ service Communicator {
|
|
|
52
55
|
rpc PostAction(google.protobuf.Empty) returns (google.protobuf.Empty) {}
|
|
53
56
|
rpc AddAppliance(Appliance) returns (google.protobuf.Empty) {}
|
|
54
57
|
rpc UpdateAppliance(Appliance) returns (google.protobuf.Empty) {}
|
|
58
|
+
rpc UpdateApplianceMetadata(Appliance) returns (google.protobuf.Empty) {}
|
|
55
59
|
rpc RemoveAppliance(Appliance) returns (google.protobuf.Empty) {}
|
|
56
60
|
rpc RemoveImageList(ImageListIdentifier) returns (google.protobuf.Empty) {}
|
|
57
61
|
rpc ImageLists(google.protobuf.Empty) returns (stream ImageListIdentifier) {}
|
|
58
62
|
rpc Appliances(ImageListIdentifier) returns (stream Appliance) {}
|
|
63
|
+
rpc RemoveExpiredAppliances(google.protobuf.Empty) returns (google.protobuf.Empty) {}
|
|
59
64
|
}
|
|
File without changes
|
|
@@ -1,14 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
funded by the EGI-Engage project co-funded by the European Union (EU)
|
|
3
|
-
Horizon 2020 program under Grant number 654142.
|
|
4
|
-
|
|
5
|
-
Copyright (c) 2017 CESNET
|
|
1
|
+
Copyright 2018 Michal Kimle
|
|
6
2
|
|
|
7
3
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
8
4
|
you may not use this file except in compliance with the License.
|
|
9
5
|
You may obtain a copy of the License at
|
|
10
6
|
|
|
11
|
-
http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
|
12
8
|
|
|
13
9
|
Unless required by applicable law or agreed to in writing, software
|
|
14
10
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
---
|
|
2
|
+
# Compatible with GRPC status codes
|
|
3
|
+
Ok: 0
|
|
4
|
+
Unknown: 2
|
|
5
|
+
PermissionDenied: 7
|
|
6
|
+
Unauthenticated: 16
|
|
7
|
+
# Custom status codes
|
|
8
|
+
ApplianceNotFound: 101
|
|
9
|
+
FailedApplianceTransfer: 102
|
|
10
|
+
ResourceNotFound: 103
|
|
11
|
+
FailedResourceRetrieval: 104
|
|
12
|
+
InvalidResourceState: 105
|
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: cloudkeeper-one
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version:
|
|
4
|
+
version: 2.0.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Michal Kimle
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2018-
|
|
11
|
+
date: 2018-11-29 00:00:00.000000000 Z
|
|
12
12
|
dependencies:
|
|
13
13
|
- !ruby/object:Gem::Dependency
|
|
14
14
|
name: bundler
|
|
@@ -28,22 +28,16 @@ dependencies:
|
|
|
28
28
|
name: grpc-tools
|
|
29
29
|
requirement: !ruby/object:Gem::Requirement
|
|
30
30
|
requirements:
|
|
31
|
-
- - "
|
|
32
|
-
- !ruby/object:Gem::Version
|
|
33
|
-
version: '1.1'
|
|
34
|
-
- - "<="
|
|
31
|
+
- - "~>"
|
|
35
32
|
- !ruby/object:Gem::Version
|
|
36
|
-
version: 1.
|
|
33
|
+
version: '1.14'
|
|
37
34
|
type: :development
|
|
38
35
|
prerelease: false
|
|
39
36
|
version_requirements: !ruby/object:Gem::Requirement
|
|
40
37
|
requirements:
|
|
41
|
-
- - "
|
|
42
|
-
- !ruby/object:Gem::Version
|
|
43
|
-
version: '1.1'
|
|
44
|
-
- - "<="
|
|
38
|
+
- - "~>"
|
|
45
39
|
- !ruby/object:Gem::Version
|
|
46
|
-
version: 1.
|
|
40
|
+
version: '1.14'
|
|
47
41
|
- !ruby/object:Gem::Dependency
|
|
48
42
|
name: pry
|
|
49
43
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -78,14 +72,14 @@ dependencies:
|
|
|
78
72
|
requirements:
|
|
79
73
|
- - "~>"
|
|
80
74
|
- !ruby/object:Gem::Version
|
|
81
|
-
version: '
|
|
75
|
+
version: '12.3'
|
|
82
76
|
type: :development
|
|
83
77
|
prerelease: false
|
|
84
78
|
version_requirements: !ruby/object:Gem::Requirement
|
|
85
79
|
requirements:
|
|
86
80
|
- - "~>"
|
|
87
81
|
- !ruby/object:Gem::Version
|
|
88
|
-
version: '
|
|
82
|
+
version: '12.3'
|
|
89
83
|
- !ruby/object:Gem::Dependency
|
|
90
84
|
name: rspec
|
|
91
85
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -162,14 +156,14 @@ dependencies:
|
|
|
162
156
|
requirements:
|
|
163
157
|
- - "~>"
|
|
164
158
|
- !ruby/object:Gem::Version
|
|
165
|
-
version: '
|
|
159
|
+
version: '4.0'
|
|
166
160
|
type: :development
|
|
167
161
|
prerelease: false
|
|
168
162
|
version_requirements: !ruby/object:Gem::Requirement
|
|
169
163
|
requirements:
|
|
170
164
|
- - "~>"
|
|
171
165
|
- !ruby/object:Gem::Version
|
|
172
|
-
version: '
|
|
166
|
+
version: '4.0'
|
|
173
167
|
- !ruby/object:Gem::Dependency
|
|
174
168
|
name: webmock
|
|
175
169
|
requirement: !ruby/object:Gem::Requirement
|
|
@@ -323,7 +317,7 @@ files:
|
|
|
323
317
|
- README.md
|
|
324
318
|
- Rakefile
|
|
325
319
|
- bin/cloudkeeper-one
|
|
326
|
-
-
|
|
320
|
+
- cloudkeeper_one.gemspec
|
|
327
321
|
- config/cloudkeeper-one.yml
|
|
328
322
|
- config/templates/image.erb
|
|
329
323
|
- config/templates/template.erb
|
|
@@ -364,7 +358,6 @@ files:
|
|
|
364
358
|
- lib/cloudkeeper/one/opennebula.rb
|
|
365
359
|
- lib/cloudkeeper/one/opennebula/appliance_handler.rb
|
|
366
360
|
- lib/cloudkeeper/one/opennebula/datastore_handler.rb
|
|
367
|
-
- lib/cloudkeeper/one/opennebula/group_handler.rb
|
|
368
361
|
- lib/cloudkeeper/one/opennebula/handler.rb
|
|
369
362
|
- lib/cloudkeeper/one/opennebula/helper.rb
|
|
370
363
|
- lib/cloudkeeper/one/opennebula/image_handler.rb
|
|
@@ -380,14 +373,14 @@ files:
|
|
|
380
373
|
- lib/cloudkeeper_grpc/cloudkeeper_pb.rb
|
|
381
374
|
- lib/cloudkeeper_grpc/cloudkeeper_services_pb.rb
|
|
382
375
|
- lib/cloudkeeper_grpc/constants.rb
|
|
383
|
-
- lib/cloudkeeper_grpc/metadata/CODE_OF_CONDUCT.md
|
|
384
|
-
- lib/cloudkeeper_grpc/metadata/LICENSE.txt
|
|
385
|
-
- lib/cloudkeeper_grpc/metadata/README.md
|
|
386
|
-
- lib/cloudkeeper_grpc/metadata/metadata.yml
|
|
387
376
|
- lib/cloudkeeper_grpc/protos/CODE_OF_CONDUCT.md
|
|
388
377
|
- lib/cloudkeeper_grpc/protos/LICENSE.txt
|
|
389
378
|
- lib/cloudkeeper_grpc/protos/README.md
|
|
390
379
|
- lib/cloudkeeper_grpc/protos/cloudkeeper.proto
|
|
380
|
+
- lib/cloudkeeper_grpc/status-codes/CODE_OF_CONDUCT.md
|
|
381
|
+
- lib/cloudkeeper_grpc/status-codes/LICENSE.txt
|
|
382
|
+
- lib/cloudkeeper_grpc/status-codes/README.md
|
|
383
|
+
- lib/cloudkeeper_grpc/status-codes/status-codes.yml
|
|
391
384
|
homepage: https://github.com/the-cloudkeeper-project/cloudkeeper-one
|
|
392
385
|
licenses:
|
|
393
386
|
- Apache License, Version 2.0
|
|
@@ -408,7 +401,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
408
401
|
version: '0'
|
|
409
402
|
requirements: []
|
|
410
403
|
rubyforge_project:
|
|
411
|
-
rubygems_version: 2.
|
|
404
|
+
rubygems_version: 2.7.4
|
|
412
405
|
signing_key:
|
|
413
406
|
specification_version: 4
|
|
414
407
|
summary: OpenNebula backend for cloudkeeper
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
keys:
|
|
2
|
-
- status
|
|
3
|
-
- message
|
|
4
|
-
status:
|
|
5
|
-
- SUCCESS
|
|
6
|
-
- ERROR
|
|
7
|
-
- ERROR_APPLIANCE_NOT_FOUND
|
|
8
|
-
- ERROR_APPLIANCE_TRANSFER
|
|
9
|
-
- ERROR_AUTHENTICATION
|
|
10
|
-
- ERROR_USER_NOT_AUTHORIZED
|
|
11
|
-
- ERROR_RESOURCE_NOT_FOUND
|
|
12
|
-
- ERROR_RESOURCE_RETRIEVAL
|
|
13
|
-
- ERROR_RESOURCE_STATE
|