Skip to content
This repository has been archived by the owner on Jun 25, 2024. It is now read-only.

Commit

Permalink
Merge pull request #755 from bshephar/dnsDataStruct
Browse files Browse the repository at this point in the history
This change introduces a struct for DNS configuration items.
  • Loading branch information
openshift-merge-bot[bot] authored Mar 12, 2024
2 parents 2257ed7 + 44a74c2 commit 39da141
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 53 deletions.
16 changes: 8 additions & 8 deletions controllers/openstackdataplanenodeset_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -231,16 +231,17 @@ func (r *OpenStackDataPlaneNodeSetReconciler) Reconcile(ctx context.Context, req
}

// Ensure DNSData Required for Nodes
dnsAddresses, dnsClusterAddresses, ctlplaneSearchDomain, isReady, allHostnames, allIPs, err := deployment.EnsureDNSData(
dnsData := deployment.DataplaneDNSData{}
dnsData.EnsureDNSData(
ctx, helper,
instance, allIPSets)
if err != nil || !isReady {
return ctrl.Result{}, err
}
instance.Status.DNSClusterAddresses = dnsClusterAddresses
instance.Status.CtlplaneSearchDomain = ctlplaneSearchDomain
instance.Status.AllHostnames = allHostnames
instance.Status.AllIPs = allIPs
instance.Status.DNSClusterAddresses = dnsData.ClusterAddresses
instance.Status.CtlplaneSearchDomain = dnsData.CtlplaneSearchDomain
instance.Status.AllHostnames = dnsData.Hostnames
instance.Status.AllIPs = dnsData.AllIPs

ansibleSSHPrivateKeySecret := instance.Spec.NodeTemplate.AnsibleSSHPrivateKeySecret

Expand All @@ -259,7 +260,6 @@ func (r *OpenStackDataPlaneNodeSetReconciler) Reconcile(ctx context.Context, req
helper.GetClient(),
time.Second*5,
)

if err != nil {
if (result != ctrl.Result{}) {
instance.Status.Conditions.MarkFalse(
Expand Down Expand Up @@ -287,7 +287,7 @@ func (r *OpenStackDataPlaneNodeSetReconciler) Reconcile(ctx context.Context, req
instance.Status.Conditions.MarkUnknown(dataplanev1.NodeSetBareMetalProvisionReadyCondition,
condition.InitReason, condition.InitReason)
isReady, err := deployment.DeployBaremetalSet(ctx, helper, instance,
allIPSets, dnsAddresses)
allIPSets, dnsData.ServerAddresses)
if err != nil || !isReady {
return ctrl.Result{}, err
}
Expand All @@ -302,7 +302,7 @@ func (r *OpenStackDataPlaneNodeSetReconciler) Reconcile(ctx context.Context, req

// Generate NodeSet Inventory
_, err = deployment.GenerateNodeSetInventory(ctx, helper, instance,
allIPSets, dnsAddresses, dataplaneAnsibleImageDefaults)
allIPSets, dnsData.ServerAddresses, dataplaneAnsibleImageDefaults)
if err != nil {
errorMsg := fmt.Sprintf("Unable to generate inventory for %s", instance.Name)
util.LogErrorForObject(helper, err, errorMsg, instance)
Expand Down
108 changes: 63 additions & 45 deletions pkg/deployment/ipam.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,8 @@ import (

// EnsureIPSets Creates the IPSets
func EnsureIPSets(ctx context.Context, helper *helper.Helper,
instance *dataplanev1.OpenStackDataPlaneNodeSet) (map[string]infranetworkv1.IPSet, bool, error) {
instance *dataplanev1.OpenStackDataPlaneNodeSet,
) (map[string]infranetworkv1.IPSet, bool, error) {
allIPSets, err := reserveIPs(ctx, helper, instance)
if err != nil {
instance.Status.Conditions.MarkFalse(
Expand All @@ -60,29 +61,44 @@ func EnsureIPSets(ctx context.Context, helper *helper.Helper,
dataplanev1.NodeSetIPReservationReadyCondition,
dataplanev1.NodeSetIPReservationReadyMessage)
return allIPSets, true, nil
}

// DataplaneDNSData holds information relevant to the OpenStack DNS configuration of the cluster.
type DataplaneDNSData struct {
// ServerAddresses holds a slice of DNS servers in the environment
ServerAddresses []string
// ClusterAddresses holds a slice of Kubernetes service ClusterIPs for the DNSMasq services
ClusterAddresses []string
// CtlplaneSearchDomain is the search domain provided by IPAM
CtlplaneSearchDomain string
// Ready indicates the ready status of the DNS service
Ready bool
// Hostnames is a map of hostnames provided by the NodeSet to the FQDNs
Hostnames map[string]map[infranetworkv1.NetNameStr]string
// AllIPs holds a map of all IP addresses per hostname.
AllIPs map[string]map[infranetworkv1.NetNameStr]string
// Err holds any errors returned from the Kubernetes API while retrieving data.
Err error
}

// createOrPatchDNSData builds the DNSData
func createOrPatchDNSData(ctx context.Context, helper *helper.Helper,
func (dns *DataplaneDNSData) createOrPatchDNSData(ctx context.Context, helper *helper.Helper,
instance *dataplanev1.OpenStackDataPlaneNodeSet,
allIPSets map[string]infranetworkv1.IPSet) (
string, map[string]map[infranetworkv1.NetNameStr]string,
map[string]map[infranetworkv1.NetNameStr]string, error) {

allIPSets map[string]infranetworkv1.IPSet,
) error {
var allDNSRecords []infranetworkv1.DNSHost
var ctlplaneSearchDomain string
allHostnames := map[string]map[infranetworkv1.NetNameStr]string{}
allIPs := map[string]map[infranetworkv1.NetNameStr]string{}
dns.Hostnames = map[string]map[infranetworkv1.NetNameStr]string{}
dns.AllIPs = map[string]map[infranetworkv1.NetNameStr]string{}

// Build DNSData CR
for _, node := range instance.Spec.Nodes {
var shortName string
nets := node.Networks
hostName := node.HostName

allHostnames[hostName] = map[infranetworkv1.NetNameStr]string{}
allIPs[hostName] = map[infranetworkv1.NetNameStr]string{}
dns.Hostnames[hostName] = map[infranetworkv1.NetNameStr]string{}
dns.AllIPs[hostName] = map[infranetworkv1.NetNameStr]string{}

shortName = strings.Split(hostName, ".")[0]
if len(nets) == 0 {
Expand All @@ -100,19 +116,19 @@ func createOrPatchDNSData(ctx context.Context, helper *helper.Helper,
fqdnName := strings.Join([]string{shortName, res.DNSDomain}, ".")
if fqdnName != hostName {
fqdnNames = append(fqdnNames, fqdnName)
allHostnames[hostName][res.Network] = fqdnName
dns.Hostnames[hostName][res.Network] = fqdnName
}
if dataplanev1.NodeHostNameIsFQDN(hostName) && netLower == CtlPlaneNetwork {
fqdnNames = append(fqdnNames, hostName)
allHostnames[hostName][infranetworkv1.NetNameStr(netLower)] = hostName
dns.Hostnames[hostName][infranetworkv1.NetNameStr(netLower)] = hostName
}
allIPs[hostName][infranetworkv1.NetNameStr(netLower)] = res.Address
dns.AllIPs[hostName][infranetworkv1.NetNameStr(netLower)] = res.Address
dnsRecord.Hostnames = fqdnNames
allDNSRecords = append(allDNSRecords, dnsRecord)
// Adding only ctlplane domain for ansibleee.
// TODO (rabi) This is not very efficient.
if netLower == CtlPlaneNetwork && ctlplaneSearchDomain == "" {
ctlplaneSearchDomain = res.DNSDomain
dns.CtlplaneSearchDomain = res.DNSDomain
}
}
}
Expand All @@ -136,50 +152,47 @@ func createOrPatchDNSData(ctx context.Context, helper *helper.Helper,
return err
})
if err != nil {
return "", allHostnames, allIPs, err
return err
}
return ctlplaneSearchDomain, allHostnames, allIPs, nil

return nil
}

// EnsureDNSData Ensures DNSData is created
func EnsureDNSData(ctx context.Context, helper *helper.Helper,
func (dns *DataplaneDNSData) EnsureDNSData(ctx context.Context, helper *helper.Helper,
instance *dataplanev1.OpenStackDataPlaneNodeSet,
allIPSets map[string]infranetworkv1.IPSet) (
[]string, []string, string, bool, map[string]map[infranetworkv1.NetNameStr]string,
map[string]map[infranetworkv1.NetNameStr]string, error) {

allIPSets map[string]infranetworkv1.IPSet,
) {
// Verify dnsmasq CR exists
dnsAddresses, dnsClusterAddresses, isReady, err := CheckDNSService(
dns.CheckDNSService(
ctx, helper, instance)

if err != nil || !isReady || dnsClusterAddresses == nil {
if err != nil {
if dns.Err != nil || !dns.Ready || dns.ClusterAddresses == nil {
if dns.Err != nil {
instance.Status.Conditions.MarkFalse(
dataplanev1.NodeSetDNSDataReadyCondition,
condition.ErrorReason, condition.SeverityError,
dataplanev1.NodeSetDNSDataReadyErrorMessage)
}
if !isReady {
if !dns.Ready {
instance.Status.Conditions.MarkFalse(
dataplanev1.NodeSetDNSDataReadyCondition,
condition.RequestedReason, condition.SeverityInfo,
dataplanev1.NodeSetDNSDataReadyWaitingMessage)
}
if dnsClusterAddresses == nil {
if dns.ClusterAddresses == nil {
instance.Status.Conditions.Remove(dataplanev1.NodeSetDNSDataReadyCondition)
}
return nil, nil, "", isReady, nil, nil, err
return
}
// Create or Patch DNSData
ctlplaneSearchDomain, allHostnames, allIPs, err := createOrPatchDNSData(
err := dns.createOrPatchDNSData(
ctx, helper, instance, allIPSets)
if err != nil {
instance.Status.Conditions.MarkFalse(
dataplanev1.NodeSetDNSDataReadyCondition,
condition.ErrorReason, condition.SeverityError,
dataplanev1.NodeSetDNSDataReadyErrorMessage)
return nil, nil, "", false, nil, nil, err
return
}

dnsData := &infranetworkv1.DNSData{
Expand All @@ -195,7 +208,7 @@ func EnsureDNSData(ctx context.Context, helper *helper.Helper,
dataplanev1.NodeSetDNSDataReadyCondition,
condition.ErrorReason, condition.SeverityError,
dataplanev1.NodeSetDNSDataReadyErrorMessage)
return nil, nil, "", false, nil, nil, err
return
}

if !dnsData.IsReady() {
Expand All @@ -204,18 +217,19 @@ func EnsureDNSData(ctx context.Context, helper *helper.Helper,
dataplanev1.NodeSetDNSDataReadyCondition,
condition.RequestedReason, condition.SeverityInfo,
dataplanev1.NodeSetDNSDataReadyWaitingMessage)
return nil, nil, "", false, nil, nil, nil
dns.Ready = false
return
}
instance.Status.Conditions.MarkTrue(
dataplanev1.NodeSetDNSDataReadyCondition,
dataplanev1.NodeSetDNSDataReadyMessage)
return dnsAddresses, dnsClusterAddresses, ctlplaneSearchDomain, true, allHostnames, allIPs, nil
dns.Ready = true
}

// reserveIPs Reserves IPs by creating IPSets
func reserveIPs(ctx context.Context, helper *helper.Helper,
instance *dataplanev1.OpenStackDataPlaneNodeSet) (map[string]infranetworkv1.IPSet, error) {

instance *dataplanev1.OpenStackDataPlaneNodeSet,
) (map[string]infranetworkv1.IPSet, error) {
// Verify NetConfig CRs exist
netConfigList := &infranetworkv1.NetConfigList{}
listOpts := []client.ListOption{
Expand Down Expand Up @@ -272,24 +286,28 @@ func reserveIPs(ctx context.Context, helper *helper.Helper,
}

// CheckDNSService checks if DNS is configured and ready
func CheckDNSService(ctx context.Context, helper *helper.Helper,
instance client.Object) ([]string, []string, bool, error) {
func (dns *DataplaneDNSData) CheckDNSService(ctx context.Context, helper *helper.Helper,
instance client.Object,
) {
dnsmasqList := &infranetworkv1.DNSMasqList{}
listOpts := []client.ListOption{
client.InNamespace(instance.GetNamespace()),
}
err := helper.GetClient().List(ctx, dnsmasqList, listOpts...)
if err != nil {
return nil, nil, false, err
dns.Err = helper.GetClient().List(ctx, dnsmasqList, listOpts...)
if dns.Err != nil {
dns.Ready = false
return
}
if len(dnsmasqList.Items) == 0 {
util.LogForObject(helper, "No DNSMasq CR exists yet, DNS Service won't be used", instance)
return nil, nil, true, nil
dns.Ready = true
return
} else if !dnsmasqList.Items[0].IsReady() {
util.LogForObject(helper, "DNSMasq service exists, but not ready yet ", instance)
return nil, nil, false, nil
dns.Ready = false
return
}
dnsClusterAddresses := dnsmasqList.Items[0].Status.DNSClusterAddresses
dnsAddresses := dnsmasqList.Items[0].Status.DNSAddresses
return dnsAddresses, dnsClusterAddresses, true, nil
dns.ClusterAddresses = dnsmasqList.Items[0].Status.DNSClusterAddresses
dns.ServerAddresses = dnsmasqList.Items[0].Status.DNSAddresses
dns.Ready = true
}

0 comments on commit 39da141

Please sign in to comment.