func()

in google_guest_agent/non_windows_accounts.go [113:197]


func (a *accountsMgr) Set(ctx context.Context) error {
	config := cfg.Get()

	if sshKeys == nil {
		logger.Debugf("initialize sshKeys map")
		sshKeys = make(map[string][]string)
	}

	logger.Debugf("create sudoers file if needed")
	if err := createSudoersFile(); err != nil {
		logger.Errorf("Error creating google-sudoers file: %v.", err)
	}
	logger.Debugf("create sudoers group if needed")
	if err := createSudoersGroup(ctx, config); err != nil {
		logger.Errorf("Error creating google-sudoers group: %v.", err)
	}

	mdkeys := newMetadata.Instance.Attributes.SSHKeys
	if !newMetadata.Instance.Attributes.BlockProjectKeys {
		mdkeys = append(mdkeys, newMetadata.Project.Attributes.SSHKeys...)
	}

	mdKeyMap := getUserKeys(mdkeys)

	logger.Debugf("read google users file")
	gUsers, err := readGoogleUsersFile()
	if err != nil {
		// TODO: is this OK to continue past?
		logger.Errorf("Couldn't read google_users file: %v.", err)
	}

	// Update SSH keys, creating Google users as needed.
	for user, userKeys := range mdKeyMap {
		if _, err := getPasswd(user); err != nil {
			logger.Infof("Creating user %s.", user)
			if err := createGoogleUser(ctx, config, user); err != nil {
				logger.Errorf("Error creating user: %s.", err)
				continue
			}
			gUsers[user] = ""
		}
		if _, ok := gUsers[user]; !ok {
			logger.Infof("Adding existing user %s to google-sudoers group.", user)
			if err := addUserToGroup(ctx, user, "google-sudoers"); err != nil {
				logger.Errorf("%v.", err)
			}
		}
		if !compareStringSlice(userKeys, sshKeys[user]) {
			logger.Infof("Updating keys for user %s.", user)
			if err := updateAuthorizedKeysFile(ctx, user, userKeys); err != nil {
				logger.Errorf("Error updating SSH keys for %s: %v.", user, err)
				continue
			}
			sshKeys[user] = userKeys
		}
	}

	// Remove Google users not found in metadata.
	for user := range gUsers {
		if _, ok := mdKeyMap[user]; !ok && user != "" {
			logger.Infof("Removing user %s.", user)
			err = removeGoogleUser(ctx, config, user)
			if err != nil {
				logger.Errorf("Error removing user: %v.", err)
			}
			delete(sshKeys, user)
		}
	}

	// Update the google_users file if we've added or removed any users.
	logger.Debugf("write google_users file")
	if err := writeGoogleUsersFile(); err != nil {
		logger.Errorf("Error writing google_users file: %v.", err)
	}

	// Start SSHD if not started. We do this in agent instead of adding a
	// Wants= directive, and here instead of instance setup, so that this
	// can be disabled by the instance configs file.
	for _, svc := range []string{"ssh", "sshd"} {
		// Ignore output, it's just a best effort.
		systemctlStart(ctx, svc)
	}

	return nil
}