github.com/Jeffail/benthos/v3@v3.65.0/internal/impl/azure/azure.go (about) 1 package azure 2 3 import ( 4 "errors" 5 "fmt" 6 "net/url" 7 "os" 8 "strings" 9 10 "github.com/Azure/azure-storage-queue-go/azqueue" 11 ) 12 13 const ( 14 azQueueEndpointExp = "https://%s.queue.core.windows.net" 15 devQueueEndpointExp = "http://localhost:10001/%s" 16 azAccountName = "accountname" 17 azAccountKey = "accountkey" 18 devAccountName = "devstoreaccount1" 19 devAccountKey = "Eby8vdM02xNOcqFlqUwJPLlmEtlCDXJ1OUzFT50uSRZ6IFsuFq2UVErCz4I6tq/K1SZFPTOtr/KBHBeksoGMGw==" 20 ) 21 22 // GetQueueServiceURL creates an Azure Queue URL from storage fields. 23 func GetQueueServiceURL(storageAccount, storageAccessKey, storageConnectionString string) (*azqueue.ServiceURL, error) { 24 if storageAccount == "" && storageConnectionString == "" { 25 return nil, errors.New("invalid azure storage account credentials") 26 } 27 var endpointExp = azQueueEndpointExp 28 var err error 29 if storageConnectionString != "" { 30 if strings.Contains(storageConnectionString, "UseDevelopmentStorage=true;") { 31 storageAccount = devAccountName 32 storageAccessKey = devAccountKey 33 endpointExp = devQueueEndpointExp 34 if ap := os.Getenv("AZURITE_QUEUE_ENDPOINT_PORT"); ap != "" { 35 endpointExp = strings.ReplaceAll(devQueueEndpointExp, "10001", ap) 36 } 37 } else { 38 storageAccount, storageAccessKey, err = parseConnectionString(storageConnectionString) 39 if err != nil { 40 return nil, err 41 } 42 if strings.Contains(storageConnectionString, devAccountName) { 43 endpointExp = devQueueEndpointExp 44 } 45 } 46 } 47 if storageAccount == "" { 48 return nil, fmt.Errorf("invalid azure storage account credentials: %v", err) 49 } 50 var credential azqueue.Credential 51 if storageAccessKey != "" { 52 credential, _ = azqueue.NewSharedKeyCredential(storageAccount, storageAccessKey) 53 } else { 54 credential = azqueue.NewAnonymousCredential() 55 } 56 57 p := azqueue.NewPipeline(credential, azqueue.PipelineOptions{}) 58 endpoint, _ := url.Parse(fmt.Sprintf(endpointExp, storageAccount)) 59 serviceURL := azqueue.NewServiceURL(*endpoint, p) 60 61 return &serviceURL, err 62 } 63 64 // parseConnectionString extracts the credentials from the connection string. 65 func parseConnectionString(input string) (storageAccount, storageAccessKey string, err error) { 66 // build a map of connection string key/value pairs 67 parts := map[string]string{} 68 for _, pair := range strings.Split(input, ";") { 69 if pair == "" { 70 continue 71 } 72 equalDex := strings.IndexByte(pair, '=') 73 if equalDex <= 0 { 74 fmt.Println(fmt.Errorf("invalid connection segment %q", pair)) 75 } 76 value := strings.TrimSpace(pair[equalDex+1:]) 77 key := strings.TrimSpace(strings.ToLower(pair[:equalDex])) 78 parts[key] = value 79 } 80 accountName, ok := parts[azAccountName] 81 if !ok { 82 return "", "", errors.New("invalid connection string") 83 } 84 accountKey, ok := parts[azAccountKey] 85 if !ok { 86 return "", "", errors.New("invalid connection string") 87 } 88 return accountName, accountKey, nil 89 }