Skip to content

Commit

Permalink
fix: add support for legacy project names in FUSE (#137)
Browse files Browse the repository at this point in the history
  • Loading branch information
enocom authored Sep 21, 2022
1 parent e383f58 commit b137ae0
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 6 deletions.
54 changes: 54 additions & 0 deletions internal/proxy/other_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,55 @@ func TestClientUsesSyncAtomicAlignment(t *testing.T) {
}
}

func TestUnixSocketDir(t *testing.T) {
tcs := []struct {
desc string
in string
want string
wantErr bool
}{
{
desc: "good input",
in: "projects/proj/locations/reg/clusters/clust/instances/inst",
want: "proj.reg.clust.inst",
},
{
desc: "irregular casing",
in: "projects/PROJ/locations/REG/clusters/CLUST/instances/INST",
want: "proj.reg.clust.inst",
},
{
desc: "legacy domain project",
in: "projects/google.com:proj/locations/reg/clusters/clust/instances/inst",
want: "google.com_proj.reg.clust.inst",
},
{
in: "projects/myproj/locations/reg/clusters/clust/instances/",
wantErr: true,
},
{
in: "projects/google.com:bad:PROJECT/locations/reg/clusters/clust/instances/inst",
wantErr: true,
},
}

for _, tc := range tcs {
t.Run(tc.desc, func(t *testing.T) {
got, gotErr := UnixSocketDir("", tc.in)
if tc.wantErr {
if gotErr == nil {
t.Fatal("want err != nil, got err == nil")
}
return
}
if got != tc.want {
t.Fatalf("want = %v, got = %v", tc.want, got)
}

})
}
}

func TestToFullURI(t *testing.T) {
tcs := []struct {
desc string
Expand All @@ -41,6 +90,11 @@ func TestToFullURI(t *testing.T) {
in: "myproj.reg.clust.inst",
want: "projects/myproj/locations/reg/clusters/clust/instances/inst",
},
{
desc: "legacy project name",
in: "google.com_myproj.reg.clust.inst",
want: "projects/google.com:myproj/locations/reg/clusters/clust/instances/inst",
},
{
desc: "invalid name",
in: ".Trash",
Expand Down
23 changes: 17 additions & 6 deletions internal/proxy/proxy.go
Original file line number Diff line number Diff line change
Expand Up @@ -159,23 +159,30 @@ var (
// Instance URI is in the format:
// 'projects/<PROJECT>/locations/<REGION>/clusters/<CLUSTER>/instances/<INSTANCE>'
// Additionally, we have to support legacy "domain-scoped" projects (e.g. "google.com:PROJECT")
instURIRegex = regexp.MustCompile("projects/([^:]+(:[^:]+)?)/locations/([^:]+)/clusters/([^:]+)/instances/([^:]+)")
instURIRegex = regexp.MustCompile("projects/([^:]+(?::[^:]+)?)/locations/(.+)/clusters/(.+)/instances/(.+)")
// unixRegex is the expected format for a Unix socket
// e.g. project.region.cluster.instance
unixRegex = regexp.MustCompile(`([^:]+)\.([^:]+)\.([^:]+)\.([^:]+)`)
unixRegex = regexp.MustCompile(`([^:]+(?:-[^:]+)?)\.(.+)\.(.+)\.(.+)`)
)

// UnixSocketDir returns a shorted instance connection name to prevent
// exceeding the Unix socket length, e.g., project.region.cluster.instance
func UnixSocketDir(dir, inst string) (string, error) {
inst = strings.ToLower(inst)
m := instURIRegex.FindSubmatch([]byte(inst))
if m == nil {
return "", fmt.Errorf("invalid instance name: %v", inst)
}
project := string(m[1])
region := string(m[3])
cluster := string(m[4])
name := string(m[5])
// Colons are not allowed on Windows, but are present in legacy project
// names (e.g., google.com:myproj). Replace any colon with an underscore to
// support Windows. Underscores are not allowed in project names. So use an
// underscore to have a Windows-friendly delimitor that can serve as a
// marker to recover the legacy project name when necessary (e.g., FUSE).
project = strings.ReplaceAll(project, ":", "_")
region := string(m[2])
cluster := string(m[3])
name := string(m[4])
shortName := strings.Join([]string{project, region, cluster, name}, ".")
return filepath.Join(dir, shortName), nil
}
Expand All @@ -188,11 +195,15 @@ func toFullURI(short string) (string, error) {
return "", fmt.Errorf("invalid short name: %v", short)
}
project := string(m[1])
// Adjust short name for legacy projects. Google Cloud projects cannot have
// underscores in them. When there's an underscore in the short name, it's a
// marker for a colon. So replace the underscore with the original colon.
project = strings.ReplaceAll(project, "_", ":")
region := string(m[2])
cluster := string(m[3])
name := string(m[4])
return fmt.Sprintf(
"projects/%v/locations/%v/clusters/%v/instances/%v",
"projects/%s/locations/%s/clusters/%s/instances/%s",
project, region, cluster, name,
), nil
}
Expand Down

0 comments on commit b137ae0

Please sign in to comment.