Получение секретов Github с пробелами из скрипта golang
У меня есть сценарий golang, в котором я выполняю несколько тестов. Я выполняю его из действий github, поэтому вызываю кучу секретов Github, созданных ранее таким образом:
func SpecklePostConvert(t *testing.T, speckleServerURL string) {
type SpeckleLogin struct {
token string
}
method := "GET"
headers := map[string][]string{
"Content-Type": []string{"application/json, text/plain, */*"},
"Authorization": []string{os.Getenv("SPECKLE_USER_JWT")},
}
jsonLogin := []byte(fmt.Sprintf(`{
"email":"%s",
"password": "%s"
}`, os.Getenv("SPECKLE_EMAIL"), os.Getenv("SPECKLE_PASSWORD")))
fmt.Println("SPECKLE JWT", os.Getenv("SPECKLE_USER_JWT"))
reqLogin, errReq := http.NewRequest(method, speckleServerURL+"/api/accounts", bytes.NewBuffer(jsonLogin))
reqLogin.Header = headers
Но я столкнулся с особой ситуацией:
Когда я звоню
os.Getenv("SPECKLE_EMAIL")
а также
os.Getenv("SPECKLE_PASSWORD")
, Я получаю реальные значения из секретов Github. Их значения представляют собой строку без пробелов.
Но когда я звоню сюда, я являюсь секретарем github:
headers := map[string][]string{
"Content-Type": []string{"application/json, text/plain, */*"},
"Authorization": []string{os.Getenv("SPECKLE_USER_JWT")},
}
При выполнении проверки из действий GitHub я не получаю значение из секрета github. Дело в том, что его секретное значение представляет собой составную строку с пробелом, таким образом:
Боюсь, я не получаю пользы от
SPECKLE_USER_JWT
Секрет GitHub, вызвав его как переменную env(
os.Getenv("SPECKLE_USER_JWT")
) потому что этот пробел между "JWT" и токеном, я имею в виду
JWT <token-string>
.
Здесь говорится:
Имена секретов могут содержать только буквенно-цифровые символы ([az], [AZ], [0-9]) или символы подчеркивания (_). Пробелы не допускаются.
Вот почему я не могу получить секретное значение.
Я не уверен, как мне получить это из моего скрипта golang, я даже пытался изменить секретное значение github, просто имея там
<token-string>
чтобы избежать пробела в значении, и я вызываю его таким образом:
"Authorization": []string{"JWT ", os.Getenv("SPECKLE_USER_JWT")}
Но это не работает. Я читал здесь, что при вызове секретов со специальными символами из действий github мы должны экранировать его одинарными кавычками
' '
но это от
.yaml
файл действия github. Не уверен, как мне избежать секрета с пробелом в строке, как у меня от голанга.
1 ответ
Мне удалось прочитать секрет JWT, хранящийся в секретах GitHub, из действия GitHub, выполняющего код golang terratest.
Как уже упоминалось, поскольку секреты Github не допускают пробелов
" "
и символы точек и токен имеет несколько точек плюс один пробел, что я сначала сделал, чтобы закодировать его
echo -n '<token-value>' | base64
Это генерирует целую строку без
.
или пробелы, а затем я сохранил это значение в секретах Github. И я прочитал это с голанга так:
func main() {
var t *testing.T
serverURL := os.Getenv("SERVER_URL")
MyTestFunction(t, serverURL)
}
func MyTestFunction(t *testing.T, serverURL string) {
type SpeckleLogin struct {
token string
}
method := "GET"
// The encoded token is read from github secrets
b64EncodeJwt := os.Getenv("USER_JWT_ENCODE")
// fmt.Println("The encode JWT is:", b64EncodeJwt)
// The encoded read token is decoded
b64DecodeJwt, _ := b64.StdEncoding.DecodeString(b64EncodeJwt)
// fmt.Println("JWT Decoded", string(b64DecodeJwt))
// fmt.Println()
headers := map[string][]string{
"Content-Type": []string{"application/json, text/plain, */*"},
// The content of the token already decoded is included in the headers slice of strings.
"Authorization": []string{(string(b64DecodeJwt))},
}
jsonLogin := []byte(fmt.Sprintf(`{
"email":"%s",
"password": "%s"
}`, os.Getenv("USER_EMAIL"), os.Getenv("USER_PASSWORD")))
// The HTTP request is created
reqLogin, errReq := http.NewRequest(method, serverURL+"/api/accounts", bytes.NewBuffer(jsonLogin))
// The headers are added to the HTTP request
reqLogin.Header = headers
if errReq != nil {
messageReq := fmt.Sprintf("Error GET login request: %s", errReq.Error())
t.Fatal(messageReq)
}
clientLogin := &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
}
// Sending the request
respLogin, errResp := clientLogin.Do(reqLogin)
if errResp != nil {
messageResp := fmt.Sprintf("Error GET login response: %s", errResp.Error())
t.Fatal(messageResp)
}
defer respLogin.Body.Close()
body, _ := ioutil.ReadAll(respLogin.Body)
// fmt.Println("BODY IS:")
// fmt.Println(string(body))
var speckleLogin map[string]interface{}
if err := json.Unmarshal([]byte(body), &speckleLogin); err != nil {
t.Fatal("Could not unmarshal json")
}
// We take the API token from the response
data := speckleLogin["resource"].(map[string]interface{})["apitoken"]
if speckleToken, ok := data.(string); ok {
// Here we assert the token is not empty
assert.NotEmpty(t, speckleToken)
}
Но в дополнение, как Wishwa Perera пытается сказать мне, новая переменная среды, которую я использую из golang, называется
SPECKLE_USER_JWT_ENCODE
выше, должен быть включен в мои действия на github на данный момент, чтобы запускать эти тесты из
go test
команда. Итак, мое действие на github
.yaml
файл, наконец, выглядит так:
name: Preview_Workflow
on:
pull_request:
branches:
- master
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: 'Checkout GitHub Action'
uses: actions/checkout@master
- name: Install terraform
uses: hashicorp/setup-terraform@v1
with:
terraform_version: 0.13.5
terraform_wrapper: false
- name: 'Terraform Version'
shell: bash
run: |
terraform version
- name: 'Login via Azure CLI'
uses: azure/login@v1
with:
creds: ${{ secrets.AZURE_CREDENTIALS }}
- name: 'Setup Go'
id: go
uses: actions/setup-go@v2
with:
go-version: '^1.16.5'
- name: 'Run Terratest'
id: terratest
run: |
cd tests
go get -u github.com/Azure/azure-storage-blob-go/azblob
go get -u github.com/gruntwork-io/terratest/modules/terraform
go get -u github.com/stretchr/testify/assert
// executing the test
go test
env:
SERVER_URL: "https://my-service-application-url"
USER_EMAIL: ${{ secrets.USER_EMAIL }}
USER_PASSWORD: ${{ secrets.USER_PASSWORD }}
USER_JWT_ENCODE: ${{ secrets.USER_JWT_ENCODE }}
# I am using these other ones to connect to azure.
ARM_CLIENT_ID: ${{ secrets.ARM_CLIENT_ID }}
ARM_CLIENT_SECRET: ${{ secrets.ARM_CLIENT_SECRET }}
ARM_SUBSCRIPTION_ID: ${{ secrets.ARM_SUBSCRIPTION_ID }}
ARM_TENANT_ID: ${{ secrets.ARM_TENANT_ID }}
- name: Azure logout
run: |
az logout
Хорошая ссылка, чтобы немного понять, как обрабатывать пакет HTTP