Skip to content

Commit dfdf7ea

Browse files
authored
Merge pull request #1 from teeaa/support_gcp_aws_secrets
Support gcp aws secrets
2 parents 0513259 + b7a48b1 commit dfdf7ea

File tree

11 files changed

+395
-74
lines changed

11 files changed

+395
-74
lines changed

README.md

Lines changed: 32 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@
44

55
Minimalistic configuration reader
66

7-
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)
8-
[![GoDoc](https://godoc.org/github.com/ilyakaznacheev/cleanenv?status.svg)](https://godoc.org/github.com/ilyakaznacheev/cleanenv)
9-
[![Go Report Card](https://goreportcard.com/badge/github.com/ilyakaznacheev/cleanenv)](https://goreportcard.com/report/github.com/ilyakaznacheev/cleanenv)
10-
[![Coverage Status](https://codecov.io/github/ilyakaznacheev/cleanenv/coverage.svg?branch=master)](https://codecov.io/gh/ilyakaznacheev/cleanenv)
11-
[![Build Status](https://img.shields.io/github/actions/workflow/status/ilyakaznacheev/cleanenv/test.yml)](https://github.com/ilyakaznacheev/cleanenv/actions)
12-
[![Release](https://img.shields.io/github/release/ilyakaznacheev/cleanenv.svg)](https://github.com/ilyakaznacheev/cleanenv/releases/)
13-
[![License](https://img.shields.io/github/license/ilyakaznacheev/cleanenv.svg)](https://github.com/ilyakaznacheev/cleanenv/blob/master/LICENSE)
7+
[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)
8+
[![GoDoc](https://godoc.org/github.com/teeaa/cleanenv?status.svg)](https://godoc.org/github.com/teeaa/cleanenv)
9+
[![Go Report Card](https://goreportcard.com/badge/github.com/teeaa/cleanenv)](https://goreportcard.com/report/github.com/teeaa/cleanenv)
10+
[![Coverage Status](https://codecov.io/github/teeaa/cleanenv/coverage.svg?branch=master)](https://codecov.io/gh/teeaa/cleanenv)
11+
[![Build Status](https://img.shields.io/github/actions/workflow/status/teeaa/cleanenv/test.yml)](https://github.com/teeaa/cleanenv/actions)
12+
[![Release](https://img.shields.io/github/release/teeaa/cleanenv.svg)](https://github.com/teeaa/cleanenv/releases/)
13+
[![License](https://img.shields.io/github/license/teeaa/cleanenv.svg)](https://github.com/teeaa/cleanenv/blob/master/LICENSE)
1414

1515
## Overview
1616

@@ -22,30 +22,35 @@ This is a simple configuration reading tool. It just does the following:
2222

2323
## Content
2424

25-
- [Installation](#installation)
26-
- [Usage](#usage)
25+
- [Clean Env](#clean-env)
26+
- [Overview](#overview)
27+
- [Content](#content)
28+
- [Installation](#installation)
29+
- [Usage](#usage)
2730
- [Read Configuration](#read-configuration)
2831
- [Read Environment Variables Only](#read-environment-variables-only)
2932
- [Update Environment Variables](#update-environment-variables)
3033
- [Description](#description)
31-
- [Model Format](#model-format)
32-
- [Supported types](#supported-types)
33-
- [Custom Functions](#custom-functions)
34+
- [Model Format](#model-format)
35+
- [Supported types](#supported-types)
36+
- [Custom Functions](#custom-functions)
3437
- [Custom Value Setter](#custom-value-setter)
3538
- [Custom Value Update](#custom-value-update)
36-
- [Supported File Formats](#supported-file-formats)
37-
- [Integration](#integration)
39+
- [Supported File Formats](#supported-file-formats)
40+
- [Integration](#integration)
3841
- [Flag](#flag)
39-
- [Examples](#examples)
40-
- [Contribution](#contribution)
41-
- [Thanks](#thanks)
42+
- [Examples](#examples)
43+
- [Version Support Policy](#version-support-policy)
44+
- [Contribution](#contribution)
45+
- [Thanks](#thanks)
46+
- [Blog Posts](#blog-posts)
4247

4348
## Installation
4449

4550
To install the package run
4651

4752
```bash
48-
go get -u github.com/ilyakaznacheev/cleanenv
53+
go get -u github.com/teeaa/cleanenv
4954
```
5055

5156
## Usage
@@ -65,7 +70,7 @@ There are just several actions you can do with this tool and probably only thing
6570
You can read a configuration file and environment variables in a single function call.
6671

6772
```go
68-
import "github.com/ilyakaznacheev/cleanenv"
73+
import "github.com/teeaa/cleanenv"
6974

7075
type ConfigDatabase struct {
7176
Port string `yaml:"port" env:"PORT" env-default:"5432"`
@@ -93,8 +98,8 @@ This will do the following:
9398

9499
Sometimes you don't want to use configuration files at all, or you may want to use `.env` file format instead. Thus, you can limit yourself with only reading environment variables:
95100

96-
```go
97-
import "github.com/ilyakaznacheev/cleanenv"
101+
```go
102+
import "github.com/teeaa/cleanenv"
98103

99104
type ConfigDatabase struct {
100105
Port string `env:"PORT" env-default:"5432"`
@@ -117,7 +122,7 @@ if err != nil {
117122
Some environment variables may change during the application run. To get the new values you need to mark these variables as updatable with the tag `env-upd` and then run the update function:
118123

119124
```go
120-
import "github.com/ilyakaznacheev/cleanenv"
125+
import "github.com/teeaa/cleanenv"
121126

122127
type ConfigRemote struct {
123128
Port string `env:"PORT" env-upd`
@@ -144,7 +149,7 @@ Here remote host and port may change in a distributed system architecture. Field
144149
You can get descriptions of all environment variables to use them in the help documentation.
145150

146151
```go
147-
import "github.com/ilyakaznacheev/cleanenv"
152+
import "github.com/teeaa/cleanenv"
148153

149154
type ConfigServer struct {
150155
Port string `env:"PORT" env-description:"server port"`
@@ -179,6 +184,8 @@ Library uses tags to configure the model of configuration structure. There are t
179184
- `env-description="<value>"` - environment variable description;
180185
- `env-layout="<value>"` - parsing layout (for types like `time.Time`);
181186
- `env-prefix="<value>"` - prefix for all fields of nested structure (only for nested structures);
187+
- `gcp_secret="projects/<project_id>/secrets/<secret_id>/versions/<version_id>"` - flag for GCP secrets, this tag will hold the full resource name of the secret version. You can use latest for the `version_id` to always get the newest version;
188+
- `aws_secret-"<secret_name_or_arn>"` - flag for AWS secrets, this tag will hold the name or ARN of the secret;
182189

183190
## Supported types
184191

@@ -265,7 +272,7 @@ You can use the cleanenv help together with Golang `flag` package.
265272

266273
```go
267274
// create some config structure
268-
var cfg config
275+
var cfg config
269276

270277
// create flag set using `flag` package
271278
fset := flag.NewFlagSet("Example", flag.ContinueOnError)
@@ -320,4 +327,4 @@ The logo was made by [alexchoffy](https://www.instagram.com/alexchoffy/).
320327

321328
## Blog Posts
322329

323-
[Clean Configuration Management in Golang](https://dev.to/ilyakaznacheev/clean-configuration-management-in-golang-1c89).
330+
[Clean Configuration Management in Golang](https://dev.to/teeaa/clean-configuration-management-in-golang-1c89).

cleanenv.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ const (
5151

5252
// TagEnvPrefix flag to specify prefix for structure fields
5353
TagEnvPrefix = "env-prefix"
54+
55+
// TagGcpSecret flag to specify secret in GCP Secret Manager
56+
TagGcpSecret = "gcp_secret"
57+
58+
// TagAwsSecret flag to specify secret in AWS Secrets Manager
59+
TagAwsSecret = "aws_secret"
5460
)
5561

5662
// Setter is an interface for a custom value setter.
@@ -262,7 +268,6 @@ type parseFunc func(*reflect.Value, string, *string) error
262268

263269
// Any specific supported struct can be added here
264270
var validStructs = map[reflect.Type]parseFunc{
265-
266271
reflect.TypeOf(time.Time{}): func(field *reflect.Value, value string, layout *string) error {
267272
var l string
268273
if layout != nil {
@@ -337,7 +342,7 @@ func readStructMetadata(cfgRoot interface{}) ([]structMeta, error) {
337342

338343
// process nested structure (except of supported ones)
339344
if fld := s.Field(idx); fld.Kind() == reflect.Struct {
340-
//skip unexported
345+
// skip unexported
341346
if !fld.CanInterface() {
342347
continue
343348
}

cleanenv_test.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ func TestReadEnvVarsTime(t *testing.T) {
515515
})
516516
}
517517
}
518+
518519
func TestReadEnvVarsWithPrefix(t *testing.T) {
519520
type Logging struct {
520521
Debug bool `env:"DEBUG"`
@@ -532,7 +533,7 @@ func TestReadEnvVarsWithPrefix(t *testing.T) {
532533
Extra DBConfig `env-prefix:"EXTRA_"`
533534
}
534535

535-
var env = map[string]string{
536+
env := map[string]string{
536537
"DB_HOST": "db1.host",
537538
"DB_PORT": "10000",
538539
"DB_DEBUG": "true",
@@ -552,7 +553,7 @@ func TestReadEnvVarsWithPrefix(t *testing.T) {
552553
t.Fatal("failed to read env vars", err)
553554
}
554555

555-
var expected = Config{
556+
expected := Config{
556557
Default: DBConfig{
557558
Host: "db1.host",
558559
Port: 10000,
@@ -595,7 +596,6 @@ type testConfigUpdateNoFunction struct {
595596
}
596597

597598
func TestReadUpdateFunctions(t *testing.T) {
598-
599599
tests := []struct {
600600
name string
601601
cfg interface{}
@@ -1511,7 +1511,8 @@ func TestParseJSON(t *testing.T) {
15111511
t.Run(tt.name, func(t *testing.T) {
15121512
var cfg config
15131513
var err error
1514-
if err := ParseJSON(tt.r, &cfg); (err != nil) != tt.wantErr {
1514+
err = ParseJSON(tt.r, &cfg)
1515+
if err != nil && tt.wantErr {
15151516
t.Errorf("ParseJSON() error = %v, wantErr %v", err, tt.wantErr)
15161517
}
15171518
if err == nil && !reflect.DeepEqual(&cfg, tt.want) {
@@ -1569,7 +1570,8 @@ two = 2`),
15691570
t.Run(tt.name, func(t *testing.T) {
15701571
var cfg config
15711572
var err error
1572-
if err := ParseTOML(tt.r, &cfg); (err != nil) != tt.wantErr {
1573+
err = ParseTOML(tt.r, &cfg)
1574+
if err != nil && tt.wantErr {
15731575
t.Errorf("ParseTOML() error = %v, wantErr %v", err, tt.wantErr)
15741576
}
15751577
if err == nil && !reflect.DeepEqual(&cfg, tt.want) {

example/custom_setter/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"os"
77
"strings"
88

9-
"github.com/ilyakaznacheev/cleanenv"
9+
"github.com/teeaa/cleanenv"
1010
)
1111

1212
type config struct {

example/env_config/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"os"
88
"time"
99

10-
"github.com/ilyakaznacheev/cleanenv"
10+
"github.com/teeaa/cleanenv"
1111
)
1212

1313
type config struct {

example/parse_multiple_files/main.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ package main
33
import (
44
"log"
55

6-
"github.com/ilyakaznacheev/cleanenv"
6+
"github.com/teeaa/cleanenv"
77
)
88

99
type config struct {

example/simple_config/example.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import (
77
"net/http"
88
"os"
99

10-
"github.com/ilyakaznacheev/cleanenv"
10+
"github.com/teeaa/cleanenv"
1111
)
1212

1313
// Config is a application configuration structure

example_test.go

Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import (
66
"net/url"
77
"os"
88

9-
"github.com/ilyakaznacheev/cleanenv"
9+
"github.com/teeaa/cleanenv"
1010
)
1111

1212
// ExampleGetDescription builds a description text from structure tags
@@ -25,7 +25,7 @@ func ExampleGetDescription() {
2525
}
2626

2727
fmt.Println(text)
28-
//Output: Environment variables:
28+
// Output: Environment variables:
2929
// ONE int64
3030
// first parameter
3131
// THREE string
@@ -50,7 +50,7 @@ func ExampleGetDescription_defaults() {
5050
}
5151

5252
fmt.Println(text)
53-
//Output: Environment variables:
53+
// Output: Environment variables:
5454
// ONE int64
5555
// first parameter (default "1")
5656
// THREE string
@@ -73,7 +73,7 @@ func ExampleGetDescription_variableList() {
7373
}
7474

7575
fmt.Println(text)
76-
//Output: Environment variables:
76+
// Output: Environment variables:
7777
// ONE int64
7878
// first found parameter
7979
// THREE int64 (alternative to ONE)
@@ -100,7 +100,7 @@ func ExampleGetDescription_customHeaderText() {
100100
}
101101

102102
fmt.Println(text)
103-
//Output: Custom header text:
103+
// Output: Custom header text:
104104
// ONE int64
105105
// first parameter
106106
// THREE string
@@ -135,19 +135,19 @@ func ExampleUpdateEnv() {
135135
cleanenv.UpdateEnv(&cfg)
136136
fmt.Printf("%+v\n", cfg)
137137

138-
//Output: {One:1 Two:2}
138+
// Output: {One:1 Two:2}
139139
// {One:1 Two:22}
140-
141140
}
142141

143142
// ExampleReadEnv reads environment variables or default values into the structure
144143
func ExampleReadEnv() {
145144
type config struct {
146-
Port string `env:"PORT" env-default:"5432"`
147-
Host string `env:"HOST" env-default:"localhost"`
148-
Name string `env:"NAME" env-default:"postgres"`
149-
User string `env:"USER" env-default:"user"`
150-
Password string `env:"PASSWORD"`
145+
Port string `env:"PORT" env-default:"5432"`
146+
Host string `env:"HOST" env-default:"localhost"`
147+
Name string `env:"NAME" env-default:"postgres"`
148+
User string `env:"USER" env-default:"user"`
149+
Password string `env:"PASSWORD"`
150+
ImageCDN url.URL `env:"IMAGE_CDN"`
151151
}
152152

153153
var cfg config
@@ -156,27 +156,12 @@ func ExampleReadEnv() {
156156
os.Setenv("NAME", "redis")
157157
os.Setenv("USER", "tester")
158158
os.Setenv("PASSWORD", "*****")
159-
160-
cleanenv.ReadEnv(&cfg)
161-
fmt.Printf("%+v\n", cfg)
162-
163-
//Output: {Port:5050 Host:localhost Name:redis User:tester Password:*****}
164-
}
165-
166-
// ExampleReadEnv reads environment variables or default values into the structure
167-
func ExampleReadEnvWithURL() {
168-
type config struct {
169-
ImageCDN url.URL `env:"IMAGE_CDN"`
170-
}
171-
172-
var cfg config
173-
174159
os.Setenv("IMAGE_CDN", "https://images.cdn/")
175160

176161
cleanenv.ReadEnv(&cfg)
177-
fmt.Printf("%+v\n", cfg.ImageCDN.String())
162+
fmt.Printf("%+v\n", cfg)
178163

179-
//Output: https://images.cdn/
164+
// Output: {Port:5050 Host:localhost Name:redis User:tester Password:***** ImageCDN:{Scheme:https Opaque: User: Host:images.cdn Path:/ RawPath: OmitHost:false ForceQuery:false RawQuery: Fragment: RawFragment:}}
180165
}
181166

182167
// MyField1 is an example type with a custom setter
@@ -221,7 +206,7 @@ func Example_setter() {
221206

222207
cleanenv.ReadEnv(&cfg)
223208
fmt.Printf("%+v\n", cfg)
224-
//Output: {Default:test1 Custom1:my field is: test2 Custom2:my field is: test3}
209+
// Output: {Default:test1 Custom1:my field is: test2 Custom2:my field is: test3}
225210
}
226211

227212
// ConfigUpdate is a type with a custom updater
@@ -243,11 +228,11 @@ func Example_updater() {
243228

244229
cleanenv.ReadEnv(&cfg)
245230
fmt.Printf("%+v\n", cfg)
246-
//Output: {Default:default Custom:custom}
231+
// Output: {Default:default Custom:custom}
247232
}
248233

249234
func ExampleUsage() {
250-
os.Stderr = os.Stdout //replace STDERR with STDOUT for test
235+
os.Stderr = os.Stdout // replace STDERR with STDOUT for test
251236

252237
type config struct {
253238
One int64 `env:"ONE" env-description:"first parameter"`

0 commit comments

Comments
 (0)