Skip to content

Commit

Permalink
Merge branch 'main' into go-1-21-3
Browse files Browse the repository at this point in the history
Signed-off-by: Faisal Memon <[email protected]>
  • Loading branch information
faisal-memon authored Dec 13, 2023
2 parents 3bf4833 + 2c06c6e commit 885383d
Show file tree
Hide file tree
Showing 9 changed files with 302 additions and 86 deletions.
31 changes: 20 additions & 11 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,20 @@ If `-config` is not specified, the default value `helper.conf` is assumed.
## Configuration
The configuration file is an [HCL](https://github.com/hashicorp/hcl) formatted file that defines the following configurations:

|Configuration | Description | Example Value |
|--------------------------|------------------------------------------------------------------------------------------------| ------------- |
|`agent_address` | Socket address of SPIRE Agent. | `"/tmp/agent.sock"` |
|`cmd` | The path to the process to launch. | `"ghostunnel"` |
|`cmd_args` | The arguments of the process to launch. | `"server --listen localhost:8002 --target localhost:8001--keystore certs/svid_key.pem --cacert certs/svid_bundle.pem --allow-uri-san spiffe://example.org/Database"` |
|`cert_dir` | Directory name to store the fetched certificates. This directory must be created previously. | `"certs"` |
|`add_intermediates_to_bundle`| Add intermediate certificates into Bundle file instead of SVID file. | `true` |
|`renew_signal` | The signal that the process to be launched expects to reload the certificates. It is not supported on Windows. | `"SIGUSR1"` |
|`svid_file_name` | File name to be used to store the X.509 SVID public certificate in PEM format. | `"svid.pem"` |
|`svid_key_file_name` | File name to be used to store the X.509 SVID private key and public certificate in PEM format. | `"svid_key.pem"` |
|`svid_bundle_file_name` | File name to be used to store the X.509 SVID Bundle in PEM format. | `"svid_bundle.pem"` |
| Configuration | Description | Example Value |
|-----------------------------|----------------------------------------------------------------------------------------------------------------| -------------------- |
|`agent_address` | Socket address of SPIRE Agent. | `"/tmp/agent.sock"` |
|`cmd` | The path to the process to launch. | `"ghostunnel"` |
|`cmd_args` | The arguments of the process to launch. | `"server --listen localhost:8002 --target localhost:8001--keystore certs/svid_key.pem --cacert certs/svid_bundle.pem --allow-uri-san spiffe://example.org/Database"` |
|`cert_dir` | Directory name to store the fetched certificates. This directory must be created previously. | `"certs"` |
|`add_intermediates_to_bundle`| Add intermediate certificates into Bundle file instead of SVID file. | `true` |
|`renew_signal` | The signal that the process to be launched expects to reload the certificates. It is not supported on Windows. | `"SIGUSR1"` |
|`svid_file_name` | File name to be used to store the X.509 SVID public certificate in PEM format. | `"svid.pem"` |
|`svid_key_file_name` | File name to be used to store the X.509 SVID private key and public certificate in PEM format. | `"svid_key.pem"` |
|`svid_bundle_file_name` | File name to be used to store the X.509 SVID Bundle in PEM format. | `"svid_bundle.pem"` |
|`jwt_audience` | JWT SVID audience. | `"your-audience"` |
|`jwt_svid_file_name` | File name to be used to store JWT SVID in Base64-encoded string. | `"jwt_svid.token"` |
|`jwt_bundle_file_name` | File name to be used to store JWT Bundle in JSON format. | `"jwt_bundle.json"` |

### Configuration example
```
Expand All @@ -38,6 +41,9 @@ renew_signal = "SIGUSR1"
svid_file_name = "svid.pem"
svid_key_file_name = "svid_key.pem"
svid_bundle_file_name = "svid_bundle.pem"
jwt_audience = "your-audience"
jwt_svid_file_name = "jwt.token"
jwt_bundle_file_name = "bundle.json"
```

### Windows example
Expand All @@ -47,4 +53,7 @@ cert_dir = "certs"
svid_file_name = "svid.pem"
svid_key_file_name = "svid_key.pem"
svid_bundle_file_name = "svid_bundle.pem"
jwt_audience = "your-audience"
jwt_svid_file_name = "jwt.token"
jwt_bundle_file_name = "bundle.json"
```
12 changes: 6 additions & 6 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ require (
github.com/hashicorp/hcl v1.0.0
github.com/spiffe/go-spiffe/v2 v2.1.6
github.com/stretchr/testify v1.8.4
golang.org/x/sys v0.14.0
google.golang.org/grpc v1.59.0
golang.org/x/sys v0.15.0
google.golang.org/grpc v1.60.0
)

require google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d // indirect
require google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 // indirect

require (
github.com/Microsoft/go-winio v0.6.0 // indirect
Expand All @@ -21,10 +21,10 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/sirupsen/logrus v1.9.3
github.com/zeebo/errs v1.3.0 // indirect
golang.org/x/crypto v0.12.0 // indirect
golang.org/x/crypto v0.14.0 // indirect
golang.org/x/mod v0.8.0 // indirect
golang.org/x/net v0.14.0 // indirect
golang.org/x/text v0.12.0 // indirect
golang.org/x/net v0.16.0 // indirect
golang.org/x/text v0.13.0 // indirect
golang.org/x/tools v0.6.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
Expand Down
27 changes: 13 additions & 14 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -34,30 +34,29 @@ github.com/zeebo/errs v1.3.0 h1:hmiaKqgYZzcVgRL1Vkc1Mn2914BbzB0IBxs+ebeutGs=
github.com/zeebo/errs v1.3.0/go.mod h1:sgbWHsvVuTPHcqJJGQ1WhI5KbWlHYz+2+2C/LSEtCw4=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk=
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
golang.org/x/crypto v0.14.0 h1:wBqGXzWJW6m1XrIKlAH0Hs1JJ7+9KBwnIO8v66Q9cHc=
golang.org/x/crypto v0.14.0/go.mod h1:MVFd36DqK4CsrnJYDkBA3VC4m2GkXAM0PvzMCn4JQf4=
golang.org/x/mod v0.8.0 h1:LUYupSeNrTNCGzR/hVBk2NHZO4hXcVaW1k4Qx7rjPx8=
golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
golang.org/x/net v0.16.0 h1:7eBu7KsSvFDtSXUIDbh3aqlK4DPsZ1rByC8PFfBThos=
golang.org/x/net v0.16.0/go.mod h1:NxSsAGuq816PNPmqtQdLE42eU2Fs7NoRIZrHJAlaCOE=
golang.org/x/sync v0.4.0 h1:zxkM55ReGkDlKSM+Fu41A+zmbZuaPVbGMzvvdUPznYQ=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.14.0 h1:Vz7Qs629MkJkGyHxUlRHizWJRG2j8fbQKjELVSNhy7Q=
golang.org/x/sys v0.14.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/text v0.13.0 h1:ablQoSUd0tRdKxZewP80B+BaqeKJuVhuRxj/dkrun3k=
golang.org/x/text v0.13.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
golang.org/x/tools v0.6.0 h1:BOw41kyTf3PuCW1pVQf8+Cyg8pMlkYB1oo9iJ6D/lKM=
golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d h1:uvYuEyMHKNt+lT4K3bN6fGswmK8qSvcreM3BwjDh+y4=
google.golang.org/genproto/googleapis/rpc v0.0.0-20230822172742-b8732ec3820d/go.mod h1:+Bk1OCOj40wS2hwAMA+aCW9ypzm63QTBBHp6lQ3p+9M=
google.golang.org/grpc v1.59.0 h1:Z5Iec2pjwb+LEOqzpB2MR12/eKFhDPhuqW91O+4bwUk=
google.golang.org/grpc v1.59.0/go.mod h1:aUPDwccQo6OTjy7Hct4AfBPD1GptF4fyUjIkQ9YtF98=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97 h1:6GQBEOdGkX6MMTLT9V+TjtIRZCw9VPD5Z+yHY9wMgS0=
google.golang.org/genproto/googleapis/rpc v0.0.0-20231002182017-d307bd883b97/go.mod h1:v7nGkzlmW8P3n/bKmWBn2WpBjpOEx8Q6gMueudAmKfY=
google.golang.org/grpc v1.60.0 h1:6FQAR0kM31P6MRdeluor2w2gPaS4SVNrD/DNTxrQ15k=
google.golang.org/grpc v1.60.0/go.mod h1:OlCHIeLYqSSsLi6i49B5QGdzaMZK9+M7LXN2FKz4eGM=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.31.0 h1:g0LDEJHgrBl9N9r17Ru3sqWhkIx2NB67okBHPwC7hs8=
Expand Down
40 changes: 31 additions & 9 deletions pkg/sidecar/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,12 @@ type Config struct {
SvidBundleFileNameDeprecated string `hcl:"svidBundleFileName"`
RenewSignal string `hcl:"renew_signal"`
RenewSignalDeprecated string `hcl:"renewSignal"`

// JWT configuration
JWTAudience string `hcl:"jwt_audience"`
JWTSvidFilename string `hcl:"jwt_svid_file_name"`
JWTBundleFilename string `hcl:"jwt_bundle_file_name"`

// TODO: is there a reason for this to be exposed? and inside of config?
ReloadExternalProcess func() error
// TODO: is there a reason for this to be exposed? and inside of config?
Expand Down Expand Up @@ -114,18 +120,34 @@ func ValidateConfig(c *Config) error {
c.RenewSignal = c.RenewSignalDeprecated
}

switch {
case c.SvidFileName == "":
return errors.New("svid_file_name is required")
case c.SvidKeyFileName == "":
return errors.New("svid_key_file_name is required")
case c.SvidBundleFileName == "":
return errors.New("svid_bundle_file_name is required")
default:
return nil
x509EmptyCount := countEmpty(c.SvidFileName, c.SvidBundleFileName, c.SvidKeyFileName)
jwtSVIDEmptyCount := countEmpty(c.JWTSvidFilename, c.JWTAudience)
jwtBundleEmptyCount := countEmpty(c.SvidBundleFileName)
if x509EmptyCount == 3 && jwtSVIDEmptyCount == 2 && jwtBundleEmptyCount == 1 {
return errors.New("at least one of the sets ('svid_file_name', 'svid_key_file_name', 'svid_bundle_file_name'), ('jwt_file_name', 'jwt_audience'), or ('jwt_bundle_file_name') must be fully specified")
}

if x509EmptyCount != 0 && x509EmptyCount != 3 {
return errors.New("all or none of 'svid_file_name', 'svid_key_file_name', 'svid_bundle_file_name' must be specified")
}

if jwtSVIDEmptyCount != 0 && jwtSVIDEmptyCount != 2 {
return errors.New("all or none of 'jwt_file_name', 'jwt_audience' must be specified")
}

return nil
}

func getWarning(s1 string, s2 string) string {
return s1 + " will be deprecated, should be used as " + s2
}

func countEmpty(configs ...string) int {
cnt := 0
for _, config := range configs {
if config == "" {
cnt++
}
}
return cnt
}
45 changes: 27 additions & 18 deletions pkg/sidecar/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,9 @@ func TestParseConfig(t *testing.T) {
expectedSvidFileName := "svid.pem"
expectedKeyFileName := "svid_key.pem"
expectedSvidBundleFileName := "svid_bundle.pem"
expectedJWTSVIDFileName := "jwt_svid.token"
expectedJWTBundleFileName := "jwt_bundle.json"
expectedJWTAudience := "your-audience"

assert.Equal(t, expectedAgentAddress, c.AgentAddress)
assert.Equal(t, expectedCmd, c.Cmd)
Expand All @@ -31,6 +34,9 @@ func TestParseConfig(t *testing.T) {
assert.Equal(t, expectedSvidFileName, c.SvidFileName)
assert.Equal(t, expectedKeyFileName, c.SvidKeyFileName)
assert.Equal(t, expectedSvidBundleFileName, c.SvidBundleFileName)
assert.Equal(t, expectedJWTSVIDFileName, c.JWTSvidFilename)
assert.Equal(t, expectedJWTBundleFileName, c.JWTBundleFilename)
assert.Equal(t, expectedJWTAudience, c.JWTAudience)
assert.True(t, c.AddIntermediatesToBundle)
}

Expand All @@ -51,33 +57,37 @@ func TestValidateConfig(t *testing.T) {
},
},
{
name: "no SVID file",
name: "no error",
config: &Config{
AgentAddress: "path",
SvidKeyFileName: "key.pem",
SvidBundleFileName: "bundle.pem",
AgentAddress: "path",
JWTAudience: "your-audience",
JWTSvidFilename: "jwt.token",
JWTBundleFilename: "bundle.json",
},
expectError: "svid_file_name is required",
},
{
name: "no key file",
name: "no set specified",
config: &Config{
AgentAddress: "path",
SvidFileName: "cert.pem",
SvidBundleFileName: "bundle.pem",
AgentAddress: "path",
},
expectError: "svid_key_file_name is required",
expectError: "at least one of the sets ('svid_file_name', 'svid_key_file_name', 'svid_bundle_file_name'), ('jwt_file_name', 'jwt_audience'), or ('jwt_bundle_file_name') must be fully specified",
},
{
name: "no bundle file",
name: "missing svid config",
config: &Config{
AgentAddress: "path",
SvidFileName: "cert.pem",
},
expectError: "all or none of 'svid_file_name', 'svid_key_file_name', 'svid_bundle_file_name' must be specified",
},
{
name: "missing jwt config",
config: &Config{
AgentAddress: "path",
SvidFileName: "cert.pem",
SvidKeyFileName: "key.pem",
JWTSvidFilename: "cert.pem",
},
expectError: "svid_bundle_file_name is required",
expectError: "all or none of 'jwt_file_name', 'jwt_audience' must be specified",
},

// Duplicated field error:
{
name: "Both agent_address & agentAddress in use",
Expand All @@ -88,7 +98,7 @@ func TestValidateConfig(t *testing.T) {
SvidKeyFileName: "key.pem",
SvidBundleFileName: "bundle.pem",
},
expectError: "use of agent_address and AgentAddress found, use only agent_address",
expectError: "use of agent_address and agentAddress found, use only agent_address",
},
{
name: "Both cmd_args & cmdArgs in use",
Expand Down Expand Up @@ -159,7 +169,6 @@ func TestValidateConfig(t *testing.T) {
},
expectError: "use of renew_signal and renewSignal found, use only renew_signal",
},

// Deprecated field warning:
{
name: "Using AgentAddressDeprecated",
Expand Down Expand Up @@ -276,7 +285,7 @@ func TestValidateConfig(t *testing.T) {
require.ElementsMatch(t, tt.expectLogs, getShortEntries(hook.AllEntries()))

if tt.expectError != "" {
require.Error(t, err, tt.expectError)
require.EqualError(t, err, tt.expectError)
return
}

Expand Down
Loading

0 comments on commit 885383d

Please sign in to comment.