Project

General

Profile

Revision bc82d5d5

Added by Vanya Jauhal over 7 years ago

Fixes #7865 - Adds support for configuring dns during container creation

View differences:

app/models/container.rb
16 16
                            :class_name => 'ExposedPort',
17 17
                            :validate => true
18 18

  
19
  has_many :dns,  :dependent  => :destroy, :foreign_key => :reference_id,
20
                  :inverse_of => :container,
21
                  :class_name => 'ForemanDocker::Dns',
22
                  :validate => true
23

  
19 24
  accepts_nested_attributes_for :exposed_ports, :allow_destroy => true
20 25
  scoped_search :on => :name
21 26

  
22 27
  attr_accessible :command, :repository_name, :name, :compute_resource_id, :entrypoint,
23 28
                  :cpu_set, :cpu_shares, :memory, :tty, :attach_stdin, :registry_id,
24 29
                  :attach_stdout, :attach_stderr, :tag, :uuid, :environment_variables_attributes,
25
                  :katello, :exposed_ports_attributes
30
                  :katello, :exposed_ports_attributes, :dns
26 31

  
27 32
  def repository_pull_url
28 33
    repo = tag.blank? ? repository_name : "#{repository_name}:#{tag}"
......
39 44
      'AttachStderr' => attach_stderr,          'CpuShares'    => cpu_shares,
40 45
      'Cpuset'       => cpu_set,
41 46
      'Env' => environment_variables.map { |env| "#{env.name}=#{env.value}" },
42
      'ExposedPorts' => Hash[*exposed_ports.map { |v| [v.name + "/" + v.value, {}] }.flatten]
43
    }
47
      'ExposedPorts' => Hash[*exposed_ports.map { |v| [v.name + "/" + v.value, {}] }.flatten],
48
      'HostConfig' => {
49
        'Dns' => dns.map { |env| "#{env.name}" }
50
      } }
44 51
  end
45 52

  
46 53
  def in_fog
app/models/docker_container_wizard_state.rb
11 11
  delegate :compute_resource_id,   :to => :preliminary
12 12
  delegate :environment_variables, :to => :environment
13 13
  delegate :exposed_ports, :to => :environment
14
  delegate :dns, :to => :environment
14 15

  
15 16
  def container_attributes
16 17
    { :repository_name     => image.repository_name,
app/models/docker_container_wizard_states/dns.rb
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
app/models/docker_container_wizard_states/environment.rb
17 17
                              :inverse_of => :environment,
18 18
                              :class_name => 'DockerContainerWizardStates::ExposedPort',
19 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
20 24

  
21 25
    accepts_nested_attributes_for :environment_variables, :allow_destroy => true
22 26
    accepts_nested_attributes_for :exposed_ports, :allow_destroy => true
27
    accepts_nested_attributes_for :dns, :allow_destroy => true
23 28

  
24 29
    def parameters_symbol
25 30
      :environment_variables
app/models/foreman_docker/dns.rb
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
app/models/service/containers.rb
13 13

  
14 14
          load_environment_variables(state, r)
15 15
          load_exposed_ports(state, r)
16
          load_dns(state, r)
16 17
        end
17 18

  
18 19
        Taxonomy.enabled_taxonomies.each do |taxonomy|
......
61 62
                              :priority => e.priority
62 63
      end
63 64
    end
65

  
66
    def load_dns(state, r)
67
      state.dns.each do |e|
68
        r.dns.build :name => e.name,
69
                    :priority => e.priority
70
      end
71
    end
64 72
  end
65 73
end
app/views/containers/show.html.erb
54 54
              </td>
55 55
            </tr>
56 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>            
64
            <tr>
57 65
              <td><%= _('Environment Variables') %></td>
58 66
              <td>
59 67
                <table id="environment_variables" class="table table-bordered" style="table-layout:fixed; word-wrap: break-word">
app/views/containers/steps/environment.html.erb
22 22
        <% end %>
23 23
        <%= link_to_add_fields(_("Add Exposed Port"), f, :exposed_ports,
24 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') %>                               
25 31
      </div>
26 32
   </div>
27 33
   <%= render :partial => 'form_buttons' %>
app/views/foreman_docker/common_parameters/_dns.erb
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>
test/functionals/containers_steps_controller_test.rb
59 59
      assert @container.parametrize["ExposedPorts"].key? "1654/tcp"
60 60
      assert @container.parametrize["ExposedPorts"].key? "1655/udp"
61 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
62 85
  end
63 86
end

Also available in: Unified diff