func GenerateToken(s *kubeadmapi.Secrets) error {
	_, tokenID, err := RandBytes(TokenIDLen / 2)
	if err != nil {
		return err
	}

	tokenBytes, token, err := RandBytes(TokenBytes)
	if err != nil {
		return err
	}

	s.TokenID = tokenID
	s.BearerToken = token
	s.Token = tokenBytes
	s.GivenToken = fmt.Sprintf("%s.%s", tokenID, token)
	return nil
}
func UseGivenTokenIfValid(s *kubeadmapi.Secrets) (bool, error) {
	if s.GivenToken == "" {
		return false, nil // not given
	}
	fmt.Println("<util/tokens> validating provided token")
	givenToken := strings.Split(strings.ToLower(s.GivenToken), ".")
	// TODO(phase1+) could also print more specific messages in each case
	invalidErr := "<util/tokens> provided token does not match expected <6 characters>.<16 characters> format - %s"
	if len(givenToken) != 2 {
		return false, fmt.Errorf(invalidErr, "not in 2-part dot-separated format")
	}
	if len(givenToken[0]) != TokenIDLen {
		return false, fmt.Errorf(invalidErr, fmt.Sprintf(
			"length of first part is incorrect [%d (given) != %d (expected) ]",
			len(givenToken[0]), TokenIDLen))
	}
	tokenBytes := []byte(givenToken[1])
	s.TokenID = givenToken[0]
	s.BearerToken = givenToken[1]
	s.Token = tokenBytes
	return true, nil // given and valid
}