foreman_docker 1.2.4 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -4
- data/app/controllers/api/v2/containers_controller.rb +11 -3
- data/app/controllers/api/v2/registries_controller.rb +65 -0
- data/app/controllers/containers/steps_controller.rb +5 -1
- data/app/models/container.rb +23 -2
- data/app/models/docker_container_wizard_state.rb +2 -0
- data/app/models/docker_container_wizard_states/dns.rb +18 -0
- data/app/models/docker_container_wizard_states/environment.rb +11 -0
- data/app/models/docker_container_wizard_states/exposed_port.rb +18 -0
- data/app/models/docker_registry.rb +4 -0
- data/app/models/exposed_port.rb +19 -0
- data/app/models/foreman_docker/dns.rb +20 -0
- data/app/models/service/containers.rb +40 -8
- data/app/views/api/v2/registries/base.json.rabl +3 -0
- data/app/views/api/v2/registries/index.json.rabl +3 -0
- data/app/views/api/v2/registries/main.json.rabl +6 -0
- data/app/views/api/v2/registries/show.json.rabl +7 -0
- data/app/views/containers/show.html.erb +19 -1
- data/app/views/containers/steps/environment.html.erb +13 -0
- data/app/views/containers/steps/image.html.erb +1 -1
- data/app/views/foreman_docker/common_parameters/_dns.erb +16 -0
- data/app/views/foreman_docker/common_parameters/_exposed_ports.erb +17 -0
- data/config/routes.rb +1 -0
- data/lib/foreman_docker/engine.rb +31 -16
- data/lib/foreman_docker/version.rb +1 -1
- data/test/functionals/api/v2/containers_controller_test.rb +9 -0
- data/test/functionals/api/v2/registries_controller_test.rb +56 -0
- data/test/functionals/containers_steps_controller_test.rb +47 -0
- data/test/units/docker_registry_test.rb +3 -1
- metadata +15 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: fd4bd81fe224e418f11ab1338a1f65101dc8c9b5
|
4
|
+
data.tar.gz: dd31c502a1885ecdd88621d33cb58bc7e12d2496
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 509eae97cbccfe1572e5460f19c87514a868cb67afba233d4a32fdb9c419c5d0c2e10cea9ace9b5e3e9eed79a344264932e9630331dd01b23d058bb9b412bed3
|
7
|
+
data.tar.gz: 9056eddf57601b9055f9a060c91ece977e8cbefd9ee1362e205d6f843fd407a7515232e96febee0a211d28dab17c8b0f7aebfe2ec95e1ae369fdcbf9b91d83e1
|
data/README.md
CHANGED
@@ -88,10 +88,7 @@ That's it. You're now ready to create and manage containers in your new Docker c
|
|
88
88
|
| >= 1.6 | 0.1.0 - 0.2.0 |
|
89
89
|
| >= 1.7 | 1.0.0+ |
|
90
90
|
|
91
|
-
|
92
|
-
* MAJOR versions: will break compatibility with the latest supported Foreman version. For instance, foreman-docker 1.0 breaks Foreman 1.6 compatibility.
|
93
|
-
* MINOR versions: will enhance foreman-docker with features in a backwards-compatible manner.
|
94
|
-
* PATCH versions: will contain bugfixes for the latest minor version in a backwards-compatible manner.
|
91
|
+
See extras/RELEASE.md for more detailed information on compatibility and releases.
|
95
92
|
|
96
93
|
## How to contribute?
|
97
94
|
|
@@ -69,9 +69,17 @@ module Api
|
|
69
69
|
param_group :container, :as => :create
|
70
70
|
|
71
71
|
def create
|
72
|
-
|
73
|
-
|
74
|
-
|
72
|
+
service = Service::Containers.new
|
73
|
+
@container = service.start_container!(set_wizard_state)
|
74
|
+
if service.errors.any?
|
75
|
+
render :json => { :errors => service.errors,
|
76
|
+
:full_messages => service.full_messages
|
77
|
+
},
|
78
|
+
:status => :unprocessable_entity
|
79
|
+
else
|
80
|
+
set_container_taxonomies
|
81
|
+
process_response @container.save
|
82
|
+
end
|
75
83
|
rescue ActiveModel::MassAssignmentSecurity::Error => e
|
76
84
|
render :json => { :error => _("Wrong attributes: %s") % e.message },
|
77
85
|
:status => :unprocessable_entity
|
@@ -0,0 +1,65 @@
|
|
1
|
+
module Api
|
2
|
+
module V2
|
3
|
+
class RegistriesController < ::Api::V2::BaseController
|
4
|
+
before_filter :find_resource, :except => %w(index create)
|
5
|
+
|
6
|
+
resource_description do
|
7
|
+
resource_id 'registries'
|
8
|
+
api_version 'v2'
|
9
|
+
api_base_url '/docker/api/v2'
|
10
|
+
end
|
11
|
+
|
12
|
+
def_param_group :registry do
|
13
|
+
param :registry, Hash, :required => true, :action_aware => true do
|
14
|
+
param :name, String, :required => true
|
15
|
+
param :url, String, :required => true
|
16
|
+
param :description, String
|
17
|
+
param :username, String
|
18
|
+
param :password, String
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
api :GET, '/registries/', N_('List all docker registries')
|
23
|
+
param_group :search_and_pagination, ::Api::V2::BaseController
|
24
|
+
def index
|
25
|
+
@registries = DockerRegistry.search_for(params[:search], :order => params[:order])
|
26
|
+
.paginate(:page => params[:page])
|
27
|
+
end
|
28
|
+
|
29
|
+
api :GET, '/registries/:id', N_("Show a docker registry")
|
30
|
+
param :id, :identifier, :required => true
|
31
|
+
def show
|
32
|
+
end
|
33
|
+
|
34
|
+
api :POST, '/registries/', N_('Create a docker registry')
|
35
|
+
param_group :registry, :as => :create
|
36
|
+
def create
|
37
|
+
@registry = DockerRegistry.new(params[:registry])
|
38
|
+
process_response @registry.save
|
39
|
+
end
|
40
|
+
|
41
|
+
api :PUT, '/registries/:id', N_('Update a docker registry')
|
42
|
+
param :id, :identifier, :required => true
|
43
|
+
param_group :registry, :as => :update
|
44
|
+
def update
|
45
|
+
process_response @registry.update_attributes(params[:registry])
|
46
|
+
end
|
47
|
+
|
48
|
+
api :DELETE, '/registries/:id/', N_('Delete a docker registry')
|
49
|
+
param :id, :identifier, :required => true
|
50
|
+
def destroy
|
51
|
+
process_response @registry.destroy
|
52
|
+
end
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def resource_class
|
57
|
+
DockerRegistry
|
58
|
+
end
|
59
|
+
|
60
|
+
def docker_registry_url(registry)
|
61
|
+
registry_url(registry)
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
data/app/models/container.rb
CHANGED
@@ -11,12 +11,25 @@ class Container < ActiveRecord::Base
|
|
11
11
|
accepts_nested_attributes_for :environment_variables, :allow_destroy => true
|
12
12
|
include ForemanDocker::ParameterValidators
|
13
13
|
|
14
|
+
has_many :exposed_ports, :dependent => :destroy, :foreign_key => :reference_id,
|
15
|
+
:inverse_of => :container,
|
16
|
+
:class_name => 'ExposedPort',
|
17
|
+
:validate => true
|
18
|
+
|
19
|
+
has_many :dns, :dependent => :destroy, :foreign_key => :reference_id,
|
20
|
+
:inverse_of => :container,
|
21
|
+
:class_name => 'ForemanDocker::Dns',
|
22
|
+
:validate => true
|
23
|
+
|
24
|
+
accepts_nested_attributes_for :exposed_ports, :allow_destroy => true
|
14
25
|
scoped_search :on => :name
|
15
26
|
|
16
27
|
attr_accessible :command, :repository_name, :name, :compute_resource_id, :entrypoint,
|
17
28
|
:cpu_set, :cpu_shares, :memory, :tty, :attach_stdin, :registry_id,
|
18
29
|
:attach_stdout, :attach_stderr, :tag, :uuid, :environment_variables_attributes,
|
19
|
-
:katello
|
30
|
+
:katello, :exposed_ports_attributes, :dns
|
31
|
+
|
32
|
+
validates :name, :uniqueness => { :scope => :compute_resource_id }
|
20
33
|
|
21
34
|
def repository_pull_url
|
22
35
|
repo = tag.blank? ? repository_name : "#{repository_name}:#{tag}"
|
@@ -32,10 +45,18 @@ class Container < ActiveRecord::Base
|
|
32
45
|
'AttachStdout' => attach_stdout, 'AttachStdin' => attach_stdin,
|
33
46
|
'AttachStderr' => attach_stderr, 'CpuShares' => cpu_shares,
|
34
47
|
'Cpuset' => cpu_set,
|
35
|
-
'Env' => environment_variables.map { |env| "#{env.name}=#{env.value}" }
|
48
|
+
'Env' => environment_variables.map { |env| "#{env.name}=#{env.value}" },
|
49
|
+
'ExposedPorts' => Hash[*exposed_ports.map { |v| [v.name + "/" + v.value, {}] }.flatten],
|
50
|
+
'HostConfig' => {
|
51
|
+
'Dns' => dns.map { |env| "#{env.name}" }
|
52
|
+
} }
|
36
53
|
end
|
37
54
|
|
38
55
|
def in_fog
|
39
56
|
@fog_container ||= compute_resource.vms.get(uuid)
|
40
57
|
end
|
58
|
+
|
59
|
+
def self.humanize_class_name(_name = nil)
|
60
|
+
_("Docker/Container")
|
61
|
+
end
|
41
62
|
end
|
@@ -10,6 +10,8 @@ class DockerContainerWizardState < ActiveRecord::Base
|
|
10
10
|
|
11
11
|
delegate :compute_resource_id, :to => :preliminary
|
12
12
|
delegate :environment_variables, :to => :environment
|
13
|
+
delegate :exposed_ports, :to => :environment
|
14
|
+
delegate :dns, :to => :environment
|
13
15
|
|
14
16
|
def container_attributes
|
15
17
|
{ :repository_name => image.repository_name,
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DockerContainerWizardStates
|
2
|
+
class Dns < Parameter
|
3
|
+
# The Parameter class from which this Dns class inherits,validates for the
|
4
|
+
# presence of an associated domain, operating system, host or host group.
|
5
|
+
# We will have to reset those validations for the Dns class as they do not
|
6
|
+
# make any sense for the context in which this class is being used here.
|
7
|
+
Dns.reset_callbacks(:validate)
|
8
|
+
|
9
|
+
belongs_to :environment, :foreign_key => :reference_id,
|
10
|
+
:inverse_of => :dns,
|
11
|
+
:class_name => 'DockerContainerWizardStates::Environment'
|
12
|
+
validates :name, :uniqueness => { :scope => :reference_id },
|
13
|
+
:format => {
|
14
|
+
:with => Regexp.union(Resolv::IPv4::Regex,
|
15
|
+
Resolv::IPv6::Regex,
|
16
|
+
/^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}$/) }
|
17
|
+
end
|
18
|
+
end
|
@@ -13,7 +13,18 @@ module DockerContainerWizardStates
|
|
13
13
|
:validate => false
|
14
14
|
include ::ParameterValidators
|
15
15
|
|
16
|
+
has_many :exposed_ports, :dependent => :destroy, :foreign_key => :reference_id,
|
17
|
+
:inverse_of => :environment,
|
18
|
+
:class_name => 'DockerContainerWizardStates::ExposedPort',
|
19
|
+
:validate => true
|
20
|
+
has_many :dns, :dependent => :destroy, :foreign_key => :reference_id,
|
21
|
+
:inverse_of => :environment,
|
22
|
+
:class_name => 'DockerContainerWizardStates::Dns',
|
23
|
+
:validate => true
|
24
|
+
|
16
25
|
accepts_nested_attributes_for :environment_variables, :allow_destroy => true
|
26
|
+
accepts_nested_attributes_for :exposed_ports, :allow_destroy => true
|
27
|
+
accepts_nested_attributes_for :dns, :allow_destroy => true
|
17
28
|
|
18
29
|
def parameters_symbol
|
19
30
|
:environment_variables
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module DockerContainerWizardStates
|
2
|
+
class ExposedPort < Parameter
|
3
|
+
# The Parameter class from which ExposedPort class inherits,validates for the
|
4
|
+
# presence of an associated domain, operating system, host or host group. We
|
5
|
+
# will have to reset those validations for the ExposedPort class as they do
|
6
|
+
# not make any sense for the context in which this class is being used here.
|
7
|
+
ExposedPort.reset_callbacks(:validate)
|
8
|
+
|
9
|
+
belongs_to :environment, :foreign_key => :reference_id, :inverse_of => :exposed_ports,
|
10
|
+
:class_name => 'DockerContainerWizardStates::Environment'
|
11
|
+
validates :name, :uniqueness => { :scope => :reference_id },
|
12
|
+
:numericality => { :only_integer => true,
|
13
|
+
:greater_than => 0,
|
14
|
+
:less_than_or_equal_to => 655_35 }
|
15
|
+
validates :value, :presence => true,
|
16
|
+
:inclusion => { :in => %w(tcp udp) }
|
17
|
+
end
|
18
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class ExposedPort < Parameter
|
2
|
+
# The Parameter class from which ExposedPort class inherits,validates for the
|
3
|
+
# presence of an associated domain, operating system, host or host group. We
|
4
|
+
# will have to reset those validations for the ExposedPort class as they do
|
5
|
+
# not make any sense for the context in which this class is being used here.
|
6
|
+
ExposedPort.reset_callbacks(:validate)
|
7
|
+
|
8
|
+
belongs_to :container, :foreign_key => :reference_id, :inverse_of => :exposed_ports
|
9
|
+
audited :except => [:priority], :associated_with => :container, :allow_mass_assignment => true
|
10
|
+
validates :name, :uniqueness => { :scope => :reference_id }
|
11
|
+
validates :name, :numericality => { :only_integer => true,
|
12
|
+
:greater_than => 0,
|
13
|
+
:less_than_or_equal_to => 655_35,
|
14
|
+
:message => "%{value} is not a valid port number" }
|
15
|
+
|
16
|
+
validates :value, :presence => true,
|
17
|
+
:inclusion => { :in => %w(tcp udp),
|
18
|
+
:message => "%{value} is not a valid protocol" }
|
19
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module ForemanDocker
|
2
|
+
class Dns < Parameter
|
3
|
+
# The Parameter class from which this Dns class inherits,validates for the
|
4
|
+
# presence of an associated domain, operating system, host or host group.
|
5
|
+
# We will have to reset those validations for the Dns class as they do not
|
6
|
+
# make any sense for the context in which this class is being used here.
|
7
|
+
ForemanDocker::Dns.reset_callbacks(:validate)
|
8
|
+
|
9
|
+
belongs_to :container, :foreign_key => :reference_id,
|
10
|
+
:inverse_of => :dns,
|
11
|
+
:class_name => "Container"
|
12
|
+
|
13
|
+
audited :except => [:priority], :associated_with => :container, :allow_mass_assignment => true
|
14
|
+
validates :name, :uniqueness => { :scope => :reference_id },
|
15
|
+
:format => {
|
16
|
+
:with => Regexp.union(Resolv::IPv4::Regex,
|
17
|
+
Resolv::IPv6::Regex,
|
18
|
+
/^[a-z0-9]+([\-\.]{1}[a-z0-9]+)*\.[a-z]{2,5}$/) }
|
19
|
+
end
|
20
|
+
end
|
@@ -7,19 +7,24 @@ module Service
|
|
7
7
|
def start_container!(wizard_state)
|
8
8
|
ActiveRecord::Base.transaction do
|
9
9
|
container = Container.new(wizard_state.container_attributes) do |r|
|
10
|
-
# eagerly load environment variables
|
11
|
-
state = DockerContainerWizardState.includes(
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
10
|
+
# eagerly load environment variables and exposed ports configuration
|
11
|
+
state = DockerContainerWizardState.includes(
|
12
|
+
:environment => [:environment_variables, :exposed_ports]).find(wizard_state.id)
|
13
|
+
|
14
|
+
load_environment_variables(state, r)
|
15
|
+
load_exposed_ports(state, r)
|
16
|
+
load_dns(state, r)
|
18
17
|
end
|
18
|
+
|
19
19
|
Taxonomy.enabled_taxonomies.each do |taxonomy|
|
20
20
|
container.send(:"#{taxonomy}=", wizard_state.preliminary.send(:"#{taxonomy}"))
|
21
21
|
end
|
22
22
|
|
23
|
+
unless container.valid?
|
24
|
+
@errors = container.errors
|
25
|
+
fail ActiveRecord::Rollback
|
26
|
+
end
|
27
|
+
|
23
28
|
fail ActiveRecord::Rollback unless pull_image(container) && start_container(container)
|
24
29
|
|
25
30
|
container.save!
|
@@ -46,5 +51,32 @@ module Service
|
|
46
51
|
wizard_state.destroy
|
47
52
|
DockerContainerWizardState.destroy_all(["updated_at < ?", (Time.now - 24.hours)])
|
48
53
|
end
|
54
|
+
|
55
|
+
def load_environment_variables(state, r)
|
56
|
+
state.environment_variables.each do |environment_variable|
|
57
|
+
r.environment_variables.build :name => environment_variable.name,
|
58
|
+
:value => environment_variable.value,
|
59
|
+
:priority => environment_variable.priority
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def load_exposed_ports(state, r)
|
64
|
+
state.exposed_ports.each do |e|
|
65
|
+
r.exposed_ports.build :name => e.name,
|
66
|
+
:value => e.value,
|
67
|
+
:priority => e.priority
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
def load_dns(state, r)
|
72
|
+
state.dns.each do |e|
|
73
|
+
r.dns.build :name => e.name,
|
74
|
+
:priority => e.priority
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def full_messages
|
79
|
+
@errors.respond_to?(:full_messages) ? @errors.full_messages : @errors
|
80
|
+
end
|
49
81
|
end
|
50
82
|
end
|
@@ -41,8 +41,26 @@
|
|
41
41
|
</tr>
|
42
42
|
<tr>
|
43
43
|
<td><%= _('Exposed ports') %></td>
|
44
|
-
<td
|
44
|
+
<td>
|
45
|
+
<table id="exposed_ports" class="table table-bordered" style="table-layout:fixed; word-wrap: break-word">
|
46
|
+
<% (@container.in_fog.exposed_ports || []).each do |exposed_port| %>
|
47
|
+
<% pair = exposed_port.first.split("/") %>
|
48
|
+
<tr>
|
49
|
+
<td><b><%= pair.first %></b></td>
|
50
|
+
<td><i><%= pair.second %></i></td>
|
51
|
+
</tr>
|
52
|
+
<% end %>
|
53
|
+
</table>
|
54
|
+
</td>
|
45
55
|
</tr>
|
56
|
+
<tr>
|
57
|
+
<td><%= _('DNS') %></td>
|
58
|
+
<td>
|
59
|
+
<% (@container.in_fog.attributes['host_config_dns'] || []).each do |dns| %>
|
60
|
+
<%= dns %><br/>
|
61
|
+
<% end %>
|
62
|
+
</td>
|
63
|
+
</tr>
|
46
64
|
<tr>
|
47
65
|
<td><%= _('Environment Variables') %></td>
|
48
66
|
<td>
|
@@ -15,6 +15,19 @@
|
|
15
15
|
<% end %>
|
16
16
|
<%= link_to_add_fields(_("Add environment variable"), f, :environment_variables,
|
17
17
|
'foreman_docker/common_parameters/environment_variable') %>
|
18
|
+
|
19
|
+
<h3><%= _("Exposed Ports") %></h3>
|
20
|
+
<%= f.fields_for :exposed_ports, @docker_container_wizard_states_environment.exposed_ports do |builder| %>
|
21
|
+
<%= render 'foreman_docker/common_parameters/exposed_ports', :f => builder %>
|
22
|
+
<% end %>
|
23
|
+
<%= link_to_add_fields(_("Add Exposed Port"), f, :exposed_ports,
|
24
|
+
'foreman_docker/common_parameters/exposed_ports') %>
|
25
|
+
<h3><%= _("DNS") %></h3>
|
26
|
+
<%= f.fields_for :dns, @docker_container_wizard_states_environment.dns do |builder| %>
|
27
|
+
<%= render 'foreman_docker/common_parameters/dns', :f => builder %>
|
28
|
+
<% end %>
|
29
|
+
<%= link_to_add_fields(_("Add DNS"), f, :dns,
|
30
|
+
'foreman_docker/common_parameters/dns') %>
|
18
31
|
</div>
|
19
32
|
</div>
|
20
33
|
<%= render :partial => 'form_buttons' %>
|
@@ -0,0 +1,16 @@
|
|
1
|
+
<div class='fields'>
|
2
|
+
<table class="table table-bordered table-hover table-striped">
|
3
|
+
<tr class="form-group <%= 'has-error' if f.object.errors.any? %>">
|
4
|
+
<td><%= f.text_field(:name, :class => "form-control",
|
5
|
+
:placeholder => _("DNS e.g: 8.8.8.8")) %></td>
|
6
|
+
<td style='vertical-align: middle' class='text-center'>
|
7
|
+
<span class="help-block">
|
8
|
+
<%= link_to_remove_fields('', f) %>
|
9
|
+
</span>
|
10
|
+
</td>
|
11
|
+
<span class="help-block">
|
12
|
+
<%= f.object.errors.full_messages.to_sentence %>
|
13
|
+
</span>
|
14
|
+
</tr>
|
15
|
+
</table>
|
16
|
+
</div>
|
@@ -0,0 +1,17 @@
|
|
1
|
+
<div class='fields'>
|
2
|
+
<table class="table table-bordered table-hover table-striped">
|
3
|
+
<tr class="form-group <%= 'has-error' if f.object.errors.any? %>">
|
4
|
+
<td><%= f.text_field(:name, :class => "form-control",
|
5
|
+
:placeholder => _("Port Number e.g: 22")) %></td>
|
6
|
+
<td><%= f.select :value, [['TCP','tcp'],['UDP','udp']] %></td>
|
7
|
+
<td style='vertical-align: middle' class='text-center'>
|
8
|
+
<span class="help-block">
|
9
|
+
<%= link_to_remove_fields('', f) %>
|
10
|
+
</span>
|
11
|
+
</td>
|
12
|
+
<span class="help-block">
|
13
|
+
<%= f.object.errors.full_messages.to_sentence %>
|
14
|
+
</span>
|
15
|
+
</tr>
|
16
|
+
</table>
|
17
|
+
</div>
|
data/config/routes.rb
CHANGED
@@ -58,32 +58,47 @@ module ForemanDocker
|
|
58
58
|
|
59
59
|
security_block :containers do
|
60
60
|
permission :view_containers,
|
61
|
-
:containers => [:index, :show],
|
62
|
-
|
63
|
-
|
61
|
+
{ :containers => [:index, :show],
|
62
|
+
:'api/v2/containers' => [:index, :show, :logs] },
|
63
|
+
:resource_type => 'Container'
|
64
|
+
permission :commit_containers, { :containers => [:commit] },
|
65
|
+
:resource_type => 'Container'
|
64
66
|
permission :create_containers,
|
65
|
-
:'containers/steps' => [:show, :update],
|
66
|
-
|
67
|
-
|
67
|
+
{ :'containers/steps' => [:show, :update],
|
68
|
+
:containers => [:new],
|
69
|
+
:'api/v2/containers' => [:create, :power] },
|
70
|
+
:resource_type => 'Container'
|
68
71
|
permission :destroy_containers,
|
69
|
-
:containers => [:destroy],
|
70
|
-
|
72
|
+
{ :containers => [:destroy],
|
73
|
+
:'api/v2/containers' => [:destroy] },
|
74
|
+
:resource_type => 'Container'
|
71
75
|
permission :power_compute_resources_vms,
|
72
|
-
:containers => [:power],
|
73
|
-
|
76
|
+
{ :containers => [:power],
|
77
|
+
:'api/v2/containers' => [:create, :power] },
|
78
|
+
:resource_type => 'ComputeResource'
|
74
79
|
end
|
75
80
|
|
76
81
|
security_block :registries do
|
77
|
-
permission :view_registries,
|
78
|
-
|
79
|
-
|
82
|
+
permission :view_registries,
|
83
|
+
{ :registries => [:index, :show],
|
84
|
+
:'api/v2/registries' => [:index, :show] },
|
85
|
+
:resource_type => 'DockerRegistry'
|
86
|
+
permission :create_registries,
|
87
|
+
{ :registries => [:new, :create, :update, :edit],
|
88
|
+
:'api/v2/registries' => [:create, :update] },
|
89
|
+
:resource_type => 'DockerRegistry'
|
90
|
+
permission :destroy_registries,
|
91
|
+
{ :registries => [:destroy],
|
92
|
+
:'api/v2/registries' => [:destroy] },
|
93
|
+
:resource_type => 'DockerRegistry'
|
80
94
|
end
|
81
95
|
|
82
96
|
security_block :image_search do
|
83
97
|
permission :search_repository_image_search,
|
84
|
-
:image_search => [:auto_complete_repository_name,
|
85
|
-
|
86
|
-
|
98
|
+
{ :image_search => [:auto_complete_repository_name,
|
99
|
+
:auto_complete_image_tag,
|
100
|
+
:search_repository] },
|
101
|
+
:resource_type => 'Docker/ImageSearch'
|
87
102
|
end
|
88
103
|
|
89
104
|
# apipie API documentation
|
@@ -119,6 +119,15 @@ module Api
|
|
119
119
|
:tag => tag }
|
120
120
|
assert_response :created
|
121
121
|
end
|
122
|
+
|
123
|
+
test 'creation fails with invalid container name' do
|
124
|
+
post :create, :container => { :compute_resource_id => @container.compute_resource_id,
|
125
|
+
:name => @container.name,
|
126
|
+
:registry_id => @registry.id,
|
127
|
+
:repository_name => 'centos',
|
128
|
+
:tag => 'latest' }
|
129
|
+
assert_response :unprocessable_entity
|
130
|
+
end
|
122
131
|
end
|
123
132
|
end
|
124
133
|
end
|
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'test_plugin_helper'
|
2
|
+
|
3
|
+
module Api
|
4
|
+
module V2
|
5
|
+
class RegistriesControllerTest < ActionController::TestCase
|
6
|
+
setup do
|
7
|
+
@registry = FactoryGirl.create(:docker_registry)
|
8
|
+
end
|
9
|
+
|
10
|
+
test 'index returns a list of all containers' do
|
11
|
+
get :index, {}, set_session_user
|
12
|
+
assert_response :success
|
13
|
+
assert_template 'index'
|
14
|
+
end
|
15
|
+
|
16
|
+
test 'index can be filtered by name' do
|
17
|
+
%w(thomas clayton wolfe).each do |name|
|
18
|
+
FactoryGirl.create(:docker_registry, :name => name)
|
19
|
+
end
|
20
|
+
get :index, { :search => 'name = thomas' }, set_session_user
|
21
|
+
assert_response :success
|
22
|
+
assert_equal 1, assigns(:registries).length
|
23
|
+
end
|
24
|
+
|
25
|
+
test 'creates a new registry with valid params' do
|
26
|
+
docker_attrs = FactoryGirl.attributes_for(:docker_registry)
|
27
|
+
post :create, :registry => docker_attrs
|
28
|
+
assert_response :success
|
29
|
+
end
|
30
|
+
|
31
|
+
test 'does not create a new registry with invalid params' do
|
32
|
+
docker_attrs = FactoryGirl.attributes_for(:docker_registry)
|
33
|
+
docker_attrs.delete(:name)
|
34
|
+
post :create, :registry => docker_attrs
|
35
|
+
assert_response 422
|
36
|
+
end
|
37
|
+
|
38
|
+
test 'shows a docker registry' do
|
39
|
+
get :show, :id => @registry.id
|
40
|
+
assert_response :success
|
41
|
+
end
|
42
|
+
|
43
|
+
test 'update a docker registry' do
|
44
|
+
put :update, :id => @registry.id, :registry => { :name => 'hello_world' }
|
45
|
+
assert_response :success
|
46
|
+
assert DockerRegistry.exists?(:name => 'hello_world')
|
47
|
+
end
|
48
|
+
|
49
|
+
test 'deletes a docker registry' do
|
50
|
+
delete :destroy, :id => @registry.id
|
51
|
+
assert_response :success
|
52
|
+
refute DockerRegistry.exists?(@registry.id)
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
@@ -35,5 +35,52 @@ module Containers
|
|
35
35
|
end
|
36
36
|
assert_equal state.image, docker_image
|
37
37
|
end
|
38
|
+
|
39
|
+
test 'new container respects exposed_ports configuration' do
|
40
|
+
state = DockerContainerWizardState.create!
|
41
|
+
environment_options = {
|
42
|
+
:docker_container_wizard_state_id => state.id
|
43
|
+
}
|
44
|
+
state.environment = DockerContainerWizardStates::Environment.create!(environment_options)
|
45
|
+
state.environment.exposed_ports.create!(:name => '1654', :value => 'tcp')
|
46
|
+
state.environment.exposed_ports.create!(:name => '1655', :value => 'udp')
|
47
|
+
get :show, { :wizard_state_id => state.id, :id => :environment }, set_session_user
|
48
|
+
assert response.body.include?("1654")
|
49
|
+
assert response.body.include?("1655")
|
50
|
+
|
51
|
+
# Load ExposedPort variables into container
|
52
|
+
state.environment.exposed_ports.each do |e|
|
53
|
+
@container.exposed_ports.build :name => e.name,
|
54
|
+
:value => e.value,
|
55
|
+
:priority => e.priority
|
56
|
+
end
|
57
|
+
# Check if parametrized value of container matches Docker API's expectations
|
58
|
+
assert @container.parametrize.key? "ExposedPorts"
|
59
|
+
assert @container.parametrize["ExposedPorts"].key? "1654/tcp"
|
60
|
+
assert @container.parametrize["ExposedPorts"].key? "1655/udp"
|
61
|
+
end
|
62
|
+
|
63
|
+
test 'new container respects dns configuration' do
|
64
|
+
state = DockerContainerWizardState.create!
|
65
|
+
environment_options = {
|
66
|
+
:docker_container_wizard_state_id => state.id
|
67
|
+
}
|
68
|
+
state.environment = DockerContainerWizardStates::Environment.create!(environment_options)
|
69
|
+
state.environment.dns.create!(:name => '18.18.18.18')
|
70
|
+
state.environment.dns.create!(:name => '19.19.19.19')
|
71
|
+
get :show, { :wizard_state_id => state.id, :id => :environment }, set_session_user
|
72
|
+
assert response.body.include?("18.18.18.18")
|
73
|
+
assert response.body.include?("19.19.19.19")
|
74
|
+
|
75
|
+
# Load Dns variables into container
|
76
|
+
state.environment.dns.each do |e|
|
77
|
+
@container.dns.build :name => e.name,
|
78
|
+
:priority => e.priority
|
79
|
+
end
|
80
|
+
# Check if parametrized value of container matches Docker API's expectations
|
81
|
+
assert @container.parametrize.key? "HostConfig"
|
82
|
+
assert @container.parametrize["HostConfig"].key? "Dns"
|
83
|
+
assert @container.parametrize["HostConfig"].value? ["18.18.18.18", "19.19.19.19"]
|
84
|
+
end
|
38
85
|
end
|
39
86
|
end
|
@@ -18,7 +18,9 @@ class DockerRegistryTest < ActiveSupport::TestCase
|
|
18
18
|
end
|
19
19
|
|
20
20
|
test 'password is stored encrypted' do
|
21
|
-
registry = as_admin { FactoryGirl.
|
21
|
+
registry = as_admin { FactoryGirl.build(:docker_registry) }
|
22
|
+
registry.password = 'encrypted-whatever'
|
23
|
+
DockerRegistry.any_instance.expects(:encryption_key).at_least_once.returns('fakeencryptionkey')
|
22
24
|
assert registry.is_decryptable?(registry.password_in_db)
|
23
25
|
end
|
24
26
|
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: foreman_docker
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Daniel Lobato, Amos Benari
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-04-28 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: docker-api
|
@@ -52,6 +52,7 @@ files:
|
|
52
52
|
- app/assets/stylesheets/foreman_docker/autocomplete.css.scss
|
53
53
|
- app/assets/stylesheets/foreman_docker/terminal.css.scss
|
54
54
|
- app/controllers/api/v2/containers_controller.rb
|
55
|
+
- app/controllers/api/v2/registries_controller.rb
|
55
56
|
- app/controllers/concerns/foreman_docker/find_container.rb
|
56
57
|
- app/controllers/containers/steps_controller.rb
|
57
58
|
- app/controllers/containers_controller.rb
|
@@ -66,12 +67,16 @@ files:
|
|
66
67
|
- app/models/container.rb
|
67
68
|
- app/models/docker_container_wizard_state.rb
|
68
69
|
- app/models/docker_container_wizard_states/configuration.rb
|
70
|
+
- app/models/docker_container_wizard_states/dns.rb
|
69
71
|
- app/models/docker_container_wizard_states/environment.rb
|
70
72
|
- app/models/docker_container_wizard_states/environment_variable.rb
|
73
|
+
- app/models/docker_container_wizard_states/exposed_port.rb
|
71
74
|
- app/models/docker_container_wizard_states/image.rb
|
72
75
|
- app/models/docker_container_wizard_states/preliminary.rb
|
73
76
|
- app/models/docker_registry.rb
|
74
77
|
- app/models/environment_variable.rb
|
78
|
+
- app/models/exposed_port.rb
|
79
|
+
- app/models/foreman_docker/dns.rb
|
75
80
|
- app/models/foreman_docker/docker.rb
|
76
81
|
- app/models/foreman_docker/taxonomy_extensions.rb
|
77
82
|
- app/models/service/containers.rb
|
@@ -82,6 +87,10 @@ files:
|
|
82
87
|
- app/views/api/v2/containers/index.json.rabl
|
83
88
|
- app/views/api/v2/containers/main.json.rabl
|
84
89
|
- app/views/api/v2/containers/show.json.rabl
|
90
|
+
- app/views/api/v2/registries/base.json.rabl
|
91
|
+
- app/views/api/v2/registries/index.json.rabl
|
92
|
+
- app/views/api/v2/registries/main.json.rabl
|
93
|
+
- app/views/api/v2/registries/show.json.rabl
|
85
94
|
- app/views/compute_resources/form/_docker.html.erb
|
86
95
|
- app/views/compute_resources/show/_docker.html.erb
|
87
96
|
- app/views/compute_resources_vms/form/_docker.html.erb
|
@@ -97,7 +106,9 @@ files:
|
|
97
106
|
- app/views/containers/steps/environment.html.erb
|
98
107
|
- app/views/containers/steps/image.html.erb
|
99
108
|
- app/views/containers/steps/preliminary.html.erb
|
109
|
+
- app/views/foreman_docker/common_parameters/_dns.erb
|
100
110
|
- app/views/foreman_docker/common_parameters/_environment_variable.html.erb
|
111
|
+
- app/views/foreman_docker/common_parameters/_exposed_ports.erb
|
101
112
|
- app/views/image_search/_repository_search_results.html.erb
|
102
113
|
- app/views/images/form/_docker.html.erb
|
103
114
|
- app/views/registries/_form.html.erb
|
@@ -130,6 +141,7 @@ files:
|
|
130
141
|
- test/factories/containers.rb
|
131
142
|
- test/factories/docker_registry.rb
|
132
143
|
- test/functionals/api/v2/containers_controller_test.rb
|
144
|
+
- test/functionals/api/v2/registries_controller_test.rb
|
133
145
|
- test/functionals/containers_controller_test.rb
|
134
146
|
- test/functionals/containers_steps_controller_test.rb
|
135
147
|
- test/functionals/image_search_controller_test.rb
|
@@ -166,6 +178,7 @@ specification_version: 4
|
|
166
178
|
summary: Provision and manage Docker containers and images from Foreman
|
167
179
|
test_files:
|
168
180
|
- test/functionals/api/v2/containers_controller_test.rb
|
181
|
+
- test/functionals/api/v2/registries_controller_test.rb
|
169
182
|
- test/functionals/containers_steps_controller_test.rb
|
170
183
|
- test/functionals/image_search_controller_test.rb
|
171
184
|
- test/functionals/containers_controller_test.rb
|