-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #1 from videsk/develop
Stable v1.0
- Loading branch information
Showing
4 changed files
with
204 additions
and
0 deletions.
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,92 @@ | ||
# Doppler Go SDK | ||
|
||
To start using this SDK, just: | ||
|
||
## 1. Install the package | ||
|
||
```bash | ||
go get github.com/videsk/doppler-go-sdk | ||
``` | ||
|
||
## 2. Import the package | ||
|
||
Using the method `GetSecrets` you will retrieve all secrets in once. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"github.com/videsk/doppler-go-sdk" | ||
) | ||
|
||
func main() { | ||
|
||
dopplerClient, err := doppler.NewDoppler("projectName", "secretKey", "environment") | ||
if err != nil { | ||
log.Fatalf("Error with Doppler instance: %v", err) | ||
} | ||
|
||
dopplerClient.SetHTTPClient(http.DefaultClient) | ||
|
||
secrets, err := dopplerClient.GetSecrets() | ||
if err != nil { | ||
log.Fatalf("Error getting the secrets: %v", err) | ||
} | ||
|
||
for key, value := range secrets { | ||
log.Printf("Error getting: %s, Value: %s\n", key, value) | ||
} | ||
|
||
// The rest of the code ... | ||
} | ||
``` | ||
|
||
## 3. Get specific secret by name | ||
|
||
Using the method `GetOne` you will retrieve one secret in once, but calling `getSecrets`. Which is not efficient if you need get more than one at the same time. | ||
|
||
```go | ||
package main | ||
|
||
import ( | ||
"log" | ||
|
||
"github.com/videsk/doppler-go-sdk" | ||
) | ||
|
||
func main() { | ||
|
||
dopplerClient, err := doppler.NewDoppler("projectName", "secretKey", "environment") | ||
if err != nil { | ||
log.Fatalf("Error with Doppler instance: %v", err) | ||
} | ||
|
||
dopplerClient.SetHTTPClient(http.DefaultClient) | ||
|
||
secretName := "my_secret_name" | ||
secretValue, err := dopplerClient.GetOne(secretName) | ||
if err != nil { | ||
log.Fatalf("Error getting the secret %s: %v", secretName, err) | ||
} | ||
|
||
log.Printf("The secret value is '%s': %s\n", secretName, secretValue) | ||
|
||
// The rest of the code ... | ||
} | ||
``` | ||
## Efficient single value | ||
|
||
In case you want retrieve multiples values you can just: | ||
|
||
```go | ||
secrets, err := dopplerClient.GetSecrets() | ||
|
||
if err != nil { | ||
log.Fatalf("Error getting the secrets: %v", err) | ||
} | ||
|
||
mySecret1 := secrets["my_secret_name"] | ||
mySecret2 := secrets["my_super_secret"] | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
module doppler-sdk | ||
|
||
go 1.18 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
package doppler | ||
|
||
import ( | ||
"encoding/base64" | ||
"encoding/json" | ||
"errors" | ||
"fmt" | ||
"io/ioutil" | ||
"net/http" | ||
"net/url" | ||
) | ||
|
||
type Doppler struct { | ||
Project string | ||
Environment string | ||
BasicURL string | ||
Secret string | ||
httpClient *http.Client | ||
} | ||
|
||
func NewDoppler(project, secretKey, environment string) (*Doppler, error) { | ||
if project == "" { | ||
return nil, errors.New("project name is mandatory to instance Doppler") | ||
} | ||
if environment == "" { | ||
environment = "production" | ||
} | ||
|
||
return &Doppler{ | ||
Project: project, | ||
Environment: environment, | ||
BasicURL: "https://api.doppler.com/v3/configs/config", | ||
Secret: base64.StdEncoding.EncodeToString([]byte(secretKey + ":")), | ||
httpClient: &http.Client{}, | ||
}, nil | ||
} | ||
|
||
func (d *Doppler) SetHTTPClient(client *http.Client) { | ||
d.httpClient = client | ||
} | ||
|
||
func (d *Doppler) GetOne(secretKey string) (string, error) { | ||
secrets, err := d.GetSecrets() | ||
if err != nil { | ||
return "", err | ||
} | ||
value, exists := secrets[secretKey] | ||
if !exists { | ||
return "", fmt.Errorf("secret key %s not found", secretKey) | ||
} | ||
return value, nil | ||
} | ||
|
||
func (d *Doppler) GetSecrets() (map[string]string, error) { | ||
if d.httpClient == nil { | ||
return nil, errors.New("the http client is nil, please set it with an HTTP client") | ||
} | ||
|
||
params := url.Values{} | ||
params.Add("project", d.Project) | ||
params.Add("config", d.Environment) | ||
endpointUrl := fmt.Sprintf("%s/secrets?%s", d.BasicURL, params.Encode()) | ||
req, err := http.NewRequest("GET", endpointUrl, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
req.Header.Add("Authorization", "Basic "+d.Secret) | ||
req.Header.Add("Accepts", "application/json") | ||
req.Header.Add("Content-Type", "application/json") | ||
|
||
resp, err := d.httpClient.Do(req) | ||
if err != nil { | ||
return nil, err | ||
} | ||
defer resp.Body.Close() | ||
|
||
if resp.StatusCode != http.StatusOK { | ||
return nil, fmt.Errorf("failed to fetch secrets, status code: %d", resp.StatusCode) | ||
} | ||
|
||
var secretsResponse struct { | ||
Secrets map[string]struct { | ||
Computed string `json:"computed"` | ||
} `json:"secrets"` | ||
} | ||
body, err := ioutil.ReadAll(resp.Body) | ||
if err != nil { | ||
return nil, err | ||
} | ||
if err := json.Unmarshal(body, &secretsResponse); err != nil { | ||
return nil, err | ||
} | ||
|
||
secrets := make(map[string]string) | ||
for k, v := range secretsResponse.Secrets { | ||
secrets[k] = v.Computed | ||
} | ||
|
||
return secrets, nil | ||
} |