foreman_docker 1.2.4 → 1.3.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 +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
|