ingress bugfix

This commit is contained in:
Chris
2025-12-10 13:38:48 -08:00
parent cea3a4920c
commit 34b79257e5
10 changed files with 61 additions and 39 deletions

View File

@@ -3,15 +3,20 @@ class Networks::CheckDns
expects :ingress, :connection
class << self
def infer_expected_ip(ingress, connection)
def infer_expected_dns(ingress, connection)
ingress.connect(connection)
ip = ingress.ip_address
dns_record = ingress.hostname
if is_private_ip?(ip)
if dns_record[:type] == :ip_address && is_private_ip?(dns_record[:value])
cluster = ingress.service.project.cluster
ip = infer_public_ip_from_cluster(connection)
# This only works if it is a single node cluster like k3s
public_ip = infer_public_ip_from_cluster(connection)
dns_record = {
value: public_ip,
type: :ip_address
}
end
ip
dns_record
end
def is_private_ip?(ip)
@@ -40,7 +45,7 @@ class Networks::CheckDns
executed do |context|
# TODO
expected_ip = infer_expected_ip(context.ingress, context.connection)
expected_ip = infer_expected_dns(context.ingress, context.connection)
context.ingress.service.domains.each do |domain|
ip_addresses = Resolv::DNS.open do |dns|
dns.getresources(domain.domain_name, Resolv::DNS::Resource::IN::A).map do |resource|

View File

@@ -4,7 +4,6 @@ export default class extends Controller {
static targets = ["button", "result"]
async test(event) {
debugger
event.preventDefault()
const form = this.element.closest("form")

View File

@@ -28,27 +28,27 @@ class K8::Stateless::Ingress < K8::Base
results['items'].find { |r| r['metadata']['name'] == "#{@service.project.namespace}-ingress" }
end
def self.ip_address(client)
def self.hostname(client)
service = client.get_services.find { |s| s['metadata']['name'] == 'ingress-nginx-controller' }
if service.nil?
raise "Ingress-nginx-controller service not installed"
end
if service.status.loadBalancer.ingress[0].ip
{
ip: service.status.loadBalancer.ingress[0].ip,
record_type: :a_record
value: service.status.loadBalancer.ingress[0].ip,
type: :ip_address
}
else
{
ip: service.status.loadBalancer.ingress[0].hostname,
record_type: :cname_record
value: service.status.loadBalancer.ingress[0].hostname,
type: :hostname
}
end
end
def ip_address
@ip_address ||= begin
self.class.ip_address(self.client)
def hostname
@hostname ||= begin
self.class.hostname(self.client)
end
rescue StandardError => e
Rails.logger.error("Error getting ingress ip address: #{e.message}")

View File

@@ -224,8 +224,6 @@ module LDAP
"#{username}@#{domain}"
end
# ---------------- GROUP MEMBERSHIP ----------------
def fetch_group_membership(user_entry)
reader_ldap = build_reader_connection
@@ -270,7 +268,7 @@ module LDAP
memo | f
end
group_filter = Net::LDAP::Filter.eq('objectClass', 'groupOfNames') |
group_filter = Net::LDAP::Filter.eq('objectClass', 'groupOfNames') |
Net::LDAP::Filter.eq('objectClass', 'groupOfUniqueNames') |
Net::LDAP::Filter.eq('objectClass', 'posixGroup')

View File

@@ -7,7 +7,7 @@ class Async::K8::CertificateStatusViewModel < Async::BaseViewModel
end
def initial_render
"Certificate Status: <div class='loading loading-spinner loading-sm'></div>"
"<div class='flex items-center gap-2'>Certificate Status: <div class='loading loading-spinner loading-sm'></div></div>"
end
def connection
@@ -15,12 +15,12 @@ class Async::K8::CertificateStatusViewModel < Async::BaseViewModel
end
def async_render
template = <<-HTML
<div>
<div class="flex items-center gap-2">
Certificate Status:
<% if K8::Stateless::Ingress.new(service).connect(connection).certificate_status %>
<span class="text-success ml-2 font-semibold">Issued</span>
<span class="text-success font-semibold">Issued</span>
<% else %>
<span class="text-warning ml-2 font-semibold">Issuing</span>
<span class="text-warning font-semibold">Issuing</span>
<% end %>
</div>
HTML

View File

@@ -12,7 +12,21 @@ class Async::K8::ClusterIpViewModel < Async::BaseViewModel
def async_render
connection = K8::Connection.new(service.project, current_user)
ingress = K8::Stateless::Ingress.new(service)
ip = Networks::CheckDns.infer_expected_ip(ingress, connection)
"<pre class='cursor-pointer' data-controller='clipboard' data-clipboard-text='#{ip}'>#{ip}</pre>"
record = Networks::CheckDns.infer_expected_dns(ingress, connection)
if record[:type] == :ip_address
ip = record[:value]
<<~HTML
<div class='flex items-center gap-2'>
<pre>A Record</pre> / <pre class='cursor-pointer' data-controller='clipboard' data-clipboard-text='#{ip}'>#{ip}</pre>
</div>
HTML
else
hostname = record[:value]
<<~HTML
<div class='flex items-center gap-2'>
<pre>CNAME Record</pre> / <pre class='cursor-pointer' data-controller='clipboard' data-clipboard-text='#{hostname}'>#{hostname}</pre>
</div>
HTML
end
end
end

View File

@@ -29,7 +29,13 @@
<p class="text-sm text-gray-500">Comma separated list of domains to use for this endpoint</p>
</div>
<div class="my-4 alert alert-warning inline-block">
Make sure to create an A Record to <pre class="inline font-semibold cursor-pointer" data-controller="clipboard" data-clipboard-text="<%= @ip_address %>"><%= @ip_address %></pre> for any domain you add here.
Make sure to create an A Record to
<pre
class="inline font-semibold cursor-pointer"
data-controller="clipboard"
data-clipboard-text="<%= @ip_address %>">
<%= @ip_address %>
</pre> for any domain you add here.
</div>
<div class="form-footer">

View File

@@ -9,13 +9,13 @@
<%= render "projects/services/telepresence_guide", cluster: @project.cluster, url: "http://#{service.internal_url}" %>
</div>
<div>
<h2 class="text-xl font-bold">Public Networking</h2>
<hr class="mt-3 mb-4 border-t border-base-300" />
<% if service.allow_public_networking? %>
<% if service.allow_public_networking? %>
<div>
<h2 class="text-xl font-bold">Public Networking</h2>
<hr class="mt-3 mb-4 border-t border-base-300" />
<div class="form-control form-group">
<%= render "projects/services/domains/index", service: service %>
</div>
<% end %>
</div>
</div>
<% end %>
</div>

View File

@@ -2,7 +2,7 @@
<thead>
<tr>
<th>Domain</th>
<th>A Record</th>
<th>DNS Type / Value</th>
<th>DNS Status</th>
<th></th>
</tr>

View File

@@ -8,25 +8,25 @@ RSpec.describe Networks::CheckDns do
let(:connection) { K8::Connection.new(cluster, user) }
let(:ingress) { K8::Stateless::Ingress.new(service).connect(connection) }
describe '.infer_expected_ip' do
describe '.infer_expected_dns' do
context 'when ingress returns public IP' do
before do
allow(ingress).to receive(:ip_address).and_return('8.8.8.8')
allow(ingress).to receive(:hostname).and_return({ value: '8.8.8.8', type: :ip_address })
end
it 'returns the IP' do
expect(described_class.infer_expected_ip(ingress, connection)).to eq('8.8.8.8')
expect(described_class.infer_expected_dns(ingress, connection)).to eq({ value: "8.8.8.8", type: :ip_address })
end
end
context 'when ingress returns private IP' do
before do
allow(ingress).to receive(:ip_address).and_return('10.0.0.1')
allow(ingress).to receive(:hostname).and_return({ value: '10.0.0.1', type: :ip_address })
allow(Resolv).to receive(:getaddress).with('example.com').and_return('1.2.3.4')
end
it 'resolves and returns public IP' do
expect(described_class.infer_expected_ip(ingress, connection)).to eq('1.2.3.4')
expect(described_class.infer_expected_dns(ingress, connection)).to eq({ value: "1.2.3.4", type: :ip_address })
end
end
@@ -45,11 +45,11 @@ RSpec.describe Networks::CheckDns do
end
before do
allow(ingress).to receive(:ip_address).and_return('10.0.0.1')
allow(ingress).to receive(:hostname).and_return({ value: '1.2.3.4', type: :ip_address })
end
it 'returns the hostname IP' do
expect(described_class.infer_expected_ip(ingress, connection)).to eq('1.2.3.4')
expect(described_class.infer_expected_dns(ingress, connection)).to eq({ value: "1.2.3.4", type: :ip_address })
end
end
end