Example #1
0
// CreateInterface creates a clouddns.Interface object using the specified parameters.
// If no tokenSource is specified, uses oauth2.DefaultTokenSource.
func CreateInterface(projectID string, tokenSource oauth2.TokenSource) (*Interface, error) {
	if tokenSource == nil {
		var err error
		tokenSource, err = google.DefaultTokenSource(
			oauth2.NoContext,
			compute.CloudPlatformScope,
			compute.ComputeScope)
		glog.Infof("Using DefaultTokenSource %#v", tokenSource)
		if err != nil {
			return nil, err
		}
	} else {
		glog.Infof("Using existing Token Source %#v", tokenSource)
	}

	oauthClient := oauth2.NewClient(oauth2.NoContext, tokenSource)

	service, err := dns.New(oauthClient)
	if err != nil {
		glog.Errorf("Failed to get Cloud DNS client: %v", err)
	}
	glog.Infof("Successfully got DNS service: %v\n", service)
	return newInterfaceWithStub(projectID, internal.NewService(service)), nil
}
Example #2
0
// Periodically populate DNS using the host-inventory:
func Updater(config *types.Config) {

	// Run forever:
	log.Infof("[dnsUpdater] Started")
	for {

		// Sleep until the next run:
		log.Debugf("[dnsUpdater] Sleeping for %vs ...", config.DNSUpdateFrequency)
		time.Sleep(time.Duration(config.DNSUpdateFrequency) * time.Second)

		// Lock the host-list (so we don't try to access it when another go-routine is modifying it):
		log.Tracef("[dnsUpdater] Trying to lock config.HostInventoryMutex ...")
		config.HostInventoryMutex.Lock()
		log.Tracef("[dnsUpdater] Locked config.HostInventoryMutex")

		// See if we actually have any changes to make:
		if len(config.HostInventory.Environments) > 0 {

			// Connect to GCE (either from GCE permissions, JSON file, or ENV-vars):
			client, err := google.DefaultClient(context.Background(), googledns.CloudPlatformScope)
			if err != nil {
				log.Errorf("[dnsUpdater] Unable to authenticate to GCE! (%s)", err)
				continue
			}

			// Get a DNS service-object:
			dnsService, err := googledns.New(client)
			if err != nil {
				log.Errorf("[dnsUpdater] Failed to connecting to GCE! %v", err)
				continue
			}

			// Get the project:
			googleComputeProject, err := metadata.ProjectID()
			if err != nil {
				log.Errorf("[hostInventoryUpdater] Unable to retrieve metadata from instance! (%s)", err)
				continue
			} else {
				log.Debugf("[hostInventoryUpdater] Found project-id (%v)", googleComputeProject)
			}

			// Get a list of pre-existing DNS records in this zone:
			resourceRecordSetsList, err := dnsService.ResourceRecordSets.List(googleComputeProject, config.DNSZoneName).Do()
			if err != nil {
				log.Errorf("[dnsUpdater] Unable to make DNS ResourceRecordSets.List() call! (%s)", err)
				continue
			} else {
				log.Debugf("[dnsUpdater] Found %v pre-existing DNS records", len(resourceRecordSetsList.Rrsets))
			}

			// Go through each environment:
			for environmentName, environment := range config.HostInventory.Environments {

				// Prepare a "change" (which is a list of records to add):
				change := &googledns.Change{
					Additions: []*googledns.ResourceRecordSet{},
				}

				// See if we already have a DNS entry:
				for _, resourceRecordSet := range resourceRecordSetsList.Rrsets {
					record, ok := environment.DNSRecords[resourceRecordSet.Name]
					if ok {
						// See if the record needs to be deleted and changed:
						if fmt.Sprintf("%v", record) == fmt.Sprintf("%v", resourceRecordSet.Rrdatas) {
							// Delete the record from the host-inventory (to prevent it from being created again):
							log.Debugf("[dnsUpdater] Record %v already exists in DNS (%v) - no need to make it again", resourceRecordSet.Name, record)
							delete(environment.DNSRecords, resourceRecordSet.Name)
						} else {
							// The record doesn't match, so we'll ask for it to be deleted:
							change.Deletions = append(change.Deletions, resourceRecordSet)
						}
					}
				}

				// Now iterate over the host-inventory:
				log.Debugf("[dnsUpdater] Creating requests for the '%v' environment ...", environmentName)
				for dnsRecordName, dnsRecordValue := range environment.DNSRecords {

					// Prepare a resourceRecordSet:
					log.Debugf("[dnsUpdater] Record: %v => %v", dnsRecordName, dnsRecordValue)
					change.Additions = append(change.Additions, &googledns.ResourceRecordSet{
						Name:    dnsRecordName,
						Rrdatas: dnsRecordValue,
						Ttl:     config.DNSTTL,
						Type:    "A",
					})

				}

				// Make the Create() call:
				if len(change.Additions) > 0 || len(change.Deletions) > 0 {
					changeMade, err := dnsService.Changes.Create(googleComputeProject, config.DNSZoneName, change).Do()
					if err != nil {
						log.Errorf("[dnsUpdater] Unable to make DNS Changes.Create() call! (%s)", err)
						continue
					} else {
						log.Debugf("[dnsUpdater] Made %v changes to DNS zone (%v), status: %v", len(changeMade.Additions), googleComputeProject, changeMade.Status)
					}
				} else {
					log.Infof("[dnsUpdater] No changes to be made")
				}

			}

		} else {
			log.Info("[dnsUpdater] No DNS changes to make")
		}

		// Unlock the host-inventory:
		log.Tracef("[dnsUpdater] Unlocking config.HostInventoryMutex ...")
		config.HostInventoryMutex.Unlock()

	}

}