foreman_datacenter 1.24.1 → 2.0.2

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d92338ad9dbcbb8535e563a11151dc94e5f0cf0e4ca2b67aaa80cc025bf553e5
4
- data.tar.gz: 0a26582a81e88b47f3205cfe9ab278cfc7e809a864d4e1f9b4cf73ce6ccb0a82
3
+ metadata.gz: 07f024a45f508486241e05667bea284b6db826402c2d65ee9ef62e98954940aa
4
+ data.tar.gz: 3906b2f835de97a213a4030ba04869cc9d08e0570f575f4600b358c696309a95
5
5
  SHA512:
6
- metadata.gz: 829d263770d9b13f7f31ac94142e53654036eb7499debac6855e3287215d7afc389e62de47c0fe97fcc1cfd881e185887d1d765f66b62d666f9a46a32d5dcbf3
7
- data.tar.gz: 0e76d5be4b412cd6f3df9890ef45d36a5465f7b7f1ad55b1c07b2472670d5ef414e176af5f8133e311f491675a1540de09cd70da8e0ed47b4f67b14e9bfb781f
6
+ metadata.gz: a8b3f7fe077808e782eda0f1cd93971f13c82ed82a5be3e3c9150cdf4276a7713d552b96260c88efb2cbabf0d51d73d505e18b9531cba1550a1e3024dfa235e2
7
+ data.tar.gz: ef1bfea3004c84af84dbeb465e20eba4bc1f9dc4be6358b9566726d8f508abf2a00c5232b354ac49731b77a5007b2885353ca735bcf9df9b9e0bcd29cd65658e
@@ -0,0 +1,56 @@
1
+ .rack-grid {
2
+ width: 100%;
3
+ border-bottom: 1px solid #d1d1d1;
4
+ border-left: 1px solid #d1d1d1;
5
+ display: inline-grid;
6
+ }
7
+
8
+ .item {
9
+ justify-content: center;
10
+ padding: 2px 10px 3px;
11
+ border-top: 1px solid #d1d1d1;
12
+ border-right: 1px solid #d1d1d1;
13
+ }
14
+
15
+ .item-dev {
16
+ position: relative;
17
+ text-align: center;
18
+ }
19
+
20
+ .dev-cell {
21
+ overflow: hidden;
22
+ text-overflow: ellipsis;
23
+ white-space: nowrap;
24
+ position: absolute;
25
+ height: inherit;
26
+ width: 90%;
27
+ text-align: center;
28
+ }
29
+
30
+ .a:hover {
31
+ overflow: visible;
32
+ }
33
+
34
+ .no-border {
35
+ border: none !important;
36
+ }
37
+
38
+ .panel-head-border {
39
+ border-top: 1px solid #ddd !important;
40
+ border-left: 1px solid #ddd !important;
41
+ border-right: 1px solid #ddd !important;
42
+ border-bottom: none !important;
43
+ }
44
+
45
+ .item-row {
46
+ white-space: nowrap;
47
+ text-overflow: ellipsis;
48
+ overflow: hidden;
49
+ }
50
+
51
+ .item-row:hover {
52
+ overflow: visible;
53
+ }
54
+
55
+ .item-empty-cell {
56
+ }
@@ -92,6 +92,8 @@ module ForemanDatacenter
92
92
  'move'
93
93
  when 'racks'
94
94
  'racks'
95
+ when 'export_to_csv'
96
+ 'export_to_csv'
95
97
  else
96
98
  super
97
99
  end
@@ -61,6 +61,7 @@ module ForemanDatacenter
61
61
  def racks
62
62
  @racks = @rack_group.racks.includes(devices: [:device_role])
63
63
  process_error redirect: rack_groups_path(@rack_group), error_msg: 'Current Rack Group haven\'t any Racks.' if @racks.empty?
64
+ @order = params[:order] || "desc"
64
65
  end
65
66
 
66
67
  def update_associated_objects
@@ -3,7 +3,7 @@ module ForemanDatacenter
3
3
  include Foreman::Controller::AutoCompleteSearch
4
4
  include ForemanDatacenter::Controller::Parameters::Rack
5
5
 
6
- before_action :find_resource, only: [:show, :edit, :update, :destroy, :devices, :move]
6
+ before_action :find_resource, only: [:show, :edit, :update, :destroy, :devices, :move, :export_to_csv]
7
7
 
8
8
  def index
9
9
  @racks = resource_base_search_and_page.includes(:site, :rack_group)
@@ -17,6 +17,7 @@ module ForemanDatacenter
17
17
 
18
18
  def show
19
19
  @rack = resource_base.includes(devices: [:device_role]).find(params[:id])
20
+ @order = params[:order] || "desc"
20
21
  end
21
22
 
22
23
  def new
@@ -64,6 +65,13 @@ module ForemanDatacenter
64
65
  process_error object: @rack, error_msg: 'Current Rack haven\'t any Devices.' if @devices.empty?
65
66
  end
66
67
 
68
+ def export_to_csv
69
+ data = @rack.format_for_csv
70
+ file = File.open("#{@rack.name}.csv", "r")
71
+ send_file(file)
72
+ file.close
73
+ end
74
+
67
75
  def update_associated_objects
68
76
  begin
69
77
  @rack = ForemanDatacenter::Rack.find(request.env['HTTP_REFERER'].split('/')[-2])
@@ -4,5 +4,101 @@ module ForemanDatacenter
4
4
  collection = rack.site ? rack.site.rack_groups : []
5
5
  options_from_collection_for_select(collection, 'id', 'name', rack.rack_group_id)
6
6
  end
7
+
8
+ def grid_u_desc(rack)
9
+ i = rack.height + 1
10
+ limit = 0
11
+ result = ""
12
+
13
+ while limit <= i do
14
+ if i == 0 && !rack.unpositioned_devices.empty?
15
+ concat content_tag(:div, "Unpositioned Devices")
16
+ else
17
+ if i != 0
18
+ if rack.child_devices.any? { |d| d.position == i }
19
+ concat content_tag :div, &-> do
20
+ concat "#{i}U"
21
+ rack.child_devices.each do |d|
22
+ if d.position == i
23
+ concat content_tag :strong, &-> do
24
+ concat link_to("Child", device_path(d))
25
+ end
26
+ end
27
+ end
28
+ end
29
+ else
30
+ concat content_tag(:div, "#{i}U")
31
+ end
32
+ end
33
+ end
34
+ i -= 1
35
+ end
36
+ end
37
+
38
+ def grid_empty_style(cell, id)
39
+ case cell[1]
40
+ when ["right"]
41
+ column = "grid-area: rack-#{id}-row-#{cell[0]}-right-empty"
42
+ when ["left"]
43
+ column = "grid-area: rack-#{id}-row-#{cell[0]}-left-empty"
44
+ when ["left", "right"] || ["right", "left"]
45
+ column = "grid-area: rack-#{id}-row-#{cell[0]}-full-empty"
46
+ end
47
+ return column
48
+ end
49
+
50
+ def margin_style(height)
51
+ result = "top: "
52
+ case height
53
+ when 1
54
+ result += "7%"
55
+ when 2
56
+ result += "30%"
57
+ when 3
58
+ result += "35%"
59
+ when 4
60
+ result += "40%"
61
+ else
62
+ result += "45%"
63
+ end
64
+ end
65
+
66
+ def grid_rack_style(device)
67
+ css_class_name = device.name.gsub(/[.@#\s]/, "_")
68
+ return "grid-area: #{css_class_name}"
69
+ end
70
+
71
+ def grid_rack_height(height)
72
+ return (height + 1)
73
+ end
74
+
75
+ def grid_template(grid, id, order)
76
+ result = []
77
+ gr = JSON.parse(grid)
78
+ gr = gr.to_a.reverse.to_h if order == "desc"
79
+
80
+ gr.each do |k,v|
81
+ row = "rack-#{id}-u#{k}"
82
+ if v.instance_of? Array
83
+ if k == "0"
84
+ row += " rack-#{id}-unpos-devs rack-#{id}-unpos-devs"
85
+ else
86
+ row += " rack-#{id}-row-#{k}-full-empty rack-#{id}-row-#{k}-full-empty"
87
+ end
88
+ else
89
+ if v.size > 1
90
+ row += " #{v['left']} #{v['right']}"
91
+ else
92
+ row += " #{v['left']} rack-#{id}-row-#{k}-right-empty" if v.key?("left")
93
+ row += " rack-#{id}-row-#{k}-left-empty #{v['right']}" if v.key?("right")
94
+ row += " #{v['full']} #{v['full']}" if v.key?("full")
95
+ end
96
+ end
97
+ result << row
98
+ end
99
+ final = result.join("' '").prepend("'") + "'"
100
+ return "grid-template-areas: #{final}; grid-template-columns: 22% 39% 39%"
101
+ end
102
+
7
103
  end
8
104
  end
@@ -34,6 +34,7 @@ module ForemanDatacenter
34
34
  validates :serial, length: { maximum: 50 }
35
35
  validates :rack_id, presence: true
36
36
  validates :position, numericality: { only_integer: true }, allow_nil: true
37
+ validate :correct_position
37
38
 
38
39
  after_create :create_interfaces
39
40
  after_create :import_interfaces_from_host
@@ -72,6 +73,10 @@ module ForemanDatacenter
72
73
  device_type.try(:subdevice_role) == 'Parent'
73
74
  end
74
75
 
76
+ def child?
77
+ device_type.try(:subdevice_role) == 'Child'
78
+ end
79
+
75
80
  def free_interfaces
76
81
  interfaces.where(mgmt_only: false).reject(&:connected?)
77
82
  end
@@ -139,6 +144,39 @@ module ForemanDatacenter
139
144
  end
140
145
  end
141
146
 
147
+ def correct_position
148
+ if position > 0
149
+ grid_template = JSON.parse(self.rack.grid_template_areas)
150
+ correct_pos = true
151
+ pos = []
152
+ sz = (size == 0 || size == 1) ? [position] : [*position..(position + (size - 1))]
153
+ sd = (side.nil?) ? "full" : side
154
+ sz.each do |i|
155
+ if grid_template["#{i}"].is_a?(Hash)
156
+ if grid_template["#{i}"].key?("full") && grid_template["#{i}"]["full"] != "device-#{self.id}"
157
+ correct_pos = false
158
+ pos << "#{i}(full)"
159
+ end
160
+ if sd == "full"
161
+ ["left", "right"].each do |s|
162
+ if grid_template["#{i}"].key?("#{s}") && grid_template["#{i}"]["#{s}"] != "device-#{self.id}"
163
+ correct_pos = false
164
+ pos << "#{i}(#{s})"
165
+ end
166
+ end
167
+ else
168
+ if grid_template["#{i}"].key?("#{sd}") && grid_template["#{i}"]["#{sd}"] != "device-#{self.id}"
169
+ correct_pos = false
170
+ pos << "#{i}(#{sd})"
171
+ end
172
+ end
173
+ end
174
+ end
175
+ pos.uniq!
176
+ errors.add(:position, "Positions: #{pos.join(', ')} already taken") if correct_pos == false
177
+ end
178
+ end
179
+
142
180
  private
143
181
 
144
182
  def create_interfaces
@@ -12,6 +12,7 @@ module ForemanDatacenter
12
12
  validates :facility_id, length: { maximum: 30 }
13
13
  validates :height, presence: true
14
14
  validates_numericality_of :height, only_integer: true, greater_than: 0
15
+ validate :correct_position
15
16
 
16
17
  scoped_search on: :name, complete_value: true
17
18
  scoped_search on: :height, validator: ScopedSearch::Validators::INTEGER
@@ -22,6 +23,7 @@ module ForemanDatacenter
22
23
  scoped_search in: :site, on: :name, complete_value: true, rename: :site
23
24
  scoped_search in: :rack_group, on: :name, complete_value: true, rename: :rack_group
24
25
 
26
+
25
27
  def device_at(position)
26
28
  devices.where(position: position).to_a
27
29
  end
@@ -43,7 +45,7 @@ module ForemanDatacenter
43
45
  end
44
46
 
45
47
  def unpositioned_devices
46
- devices.where(position: nil).to_a
48
+ devices.where(position: nil).or(devices.where(position: "0")).to_a
47
49
  end
48
50
 
49
51
  def devices_count
@@ -52,8 +54,108 @@ module ForemanDatacenter
52
54
  count
53
55
  end
54
56
 
57
+ def format_for_csv
58
+ positioned_devices = self.positioned_devices
59
+ unpositioned_devices = self.unpositioned_devices
60
+ csv_string = CSV.generate do |csv|
61
+ csv << ["positions", "left", "full", "right", "no side"]
62
+ positioned_devices.each do |i|
63
+ pos = i[0].map{|p| "#{p}"+"U"}.join(",")
64
+ if i[1].size > 0
65
+ sort = sort_for_csv(i[1])
66
+ csv << [pos, sort[0], sort[1], sort[2], sort[3]]
67
+ else
68
+ csv << [pos]
69
+ end
70
+ end
71
+ unless unpositioned_devices.empty?
72
+ csv << []
73
+ csv << ["Unpositioned", unpositioned_devices.map(&:name).join(",")]
74
+ end
75
+
76
+ end
77
+ File.open("#{self.name}.csv", "w") {|f| f << csv_string}
78
+ end
79
+
80
+ # Finding all empty cells for grid layout
81
+ def empty_cells
82
+ cells = {} # all cells of grid
83
+ devices_cells = {} # cells with devices
84
+ height.times.each do |i|
85
+ cells[i+1] = ["left", "right"]
86
+ end
87
+ devices.each do |d|
88
+ if d.size > 0
89
+ if !d.position.nil? && d.position != 0
90
+ s = (d.size == 0 || d.size == 1) ? 0 : (d.size - 1)
91
+ places = [*d.position..d.position+s]
92
+ places.each do |p|
93
+ devices_cells[p] = [] unless devices_cells.key?(p)
94
+ if (d.side == "full" || d.side.nil?)
95
+ ["left", "right"].each {|side| devices_cells[p] << side}
96
+ else
97
+ devices_cells[p] << d.side
98
+ end
99
+ end
100
+ end
101
+ end
102
+ end
103
+ devices_cells.each do |k,v|
104
+ v.each {|c| cells[k].delete(c)}
105
+ end
106
+ cells.each {|k,v| cells.except!(k) if cells[k] == []}
107
+ return cells
108
+ end
109
+
110
+ def grid_template_areas
111
+ result = {}
112
+ (height+1).times.each do |i|
113
+ if i == 0
114
+ result[0] = unpositioned_devices.map{|d| "device-#{d.id}"}
115
+ else
116
+ dev = {}
117
+ devices.each do |d|
118
+ if d.size > 0
119
+ if !d.position.nil? && d.position != 0
120
+ css_class_name = "device-#{d.id}"
121
+ s = (d.size == 1 || d.size == 0) ? 0 : (d.size - 1)
122
+ if [*d.position..(d.position + s)].include?(i)
123
+ if d.side.nil?
124
+ dev["full"] = css_class_name
125
+ else
126
+ dev["#{d.side}"] = css_class_name
127
+ end
128
+ result[i] = dev
129
+ end
130
+ end
131
+ end
132
+ end
133
+ end
134
+ end
135
+ (height+1).times.each do |i|
136
+ result[i] = [] if result[i].nil?
137
+ end
138
+ # result[0].reject! if result[0].empty?
139
+ return result.sort_by{|k,v| k}.to_h.to_json
140
+ end
141
+
142
+ def child_devices
143
+ devices.joins(:device_type).where("device_types.subdevice_role = ?", "Child")
144
+ end
145
+
55
146
  private
56
147
 
148
+ def sort_for_csv(device_array)
149
+ left, full, right, no_side = "", "", "", []
150
+ device_array.each do |d|
151
+ left = d.name if d.side == "left"
152
+ right = d.name if d.side == "right"
153
+ full = d.name if d.side == "full"
154
+ no_side << d.name if d.side == nil
155
+ end
156
+ [left, full, right, no_side.join(",")]
157
+ end
158
+
57
159
  def device_sorting(devices)
58
160
  devices.reverse.map { |d| [d[0].reverse, d[1]] }
59
161
  end
@@ -70,7 +70,7 @@
70
70
  </tr>
71
71
  <tr>
72
72
  <td><%= _("Position") %></td>
73
- <td><%= @device.positions.join(", ") %> / <%= @device.face %> / <%= @device.side %></td>
73
+ <td><%= (@device.position > 0) ? (@device.child? ? "#{@device.position} (Child)" : @device.positions.join(", ")) : 0 %> / <%= @device.face %> / <%= @device.side %></td>
74
74
  </tr>
75
75
  <tr>
76
76
  <td><%= _("Device Type") %></td>
@@ -1,5 +1,14 @@
1
1
  <div class="panel panel-default">
2
- <div class="panel-heading text-center"><h4 class="nonmargintop nonmarginbottom"><strong><%= link_to _("#{rack.name}"), rack_path(rack) %></strong></h4></div>
2
+ <div class="panel-heading text-center">
3
+ <h4 class="nonmargintop nonmarginbottom">
4
+ <strong>
5
+ <%= link_to _("#{rack.name}"), rack_path(rack) %>
6
+ </strong>
7
+ <strong>
8
+ <%= link_to 'Export to CSV', export_to_csv_rack_path(rack.id), class: "btn btn-primary btn-xs pull-right" %>
9
+ </strong>
10
+ </h4>
11
+ </div>
3
12
  <table class="<%= table_css_classes 'table-hover panel-body nonmarginbottom' %>">
4
13
  <tbody>
5
14
  <% rack.positioned_devices.each do |positions, devices| %>
@@ -0,0 +1,91 @@
1
+ <div class="panel panel-default no-border">
2
+ <div class="panel-heading text-center panel-head-border">
3
+ <h4 class="nonmargintop nonmarginbottom">
4
+ <strong>
5
+ <%= link_to rack.name, rack_path(rack) %>
6
+ </strong>
7
+ <strong>
8
+ <%= link_to 'Export to CSV', export_to_csv_rack_path(rack.id), class: "btn btn-primary btn-xs pull-right" %>
9
+ </strong>
10
+ <strong>
11
+ <% if @order == "asc" %>
12
+ <%= link_to 'DESC', url_for(), class: "btn btn-success btn-xs pull-left" %>
13
+ <% else %>
14
+ <%= link_to 'ASC', url_for(order: "asc"), class: "btn btn-success btn-xs pull-left" %>
15
+ <% end %>
16
+ </strong>
17
+ </h4>
18
+ </div>
19
+
20
+ <!-- Grid -->
21
+ <div class="rack-grid rack-<%= rack.id %>" style="<%= grid_template(rack.grid_template_areas, rack.id, @order) %>">
22
+
23
+ <!-- Rows -->
24
+ <% (rack.height+1).times.each do |i| %>
25
+ <% if i == 0 && !rack.unpositioned_devices.empty? %>
26
+ <div class="item item-row" style="grid-area: rack-<%= rack.id %>-u<%= i %>">
27
+ <%= i == 0 ? "Unpositioned Devices" : "#{i}U"%>
28
+ </div>
29
+ <% else %>
30
+ <% if i != 0 %>
31
+ <div class="item item-row" style="grid-area: rack-<%= rack.id %>-u<%= i %>">
32
+ <%= "#{i}U" %>
33
+ <% rack.child_devices.each do |d| %>
34
+ <% if d.position == i %>
35
+ <strong>
36
+ <%= link_to "Child", device_path(d), class: "btn btn-primary btn-xs pull-right" %>
37
+ </strong>
38
+ <% end %>
39
+ <% end %>
40
+ </div>
41
+ <% else %>
42
+ <% next %>
43
+ <% end %>
44
+ <% end %>
45
+ <% end %>
46
+
47
+ <!-- Empty cells -->
48
+ <% rack.empty_cells.each do |c| %>
49
+ <div class="item item-empty-cell" style="<%= grid_empty_style(c, rack.id)%>">
50
+ &nbsp;
51
+ </div>
52
+ <% end %>
53
+
54
+ <!-- Devices -->
55
+ <% rack.devices.each do |d| %>
56
+ <% if !d.position.nil? && d.size != 0 && d.position != 0 %>
57
+ <div class="item item-dev" style="grid-area: device-<%= d.id %>">
58
+ <div class="dev-cell" style="<%= margin_style(d.size) %>">
59
+ <div class="<%= "label " + d.device_role.color.downcase.gsub(" ","") %>" style="border-radius:40px;border:0px;">&nbsp;&nbsp;</div>
60
+ <%= link_to d.name, device_path(d) %>
61
+ <% if d.side.nil? %>
62
+ *
63
+ <% end %>
64
+ <% if d.size.nil? %>
65
+ **
66
+ <% end %>
67
+ </div>
68
+ </div>
69
+ <% end %>
70
+ <% end %>
71
+
72
+ <!-- Unpositioned devices -->
73
+ <% if rack.unpositioned_devices.count != 0 %>
74
+ <div class="item item-dev" style="grid-area: rack-<%= rack.id %>-unpos-devs">
75
+ <% rack.unpositioned_devices.each do |d| %>
76
+ <div class="<%= "label " + d.device_role.color.downcase.gsub(" ","") %>" style="border-radius:40px;border:0px;">&nbsp;&nbsp;</div>
77
+ <%= link_to d.name, device_path(d) %>
78
+ <% if d.side.nil? %>
79
+ *
80
+ <% end %>
81
+ <% if d.size.nil? %>
82
+ **
83
+ <% end %>
84
+ <br>
85
+ <% end %>
86
+ </div>
87
+ <% end %>
88
+
89
+ </div>
90
+
91
+ </div>
@@ -1,5 +1,6 @@
1
1
  <% stylesheet 'foreman_datacenter/device_roles' %>
2
2
  <% stylesheet 'foreman_datacenter/datacenter' %>
3
+ <% stylesheet 'foreman_datacenter/rack_show' %>
3
4
  <% stylesheet 'foreman_datacenter/modal' %>
4
5
  <% javascript 'foreman_datacenter/modal' %>
5
6
 
@@ -89,10 +90,11 @@
89
90
  </div>
90
91
 
91
92
  <div class="col-md-6">
92
- <!-- Devices -->
93
- <%= render "device_position", rack: @rack %>
94
- <!-- Unpositioned Devices -->
95
- <%= render "unpositioned_devices", rack: @rack if @rack.unpositioned_devices.count != 0 %>
93
+ <%= render "device_position_new", rack: @rack %>
94
+ <!-- Devices -->
95
+ <%#= render "device_position", rack: @rack %>
96
+ <!-- Unpositioned Devices -->
97
+ <%#= render "unpositioned_devices", rack: @rack if @rack.unpositioned_devices.count != 0 %>
96
98
  <div><h6 class="text-right"><%= _("* side is not defined") %></h6></div>
97
99
  <div><h6 class="text-right"><%= _("** size is not defined") %></h6></div>
98
100
  </div>
@@ -113,6 +113,7 @@ Foreman::Application.routes.draw do
113
113
  end
114
114
  resources :racks do
115
115
  member do
116
+ get :export_to_csv
116
117
  get :move
117
118
  end
118
119
  collection do
@@ -1,3 +1,3 @@
1
1
  module ForemanDatacenter
2
- VERSION = '1.24.1'.freeze
2
+ VERSION = '2.0.2'.freeze
3
3
  end
@@ -4,19 +4,19 @@ FactoryBot.define do
4
4
  sequence(:manufacturer_id) { 1 }
5
5
 
6
6
  trait :full_depth do
7
- is_full_depth { true }
7
+ is_full_depth true
8
8
  end
9
9
 
10
10
  trait :console_server do
11
- is_console_server { true }
11
+ is_console_server true
12
12
  end
13
13
 
14
14
  trait :pdu do
15
- is_pdu { true }
15
+ is_pdu true
16
16
  end
17
17
 
18
18
  trait :network_device do
19
- is_network_device { true }
19
+ is_network_device true
20
20
  end
21
21
 
22
22
  trait :parent do
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: foreman_datacenter
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.24.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Pavel Ivanov
8
8
  - Eugene Loginov
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2020-04-28 00:00:00.000000000 Z
12
+ date: 2020-11-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: prawn
@@ -92,6 +92,7 @@ files:
92
92
  - app/assets/stylesheets/foreman_datacenter/devices.css
93
93
  - app/assets/stylesheets/foreman_datacenter/horizontal-scroll.css
94
94
  - app/assets/stylesheets/foreman_datacenter/modal.css
95
+ - app/assets/stylesheets/foreman_datacenter/rack_show.css
95
96
  - app/assets/stylesheets/foreman_datacenter/title_filter.css
96
97
  - app/controllers/api/v2/foreman_datacenter/base_controller.rb
97
98
  - app/controllers/api/v2/foreman_datacenter/console_port_templates_controller.rb
@@ -463,6 +464,7 @@ files:
463
464
  - app/views/foreman_datacenter/rack_groups/show.html.erb
464
465
  - app/views/foreman_datacenter/rack_groups/welcome.html.erb
465
466
  - app/views/foreman_datacenter/racks/_device_position.html.erb
467
+ - app/views/foreman_datacenter/racks/_device_position_new.html.erb
466
468
  - app/views/foreman_datacenter/racks/_dp.html.erb
467
469
  - app/views/foreman_datacenter/racks/_form.html.erb
468
470
  - app/views/foreman_datacenter/racks/_rack_groups.html.erb
@@ -588,7 +590,7 @@ files:
588
590
  homepage: https://github.com/theforeman/foreman_datacenter
589
591
  licenses: []
590
592
  metadata: {}
591
- post_install_message:
593
+ post_install_message:
592
594
  rdoc_options: []
593
595
  require_paths:
594
596
  - lib
@@ -603,62 +605,61 @@ required_rubygems_version: !ruby/object:Gem::Requirement
603
605
  - !ruby/object:Gem::Version
604
606
  version: '0'
605
607
  requirements: []
606
- rubyforge_project:
607
- rubygems_version: 2.7.6.2
608
- signing_key:
608
+ rubygems_version: 3.1.4
609
+ signing_key:
609
610
  specification_version: 4
610
611
  summary: A plugin that lets you document your servers in a datacenter
611
612
  test_files:
612
- - test/factories/device_role.rb
613
- - test/factories/foreman_datacenter_factories.rb
614
- - test/factories/rack.rb
615
- - test/factories/site.rb
616
- - test/factories/manufacturer.rb
617
- - test/factories/rack_group.rb
618
- - test/factories/device.rb
619
- - test/factories/device_type.rb
620
- - test/factories/platform.rb
621
- - test/test_plugin_helper.rb
622
- - test/controllers/foreman_datacenter/sites_contoller_test.rb
623
- - test/controllers/foreman_datacenter/devices_controller_test.rb
624
- - test/controllers/foreman_datacenter/rack_groups_contoller_test.rb
625
- - test/controllers/foreman_datacenter/manufacturers_controller_test.rb
626
- - test/controllers/foreman_datacenter/racks_contoller_test.rb
627
- - test/controllers/foreman_datacenter/manufacturers_contoller_test.rb
628
- - test/controllers/foreman_datacenter/platforms_contoller_test.rb
629
- - test/controllers/foreman_datacenter/device_roles_controller_test.rb
630
- - test/controllers/foreman_datacenter/power_port_templates_contoller_test.rb
631
- - test/controllers/foreman_datacenter/device_types_contoller_test.rb
632
- - test/integration/foreman_datacenter/rack_group_test.rb
633
- - test/integration/foreman_datacenter/rack_test.rb
634
- - test/integration/foreman_datacenter/device_role_test.rb
635
- - test/integration/foreman_datacenter/device_type_test.rb
636
- - test/integration/foreman_datacenter/platform_test.rb
637
- - test/integration/foreman_datacenter/site_test.rb
638
- - test/integration/foreman_datacenter/manufacturer_test.rb
639
- - test/fixtures/foreman_datacenter/platforms.yml
613
+ - test/fixtures/foreman_datacenter/device_interface_connections.yml
640
614
  - test/fixtures/foreman_datacenter/console_server_port_templates.yml
641
- - test/fixtures/foreman_datacenter/console_server_ports.yml
642
- - test/fixtures/foreman_datacenter/device_types.yml
643
- - test/fixtures/foreman_datacenter/racks.yml
644
- - test/fixtures/foreman_datacenter/power_port_templates.yml
645
615
  - test/fixtures/foreman_datacenter/rack_groups.yml
646
- - test/fixtures/foreman_datacenter/power_outlet_templates.yml
647
- - test/fixtures/foreman_datacenter/device_bay_templates.yml
648
- - test/fixtures/foreman_datacenter/device_modules.yml
649
- - test/fixtures/foreman_datacenter/console_ports.yml
650
616
  - test/fixtures/foreman_datacenter/device_bays.yml
617
+ - test/fixtures/foreman_datacenter/device_roles.yml
618
+ - test/fixtures/foreman_datacenter/racks.yml
619
+ - test/fixtures/foreman_datacenter/comments.yml
651
620
  - test/fixtures/foreman_datacenter/sites.yml
652
- - test/fixtures/foreman_datacenter/manufacturers.yml
653
- - test/fixtures/foreman_datacenter/power_ports.yml
654
- - test/fixtures/foreman_datacenter/console_port_templates.yml
655
- - test/fixtures/foreman_datacenter/power_outlets.yml
656
621
  - test/fixtures/foreman_datacenter/management_devices.yml
657
- - test/fixtures/foreman_datacenter/devices.yml
658
- - test/fixtures/foreman_datacenter/device_roles.yml
659
622
  - test/fixtures/foreman_datacenter/interface_templates.yml
623
+ - test/fixtures/foreman_datacenter/device_modules.yml
660
624
  - test/fixtures/foreman_datacenter/device_interfaces.yml
661
- - test/fixtures/foreman_datacenter/comments.yml
662
- - test/fixtures/foreman_datacenter/device_interface_connections.yml
625
+ - test/fixtures/foreman_datacenter/power_ports.yml
626
+ - test/fixtures/foreman_datacenter/devices.yml
627
+ - test/fixtures/foreman_datacenter/power_outlet_templates.yml
628
+ - test/fixtures/foreman_datacenter/platforms.yml
629
+ - test/fixtures/foreman_datacenter/device_bay_templates.yml
630
+ - test/fixtures/foreman_datacenter/power_port_templates.yml
631
+ - test/fixtures/foreman_datacenter/console_ports.yml
632
+ - test/fixtures/foreman_datacenter/console_port_templates.yml
633
+ - test/fixtures/foreman_datacenter/device_types.yml
634
+ - test/fixtures/foreman_datacenter/power_outlets.yml
635
+ - test/fixtures/foreman_datacenter/console_server_ports.yml
636
+ - test/fixtures/foreman_datacenter/manufacturers.yml
637
+ - test/controllers/foreman_datacenter/manufacturers_contoller_test.rb
638
+ - test/controllers/foreman_datacenter/rack_groups_contoller_test.rb
639
+ - test/controllers/foreman_datacenter/device_roles_controller_test.rb
640
+ - test/controllers/foreman_datacenter/power_port_templates_contoller_test.rb
641
+ - test/controllers/foreman_datacenter/devices_controller_test.rb
642
+ - test/controllers/foreman_datacenter/sites_contoller_test.rb
643
+ - test/controllers/foreman_datacenter/device_types_contoller_test.rb
644
+ - test/controllers/foreman_datacenter/platforms_contoller_test.rb
645
+ - test/controllers/foreman_datacenter/manufacturers_controller_test.rb
646
+ - test/controllers/foreman_datacenter/racks_contoller_test.rb
647
+ - test/test_plugin_helper.rb
663
648
  - test/unit/foreman_datacenter_test.rb
664
649
  - test/datacenter_helper.rb
650
+ - test/factories/foreman_datacenter_factories.rb
651
+ - test/factories/rack.rb
652
+ - test/factories/device_role.rb
653
+ - test/factories/site.rb
654
+ - test/factories/device_type.rb
655
+ - test/factories/device.rb
656
+ - test/factories/rack_group.rb
657
+ - test/factories/manufacturer.rb
658
+ - test/factories/platform.rb
659
+ - test/integration/foreman_datacenter/device_role_test.rb
660
+ - test/integration/foreman_datacenter/manufacturer_test.rb
661
+ - test/integration/foreman_datacenter/rack_test.rb
662
+ - test/integration/foreman_datacenter/site_test.rb
663
+ - test/integration/foreman_datacenter/platform_test.rb
664
+ - test/integration/foreman_datacenter/rack_group_test.rb
665
+ - test/integration/foreman_datacenter/device_type_test.rb