diff --git a/libs/go/sia/agent/agent.go b/libs/go/sia/agent/agent.go
index 2b4c8342c6d..5485443713e 100644
--- a/libs/go/sia/agent/agent.go
+++ b/libs/go/sia/agent/agent.go
@@ -85,10 +85,10 @@ func RoleKey(rotateKey bool, roleKey, svcKey string) (*rsa.PrivateKey, error) {
}
}
-func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
+func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, []string) {
//initialize our return state to success
- failures := 0
+ failures := make([]string, 0)
for _, role := range opts.Roles {
var roleRequest = new(zts.RoleCertificateRequest)
@@ -99,7 +99,7 @@ func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
client, err := util.ZtsClient(ztsUrl, opts.ZTSServerName, svcKeyFile, svcCertFile, opts.ZTSCACertFile)
if err != nil {
log.Printf("unable to initialize ZTS Client with url %s for role %s, err: %v\n", ztsUrl, role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
client.AddCredentials("User-Agent", opts.Version)
@@ -112,7 +112,7 @@ func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
}
if err != nil {
log.Printf("unable to read private key role %s, err: %v\n", role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
@@ -134,7 +134,7 @@ func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
csr, err := util.GenerateRoleCertCSR(key, roleCertReqOptions)
if err != nil {
log.Printf("unable to generate CSR for %s, err: %v\n", role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
roleRequest.Csr = csr
@@ -155,18 +155,18 @@ func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
roleCert, err := client.PostRoleCertificateRequestExt(roleRequest)
if err != nil {
log.Printf("PostRoleCertificateRequest failed for %s, err: %v\n", role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
roleKeyBytes := util.PrivatePem(key)
err = util.SaveRoleCertKey([]byte(roleKeyBytes), []byte(roleCert.X509Certificate), role.RoleKeyFilename, role.RoleCertFilename, svcKeyFile, role.Name, role.Uid, role.Gid, role.FileMode, opts.GenerateRoleKey, opts.RotateKey, opts.BackupDir, opts.FileDirectUpdate)
if err != nil {
log.Printf("Unable to save role cert key for role %s, err: %v\n", role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
}
- log.Printf("SIA processed %d (failures %d) role certificate requests\n", len(opts.Roles), failures)
+ log.Printf("SIA processed %d (failures %d) role certificate requests\n", len(opts.Roles), len(failures))
return len(opts.Roles), failures
}
@@ -601,7 +601,14 @@ func SetupAgent(opts *options.Options, siaMainDir, siaLinkDir string) {
}
}
-func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
+func RunAgent(siaCmds, ztsUrl string, opts *options.Options) {
+ cmds := strings.Split(siaCmds, ",")
+ for _, cmd := range cmds {
+ runAgentCommand(cmd, ztsUrl, opts)
+ }
+}
+
+func runAgentCommand(siaCmd, ztsUrl string, opts *options.Options) {
//make sure the meta endpoint is configured by the caller
if opts.MetaEndPoint == "" {
@@ -626,19 +633,25 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
switch cmd {
case "rolecert":
count, failures := GetRoleCertificates(ztsUrl, opts)
- if failures != 0 && !skipErrors {
- log.Fatalf("unable to fetch %d out of %d requested role certificates\n", failures, count)
+ if len(failures) != 0 {
+ util.ExecuteScript(opts.RunAfterCertsErrParts, strings.Join(failures, ","), false)
+ if !skipErrors {
+ log.Fatalf("unable to fetch %d out of %d requested role certificates\n", len(failures), count)
+ }
}
if count != 0 {
- util.ExecuteScript(opts.RunAfterParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
}
case "token":
if tokenOpts != nil {
err := fetchAccessToken(tokenOpts)
- if err != nil && !skipErrors {
- log.Fatalf("Unable to fetch access tokens, err: %v\n", err)
+ if err != nil {
+ util.ExecuteScript(opts.RunAfterTokensErrParts, err.Error(), false)
+ if !skipErrors {
+ log.Fatalf("Unable to fetch access tokens, err: %v\n", err)
+ }
}
- util.ExecuteScript(opts.RunAfterTokensParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterTokensOkParts, "", opts.RunAfterFailExit)
} else {
log.Print("unable to fetch access tokens, invalid or missing configuration")
}
@@ -647,14 +660,14 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
if err != nil {
log.Fatalf("Unable to register identity, err: %v\n", err)
}
- util.ExecuteScript(opts.RunAfterParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
log.Printf("identity registered for services: %s\n", svcs)
case "rotate", "refresh":
err = RefreshInstance(ztsUrl, opts)
if err != nil {
log.Fatalf("Refresh identity failed, err: %v\n", err)
}
- util.ExecuteScript(opts.RunAfterParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
log.Printf("Identity successfully refreshed for services: %s\n", svcs)
case "init":
err := RegisterInstance(ztsUrl, opts, false)
@@ -663,16 +676,22 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
}
log.Printf("identity registered for services: %s\n", svcs)
count, failures := GetRoleCertificates(ztsUrl, opts)
- if failures != 0 && !skipErrors {
- log.Fatalf("unable to fetch %d out of %d requested role certificates\n", failures, count)
+ if len(failures) != 0 {
+ util.ExecuteScript(opts.RunAfterCertsErrParts, strings.Join(failures, ","), false)
+ if !skipErrors {
+ log.Fatalf("unable to fetch %d out of %d requested role certificates\n", len(failures), count)
+ }
}
- util.ExecuteScript(opts.RunAfterParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
if tokenOpts != nil {
err := fetchAccessToken(tokenOpts)
- if err != nil && !skipErrors {
- log.Fatalf("Unable to fetch access tokens, err: %v\n", err)
+ if err != nil {
+ util.ExecuteScript(opts.RunAfterTokensErrParts, err.Error(), false)
+ if !skipErrors {
+ log.Fatalf("Unable to fetch access tokens, err: %v\n", err)
+ }
}
- util.ExecuteScript(opts.RunAfterTokensParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterTokensOkParts, "", opts.RunAfterFailExit)
}
default:
// we're going to iterate through our configured services.
@@ -729,6 +748,7 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
errors <- fmt.Errorf("refresh identity failed: %v\n", err)
return
} else {
+ util.ExecuteScriptWithoutBlock(opts.RunAfterCertsErrParts, svcs, false)
log.Printf("refresh identity failed for svcs %s, error: %v\n", svcs, err)
log.Printf("refresh will be retried in %d minutes, failure %d of %d\n", opts.RefreshInterval, failedRefreshCount, opts.FailCountForExit)
}
@@ -741,15 +761,18 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
if tokenOpts != nil {
err := accessTokenRequest(tokenOpts)
if err != nil {
- errors <- fmt.Errorf("Unable to fetch access tokens after identity refresh, err: %v\n", err)
+ util.ExecuteScriptWithoutBlock(opts.RunAfterTokensErrParts, err.Error(), false)
} else {
- util.ExecuteScriptWithoutBlock(opts.RunAfterTokensParts, opts.RunAfterFailExit)
+ util.ExecuteScriptWithoutBlock(opts.RunAfterTokensOkParts, "", opts.RunAfterFailExit)
}
} else {
log.Print("token config does not exist - do not refresh tokens")
}
- GetRoleCertificates(ztsUrl, opts)
- util.ExecuteScriptWithoutBlock(opts.RunAfterParts, opts.RunAfterFailExit)
+ _, failures := GetRoleCertificates(ztsUrl, opts)
+ if len(failures) != 0 {
+ util.ExecuteScriptWithoutBlock(opts.RunAfterCertsErrParts, strings.Join(failures, ","), false)
+ }
+ util.ExecuteScriptWithoutBlock(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
util.NotifySystemdReadyForCommand(cmd, "systemd-notify-all")
if opts.SDSUdsPath != "" {
@@ -799,9 +822,9 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
log.Printf("refreshing access-token..")
err := accessTokenRequest(tokenOpts)
if err != nil {
- errors <- fmt.Errorf("refresh access-token task got error: %v\n", err)
+ util.ExecuteScriptWithoutBlock(opts.RunAfterTokensErrParts, err.Error(), false)
} else {
- util.ExecuteScriptWithoutBlock(opts.RunAfterTokensParts, opts.RunAfterFailExit)
+ util.ExecuteScriptWithoutBlock(opts.RunAfterTokensOkParts, "", opts.RunAfterFailExit)
}
case <-stop:
errors <- nil
diff --git a/libs/go/sia/agent/agent_test.go b/libs/go/sia/agent/agent_test.go
index c83f8a3013b..2eb6143d8d9 100644
--- a/libs/go/sia/agent/agent_test.go
+++ b/libs/go/sia/agent/agent_test.go
@@ -372,7 +372,7 @@ func TestRoleCertificateRequest(test *testing.T) {
}
_, failures := GetRoleCertificates("http://127.0.0.1:5084/zts/v1", opts)
- if failures != 0 {
+ if len(failures) != 0 {
test.Errorf("Unable to get role certificate: %v", err)
return
}
diff --git a/libs/go/sia/aws/agent/agent.go b/libs/go/sia/aws/agent/agent.go
index 83731476629..5a7175e4721 100644
--- a/libs/go/sia/aws/agent/agent.go
+++ b/libs/go/sia/aws/agent/agent.go
@@ -87,10 +87,10 @@ func RoleKey(rotateKey bool, roleKey, svcKey string) (*rsa.PrivateKey, error) {
}
}
-func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
+func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, []string) {
//initialize our return state to success
- failures := 0
+ failures := make([]string, 0)
for _, role := range opts.Roles {
var roleRequest = new(zts.RoleCertificateRequest)
@@ -101,7 +101,7 @@ func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
client, err := util.ZtsClient(ztsUrl, opts.ZTSServerName, svcKeyFile, svcCertFile, opts.ZTSCACertFile)
if err != nil {
log.Printf("unable to initialize ZTS Client with url %s for role %s, err: %v\n", ztsUrl, role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
client.AddCredentials("User-Agent", opts.Version)
@@ -114,7 +114,7 @@ func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
}
if err != nil {
log.Printf("unable to read private key role %s, err: %v\n", role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
@@ -136,7 +136,7 @@ func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
csr, err := util.GenerateRoleCertCSR(key, roleCertReqOptions)
if err != nil {
log.Printf("unable to generate CSR for %s, err: %v\n", role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
roleRequest.Csr = csr
@@ -157,18 +157,18 @@ func GetRoleCertificates(ztsUrl string, opts *options.Options) (int, int) {
roleCert, err := client.PostRoleCertificateRequestExt(roleRequest)
if err != nil {
log.Printf("PostRoleCertificateRequest failed for %s, err: %v\n", role.Name, err)
- failures += 1
+ failures = append(failures, role.Name)
continue
}
roleKeyBytes := util.PrivatePem(key)
err = util.SaveRoleCertKey([]byte(roleKeyBytes), []byte(roleCert.X509Certificate), role.RoleKeyFilename, role.RoleCertFilename, svcKeyFile, role.Name, role.Uid, role.Gid, role.FileMode, opts.GenerateRoleKey, opts.RotateKey, opts.BackupDir, opts.FileDirectUpdate)
if err != nil {
- failures += 1
+ failures = append(failures, role.Name)
continue
}
}
- log.Printf("SIA processed %d (failures %d) role certificate requests\n", len(opts.Roles), failures)
+ log.Printf("SIA processed %d (failures %d) role certificate requests\n", len(opts.Roles), len(failures))
return len(opts.Roles), failures
}
@@ -597,7 +597,14 @@ func SetupAgent(opts *options.Options, siaMainDir, siaLinkDir string) {
}
}
-func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
+func RunAgent(siaCmds, ztsUrl string, opts *options.Options) {
+ cmds := strings.Split(siaCmds, ",")
+ for _, cmd := range cmds {
+ runAgentCommand(cmd, ztsUrl, opts)
+ }
+}
+
+func runAgentCommand(siaCmd, ztsUrl string, opts *options.Options) {
//make sure the meta endpoint is configured by the caller
if opts.MetaEndPoint == "" {
@@ -622,19 +629,25 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
switch cmd {
case "rolecert":
count, failures := GetRoleCertificates(ztsUrl, opts)
- if failures != 0 && !skipErrors {
- log.Fatalf("unable to fetch %d out of %d requested role certificates\n", failures, count)
+ if len(failures) != 0 {
+ util.ExecuteScript(opts.RunAfterCertsErrParts, strings.Join(failures, ","), false)
+ if !skipErrors {
+ log.Fatalf("unable to fetch %d out of %d requested role certificates\n", len(failures), count)
+ }
}
if count != 0 {
- util.ExecuteScript(opts.RunAfterParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
}
case "token":
if tokenOpts != nil {
err := fetchAccessToken(tokenOpts)
- if err != nil && !skipErrors {
- log.Fatalf("Unable to fetch access tokens, err: %v\n", err)
+ if err != nil {
+ util.ExecuteScript(opts.RunAfterTokensErrParts, err.Error(), false)
+ if !skipErrors {
+ log.Fatalf("Unable to fetch access tokens, err: %v\n", err)
+ }
}
- util.ExecuteScript(opts.RunAfterTokensParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterTokensOkParts, "", opts.RunAfterFailExit)
} else {
log.Print("unable to fetch access tokens, invalid or missing configuration")
}
@@ -643,14 +656,14 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
if err != nil {
log.Fatalf("Unable to register identity, err: %v\n", err)
}
- util.ExecuteScript(opts.RunAfterParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
log.Printf("identity registered for services: %s\n", svcs)
case "rotate", "refresh":
err = RefreshInstance(data, ztsUrl, opts)
if err != nil {
log.Fatalf("Refresh identity failed, err: %v\n", err)
}
- util.ExecuteScript(opts.RunAfterParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
log.Printf("Identity successfully refreshed for services: %s\n", svcs)
case "init":
err := RegisterInstance(data, ztsUrl, opts, false)
@@ -659,16 +672,22 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
}
log.Printf("identity registered for services: %s\n", svcs)
count, failures := GetRoleCertificates(ztsUrl, opts)
- if failures != 0 && !skipErrors {
- log.Fatalf("unable to fetch %d out of %d requested role certificates\n", failures, count)
+ if len(failures) != 0 {
+ util.ExecuteScript(opts.RunAfterCertsErrParts, strings.Join(failures, ","), false)
+ if !skipErrors {
+ log.Fatalf("unable to fetch %d out of %d requested role certificates\n", len(failures), count)
+ }
}
- util.ExecuteScript(opts.RunAfterParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
if tokenOpts != nil {
err := fetchAccessToken(tokenOpts)
- if err != nil && !skipErrors {
- log.Fatalf("Unable to fetch access tokens, err: %v\n", err)
+ if err != nil {
+ util.ExecuteScript(opts.RunAfterTokensErrParts, err.Error(), false)
+ if !skipErrors {
+ log.Fatalf("Unable to fetch access tokens, err: %v\n", err)
+ }
}
- util.ExecuteScript(opts.RunAfterTokensParts, opts.RunAfterFailExit)
+ util.ExecuteScript(opts.RunAfterTokensOkParts, "", opts.RunAfterFailExit)
}
default:
// we're going to iterate through our configured services.
@@ -730,6 +749,7 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
errors <- fmt.Errorf("refresh identity failed: %v\n", err)
return
} else {
+ util.ExecuteScriptWithoutBlock(opts.RunAfterCertsErrParts, svcs, false)
log.Printf("refresh identity failed for svcs %s, error: %v\n", svcs, err)
log.Printf("refresh will be retried in %d minutes, failure %d of %d\n", opts.RefreshInterval, failedRefreshCount, opts.FailCountForExit)
}
@@ -742,15 +762,18 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
if tokenOpts != nil {
err := accessTokenRequest(tokenOpts)
if err != nil {
- errors <- fmt.Errorf("Unable to fetch access token after identity refresh, err: %v\n", err)
+ util.ExecuteScriptWithoutBlock(opts.RunAfterTokensErrParts, err.Error(), false)
} else {
- util.ExecuteScriptWithoutBlock(opts.RunAfterTokensParts, opts.RunAfterFailExit)
+ util.ExecuteScriptWithoutBlock(opts.RunAfterTokensOkParts, "", opts.RunAfterFailExit)
}
} else {
log.Print("token config does not exist - do not refresh token")
}
- GetRoleCertificates(ztsUrl, opts)
- util.ExecuteScriptWithoutBlock(opts.RunAfterParts, opts.RunAfterFailExit)
+ _, failures := GetRoleCertificates(ztsUrl, opts)
+ if len(failures) != 0 {
+ util.ExecuteScriptWithoutBlock(opts.RunAfterCertsErrParts, strings.Join(failures, ","), false)
+ }
+ util.ExecuteScriptWithoutBlock(opts.RunAfterCertsOkParts, "", opts.RunAfterFailExit)
util.NotifySystemdReadyForCommand(cmd, "systemd-notify-all")
if opts.SDSUdsPath != "" {
@@ -800,9 +823,9 @@ func RunAgent(siaCmd, ztsUrl string, opts *options.Options) {
log.Printf("refreshing access-token..")
err := accessTokenRequest(tokenOpts)
if err != nil {
- errors <- fmt.Errorf("refresh access-token task got error: %v\n", err)
+ util.ExecuteScriptWithoutBlock(opts.RunAfterTokensErrParts, err.Error(), false)
} else {
- util.ExecuteScriptWithoutBlock(opts.RunAfterTokensParts, opts.RunAfterFailExit)
+ util.ExecuteScriptWithoutBlock(opts.RunAfterTokensOkParts, "", opts.RunAfterFailExit)
}
case <-stop:
errors <- nil
diff --git a/libs/go/sia/aws/agent/agent_test.go b/libs/go/sia/aws/agent/agent_test.go
index c29be7728e0..dfe64c87a1a 100644
--- a/libs/go/sia/aws/agent/agent_test.go
+++ b/libs/go/sia/aws/agent/agent_test.go
@@ -388,7 +388,7 @@ func TestRoleCertificateRequest(test *testing.T) {
}
_, failures := GetRoleCertificates("http://127.0.0.1:5084/zts/v1", opts)
- if failures != 0 {
+ if len(failures) != 0 {
test.Errorf("Unable to get role certificate: %v", err)
return
}
diff --git a/libs/go/sia/aws/options/options.go b/libs/go/sia/aws/options/options.go
index 8c0c65d4d6d..8fff4d8f6cf 100644
--- a/libs/go/sia/aws/options/options.go
+++ b/libs/go/sia/aws/options/options.go
@@ -79,41 +79,43 @@ type ConfigAccount struct {
// Config represents entire sia_config file
type Config struct {
- Version string `json:"version,omitempty"` //name of the provider
- Service string `json:"service,omitempty"` //name of the service for the identity
- Services map[string]ConfigService `json:"services,omitempty"` //names of the multiple services for the identity
- Ssh *bool `json:"ssh,omitempty"` //ssh certificate support
- SshHostKeyType hostkey.KeyType `json:"ssh_host_key_type,omitempty"` //ssh host key type - rsa, ecdsa, etc
- SshPrincipals string `json:"ssh_principals,omitempty"` //ssh additional principals
- SanDnsWildcard bool `json:"sandns_wildcard,omitempty"` //san dns wildcard support
- SanDnsHostname bool `json:"sandns_hostname,omitempty"` //san dns hostname support
- SanDnsX509Cnames string `json:"sandns_x509_cnames,omitempty"` //additional san dns entries to be added to the CSR
- UseRegionalSTS bool `json:"regionalsts,omitempty"` //whether to use a regional STS endpoint (default is false)
- Accounts []ConfigAccount `json:"accounts,omitempty"` //array of configured accounts
- GenerateRoleKey bool `json:"generate_role_key,omitempty"` //private key to be generated for role certificate
- RotateKey bool `json:"rotate_key,omitempty"` //rotate private key support
- User string `json:"user,omitempty"` //the username to chown the cert/key dirs to. If absent, then root
- Group string `json:"group,omitempty"` //the group name to chown the cert/key dirs to. If absent, then athenz
- SDSUdsPath string `json:"sds_uds_path,omitempty"` //uds path if the agent should support uds connections
- SDSUdsUid int `json:"sds_uds_uid,omitempty"` //uds connections must be from the given user uid
- ExpiryTime int `json:"expiry_time,omitempty"` //service and role certificate expiry in minutes
- RefreshInterval int `json:"refresh_interval,omitempty"` //specifies refresh interval in minutes
- ZTSRegion string `json:"zts_region,omitempty"` //specifies zts region for the requests
- DropPrivileges bool `json:"drop_privileges,omitempty"` //drop privileges to configured user instead of running as root
- AccessTokens map[string]ac.Role `json:"access_tokens,omitempty"` //map of role name to token attributes
- FileDirectUpdate bool `json:"file_direct_update,omitempty"` //update key/cert files directly instead of using rename
- SiaKeyDir string `json:"sia_key_dir,omitempty"` //sia keys directory to override /var/lib/sia/keys
- SiaCertDir string `json:"sia_cert_dir,omitempty"` //sia certs directory to override /var/lib/sia/certs
- SiaTokenDir string `json:"sia_token_dir,omitempty"` //sia tokens directory to override /var/lib/sia/tokens
- SiaBackupDir string `json:"sia_backup_dir,omitempty"` //sia backup directory to override /var/lib/sia/backup
- HostnameSuffix string `json:"hostname_suffix,omitempty"` //hostname suffix in case we need to auto-generate hostname
- AccessManagement bool `json:"access_management,omitempty"` //access management support
- FailCountForExit int `json:"fail_count_for_exit,omitempty"` //number of failed counts before exiting program
- RunAfter string `json:"run_after,omitempty"` //execute the command mentioned after certs are created
- RunAfterTokens string `json:"run_after_tokens,omitempty"` //execute the command mentioned after tokens are created
- SpiffeTrustDomain string `json:"spiffe_trust_domain,omitempty"` //spiffe trust domain - if configured used full spiffe uri with namespace
- StoreTokenOption *int `json:"store_token_option,omitempty"` //store access token option
- RunAfterFailExit bool `json:"run_after_fail_exit,omitempty"` //exit process if run_after script fails
+ Version string `json:"version,omitempty"` //name of the provider
+ Service string `json:"service,omitempty"` //name of the service for the identity
+ Services map[string]ConfigService `json:"services,omitempty"` //names of the multiple services for the identity
+ Ssh *bool `json:"ssh,omitempty"` //ssh certificate support
+ SshHostKeyType hostkey.KeyType `json:"ssh_host_key_type,omitempty"` //ssh host key type - rsa, ecdsa, etc
+ SshPrincipals string `json:"ssh_principals,omitempty"` //ssh additional principals
+ SanDnsWildcard bool `json:"sandns_wildcard,omitempty"` //san dns wildcard support
+ SanDnsHostname bool `json:"sandns_hostname,omitempty"` //san dns hostname support
+ SanDnsX509Cnames string `json:"sandns_x509_cnames,omitempty"` //additional san dns entries to be added to the CSR
+ UseRegionalSTS bool `json:"regionalsts,omitempty"` //whether to use a regional STS endpoint (default is false)
+ Accounts []ConfigAccount `json:"accounts,omitempty"` //array of configured accounts
+ GenerateRoleKey bool `json:"generate_role_key,omitempty"` //private key to be generated for role certificate
+ RotateKey bool `json:"rotate_key,omitempty"` //rotate private key support
+ User string `json:"user,omitempty"` //the username to chown the cert/key dirs to. If absent, then root
+ Group string `json:"group,omitempty"` //the group name to chown the cert/key dirs to. If absent, then athenz
+ SDSUdsPath string `json:"sds_uds_path,omitempty"` //uds path if the agent should support uds connections
+ SDSUdsUid int `json:"sds_uds_uid,omitempty"` //uds connections must be from the given user uid
+ ExpiryTime int `json:"expiry_time,omitempty"` //service and role certificate expiry in minutes
+ RefreshInterval int `json:"refresh_interval,omitempty"` //specifies refresh interval in minutes
+ ZTSRegion string `json:"zts_region,omitempty"` //specifies zts region for the requests
+ DropPrivileges bool `json:"drop_privileges,omitempty"` //drop privileges to configured user instead of running as root
+ AccessTokens map[string]ac.Role `json:"access_tokens,omitempty"` //map of role name to token attributes
+ FileDirectUpdate bool `json:"file_direct_update,omitempty"` //update key/cert files directly instead of using rename
+ SiaKeyDir string `json:"sia_key_dir,omitempty"` //sia keys directory to override /var/lib/sia/keys
+ SiaCertDir string `json:"sia_cert_dir,omitempty"` //sia certs directory to override /var/lib/sia/certs
+ SiaTokenDir string `json:"sia_token_dir,omitempty"` //sia tokens directory to override /var/lib/sia/tokens
+ SiaBackupDir string `json:"sia_backup_dir,omitempty"` //sia backup directory to override /var/lib/sia/backup
+ HostnameSuffix string `json:"hostname_suffix,omitempty"` //hostname suffix in case we need to auto-generate hostname
+ AccessManagement bool `json:"access_management,omitempty"` //access management support
+ FailCountForExit int `json:"fail_count_for_exit,omitempty"` //number of failed counts before exiting program
+ RunAfterCerts string `json:"run_after,omitempty"` //execute the command mentioned after certs are created
+ RunAfterCertsErr string `json:"run_after_certs_err,omitempty"` //execute the command mentioned after role certs fail to refresh
+ RunAfterTokens string `json:"run_after_tokens,omitempty"` //execute the command mentioned after tokens are created
+ RunAfterTokensErr string `json:"run_after_tokens_err,omitempty"` //execute the command mentioned after tokens fail to refresh
+ SpiffeTrustDomain string `json:"spiffe_trust_domain,omitempty"` //spiffe trust domain - if configured used full spiffe uri with namespace
+ StoreTokenOption *int `json:"store_token_option,omitempty"` //store access token option
+ RunAfterFailExit bool `json:"run_after_fail_exit,omitempty"` //exit process if run_after script fails
}
type AccessProfileConfig struct {
@@ -156,70 +158,72 @@ type Service struct {
// Options represents settings that are derived from config file and application defaults
type Options struct {
- Provider provider.Provider //provider instance
- MetaEndPoint string //meta data service endpoint
- Name string //name of the service identity
- User string //the username to chown the cert/key dirs to. If absent, then root
- Group string //the group name to chown the cert/key dirs to. If absent, then athenz
- Domain string //name of the domain for the identity
- Account string //name of the account
- Service string //name of the service for the identity
- Zts string //the ZTS to contact
- InstanceId string //instance id if ec2, task id if running within eks/ecs
- Roles []Role //map of roles to retrieve certificates for
- Region string //region name
- SanDnsWildcard bool //san dns wildcard support
- SanDnsHostname bool //san dns hostname support
- Version string //sia version number
- ZTSDomains []string //zts domain prefixes
- Services []Service //array of configured services
- Ssh bool //ssh certificate support
- UseRegionalSTS bool //use regional sts endpoint
- KeyDir string //private key directory path
- CertDir string //x.509 certificate directory path
- AthenzCACertFile string //filename to store Athenz CA certs
- ZTSCACertFile string //filename for CA certs when communicating with ZTS
- ZTSServerName string //ZTS server name, if necessary for tls
- ZTSAWSDomains []string //list of domain prefixes for sanDNS entries
- GenerateRoleKey bool //option to generate a separate key for role certificates
- RotateKey bool //rotate the private key when refreshing certificates
- BackupDir string //backup directory for key/cert rotation
- CertCountryName string //generated x.509 certificate country name
- CertOrgName string //generated x.509 certificate organization name
- SshPubKeyFile string //ssh host public key file path
- SshCertFile string //ssh host certificate file path
- SshConfigFile string //sshd config file path
- SshHostKeyType hostkey.KeyType //ssh host key type - rsa or ecdsa
- PrivateIp string //instance private ip
- EC2Document string //EC2 instance identity document
- EC2Signature string //EC2 instance identity document pkcs7 signature
- EC2StartTime *time.Time //EC2 instance start time
- InstanceIdSanDNS bool //include instance id in a san dns entry (backward compatible option)
- RolePrincipalEmail bool //include role principal in a san email field (backward compatible option)
- SDSUdsPath string //UDS path if the agent should support uds connections
- SDSUdsUid int //UDS connections must be from the given user uid
- RefreshInterval int //refresh interval for certificates - default 24 hours
- ZTSRegion string //ZTS region in case the client needs this information
- DropPrivileges bool //Drop privileges to configured user instead of running as root
- TokenDir string //Access tokens directory
- AccessTokens []ac.AccessToken //Access tokens object
- Profile string //Access profile name
- ProfileRestrictTo string //Tag associated with access profile roles
- Threshold float64 //threshold in number of days for cert expiry checks
- SshThreshold float64 //threshold in number of days for ssh cert expiry checks
- FileDirectUpdate bool //update key/cert files directly instead of using rename
- HostnameSuffix string //hostname suffix in case we need to auto-generate hostname
- SshPrincipals string //ssh additional principals
- AccessManagement bool //access management support
- AddlSanDNSEntries []string //additional san dns entries to be added to the CSR
- FailCountForExit int //number of failed counts before exiting program
- RunAfterParts []string //run after parsed parts
- RunAfterTokensParts []string //run after token parsed parts
- SpiffeTrustDomain string //spiffe uri trust domain
- SpiffeNamespace string //spiffe uri namespace
- OmitDomain bool //attestation role only includes service name
- StoreTokenOption *int //store access token option
- RunAfterFailExit bool //exit process if run_after script fails
+ Provider provider.Provider //provider instance
+ MetaEndPoint string //meta data service endpoint
+ Name string //name of the service identity
+ User string //the username to chown the cert/key dirs to. If absent, then root
+ Group string //the group name to chown the cert/key dirs to. If absent, then athenz
+ Domain string //name of the domain for the identity
+ Account string //name of the account
+ Service string //name of the service for the identity
+ Zts string //the ZTS to contact
+ InstanceId string //instance id if ec2, task id if running within eks/ecs
+ Roles []Role //map of roles to retrieve certificates for
+ Region string //region name
+ SanDnsWildcard bool //san dns wildcard support
+ SanDnsHostname bool //san dns hostname support
+ Version string //sia version number
+ ZTSDomains []string //zts domain prefixes
+ Services []Service //array of configured services
+ Ssh bool //ssh certificate support
+ UseRegionalSTS bool //use regional sts endpoint
+ KeyDir string //private key directory path
+ CertDir string //x.509 certificate directory path
+ AthenzCACertFile string //filename to store Athenz CA certs
+ ZTSCACertFile string //filename for CA certs when communicating with ZTS
+ ZTSServerName string //ZTS server name, if necessary for tls
+ ZTSAWSDomains []string //list of domain prefixes for sanDNS entries
+ GenerateRoleKey bool //option to generate a separate key for role certificates
+ RotateKey bool //rotate the private key when refreshing certificates
+ BackupDir string //backup directory for key/cert rotation
+ CertCountryName string //generated x.509 certificate country name
+ CertOrgName string //generated x.509 certificate organization name
+ SshPubKeyFile string //ssh host public key file path
+ SshCertFile string //ssh host certificate file path
+ SshConfigFile string //sshd config file path
+ SshHostKeyType hostkey.KeyType //ssh host key type - rsa or ecdsa
+ PrivateIp string //instance private ip
+ EC2Document string //EC2 instance identity document
+ EC2Signature string //EC2 instance identity document pkcs7 signature
+ EC2StartTime *time.Time //EC2 instance start time
+ InstanceIdSanDNS bool //include instance id in a san dns entry (backward compatible option)
+ RolePrincipalEmail bool //include role principal in a san email field (backward compatible option)
+ SDSUdsPath string //UDS path if the agent should support uds connections
+ SDSUdsUid int //UDS connections must be from the given user uid
+ RefreshInterval int //refresh interval for certificates - default 24 hours
+ ZTSRegion string //ZTS region in case the client needs this information
+ DropPrivileges bool //Drop privileges to configured user instead of running as root
+ TokenDir string //Access tokens directory
+ AccessTokens []ac.AccessToken //Access tokens object
+ Profile string //Access profile name
+ ProfileRestrictTo string //Tag associated with access profile roles
+ Threshold float64 //threshold in number of days for cert expiry checks
+ SshThreshold float64 //threshold in number of days for ssh cert expiry checks
+ FileDirectUpdate bool //update key/cert files directly instead of using rename
+ HostnameSuffix string //hostname suffix in case we need to auto-generate hostname
+ SshPrincipals string //ssh additional principals
+ AccessManagement bool //access management support
+ AddlSanDNSEntries []string //additional san dns entries to be added to the CSR
+ FailCountForExit int //number of failed counts before exiting program
+ RunAfterCertsOkParts []string //run after certificate parsed parts for success
+ RunAfterCertsErrParts []string //run after certificate parsed parts for errors
+ RunAfterTokensOkParts []string //run after token parsed parts for success
+ RunAfterTokensErrParts []string //run after token parsed parts for errors
+ SpiffeTrustDomain string //spiffe uri trust domain
+ SpiffeNamespace string //spiffe uri namespace
+ OmitDomain bool //attestation role only includes service name
+ StoreTokenOption *int //store access token option
+ RunAfterFailExit bool //exit process if run_after script fails
}
const (
@@ -442,12 +446,18 @@ func InitEnvConfig(config *Config) (*Config, *ConfigAccount, error) {
if config.SshPrincipals == "" {
config.SshPrincipals = os.Getenv("ATHENZ_SIA_SSH_PRINCIPALS")
}
- if config.RunAfter == "" {
- config.RunAfter = os.Getenv("ATHENZ_SIA_RUN_AFTER")
+ if config.RunAfterCerts == "" {
+ config.RunAfterCerts = os.Getenv("ATHENZ_SIA_RUN_AFTER")
}
if config.RunAfterTokens == "" {
config.RunAfterTokens = os.Getenv("ATHENZ_SIA_RUN_AFTER_TOKENS")
}
+ if config.RunAfterCertsErr == "" {
+ config.RunAfterCertsErr = os.Getenv("ATHENZ_SIA_RUN_AFTER_CERTS_ERROR")
+ }
+ if config.RunAfterTokensErr == "" {
+ config.RunAfterTokensErr = os.Getenv("ATHENZ_SIA_RUN_AFTER_TOKENS_ERROR")
+ }
if config.SpiffeTrustDomain == "" {
config.SpiffeTrustDomain = os.Getenv("ATHENZ_SIA_SPIFFE_TRUST_DOMAIN")
}
@@ -552,8 +562,10 @@ func setOptions(config *Config, account *ConfigAccount, profileConfig *AccessPro
sshPrincipals := ""
accessManagement := false
failCountForExit := 2
- runAfter := ""
+ runAfterCerts := ""
+ runAfterCertsErr := ""
runAfterTokens := ""
+ runAfterTokensErr := ""
spiffeTrustDomain := ""
addlSanDNSEntries := make([]string, 0)
runAfterFailExit := false
@@ -603,12 +615,18 @@ func setOptions(config *Config, account *ConfigAccount, profileConfig *AccessPro
if config.SshPrincipals != "" {
sshPrincipals = config.SshPrincipals
}
- if config.RunAfter != "" {
- runAfter = config.RunAfter
+ if config.RunAfterCerts != "" {
+ runAfterCerts = config.RunAfterCerts
}
if config.RunAfterTokens != "" {
runAfterTokens = config.RunAfterTokens
}
+ if config.RunAfterCertsErr != "" {
+ runAfterCertsErr = config.RunAfterCertsErr
+ }
+ if config.RunAfterTokensErr != "" {
+ runAfterTokensErr = config.RunAfterTokensErr
+ }
if config.FailCountForExit > 0 {
failCountForExit = config.FailCountForExit
}
@@ -750,47 +768,49 @@ func setOptions(config *Config, account *ConfigAccount, profileConfig *AccessPro
}
return &Options{
- Name: account.Name,
- User: account.User,
- Group: account.Group,
- Domain: account.Domain,
- Account: account.Account,
- Zts: account.Zts,
- Version: fmt.Sprintf("SIA-AWS %s", version),
- UseRegionalSTS: useRegionalSTS,
- SanDnsWildcard: sanDnsWildcard,
- SanDnsHostname: sanDnsHostname,
- HostnameSuffix: hostnameSuffix,
- Services: services,
- Roles: roles,
- TokenDir: tokenDir,
- CertDir: certDir,
- KeyDir: keyDir,
- AthenzCACertFile: fmt.Sprintf("%s/ca.cert.pem", certDir),
- GenerateRoleKey: generateRoleKey,
- RotateKey: rotateKey,
- BackupDir: backupDir,
- SDSUdsPath: sdsUdsPath,
- RefreshInterval: refreshInterval,
- ZTSRegion: ztsRegion,
- DropPrivileges: dropPrivileges,
- AccessTokens: accessTokens,
- Profile: profile,
- ProfileRestrictTo: profileRestrictTo,
- Threshold: account.Threshold,
- SshThreshold: account.SshThreshold,
- FileDirectUpdate: fileDirectUpdate,
- SshHostKeyType: sshHostKeyType,
- SshPrincipals: sshPrincipals,
- AccessManagement: accessManagement,
- FailCountForExit: failCountForExit,
- RunAfterParts: util.ParseScriptArguments(runAfter),
- RunAfterTokensParts: util.ParseScriptArguments(runAfterTokens),
- SpiffeTrustDomain: spiffeTrustDomain,
- OmitDomain: account.OmitDomain,
- StoreTokenOption: storeTokenOption,
- AddlSanDNSEntries: addlSanDNSEntries,
- RunAfterFailExit: runAfterFailExit,
+ Name: account.Name,
+ User: account.User,
+ Group: account.Group,
+ Domain: account.Domain,
+ Account: account.Account,
+ Zts: account.Zts,
+ Version: fmt.Sprintf("SIA-AWS %s", version),
+ UseRegionalSTS: useRegionalSTS,
+ SanDnsWildcard: sanDnsWildcard,
+ SanDnsHostname: sanDnsHostname,
+ HostnameSuffix: hostnameSuffix,
+ Services: services,
+ Roles: roles,
+ TokenDir: tokenDir,
+ CertDir: certDir,
+ KeyDir: keyDir,
+ AthenzCACertFile: fmt.Sprintf("%s/ca.cert.pem", certDir),
+ GenerateRoleKey: generateRoleKey,
+ RotateKey: rotateKey,
+ BackupDir: backupDir,
+ SDSUdsPath: sdsUdsPath,
+ RefreshInterval: refreshInterval,
+ ZTSRegion: ztsRegion,
+ DropPrivileges: dropPrivileges,
+ AccessTokens: accessTokens,
+ Profile: profile,
+ ProfileRestrictTo: profileRestrictTo,
+ Threshold: account.Threshold,
+ SshThreshold: account.SshThreshold,
+ FileDirectUpdate: fileDirectUpdate,
+ SshHostKeyType: sshHostKeyType,
+ SshPrincipals: sshPrincipals,
+ AccessManagement: accessManagement,
+ FailCountForExit: failCountForExit,
+ RunAfterCertsOkParts: util.ParseScriptArguments(runAfterCerts),
+ RunAfterCertsErrParts: util.ParseScriptArguments(runAfterCertsErr),
+ RunAfterTokensOkParts: util.ParseScriptArguments(runAfterTokens),
+ RunAfterTokensErrParts: util.ParseScriptArguments(runAfterTokensErr),
+ SpiffeTrustDomain: spiffeTrustDomain,
+ OmitDomain: account.OmitDomain,
+ StoreTokenOption: storeTokenOption,
+ AddlSanDNSEntries: addlSanDNSEntries,
+ RunAfterFailExit: runAfterFailExit,
}, nil
}
diff --git a/libs/go/sia/aws/options/options_test.go b/libs/go/sia/aws/options/options_test.go
index e154354e0da..a6a1407132e 100644
--- a/libs/go/sia/aws/options/options_test.go
+++ b/libs/go/sia/aws/options/options_test.go
@@ -759,6 +759,10 @@ func TestInitEnvConfig(t *testing.T) {
os.Setenv("ATHENZ_SIA_STORE_TOKEN_OPTION", "2")
os.Setenv("ATHENZ_SIA_OMIT_DOMAIN", "true")
os.Setenv("ATHENZ_SIA_SANDNS_X509_CNAMES", "svc1.athenz.io,svc2.athenz.io")
+ os.Setenv("ATHENZ_SIA_RUN_AFTER", "/run-after.sh")
+ os.Setenv("ATHENZ_SIA_RUN_AFTER_CERTS_ERROR", "/run-after-error.sh")
+ os.Setenv("ATHENZ_SIA_RUN_AFTER_TOKENS", "/run-after-tokens.sh")
+ os.Setenv("ATHENZ_SIA_RUN_AFTER_TOKENS_ERROR", "/run-after-tokens-error.sh")
cfg, cfgAccount, err := InitEnvConfig(nil)
require.Nilf(t, err, "error should be empty, error: %v", err)
@@ -798,6 +802,10 @@ func TestInitEnvConfig(t *testing.T) {
assert.Equal(t, 10, cfg.FailCountForExit)
assert.Equal(t, 2, *cfg.StoreTokenOption)
assert.True(t, cfgAccount.OmitDomain)
+ assert.Equal(t, "/run-after.sh", cfg.RunAfterCerts)
+ assert.Equal(t, "/run-after-error.sh", cfg.RunAfterCertsErr)
+ assert.Equal(t, "/run-after-tokens.sh", cfg.RunAfterTokens)
+ assert.Equal(t, "/run-after-tokens-error.sh", cfg.RunAfterTokensErr)
os.Clearenv()
}
diff --git a/libs/go/sia/options/options.go b/libs/go/sia/options/options.go
index 8926a32571e..04b6f05de5b 100644
--- a/libs/go/sia/options/options.go
+++ b/libs/go/sia/options/options.go
@@ -116,8 +116,10 @@ type Config struct {
SshThreshold float64 `json:"sshcert_threshold_to_check,omitempty"` //threshold to verify for ssh certs
AccessManagement bool `json:"access_management,omitempty"` //access management support
FailCountForExit int `json:"fail_count_for_exit,omitempty"` //number of failed counts before exiting program
- RunAfter string `json:"run_after,omitempty"` //execute the command mentioned after certs are created
+ RunAfterCerts string `json:"run_after,omitempty"` //execute the command mentioned after certs are created
+ RunAfterCertsErr string `json:"run_after_certs_err,omitempty"` //execute the command mentioned after role certs fail to refresh
RunAfterTokens string `json:"run_after_tokens,omitempty"` //execute the command mentioned after tokens are created
+ RunAfterTokensErr string `json:"run_after_tokens_err,omitempty"` //execute the command mentioned after tokens fail to refresh
SpiffeTrustDomain string `json:"spiffe_trust_domain,omitempty"` //spiffe trust domain - if configured generate full spiffe uri with namespace
StoreTokenOption *int `json:"store_token_option,omitempty"` //store access token option
RunAfterFailExit bool `json:"run_after_fail_exit,omitempty"` //exit process if run_after script fails
@@ -163,72 +165,74 @@ type Service struct {
// Options represents settings that are derived from config file and application defaults
type Options struct {
- Provider provider.Provider //provider instance
- MetaEndPoint string //meta data service endpoint
- Name string //name of the service identity
- User string //the username to chown the cert/key dirs to. If absent, then root
- Group string //the group name to chown the cert/key dirs to. If absent, then athenz
- Domain string //name of the domain for the identity
- Account string //name of the account
- Service string //name of the service for the identity
- Zts string //the ZTS to contact
- InstanceId string //instance id if ec2/vm, task id if running within eks/ecs/gke
- InstanceName string //instance name if ec2/vm
- Roles []Role //map of roles to retrieve certificates for
- Region string //region name
- SanDnsWildcard bool //san dns wildcard support
- SanDnsHostname bool //san dns hostname support
- Version string //sia version number
- ZTSDomains []string //zts domain prefixes
- Services []Service //array of configured services
- Ssh bool //ssh certificate support
- UseRegionalSTS bool //use regional sts endpoint
- KeyDir string //private key directory path
- CertDir string //x.509 certificate directory path
- AthenzCACertFile string //filename to store Athenz CA certs
- ZTSCACertFile string //filename for CA certs when communicating with ZTS
- ZTSServerName string //ZTS server name, if necessary for tls
- ZTSAWSDomains []string //list of domain prefixes for sanDNS entries
- GenerateRoleKey bool //option to generate a separate key for role certificates
- RotateKey bool //rotate the private key when refreshing certificates
- BackupDir string //backup directory for key/cert rotation
- CertCountryName string //generated x.509 certificate country name
- CertOrgName string //generated x.509 certificate organization name
- SshPubKeyFile string //ssh host public key file path
- SshCertFile string //ssh host certificate file path
- SshConfigFile string //sshd config file path
- SshHostKeyType hostkey.KeyType //ssh host key type - rsa or ecdsa
- PrivateIp string //instance private ip
- EC2Document string //EC2 instance identity document
- EC2Signature string //EC2 instance identity document pkcs7 signature
- EC2StartTime *time.Time //EC2 instance start time
- InstanceIdSanDNS bool //include instance id in a san dns entry (backward compatible option)
- RolePrincipalEmail bool //include role principal in a san email field (backward compatible option)
- SDSUdsPath string //UDS path if the agent should support uds connections
- SDSUdsUid int //UDS connections must be from the given user uid
- RefreshInterval int //refresh interval for certificates - default 24 hours
- ZTSRegion string //ZTS region in case the client needs this information
- DropPrivileges bool //Drop privileges to configured user instead of running as root
- TokenDir string //Access tokens directory
- AccessTokens []ac.AccessToken //Access tokens object
- Profile string //Access profile name
- ProfileRestrictTo string //Tag associated with access profile roles
- Threshold float64 //threshold in number of days for cert expiry checks
- SshThreshold float64 //threshold in number of days for ssh cert expiry checks
- FileDirectUpdate bool //update key/cert files directly instead of using rename
- HostnameSuffix string //hostname suffix in case we need to auto-generate hostname
- SshPrincipals string //ssh additional principals
- AccessManagement bool //access management support
- ZTSCloudDomains []string //list of domain prefixes for sanDNS entries
- AddlSanDNSEntries []string //additional san dns entries to be added to the CSR
- FailCountForExit int //number of failed counts before exiting program
- RunAfterParts []string //run after parsed parts
- RunAfterTokensParts []string //run after token parsed parts
- SpiffeTrustDomain string //spiffe uri trust domain
- SpiffeNamespace string //spiffe uri namespace
- OmitDomain bool //attestation role only includes service name
- StoreTokenOption *int //store access token option
- RunAfterFailExit bool //exit process if run_after script fails
+ Provider provider.Provider //provider instance
+ MetaEndPoint string //meta data service endpoint
+ Name string //name of the service identity
+ User string //the username to chown the cert/key dirs to. If absent, then root
+ Group string //the group name to chown the cert/key dirs to. If absent, then athenz
+ Domain string //name of the domain for the identity
+ Account string //name of the account
+ Service string //name of the service for the identity
+ Zts string //the ZTS to contact
+ InstanceId string //instance id if ec2/vm, task id if running within eks/ecs/gke
+ InstanceName string //instance name if ec2/vm
+ Roles []Role //map of roles to retrieve certificates for
+ Region string //region name
+ SanDnsWildcard bool //san dns wildcard support
+ SanDnsHostname bool //san dns hostname support
+ Version string //sia version number
+ ZTSDomains []string //zts domain prefixes
+ Services []Service //array of configured services
+ Ssh bool //ssh certificate support
+ UseRegionalSTS bool //use regional sts endpoint
+ KeyDir string //private key directory path
+ CertDir string //x.509 certificate directory path
+ AthenzCACertFile string //filename to store Athenz CA certs
+ ZTSCACertFile string //filename for CA certs when communicating with ZTS
+ ZTSServerName string //ZTS server name, if necessary for tls
+ ZTSAWSDomains []string //list of domain prefixes for sanDNS entries
+ GenerateRoleKey bool //option to generate a separate key for role certificates
+ RotateKey bool //rotate the private key when refreshing certificates
+ BackupDir string //backup directory for key/cert rotation
+ CertCountryName string //generated x.509 certificate country name
+ CertOrgName string //generated x.509 certificate organization name
+ SshPubKeyFile string //ssh host public key file path
+ SshCertFile string //ssh host certificate file path
+ SshConfigFile string //sshd config file path
+ SshHostKeyType hostkey.KeyType //ssh host key type - rsa or ecdsa
+ PrivateIp string //instance private ip
+ EC2Document string //EC2 instance identity document
+ EC2Signature string //EC2 instance identity document pkcs7 signature
+ EC2StartTime *time.Time //EC2 instance start time
+ InstanceIdSanDNS bool //include instance id in a san dns entry (backward compatible option)
+ RolePrincipalEmail bool //include role principal in a san email field (backward compatible option)
+ SDSUdsPath string //UDS path if the agent should support uds connections
+ SDSUdsUid int //UDS connections must be from the given user uid
+ RefreshInterval int //refresh interval for certificates - default 24 hours
+ ZTSRegion string //ZTS region in case the client needs this information
+ DropPrivileges bool //Drop privileges to configured user instead of running as root
+ TokenDir string //Access tokens directory
+ AccessTokens []ac.AccessToken //Access tokens object
+ Profile string //Access profile name
+ ProfileRestrictTo string //Tag associated with access profile roles
+ Threshold float64 //threshold in number of days for cert expiry checks
+ SshThreshold float64 //threshold in number of days for ssh cert expiry checks
+ FileDirectUpdate bool //update key/cert files directly instead of using rename
+ HostnameSuffix string //hostname suffix in case we need to auto-generate hostname
+ SshPrincipals string //ssh additional principals
+ AccessManagement bool //access management support
+ ZTSCloudDomains []string //list of domain prefixes for sanDNS entries
+ AddlSanDNSEntries []string //additional san dns entries to be added to the CSR
+ FailCountForExit int //number of failed counts before exiting program
+ RunAfterCertsOkParts []string //run after certificate parsed parts for success
+ RunAfterCertsErrParts []string //run after certificate parsed parts for errors
+ RunAfterTokensOkParts []string //run after token parsed parts for success
+ RunAfterTokensErrParts []string //run after token parsed parts for errors
+ SpiffeTrustDomain string //spiffe uri trust domain
+ SpiffeNamespace string //spiffe uri namespace
+ OmitDomain bool //attestation role only includes service name
+ StoreTokenOption *int //store access token option
+ RunAfterFailExit bool //exit process if run_after script fails
}
const (
@@ -489,12 +493,18 @@ func InitEnvConfig(config *Config, provider provider.Provider) (*Config, *Config
if config.SshPrincipals == "" {
config.SshPrincipals = os.Getenv("ATHENZ_SIA_SSH_PRINCIPALS")
}
- if config.RunAfter == "" {
- config.RunAfter = os.Getenv("ATHENZ_SIA_RUN_AFTER")
+ if config.RunAfterCerts == "" {
+ config.RunAfterCerts = os.Getenv("ATHENZ_SIA_RUN_AFTER")
}
if config.RunAfterTokens == "" {
config.RunAfterTokens = os.Getenv("ATHENZ_SIA_RUN_AFTER_TOKENS")
}
+ if config.RunAfterCertsErr == "" {
+ config.RunAfterCertsErr = os.Getenv("ATHENZ_SIA_RUN_AFTER_CERTS_ERROR")
+ }
+ if config.RunAfterTokensErr == "" {
+ config.RunAfterTokensErr = os.Getenv("ATHENZ_SIA_RUN_AFTER_TOKENS_ERROR")
+ }
if config.SpiffeTrustDomain == "" {
config.SpiffeTrustDomain = os.Getenv("ATHENZ_SIA_SPIFFE_TRUST_DOMAIN")
}
@@ -625,8 +635,10 @@ func setOptions(config *Config, account *ConfigAccount, profileConfig *AccessPro
sshPrincipals := ""
accessManagement := false
failCountForExit := 2
- runAfter := ""
+ runAfterCerts := ""
+ runAfterCertsErr := ""
runAfterTokens := ""
+ runAfterTokensErr := ""
spiffeTrustDomain := ""
addlSanDNSEntries := make([]string, 0)
runAfterFailExit := false
@@ -677,12 +689,18 @@ func setOptions(config *Config, account *ConfigAccount, profileConfig *AccessPro
if config.SshPrincipals != "" {
sshPrincipals = config.SshPrincipals
}
- if config.RunAfter != "" {
- runAfter = config.RunAfter
+ if config.RunAfterCerts != "" {
+ runAfterCerts = config.RunAfterCerts
}
if config.RunAfterTokens != "" {
runAfterTokens = config.RunAfterTokens
}
+ if config.RunAfterCertsErr != "" {
+ runAfterCertsErr = config.RunAfterCertsErr
+ }
+ if config.RunAfterTokensErr != "" {
+ runAfterTokensErr = config.RunAfterTokensErr
+ }
if config.FailCountForExit > 0 {
failCountForExit = config.FailCountForExit
}
@@ -831,47 +849,49 @@ func setOptions(config *Config, account *ConfigAccount, profileConfig *AccessPro
}
return &Options{
- Name: account.Name,
- User: account.User,
- Group: account.Group,
- Domain: account.Domain,
- Account: account.Account,
- Zts: account.Zts,
- Version: fmt.Sprintf("SIA %s", version),
- UseRegionalSTS: useRegionalSTS,
- SanDnsWildcard: sanDnsWildcard,
- SanDnsHostname: sanDnsHostname,
- HostnameSuffix: hostnameSuffix,
- Services: services,
- Roles: roles,
- TokenDir: tokenDir,
- CertDir: certDir,
- KeyDir: keyDir,
- AthenzCACertFile: fmt.Sprintf("%s/ca.cert.pem", certDir),
- GenerateRoleKey: generateRoleKey,
- RotateKey: rotateKey,
- BackupDir: backupDir,
- SDSUdsPath: sdsUdsPath,
- RefreshInterval: refreshInterval,
- ZTSRegion: ztsRegion,
- DropPrivileges: dropPrivileges,
- AccessTokens: accessTokens,
- Profile: profile,
- ProfileRestrictTo: profileRestrictTo,
- Threshold: account.Threshold,
- SshThreshold: account.SshThreshold,
- FileDirectUpdate: fileDirectUpdate,
- SshHostKeyType: sshHostKeyType,
- SshPrincipals: sshPrincipals,
- AccessManagement: accessManagement,
- FailCountForExit: failCountForExit,
- RunAfterParts: util.ParseScriptArguments(runAfter),
- RunAfterTokensParts: util.ParseScriptArguments(runAfterTokens),
- SpiffeTrustDomain: spiffeTrustDomain,
- OmitDomain: account.OmitDomain,
- StoreTokenOption: storeTokenOption,
- AddlSanDNSEntries: addlSanDNSEntries,
- RunAfterFailExit: runAfterFailExit,
+ Name: account.Name,
+ User: account.User,
+ Group: account.Group,
+ Domain: account.Domain,
+ Account: account.Account,
+ Zts: account.Zts,
+ Version: fmt.Sprintf("SIA %s", version),
+ UseRegionalSTS: useRegionalSTS,
+ SanDnsWildcard: sanDnsWildcard,
+ SanDnsHostname: sanDnsHostname,
+ HostnameSuffix: hostnameSuffix,
+ Services: services,
+ Roles: roles,
+ TokenDir: tokenDir,
+ CertDir: certDir,
+ KeyDir: keyDir,
+ AthenzCACertFile: fmt.Sprintf("%s/ca.cert.pem", certDir),
+ GenerateRoleKey: generateRoleKey,
+ RotateKey: rotateKey,
+ BackupDir: backupDir,
+ SDSUdsPath: sdsUdsPath,
+ RefreshInterval: refreshInterval,
+ ZTSRegion: ztsRegion,
+ DropPrivileges: dropPrivileges,
+ AccessTokens: accessTokens,
+ Profile: profile,
+ ProfileRestrictTo: profileRestrictTo,
+ Threshold: account.Threshold,
+ SshThreshold: account.SshThreshold,
+ FileDirectUpdate: fileDirectUpdate,
+ SshHostKeyType: sshHostKeyType,
+ SshPrincipals: sshPrincipals,
+ AccessManagement: accessManagement,
+ FailCountForExit: failCountForExit,
+ RunAfterCertsOkParts: util.ParseScriptArguments(runAfterCerts),
+ RunAfterCertsErrParts: util.ParseScriptArguments(runAfterCertsErr),
+ RunAfterTokensOkParts: util.ParseScriptArguments(runAfterTokens),
+ RunAfterTokensErrParts: util.ParseScriptArguments(runAfterTokensErr),
+ SpiffeTrustDomain: spiffeTrustDomain,
+ OmitDomain: account.OmitDomain,
+ StoreTokenOption: storeTokenOption,
+ AddlSanDNSEntries: addlSanDNSEntries,
+ RunAfterFailExit: runAfterFailExit,
}, nil
}
diff --git a/libs/go/sia/options/options_test.go b/libs/go/sia/options/options_test.go
index de9e2a26c20..3f35d856f85 100644
--- a/libs/go/sia/options/options_test.go
+++ b/libs/go/sia/options/options_test.go
@@ -735,6 +735,10 @@ func TestInitEnvConfigAwsProvider(t *testing.T) {
os.Setenv("ATHENZ_SIA_STORE_TOKEN_OPTION", "2")
os.Setenv("ATHENZ_SIA_OMIT_DOMAIN", "true")
os.Setenv("ATHENZ_SIA_SANDNS_X509_CNAMES", "svc1.athenz.io,svc2.athenz.io")
+ os.Setenv("ATHENZ_SIA_RUN_AFTER", "/run-after.sh")
+ os.Setenv("ATHENZ_SIA_RUN_AFTER_CERTS_ERROR", "/run-after-error.sh")
+ os.Setenv("ATHENZ_SIA_RUN_AFTER_TOKENS", "/run-after-tokens.sh")
+ os.Setenv("ATHENZ_SIA_RUN_AFTER_TOKENS_ERROR", "/run-after-tokens-error.sh")
provider := MockAWSProvider{
Name: fmt.Sprintf("athenz.aws.us-west-2"),
@@ -778,6 +782,10 @@ func TestInitEnvConfigAwsProvider(t *testing.T) {
assert.Equal(t, 10, cfg.FailCountForExit)
assert.Equal(t, 2, *cfg.StoreTokenOption)
assert.True(t, cfgAccount.OmitDomain)
+ assert.Equal(t, "/run-after.sh", cfg.RunAfterCerts)
+ assert.Equal(t, "/run-after-error.sh", cfg.RunAfterCertsErr)
+ assert.Equal(t, "/run-after-tokens.sh", cfg.RunAfterTokens)
+ assert.Equal(t, "/run-after-tokens-error.sh", cfg.RunAfterTokensErr)
os.Clearenv()
}
diff --git a/libs/go/sia/util/util.go b/libs/go/sia/util/util.go
index 3f4e6d9e3c7..9dbc79fc088 100644
--- a/libs/go/sia/util/util.go
+++ b/libs/go/sia/util/util.go
@@ -1317,11 +1317,14 @@ func ParseScriptArguments(script string) []string {
// ExecuteScript executes a script along with the provided
// arguments while blocking the agent
-func ExecuteScript(script []string, runAfterFailExit bool) error {
+func ExecuteScript(script []string, addlDetail string, runAfterFailExit bool) error {
// execute run after script (if provided)
if len(script) == 0 {
return nil
}
+ if addlDetail != "" {
+ script = append(script, addlDetail)
+ }
log.Printf("executing run after hook for: %v", script)
err := exec.Command(script[0], script[1:]...).Run()
if err != nil {
@@ -1335,9 +1338,9 @@ func ExecuteScript(script []string, runAfterFailExit bool) error {
// ExecuteScriptWithoutBlock executes a script along with the provided
// arguments in a go subroutine without blocking the agent
-func ExecuteScriptWithoutBlock(script []string, runAfterFailExit bool) {
+func ExecuteScriptWithoutBlock(script []string, addlDetail string, runAfterFailExit bool) {
go func() {
- ExecuteScript(script, runAfterFailExit)
+ ExecuteScript(script, addlDetail, runAfterFailExit)
}()
}
diff --git a/libs/go/sia/util/util_test.go b/libs/go/sia/util/util_test.go
index 3c7202789d1..63c4264e639 100644
--- a/libs/go/sia/util/util_test.go
+++ b/libs/go/sia/util/util_test.go
@@ -1756,13 +1756,13 @@ func TestParseSiaCmd(test *testing.T) {
func TestExecuteScript(test *testing.T) {
// non-existent script
- err := ExecuteScript([]string{"unknown-script"}, false)
+ err := ExecuteScript([]string{"unknown-script"}, "", false)
assert.NotNil(test, err)
// remove our test file if it exists
os.Remove("/tmp/test-after-script")
// valid script
- err = ExecuteScript([]string{"data/test_after_script.sh"}, true)
+ err = ExecuteScript([]string{"data/test_after_script.sh"}, "", true)
assert.Nil(test, err)
// verify our test file was created
_, err = os.Stat("/tmp/test-after-script")
diff --git a/pom.xml b/pom.xml
index 3c9682660f8..9b6e38425a8 100644
--- a/pom.xml
+++ b/pom.xml
@@ -178,6 +178,7 @@
provider/buildkite/sia-buildkite
provider/gcp/sia-gce
provider/gcp/sia-gke
+ provider/gcp/sia-run
provider/github/sia-actions
utils/zms-cli
utils/athenz-conf
diff --git a/provider/gcp/sia-run/pom.xml b/provider/gcp/sia-run/pom.xml
index b311f1714f8..16cf8d46d21 100644
--- a/provider/gcp/sia-run/pom.xml
+++ b/provider/gcp/sia-run/pom.xml
@@ -19,7 +19,7 @@
com.yahoo.athenz
athenz
- 1.11.64-SNAPSHOT
+ 1.11.66-SNAPSHOT
../../../pom.xml