Получение секретов 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

Другие вопросы по тегам