func parseConfig()

in cmd/root.go [713:929]


func parseConfig(cmd *Command, conf *proxy.Config, args []string) error {
	// If no instance connection names were provided AND FUSE isn't enabled,
	// error.
	if len(args) == 0 && conf.FUSEDir == "" {
		return newBadCommandError("missing instance_connection_name (e.g., project:region:instance)")
	}

	if conf.FUSEDir != "" {
		if conf.RunConnectionTest {
			return newBadCommandError("cannot run connection tests in FUSE mode")
		}

		if err := proxy.SupportsFUSE(); err != nil {
			return newBadCommandError(
				fmt.Sprintf("--fuse is not supported: %v", err),
			)
		}
	}

	if len(args) == 0 && conf.FUSEDir == "" && conf.FUSETempDir != "" {
		return newBadCommandError("cannot specify --fuse-tmp-dir without --fuse")
	}

	if userHasSetLocal(cmd, "address") && userHasSetLocal(cmd, "unix-socket") {
		return newBadCommandError("cannot specify --unix-socket and --address together")
	}
	if userHasSetLocal(cmd, "port") && userHasSetLocal(cmd, "unix-socket") {
		return newBadCommandError("cannot specify --unix-socket and --port together")
	}
	if ip := net.ParseIP(conf.Addr); ip == nil {
		return newBadCommandError(fmt.Sprintf("not a valid IP address: %q", conf.Addr))
	}
	if userHasSetLocal(cmd, "private-ip") && userHasSetLocal(cmd, "auto-ip") {
		return newBadCommandError("cannot specify --private-ip and --auto-ip together")
	}

	// If more than one IP type is set, error.
	if conf.PrivateIP && conf.PSC {
		return newBadCommandError("cannot specify --private-ip and --psc flags at the same time")
	}

	// If more than one auth method is set, error.
	if conf.Token != "" && conf.CredentialsFile != "" {
		return newBadCommandError("cannot specify --token and --credentials-file flags at the same time")
	}
	if conf.Token != "" && conf.GcloudAuth {
		return newBadCommandError("cannot specify --token and --gcloud-auth flags at the same time")
	}
	if conf.CredentialsFile != "" && conf.GcloudAuth {
		return newBadCommandError("cannot specify --credentials-file and --gcloud-auth flags at the same time")
	}
	if conf.CredentialsJSON != "" && conf.Token != "" {
		return newBadCommandError("cannot specify --json-credentials and --token flags at the same time")
	}
	if conf.CredentialsJSON != "" && conf.CredentialsFile != "" {
		return newBadCommandError("cannot specify --json-credentials and --credentials-file flags at the same time")
	}
	if conf.CredentialsJSON != "" && conf.GcloudAuth {
		return newBadCommandError("cannot specify --json-credentials and --gcloud-auth flags at the same time")
	}

	// When using token with auto-iam-authn, login-token must also be set.
	// All three are required together.
	if conf.IAMAuthN && conf.Token != "" && conf.LoginToken == "" {
		return newBadCommandError("cannot specify --auto-iam-authn and --token without --login-token")
	}
	if conf.IAMAuthN && conf.GcloudAuth {
		return newBadCommandError(`cannot use --auto-iam-authn with --gcloud-auth.
Instead use Application Default Credentials (enabled with: gcloud auth application-default login)
and re-try with just --auto-iam-authn`)
	}
	if conf.LoginToken != "" && (conf.Token == "" || !conf.IAMAuthN) {
		return newBadCommandError("cannot specify --login-token without --token and --auto-iam-authn")
	}

	if userHasSetGlobal(cmd, "http-port") && !userHasSetLocal(cmd, "prometheus") && !userHasSetLocal(cmd, "health-check") {
		cmd.logger.Infof("Ignoring --http-port because --prometheus or --health-check was not set")
	}

	if !userHasSetLocal(cmd, "telemetry-project") && userHasSetLocal(cmd, "telemetry-prefix") {
		cmd.logger.Infof("Ignoring --telementry-prefix because --telemetry-project was not set")
	}
	if !userHasSetLocal(cmd, "telemetry-project") && userHasSetLocal(cmd, "disable-metrics") {
		cmd.logger.Infof("Ignoring --disable-metrics because --telemetry-project was not set")
	}
	if !userHasSetLocal(cmd, "telemetry-project") && userHasSetLocal(cmd, "disable-traces") {
		cmd.logger.Infof("Ignoring --disable-traces because --telemetry-project was not set")
	}

	if userHasSetLocal(cmd, "user-agent") {
		userAgent += " " + cmd.conf.OtherUserAgents
		conf.UserAgent = userAgent
	}

	if userHasSetLocal(cmd, "sqladmin-api-endpoint") && userHasSetLocal(cmd, "universe-domain") {
		return newBadCommandError("cannot specify --sqladmin-api-endpoint and --universe-domain at the same time")
	}
	if userHasSetLocal(cmd, "sqladmin-api-endpoint") && conf.APIEndpointURL != "" {
		_, err := url.Parse(conf.APIEndpointURL)
		if err != nil {
			return newBadCommandError(fmt.Sprintf(
				"the value provided for --sqladmin-api-endpoint is not a valid URL, %v",
				conf.APIEndpointURL,
			))
		}

		// add a trailing '/' if omitted
		if !strings.HasSuffix(conf.APIEndpointURL, "/") {
			conf.APIEndpointURL = conf.APIEndpointURL + "/"
		}
	}

	var ics []proxy.InstanceConnConfig
	for _, a := range args {
		// Assume no query params initially
		ic := proxy.InstanceConnConfig{
			Name: a,
		}
		// If there are query params, update instance config.
		if res := strings.SplitN(a, "?", 2); len(res) > 1 {
			ic.Name = res[0]
			q, err := url.ParseQuery(res[1])
			if err != nil {
				return newBadCommandError(fmt.Sprintf("could not parse query: %q", res[1]))
			}

			a, aok := q["address"]
			p, pok := q["port"]
			u, uok := q["unix-socket"]
			up, upok := q["unix-socket-path"]

			if aok && uok {
				return newBadCommandError("cannot specify both address and unix-socket query params")
			}
			if pok && uok {
				return newBadCommandError("cannot specify both port and unix-socket query params")
			}
			if aok && upok {
				return newBadCommandError("cannot specify both address and unix-socket-path query params")
			}
			if pok && upok {
				return newBadCommandError("cannot specify both port and unix-socket-path query params")
			}
			if uok && upok {
				return newBadCommandError("cannot specify both unix-socket-path and unix-socket query params")
			}

			if aok {
				if len(a) != 1 {
					return newBadCommandError(fmt.Sprintf("address query param should be only one value: %q", a))
				}
				if ip := net.ParseIP(a[0]); ip == nil {
					return newBadCommandError(
						fmt.Sprintf("address query param is not a valid IP address: %q",
							a[0],
						))
				}
				ic.Addr = a[0]
			}

			if pok {
				if len(p) != 1 {
					return newBadCommandError(fmt.Sprintf("port query param should be only one value: %q", a))
				}
				pp, err := strconv.Atoi(p[0])
				if err != nil {
					return newBadCommandError(
						fmt.Sprintf("port query param is not a valid integer: %q",
							p[0],
						))
				}
				ic.Port = pp
			}

			if uok {
				if len(u) != 1 {
					return newBadCommandError(fmt.Sprintf("unix query param should be only one value: %q", a))
				}
				ic.UnixSocket = u[0]
			}

			if upok {
				if len(up) != 1 {
					return newBadCommandError(fmt.Sprintf("unix-socket-path query param should be only one value: %q", a))
				}
				ic.UnixSocketPath = up[0]
			}

			ic.IAMAuthN, err = parseBoolOpt(q, "auto-iam-authn")
			if err != nil {
				return err
			}

			ic.PrivateIP, err = parseBoolOpt(q, "private-ip")
			if err != nil {
				return err
			}
			if ic.PrivateIP != nil && *ic.PrivateIP && conf.AutoIP {
				return newBadCommandError("cannot use --auto-ip with private-ip")
			}

			ic.PSC, err = parseBoolOpt(q, "psc")
			if err != nil {
				return err
			}

			if ic.PrivateIP != nil && ic.PSC != nil {
				return newBadCommandError("cannot specify both private-ip and psc query params")
			}

		}
		ics = append(ics, ic)
	}

	conf.Instances = ics
	return nil
}