Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Tables] connection string parser #15187

Merged
merged 44 commits into from
Aug 24, 2021
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
da7f308
adding conn str parser
seankane-msft Jul 6, 2021
4f2de5f
Basic conn str parser
seankane-msft Jul 29, 2021
c94e1ce
adding support for custom domains
seankane-msft Jul 29, 2021
bbe00cd
invalid tests
seankane-msft Jul 29, 2021
d967e57
adding self note
seankane-msft Jul 29, 2021
c7da82f
Update sdk/tables/aztable/connection_string.go
seankane-msft Jul 29, 2021
4621f6c
Update sdk/tables/aztable/connection_string.go
seankane-msft Jul 29, 2021
ded6f8b
Merge branch 'track2-tables' of https://github.com/Azure/azure-sdk-fo…
seankane-msft Aug 11, 2021
3842a4d
improving testing
seankane-msft Aug 11, 2021
20ef734
finishing connection string portion
seankane-msft Aug 11, 2021
0d28805
formatting and improved error handling
seankane-msft Aug 11, 2021
fdac8d6
docstring addition for private method
seankane-msft Aug 11, 2021
95786a5
merge conflict
seankane-msft Aug 12, 2021
044733c
connection string error
seankane-msft Aug 12, 2021
f405a90
merge conflicts
seankane-msft Aug 17, 2021
99de9b0
splitn instead of split
seankane-msft Aug 17, 2021
f28e3f6
sas comment
seankane-msft Aug 17, 2021
3f4cc57
updating proxy-server script
seankane-msft Aug 18, 2021
2a3d5e5
configure proxy with hash of file, correct file location
seankane-msft Aug 18, 2021
48204fc
using certs in main
seankane-msft Aug 18, 2021
bb276fb
trying download with no password
seankane-msft Aug 18, 2021
34871e6
trying without the pfx file altogether
seankane-msft Aug 18, 2021
cc7a769
adding pfx portion back
seankane-msft Aug 18, 2021
7357bbf
manual copy of testproxy to common
seankane-msft Aug 18, 2021
1a40990
using common
seankane-msft Aug 18, 2021
c88ae43
fixing path
seankane-msft Aug 18, 2021
25fdd90
adding trust ps1 script
seankane-msft Aug 18, 2021
c41de6e
merge conflicts
seankane-msft Aug 18, 2021
fbf1d9a
adding step to run proxy
seankane-msft Aug 18, 2021
7c16a48
formatting and go mod x/net
seankane-msft Aug 18, 2021
542360b
fixing for latest azcore
seankane-msft Aug 18, 2021
9a54e06
fixing rqeuire
seankane-msft Aug 18, 2021
bb7978a
removing eng stuff
seankane-msft Aug 20, 2021
3e21e20
merging upstream
seankane-msft Aug 20, 2021
8194878
conn str
seankane-msft Aug 20, 2021
9c095bd
running tests
seankane-msft Aug 20, 2021
532c74e
run tests = true
seankane-msft Aug 20, 2021
caa14e8
adding build sourcesDir
seankane-msft Aug 20, 2021
ca09207
relative path
seankane-msft Aug 20, 2021
4125fd0
fixing up path
seankane-msft Aug 20, 2021
c125e2c
build-test
seankane-msft Aug 20, 2021
315a190
moving byte array response inside table pager
seankane-msft Aug 20, 2021
3b7e68d
env var playing to fix ci lint
seankane-msft Aug 20, 2021
8c9c9d6
changing package name
seankane-msft Aug 20, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
101 changes: 101 additions & 0 deletions sdk/tables/aztable/connection_string.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License.

package aztable

import (
"errors"
"fmt"
"strings"

"github.com/Azure/azure-sdk-for-go/sdk/azcore"
)

var ErrConnectionString = errors.New("connection string is either blank or malformed")
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved

func NewTableClientFromConnectionString(tableName string, connectionString string, options *TableClientOptions) (*TableClient, error) {
endpoint, credential, err := parseConnectionString(connectionString)
if err != nil {
return nil, err
}
return NewTableClient(tableName, endpoint, *credential, options)
}

func NewTableServiceClientFrommConnectionString(connectionString string, options *TableClientOptions) (*TableServiceClient, error) {
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved
endpoint, credential, err := parseConnectionString(connectionString)
if err != nil {
return nil, err
}
return NewTableServiceClient(endpoint, *credential, options)
}

func convertConnStrToMap(connStr string) (map[string]string, error) {
ret := make(map[string]string)
connStr = strings.TrimRight(connStr, ";")

splitString := strings.Split(connStr, ";")
if len(splitString) == 0 {
return ret, ErrConnectionString
}
for _, stringPart := range splitString {
parts := strings.Split(stringPart, "=")
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved
if len(parts) != 2 {
return ret, ErrConnectionString
}
ret[parts[0]] = parts[1]
}
return ret, nil
}

func parseConnectionString(connStr string) (string, *azcore.Credential, error) {
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved
var serviceURL string
var cred azcore.Credential

connStrMap, err := convertConnStrToMap(connStr)
if err != nil {
return "", nil, err
}

accountName, ok := connStrMap["AccountName"]
if !ok {
return "", nil, ErrConnectionString
}
accountKey, ok := connStrMap["AccountKey"]
if !ok {
return "", nil, ErrConnectionString
}

if accountName == "" || accountKey == "" {
// Try sharedaccesssignature
sharedAccessSignature, ok := connStrMap["sharedaccesssignature"]
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved
if !ok {
return serviceURL, nil, ErrConnectionString
}
return sharedAccessSignature, nil, errors.New("there is not support for SharedAccessSignature yet")
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved
// cred = azcore.SharedAccessSignature(sharedAccessSignature)
// TODO: fix this when shared access signatures are added.
}
defaultProtocol, ok := connStrMap["DefaultEndpointsProtocol"]
if !ok {
defaultProtocol = "https"
}

endpointSuffix, ok := connStrMap["EndpointSuffix"]
if !ok {
endpointSuffix = "core.windows.net"
}

tableEndpoint, ok := connStrMap["TableEndpoint"]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like you can combine some of this and just set 'tableEndpoint' to either their custom one or the serviceURL you formed below (and return only once). Unless there's something else interesting you have planned where they'll diverge more.

if ok {
cred, err = NewSharedKeyCredential(accountName, accountKey)
return tableEndpoint, &cred, err
}
serviceURL = fmt.Sprintf("%v://%v.table.%v", defaultProtocol, accountName, endpointSuffix)

cred, err = NewSharedKeyCredential(accountName, accountKey)
if err != nil {
return "", nil, err
}

return serviceURL, &cred, nil
}
70 changes: 70 additions & 0 deletions sdk/tables/aztable/connection_string_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright (c) Microsoft Corporation. All rights reserved.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need tests for azurite connection strings also, since they do some different things with the account name.

// Licensed under the MIT License.

package aztable

import (
"testing"

"github.com/stretchr/testify/require"
)

func TestConnectionStringParser(t *testing.T) {
require := require.New(t)

connStr := "DefaultEndpointsProtocol=https;AccountName=dummyaccount;AccountKey=secretkeykey;EndpointSuffix=core.windows.net"
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved
serviceURL, cred, err := parseConnectionString(connStr)
require.NoError(err)
require.Equal(serviceURL, "https://dummyaccount.table.core.windows.net")
require.NotNil(cred)
}

func TestConnectionStringParserHTTP(t *testing.T) {
require := require.New(t)

connStr := "DefaultEndpointsProtocol=http;AccountName=dummyaccount;AccountKey=secretkeykey;EndpointSuffix=core.windows.net"
serviceURL, cred, err := parseConnectionString(connStr)
require.NoError(err)
require.Equal(serviceURL, "http://dummyaccount.table.core.windows.net")
require.NotNil(cred)
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved
}

func TestConnectionStringParserBasic(t *testing.T) {
require := require.New(t)

connStr := "AccountName=dummyaccount;AccountKey=secretkeykey"
serviceURL, cred, err := parseConnectionString(connStr)
require.NoError(err)
require.Equal(serviceURL, "https://dummyaccount.table.core.windows.net")
require.NotNil(cred)
}

func TestConnectionStringParserCustomDomain(t *testing.T) {
require := require.New(t)

connStr := "AccountName=dummyaccount;AccountKey=secretkeykey;TableEndpoint=www.mydomain.com;"
seankane-msft marked this conversation as resolved.
Show resolved Hide resolved
serviceURL, cred, err := parseConnectionString(connStr)
require.NoError(err)
require.Equal(serviceURL, "www.mydomain.com")
require.NotNil(cred)
}

func TestConnectionStringParserInvalid(t *testing.T) {
badConnectionStrings := []string{
"",
"foobar",
"foo;bar;baz",
"foo=;bar=;",
"=",
";",
"=;==",
"foobar=baz=foo"
}
require := require.New(t)

for _, badConnStr := range badConnectionStrings {
_, _, err := parseConnectionString(badConnStr)
require.Error(err)
require.Contains(err.Error(), ErrConnectionString.Error())
}
}