foreman_datacenter 1.24.2 → 1.24.3

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: aa372e8673608cecc9343f4a2efa60d2d38dc77cb9ef37cfd55f8ec261907ccc
4
- data.tar.gz: b806528ffcea447652114e76043f216d28eb50c2386f253ca93bd8808ab0ee35
3
+ metadata.gz: 0b77182c1385f10fbeb5506db376a8fa29a079b4cebae2945ce99d07a3350aa7
4
+ data.tar.gz: 36f47250116e01a60c30a1be2503ff7c636e18bf7408fc75b00fd130b9eabc99
5
5
  SHA512:
6
- metadata.gz: 8fa308e3840207c9a77aecfaa18491b578a73f5a1307bcea72fabafa1e97d4b3dfcf6bd9386803c847bbc410e75de3515d629c1e12227d4606d5e8385096c721
7
- data.tar.gz: 3a00433a5afb85a305c687e66f153dd4279efe62f2ec842d6c67d321085062530dc261529436076b3ea0df0e74136bed184b79b388b98cf34f39eb6ecd0066b9
6
+ metadata.gz: 73e0482bff2ae27ec2b2f59ad59946c89ec6bc712362952e1f2fb77095b1953f0cce0e943506fae0814b94ccb4188172a50106e23b4b2789358886a1c9ffef04
7
+ data.tar.gz: a3ff1c963f5f22c2902a25e503b3218aa408b27edf7da7417545010b4faf3eaaeb81ae3c460d73fd6e08acd6496beceb9f0b1893f42589f3fe6e188de86b21a3
@@ -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
+ }
@@ -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
@@ -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
@@ -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
@@ -75,6 +77,72 @@ module ForemanDatacenter
75
77
  File.open("#{self.name}.csv", "w") {|f| f << csv_string}
76
78
  end
77
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
+
78
146
  private
79
147
 
80
148
  def sort_for_csv(device_array)
@@ -97,7 +165,5 @@ module ForemanDatacenter
97
165
  devices.each{|d| devs[1] << d[1][0]}
98
166
  return devs
99
167
  end
100
-
101
-
102
168
  end
103
169
  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>
@@ -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>
@@ -1,3 +1,3 @@
1
1
  module ForemanDatacenter
2
- VERSION = '1.24.2'.freeze
2
+ VERSION = '1.24.3'.freeze
3
3
  end
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.2
4
+ version: 1.24.3
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-07-31 00:00:00.000000000 Z
12
+ date: 2020-11-13 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,9 +605,8 @@ 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
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: