fix(source/cloud-sql-mssql): remove ip address field (#1822)

## Description

Removing the `ipAddress` field since it is not an input for Cloud SQL
SQL Server source.

Kept the variable in Source's config but removed this variable from
everywhere else in the code. This will PREVENT a breaking change since
the validator won't flag it as an "extra field".

**Will have to update the following as well:**
(1) Cloud docs
https://cloud.google.com/sql/docs/sqlserver/pre-built-tools-with-mcp-toolbox
(2) gemini-cli-extensions
https://github.com/gemini-cli-extensions/cloud-sql-sqlserver

## PR Checklist

> Thank you for opening a Pull Request! Before submitting your PR, there
are a
> few things you can do to make sure it goes smoothly:

- [x] Make sure you reviewed

[CONTRIBUTING.md](https://github.com/googleapis/genai-toolbox/blob/main/CONTRIBUTING.md)
- [x] Make sure to open an issue as a

[bug/issue](https://github.com/googleapis/genai-toolbox/issues/new/choose)
  before writing your code! That way we can discuss the change, evaluate
  designs, and agree on the general idea
- [x] Ensure the tests and linter pass
- [x] Code coverage does not decrease (if any source code was changed)
- [x] Appropriate docs were updated (if necessary)
- [x] Make sure to add `!` if this involve a breaking change

🛠️ Fixes #1549
This commit is contained in:
Yuan Teoh
2025-10-30 17:14:19 -07:00
committed by GitHub
parent ef28e39e90
commit 38d535de34
7 changed files with 53 additions and 41 deletions

View File

@@ -264,7 +264,6 @@ details on how to connect your AI tools (IDEs) to databases via Toolbox and MCP.
* `CLOUD_SQL_MSSQL_REGION`: The region of your Cloud SQL instance. * `CLOUD_SQL_MSSQL_REGION`: The region of your Cloud SQL instance.
* `CLOUD_SQL_MSSQL_INSTANCE`: The ID of your Cloud SQL instance. * `CLOUD_SQL_MSSQL_INSTANCE`: The ID of your Cloud SQL instance.
* `CLOUD_SQL_MSSQL_DATABASE`: The name of the database to connect to. * `CLOUD_SQL_MSSQL_DATABASE`: The name of the database to connect to.
* `CLOUD_SQL_MSSQL_IP_ADDRESS`: The IP address of the Cloud SQL instance.
* `CLOUD_SQL_MSSQL_USER`: The database username. * `CLOUD_SQL_MSSQL_USER`: The database username.
* `CLOUD_SQL_MSSQL_PASSWORD`: The password for the database user. * `CLOUD_SQL_MSSQL_PASSWORD`: The password for the database user.
* `CLOUD_SQL_MSSQL_IP_TYPE`: (Optional) The IP type i.e. "Public" or * `CLOUD_SQL_MSSQL_IP_TYPE`: (Optional) The IP type i.e. "Public" or

View File

@@ -94,7 +94,6 @@ sources:
region: my-region region: my-region
instance: my-instance instance: my-instance
database: my_db database: my_db
ipAddress: localhost
user: ${USER_NAME} user: ${USER_NAME}
password: ${PASSWORD} password: ${PASSWORD}
# ipType: private # ipType: private
@@ -114,7 +113,6 @@ instead of hardcoding your secrets into the configuration file.
| region | string | true | Name of the GCP region that the cluster was created in (e.g. "us-central1"). | | region | string | true | Name of the GCP region that the cluster was created in (e.g. "us-central1"). |
| instance | string | true | Name of the Cloud SQL instance within the cluster (e.g. "my-instance"). | | instance | string | true | Name of the Cloud SQL instance within the cluster (e.g. "my-instance"). |
| database | string | true | Name of the Cloud SQL database to connect to (e.g. "my_db"). | | database | string | true | Name of the Cloud SQL database to connect to (e.g. "my_db"). |
| ipAddress | string | true | IP address of the Cloud SQL instance to connect to. |
| user | string | true | Name of the SQL Server user to connect as (e.g. "my-pg-user"). | | user | string | true | Name of the SQL Server user to connect as (e.g. "my-pg-user"). |
| password | string | true | Password of the SQL Server user (e.g. "my-password"). | | password | string | true | Password of the SQL Server user (e.g. "my-password"). |
| ipType | string | false | IP Type of the Cloud SQL instance, must be either `public`, `private`, or `psc`. Default: `public`. | | ipType | string | false | IP Type of the Cloud SQL instance, must be either `public`, `private`, or `psc`. Default: `public`. |

View File

@@ -73,4 +73,4 @@ tools:
toolsets: toolsets:
cloud_sql_mssql_cloud_monitoring_tools: cloud_sql_mssql_cloud_monitoring_tools:
- get_system_metrics - get_system_metrics

View File

@@ -19,7 +19,6 @@ sources:
region: ${CLOUD_SQL_MSSQL_REGION} region: ${CLOUD_SQL_MSSQL_REGION}
instance: ${CLOUD_SQL_MSSQL_INSTANCE} instance: ${CLOUD_SQL_MSSQL_INSTANCE}
database: ${CLOUD_SQL_MSSQL_DATABASE} database: ${CLOUD_SQL_MSSQL_DATABASE}
ipAddress: ${CLOUD_SQL_MSSQL_IP_ADDRESS}
user: ${CLOUD_SQL_MSSQL_USER} user: ${CLOUD_SQL_MSSQL_USER}
password: ${CLOUD_SQL_MSSQL_PASSWORD} password: ${CLOUD_SQL_MSSQL_PASSWORD}
ipType: ${CLOUD_SQL_MSSQL_IP_TYPE:public} ipType: ${CLOUD_SQL_MSSQL_IP_TYPE:public}

View File

@@ -54,7 +54,7 @@ type Config struct {
Project string `yaml:"project" validate:"required"` Project string `yaml:"project" validate:"required"`
Region string `yaml:"region" validate:"required"` Region string `yaml:"region" validate:"required"`
Instance string `yaml:"instance" validate:"required"` Instance string `yaml:"instance" validate:"required"`
IPAddress string `yaml:"ipAddress" validate:"required"` IPAddress string `yaml:"ipAddress"` // Deprecated: kept for backwards compatibility
IPType sources.IPType `yaml:"ipType" validate:"required"` IPType sources.IPType `yaml:"ipType" validate:"required"`
User string `yaml:"user" validate:"required"` User string `yaml:"user" validate:"required"`
Password string `yaml:"password" validate:"required"` Password string `yaml:"password" validate:"required"`
@@ -68,7 +68,7 @@ func (r Config) SourceConfigKind() string {
func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) { func (r Config) Initialize(ctx context.Context, tracer trace.Tracer) (sources.Source, error) {
// Initializes a Cloud SQL MSSQL source // Initializes a Cloud SQL MSSQL source
db, err := initCloudSQLMssqlConnection(ctx, tracer, r.Name, r.Project, r.Region, r.Instance, r.IPAddress, r.IPType.String(), r.User, r.Password, r.Database) db, err := initCloudSQLMssqlConnection(ctx, tracer, r.Name, r.Project, r.Region, r.Instance, r.IPType.String(), r.User, r.Password, r.Database)
if err != nil { if err != nil {
return nil, fmt.Errorf("unable to create db connection: %w", err) return nil, fmt.Errorf("unable to create db connection: %w", err)
} }
@@ -106,7 +106,7 @@ func (s *Source) MSSQLDB() *sql.DB {
return s.Db return s.Db
} }
func initCloudSQLMssqlConnection(ctx context.Context, tracer trace.Tracer, name, project, region, instance, ipAddress, ipType, user, pass, dbname string) (*sql.DB, error) { func initCloudSQLMssqlConnection(ctx context.Context, tracer trace.Tracer, name, project, region, instance, ipType, user, pass, dbname string) (*sql.DB, error) {
//nolint:all // Reassigned ctx //nolint:all // Reassigned ctx
ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name) ctx, span := sources.InitConnectionSpan(ctx, tracer, SourceKind, name)
defer span.End() defer span.End()
@@ -125,7 +125,6 @@ func initCloudSQLMssqlConnection(ctx context.Context, tracer trace.Tracer, name,
url := &url.URL{ url := &url.URL{
Scheme: "sqlserver", Scheme: "sqlserver",
User: url.UserPassword(user, pass), User: url.UserPassword(user, pass),
Host: ipAddress,
RawQuery: query.Encode(), RawQuery: query.Encode(),
} }

View File

@@ -40,22 +40,20 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) {
region: my-region region: my-region
instance: my-instance instance: my-instance
database: my_db database: my_db
ipAddress: localhost
user: my_user user: my_user
password: my_pass password: my_pass
`, `,
want: server.SourceConfigs{ want: server.SourceConfigs{
"my-instance": cloudsqlmssql.Config{ "my-instance": cloudsqlmssql.Config{
Name: "my-instance", Name: "my-instance",
Kind: cloudsqlmssql.SourceKind, Kind: cloudsqlmssql.SourceKind,
Project: "my-project", Project: "my-project",
Region: "my-region", Region: "my-region",
Instance: "my-instance", Instance: "my-instance",
IPAddress: "localhost", IPType: "public",
IPType: "public", Database: "my_db",
Database: "my_db", User: "my_user",
User: "my_user", Password: "my_pass",
Password: "my_pass",
}, },
}, },
}, },
@@ -69,11 +67,38 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) {
region: my-region region: my-region
instance: my-instance instance: my-instance
database: my_db database: my_db
ipAddress: localhost
user: my_user user: my_user
password: my_pass password: my_pass
ipType: psc ipType: psc
`, `,
want: server.SourceConfigs{
"my-instance": cloudsqlmssql.Config{
Name: "my-instance",
Kind: cloudsqlmssql.SourceKind,
Project: "my-project",
Region: "my-region",
Instance: "my-instance",
IPType: "psc",
Database: "my_db",
User: "my_user",
Password: "my_pass",
},
},
},
{
desc: "with deprecated ipAddress",
in: `
sources:
my-instance:
kind: cloud-sql-mssql
project: my-project
region: my-region
instance: my-instance
ipAddress: random
database: my_db
user: my_user
password: my_pass
`,
want: server.SourceConfigs{ want: server.SourceConfigs{
"my-instance": cloudsqlmssql.Config{ "my-instance": cloudsqlmssql.Config{
Name: "my-instance", Name: "my-instance",
@@ -81,8 +106,8 @@ func TestParseFromYamlCloudSQLMssql(t *testing.T) {
Project: "my-project", Project: "my-project",
Region: "my-region", Region: "my-region",
Instance: "my-instance", Instance: "my-instance",
IPAddress: "localhost", IPAddress: "random",
IPType: "psc", IPType: "public",
Database: "my_db", Database: "my_db",
User: "my_user", User: "my_user",
Password: "my_pass", Password: "my_pass",
@@ -125,7 +150,6 @@ func TestFailParseFromYaml(t *testing.T) {
instance: my-instance instance: my-instance
ipType: fail ipType: fail
database: my_db database: my_db
ipAddress: localhost
user: my_user user: my_user
password: my_pass password: my_pass
`, `,
@@ -141,12 +165,11 @@ func TestFailParseFromYaml(t *testing.T) {
region: my-region region: my-region
instance: my-instance instance: my-instance
database: my_db database: my_db
ipAddress: localhost
user: my_user user: my_user
password: my_pass password: my_pass
foo: bar foo: bar
`, `,
err: "unable to parse source \"my-instance\" as \"cloud-sql-mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | ipAddress: localhost\n 5 | kind: cloud-sql-mssql\n 6 | ", err: "unable to parse source \"my-instance\" as \"cloud-sql-mssql\": [2:1] unknown field \"foo\"\n 1 | database: my_db\n> 2 | foo: bar\n ^\n 3 | instance: my-instance\n 4 | kind: cloud-sql-mssql\n 5 | password: my_pass\n 6 | ",
}, },
{ {
desc: "missing required field", desc: "missing required field",
@@ -157,7 +180,6 @@ func TestFailParseFromYaml(t *testing.T) {
region: my-region region: my-region
instance: my-instance instance: my-instance
database: my_db database: my_db
ipAddress: localhost
user: my_user user: my_user
password: my_pass password: my_pass
`, `,

View File

@@ -40,7 +40,6 @@ var (
CloudSQLMSSQLRegion = os.Getenv("CLOUD_SQL_MSSQL_REGION") CloudSQLMSSQLRegion = os.Getenv("CLOUD_SQL_MSSQL_REGION")
CloudSQLMSSQLInstance = os.Getenv("CLOUD_SQL_MSSQL_INSTANCE") CloudSQLMSSQLInstance = os.Getenv("CLOUD_SQL_MSSQL_INSTANCE")
CloudSQLMSSQLDatabase = os.Getenv("CLOUD_SQL_MSSQL_DATABASE") CloudSQLMSSQLDatabase = os.Getenv("CLOUD_SQL_MSSQL_DATABASE")
CloudSQLMSSQLIp = os.Getenv("CLOUD_SQL_MSSQL_IP")
CloudSQLMSSQLUser = os.Getenv("CLOUD_SQL_MSSQL_USER") CloudSQLMSSQLUser = os.Getenv("CLOUD_SQL_MSSQL_USER")
CloudSQLMSSQLPass = os.Getenv("CLOUD_SQL_MSSQL_PASS") CloudSQLMSSQLPass = os.Getenv("CLOUD_SQL_MSSQL_PASS")
) )
@@ -53,8 +52,6 @@ func getCloudSQLMSSQLVars(t *testing.T) map[string]any {
t.Fatal("'CLOUD_SQL_MSSQL_REGION' not set") t.Fatal("'CLOUD_SQL_MSSQL_REGION' not set")
case CloudSQLMSSQLInstance: case CloudSQLMSSQLInstance:
t.Fatal("'CLOUD_SQL_MSSQL_INSTANCE' not set") t.Fatal("'CLOUD_SQL_MSSQL_INSTANCE' not set")
case CloudSQLMSSQLIp:
t.Fatal("'CLOUD_SQL_MSSQL_IP' not set")
case CloudSQLMSSQLDatabase: case CloudSQLMSSQLDatabase:
t.Fatal("'CLOUD_SQL_MSSQL_DATABASE' not set") t.Fatal("'CLOUD_SQL_MSSQL_DATABASE' not set")
case CloudSQLMSSQLUser: case CloudSQLMSSQLUser:
@@ -64,25 +61,23 @@ func getCloudSQLMSSQLVars(t *testing.T) map[string]any {
} }
return map[string]any{ return map[string]any{
"kind": CloudSQLMSSQLSourceKind, "kind": CloudSQLMSSQLSourceKind,
"project": CloudSQLMSSQLProject, "project": CloudSQLMSSQLProject,
"instance": CloudSQLMSSQLInstance, "instance": CloudSQLMSSQLInstance,
"ipAddress": CloudSQLMSSQLIp, "region": CloudSQLMSSQLRegion,
"region": CloudSQLMSSQLRegion, "database": CloudSQLMSSQLDatabase,
"database": CloudSQLMSSQLDatabase, "user": CloudSQLMSSQLUser,
"user": CloudSQLMSSQLUser, "password": CloudSQLMSSQLPass,
"password": CloudSQLMSSQLPass,
} }
} }
// Copied over from cloud_sql_mssql.go // Copied over from cloud_sql_mssql.go
func initCloudSQLMSSQLConnection(project, region, instance, ipAddress, ipType, user, pass, dbname string) (*sql.DB, error) { func initCloudSQLMSSQLConnection(project, region, instance, ipType, user, pass, dbname string) (*sql.DB, error) {
// Create dsn // Create dsn
query := fmt.Sprintf("database=%s&cloudsql=%s:%s:%s", dbname, project, region, instance) query := fmt.Sprintf("database=%s&cloudsql=%s:%s:%s", dbname, project, region, instance)
url := &url.URL{ url := &url.URL{
Scheme: "sqlserver", Scheme: "sqlserver",
User: url.UserPassword(user, pass), User: url.UserPassword(user, pass),
Host: ipAddress,
RawQuery: query, RawQuery: query,
} }
@@ -118,7 +113,7 @@ func TestCloudSQLMSSQLToolEndpoints(t *testing.T) {
var args []string var args []string
db, err := initCloudSQLMSSQLConnection(CloudSQLMSSQLProject, CloudSQLMSSQLRegion, CloudSQLMSSQLInstance, CloudSQLMSSQLIp, "public", CloudSQLMSSQLUser, CloudSQLMSSQLPass, CloudSQLMSSQLDatabase) db, err := initCloudSQLMSSQLConnection(CloudSQLMSSQLProject, CloudSQLMSSQLRegion, CloudSQLMSSQLInstance, "public", CloudSQLMSSQLUser, CloudSQLMSSQLPass, CloudSQLMSSQLDatabase)
if err != nil { if err != nil {
t.Fatalf("unable to create Cloud SQL connection pool: %s", err) t.Fatalf("unable to create Cloud SQL connection pool: %s", err)
} }