docker-tools/dps.rb

145 lines
3.3 KiB
Ruby
Executable File
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env ruby
require 'json'
require 'socket'
require 'net/http'
COLOR_GREEN = ""
COLOR_RED = ""
COLOR_GRAY = ""
COLOR_RESET = ""
class Container
FIELDS = [:state, :dup, :ouroboros, :name, :vhosts, :authelia, :status, :image, :ports]
@@lengths = Hash.new(0)
def initialize(data)
@strings = {}
@data = data
set :state, (@data[:State]=="running" ? COLOR_GREEN : COLOR_RED) + @data[:State].capitalize + COLOR_RESET
set :dup, @data[:Labels][:"de.fabianonline.dup"]=="true" ? "" : ""
set :ouroboros, @data[:Labels][:"com.centurylinklabs.watchtower.enable"]=="true" ? "" : ""
set :name, @data[:Names].first[1..-1]
vh = @data[:Labels][:"nginx_virtual_host"]&.split(",")&.map{|h| h.split("@").first.strip}
if vh.nil? || vh.count==0
vh = ""
elsif vh.count==1
vh = vh.first
else
if FULL
vh = vh.join(", ")
else
vh = vh.first + ",…"
end
end
set :vhosts, vh
p = @data[:Ports].sort_by{|p| p[:PrivatePort]}.collect do |p|
type = p[:Type]=="tcp" ? "" : "/#{p[:Type]}"
if p[:PrivatePort]==p[:PublicPort]
"#{COLOR_GREEN}#{p[:PrivatePort]}#{type}"
elsif p[:PublicPort]==nil
"#{COLOR_GRAY}#{p[:PrivatePort]}#{type}"
else
"#{COLOR_RED}#{p[:PrivatePort]}->#{p[:PublicPort]}#{type}"
end
end.uniq.join(" ")
#set :nginx_allow, @data[:Labels][:"nginx_allow"]
if vh==""
set :authelia, ""
elsif @data[:Labels][:"authelia_policy"]=="one_factor"
set :authelia, "1#{COLOR_GRAY}FA#{COLOR_RESET}"
elsif @data[:Labels][:"authelia_policy"]=="two_factor"
set :authelia, "2#{COLOR_GRAY}FA#{COLOR_RESET}"
elsif @data[:Labels][:"authelia_policy"]=="bypass"
set :authelia, "#{COLOR_GREEN}BYP#{COLOR_RESET}"
elsif @data[:Labels][:"authelia_policy"]=="none"
set :authelia, "#{COLOR_GREEN}NONE#{COLOR_RESET}"
else
set :authelia, "#{COLOR_RED}?#{COLOR_RESET}"
end
st = @data[:Status]
if st.end_with?("(healthy)")
st = COLOR_GREEN + st.gsub("(healthy)", "(v)") + COLOR_RESET
elsif st.end_with?("(unhealthy)")
st = COLOR_RED + st.gsub("(unhealthy)", "(x)") + COLOR_RESET
end
set :status, st
im = @data[:Image]
im = im.split(":")[0] unless FULL
set :image, im
set :ports, p
end
def set(key, value)
@data[key] = value
@@lengths[key] = [@@lengths[key], value.cleaned.length].max if value
end
def self.lengths; FIELDS.map{|k| @@lengths[k]}; end
def data
FIELDS.map{|k| @data[k]}
end
end
class String
def cleaned
self.gsub(/\[.+?m/, "")
end
def fix_length(len)
l = self.cleaned.length
shortened = self.length - l
if l >= len
return self.slice(0, len + shortened)
else
return self + (" " * (len - l))
end
end
end
def fetch_data
socket = UNIXSocket.new("/var/run/docker.sock")
request = "GET /v1.24/containers/json?all=1 HTTP/1.0\r\n\r\n"#Host: localhost\r\n\r\n"
socket.write(request)
response = ""
loop do
break if socket.eof?
line = socket.gets
break if line=="\r\n"
end
until socket.eof?
line = socket.gets
response += line
end
return JSON.parse(response, symbolize_names: true)
end
FULL = ARGV[0]=="--full"
data = fetch_data
data = data.map{|c| Container.new(c).data}
lengths = Container.lengths
data.sort_by{|d| d[3]}.each do |row|
row.each_with_index do |d, index|
if index==row.length-1
print d.to_s
else
print d.to_s.fix_length(lengths[index]) + " "
end
end
puts
end