Example #1
0
func getProviderDnsRecords() (map[string]utils.DnsRecord, error) {
	allRecords, err := provider.GetRecords()
	if err != nil {
		return nil, err
	}

	ourRecords := make(map[string]utils.DnsRecord, len(allRecords))
	if len(allRecords) == 0 {
		return ourRecords, nil
	}

	stateFqdn := utils.StateFqdn(m.EnvironmentUUID, config.RootDomainName)
	ourFqdns := make(map[string]struct{})

	// Get the FQDNs that were created by us from the state RRSet
	logrus.Debugf("Checking for state RRSet %s", stateFqdn)
	for _, rec := range allRecords {
		if rec.Fqdn == stateFqdn && rec.Type == "TXT" {
			logrus.Debugf("FQDNs from state RRSet: %v", rec.Records)
			for _, value := range rec.Records {
				ourFqdns[value] = struct{}{}
			}
			ourRecords[stateFqdn] = rec
			break
		}
	}

	for _, rec := range allRecords {
		_, ok := ourFqdns[rec.Fqdn]
		if ok && rec.Type == "A" {
			ourRecords[rec.Fqdn] = rec
		}
	}
	return ourRecords, nil
}
Example #2
0
func (m *MetadataClient) getContainersDnsRecords(dnsEntries map[string]utils.DnsRecord) error {
	services, err := m.MetadataClient.GetServices()
	if err != nil {
		return err
	}

	ourFqdns := make(map[string]struct{})
	hostMeta := make(map[string]metadata.Host)
	for _, service := range services {
		if service.Kind != "service" && service.Kind != "loadBalancerService" {
			continue
		}

		for _, container := range service.Containers {
			if len(container.Ports) == 0 || !containerStateOK(container) {
				continue
			}

			hostUUID := container.HostUUID
			if len(hostUUID) == 0 {
				logrus.Debugf("Container's %v host_uuid is empty", container.Name)
				continue
			}

			var host metadata.Host
			if _, ok := hostMeta[hostUUID]; ok {
				host = hostMeta[hostUUID]
			} else {
				host, err = m.MetadataClient.GetHost(hostUUID)
				if err != nil {
					logrus.Warnf("Failed to get host metadata: %v", err)
					continue
				}
				hostMeta[hostUUID] = host
			}

			ip, ok := host.Labels["io.rancher.host.external_dns_ip"]
			if !ok || ip == "" {
				ip = host.AgentIP
			}

			fqdn := utils.FqdnFromTemplate(config.NameTemplate, container.ServiceName, container.StackName,
				m.EnvironmentName, config.RootDomainName)
			records := []string{ip}
			dnsEntry := utils.DnsRecord{fqdn, records, "A", config.TTL}

			addToDnsEntries(dnsEntry, dnsEntries)
			ourFqdns[fqdn] = struct{}{}
		}
	}

	if len(ourFqdns) > 0 {
		fqdn := utils.StateFqdn(m.EnvironmentUUID, config.RootDomainName)
		stateRec := utils.StateRecord(fqdn, config.TTL, ourFqdns)
		addToDnsEntries(stateRec, dnsEntries)
	}

	return nil
}
Example #3
0
// upgrade path from previous versions of external-dns.
// checks for any pre-existing A records with names matching the legacy
// suffix and TTLs matching the value of config.TTL. If any are found,
// a state RRSet is created in the zone using the FQDNs of the records
// as values.
func EnsureUpgradeToStateRRSet() error {
	allRecords, err := provider.GetRecords()
	if err != nil {
		return err
	}

	stateFqdn := utils.StateFqdn(m.EnvironmentUUID, config.RootDomainName)
	logrus.Debugf("Checking for state RRSet %s", stateFqdn)
	for _, rec := range allRecords {
		if rec.Fqdn == stateFqdn && rec.Type == "TXT" {
			logrus.Debugf("Found state RRSet with %d records", len(rec.Records))
			return nil
		}
	}

	logrus.Debug("State RRSet not found")
	ourFqdns := make(map[string]struct{})
	// records created by previous versions will match this suffix
	joins := []string{m.EnvironmentName, config.RootDomainName}
	suffix := "." + strings.ToLower(strings.Join(joins, "."))
	for _, rec := range allRecords {
		if rec.Type == "A" && strings.HasSuffix(rec.Fqdn, suffix) && rec.TTL == config.TTL {
			ourFqdns[rec.Fqdn] = struct{}{}
		}
	}

	if len(ourFqdns) > 0 {
		logrus.Infof("Creating RRSet '%s TXT' for %d pre-existing records", stateFqdn, len(ourFqdns))
		stateRec := utils.StateRecord(stateFqdn, config.TTL, ourFqdns)
		if err := provider.AddRecord(stateRec); err != nil {
			return fmt.Errorf("Failed to add RRSet to provider %v: %v", stateRec, err)
		}
	}

	return nil
}