@@ -658,56 +658,74 @@ func Test_ValidateAndCombineConfig(t *testing.T) {
658658 assert .Equal (t , VenafiConnection , got .OutputMode )
659659 })
660660
661- const arkUsername = "cluster-1-region-1-cloud-1@cyberark.cloud.123456"
662-
663661 t .Run ("--machine-hub selects MachineHub mode" , func (t * testing.T ) {
664662 t .Setenv ("POD_NAMESPACE" , "venafi" )
665663 t .Setenv ("KUBECONFIG" , withFile (t , fakeKubeconfig ))
666664 t .Setenv ("ARK_SUBDOMAIN" , "tlspk" )
667- t .Setenv ("ARK_USERNAME" , arkUsername )
668- t .Setenv ("ARK_SECRET" , "test-secret" )
669665 got , cl , err := ValidateAndCombineConfig (discardLogs (),
670- withConfig ("" ),
666+ withConfig (testutil .Undent (`
667+ cluster_name: my-cluster
668+ cyberark:
669+ service_id: dev-cluster
670+ ` )),
671671 withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
672672 require .NoError (t , err )
673673 assert .Equal (t , MachineHub , got .OutputMode )
674- assert .Equal (t , arkUsername , got .ClusterName ,
675- "the ClusterName should default to the ARK_USERNAME value if the cluster_name in the config file is empty" )
674+ assert .Equal (t , "my-cluster" , got .ClusterName )
675+ assert .Equal (t , "dev-cluster" , got .CyberArk .ServiceID )
676+ assert .IsType (t , & client.CyberArkClient {}, cl )
677+ })
678+
679+ t .Run ("--machine-hub with cluster_id fallback when cluster_name is empty" , func (t * testing.T ) {
680+ t .Setenv ("POD_NAMESPACE" , "venafi" )
681+ t .Setenv ("KUBECONFIG" , withFile (t , fakeKubeconfig ))
682+ t .Setenv ("ARK_SUBDOMAIN" , "tlspk" )
683+ got , cl , err := ValidateAndCombineConfig (discardLogs (),
684+ withConfig (testutil .Undent (`
685+ cluster_id: my-cluster-id
686+ cyberark:
687+ service_id: dev-cluster
688+ ` )),
689+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
690+ require .NoError (t , err )
691+ assert .Equal (t , MachineHub , got .OutputMode )
692+ assert .Equal (t , "my-cluster-id" , got .ClusterName ,
693+ "cluster_id should be used as cluster_name when cluster_name is empty" )
676694 assert .IsType (t , & client.CyberArkClient {}, cl )
677695 })
678696
679697 t .Run ("--machine-hub with cluster_name override" , func (t * testing.T ) {
680698 t .Setenv ("POD_NAMESPACE" , "venafi" )
681699 t .Setenv ("KUBECONFIG" , withFile (t , fakeKubeconfig ))
682700 t .Setenv ("ARK_SUBDOMAIN" , "tlspk" )
683- t .Setenv ("ARK_USERNAME" , arkUsername )
684- t .Setenv ("ARK_SECRET" , "test-secret" )
685701 got , cl , err := ValidateAndCombineConfig (discardLogs (),
686702 withConfig (testutil .Undent (`
687703 cluster_name: override-cluster-name
688- ` )),
704+ cyberark:
705+ service_id: dev-cluster
706+ ` )),
689707 withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
690708 require .NoError (t , err )
691709 assert .Equal (t , MachineHub , got .OutputMode )
692- assert .Equal (t , "override-cluster-name" , got .ClusterName ,
693- "the cluster_name in the config file should be used if not empty, even if ARK_USERNAME is set" )
710+ assert .Equal (t , "override-cluster-name" , got .ClusterName )
694711 assert .IsType (t , & client.CyberArkClient {}, cl )
695712 })
696713
697- t .Run ("--machine-hub without required environment variables " , func (t * testing.T ) {
714+ t .Run ("--machine-hub without ARK_SUBDOMAIN environment variable " , func (t * testing.T ) {
698715 t .Setenv ("POD_NAMESPACE" , "venafi" )
699716 t .Setenv ("KUBECONFIG" , withFile (t , fakeKubeconfig ))
700717 t .Setenv ("ARK_SUBDOMAIN" , "" )
701- t .Setenv ("ARK_USERNAME" , "" )
702- t .Setenv ("ARK_SECRET" , "" )
703718 got , cl , err := ValidateAndCombineConfig (discardLogs (),
704- withConfig ("" ),
719+ withConfig (testutil .Undent (`
720+ cyberark:
721+ service_id: dev-cluster
722+ ` )),
705723 withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
706724 assert .Equal (t , CombinedConfig {}, got )
707725 assert .Nil (t , cl )
708726 assert .EqualError (t , err , testutil .Undent (`
709727 validating creds: failed loading config using the MachineHub mode: 1 error occurred:
710- * missing environment variables: ARK_SUBDOMAIN, ARK_USERNAME, ARK_SECRET
728+ * missing environment variables: ARK_SUBDOMAIN
711729
712730 ` ))
713731 })
@@ -1303,6 +1321,167 @@ func Test_ValidateAndCombineConfig_NGTS(t *testing.T) {
13031321 })
13041322}
13051323
1324+ func TestConfig_CyberArk_Validation (t * testing.T ) {
1325+ // Common env setup: ARK_SUBDOMAIN is the only required env var for MachineHub mode.
1326+ setEnv := func (t * testing.T ) {
1327+ t .Helper ()
1328+ t .Setenv ("POD_NAMESPACE" , "venafi" )
1329+ t .Setenv ("KUBECONFIG" , withFile (t , fakeKubeconfig ))
1330+ t .Setenv ("ARK_SUBDOMAIN" , "tlspk" )
1331+ }
1332+
1333+ // service_id is not required at config-validation time as long as the
1334+ // legacy username/password method (ARK_USERNAME/ARK_SECRET, set via env,
1335+ // not config) is configured instead — one or the other is required,
1336+ // checked here rather than deferred to cyberark.selectAuthenticator at
1337+ // first upload. See the comment on this validation block in config.go.
1338+ t .Run ("empty service_id is valid at config time when ARK_USERNAME is set" , func (t * testing.T ) {
1339+ setEnv (t )
1340+ t .Setenv ("ARK_USERNAME" , "test@example.com" )
1341+ combined , _ , err := ValidateAndCombineConfig (discardLogs (),
1342+ withConfig (testutil .Undent (`
1343+ cyberark:
1344+ service_id: ""
1345+ ` )),
1346+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1347+ require .NoError (t , err )
1348+ assert .Equal (t , "" , combined .CyberArk .ServiceID )
1349+ })
1350+
1351+ t .Run ("missing cyberark block is valid at config time when ARK_USERNAME is set" , func (t * testing.T ) {
1352+ setEnv (t )
1353+ t .Setenv ("ARK_USERNAME" , "test@example.com" )
1354+ combined , _ , err := ValidateAndCombineConfig (discardLogs (),
1355+ withConfig ("" ),
1356+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1357+ require .NoError (t , err )
1358+ assert .Equal (t , "" , combined .CyberArk .ServiceID )
1359+ })
1360+
1361+ t .Run ("neither service_id nor ARK_USERNAME is an error at config time" , func (t * testing.T ) {
1362+ setEnv (t )
1363+ _ , _ , err := ValidateAndCombineConfig (discardLogs (),
1364+ withConfig ("" ),
1365+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1366+ require .Error (t , err )
1367+ assert .Contains (t , err .Error (), "MachineHub mode requires either cyberark.service_id or ARK_USERNAME/ARK_SECRET" )
1368+ })
1369+
1370+ // cluster_name fallback order: cluster_name > cluster_id > ARK_USERNAME > empty.
1371+ t .Run ("cluster_name falls back to cluster_id when set, even if ARK_USERNAME is also set" , func (t * testing.T ) {
1372+ setEnv (t )
1373+ t .Setenv ("ARK_USERNAME" , "svc-agent@tenant" )
1374+ got , _ , err := ValidateAndCombineConfig (discardLogs (),
1375+ withConfig (testutil .Undent (`
1376+ cluster_id: my-cluster-id
1377+ cyberark:
1378+ service_id: dev-cluster
1379+ ` )),
1380+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1381+ require .NoError (t , err )
1382+ assert .Equal (t , "my-cluster-id" , got .ClusterName )
1383+ })
1384+
1385+ t .Run ("cluster_name falls back to ARK_USERNAME when cluster_id is unset" , func (t * testing.T ) {
1386+ setEnv (t )
1387+ t .Setenv ("ARK_USERNAME" , "svc-agent@tenant" )
1388+ got , _ , err := ValidateAndCombineConfig (discardLogs (),
1389+ withConfig ("" ),
1390+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1391+ require .NoError (t , err )
1392+ assert .Equal (t , "svc-agent@tenant" , got .ClusterName )
1393+ })
1394+
1395+ t .Run ("cluster_name is empty when cluster_name, cluster_id, and ARK_USERNAME are all unset" , func (t * testing.T ) {
1396+ setEnv (t )
1397+ got , _ , err := ValidateAndCombineConfig (discardLogs (),
1398+ withConfig (testutil .Undent (`
1399+ cyberark:
1400+ service_id: dev-cluster
1401+ ` )),
1402+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1403+ require .NoError (t , err )
1404+ assert .Equal (t , "" , got .ClusterName )
1405+ })
1406+
1407+ t .Run ("jwt_source spiffe is rejected" , func (t * testing.T ) {
1408+ setEnv (t )
1409+ _ , _ , err := ValidateAndCombineConfig (discardLogs (),
1410+ withConfig (testutil .Undent (`
1411+ cyberark:
1412+ service_id: dev-cluster
1413+ jwt_source: spiffe
1414+ ` )),
1415+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1416+ require .Error (t , err )
1417+ assert .Contains (t , err .Error (), `cyberark.jwt_source "spiffe" is not supported` )
1418+ })
1419+
1420+ t .Run ("jwt_source file is accepted" , func (t * testing.T ) {
1421+ setEnv (t )
1422+ got , cl , err := ValidateAndCombineConfig (discardLogs (),
1423+ withConfig (testutil .Undent (`
1424+ cyberark:
1425+ service_id: dev-cluster
1426+ jwt_source: file
1427+ jwt_file_path: /var/run/secrets/tokens/agent-token
1428+ ` )),
1429+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1430+ require .NoError (t , err )
1431+ assert .Equal (t , "dev-cluster" , got .CyberArk .ServiceID )
1432+ assert .Equal (t , "file" , got .CyberArk .JWTSource )
1433+ assert .Equal (t , "/var/run/secrets/tokens/agent-token" , got .CyberArk .JWTFilePath )
1434+ assert .IsType (t , & client.CyberArkClient {}, cl )
1435+ })
1436+
1437+ t .Run ("jwt_source empty string is accepted" , func (t * testing.T ) {
1438+ setEnv (t )
1439+ got , cl , err := ValidateAndCombineConfig (discardLogs (),
1440+ withConfig (testutil .Undent (`
1441+ cyberark:
1442+ service_id: dev-cluster
1443+ ` )),
1444+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1445+ require .NoError (t , err )
1446+ assert .Equal (t , "dev-cluster" , got .CyberArk .ServiceID )
1447+ assert .Equal (t , "" , got .CyberArk .JWTSource )
1448+ assert .IsType (t , & client.CyberArkClient {}, cl )
1449+ })
1450+
1451+ t .Run ("account and jwt_file_path are optional" , func (t * testing.T ) {
1452+ setEnv (t )
1453+ got , _ , err := ValidateAndCombineConfig (discardLogs (),
1454+ withConfig (testutil .Undent (`
1455+ cyberark:
1456+ service_id: dev-cluster
1457+ account: myaccount
1458+ jwt_file_path: /tmp/token
1459+ ` )),
1460+ withCmdLineFlags ("--period" , "1m" , "--machine-hub" ))
1461+ require .NoError (t , err )
1462+ assert .Equal (t , "myaccount" , got .CyberArk .Account )
1463+ assert .Equal (t , "/tmp/token" , got .CyberArk .JWTFilePath )
1464+ })
1465+
1466+ t .Run ("cyberark block is ignored in non-MachineHub modes" , func (t * testing.T ) {
1467+ t .Setenv ("POD_NAMESPACE" , "venafi" )
1468+ fakeCredsPath := withFile (t , `{"user_id":"foo","user_secret":"bar","client_id": "baz","client_secret": "foobar","auth_server_domain":"bazbar"}` )
1469+ got , _ , err := ValidateAndCombineConfig (discardLogs (),
1470+ withConfig (testutil .Undent (`
1471+ server: https://preflight.jetstack.io
1472+ organization_id: my-org
1473+ cluster_id: my-cluster
1474+ period: 1h
1475+ cyberark:
1476+ service_id: should-be-ignored
1477+ ` )),
1478+ withCmdLineFlags ("--credentials-file" , fakeCredsPath ))
1479+ require .NoError (t , err )
1480+ // CyberArk config is not copied into CombinedConfig for non-MachineHub modes.
1481+ assert .Equal (t , CyberArkConfig {}, got .CyberArk )
1482+ })
1483+ }
1484+
13061485const fakePrivKeyPEM = `-----BEGIN PRIVATE KEY-----
13071486MHcCAQEEIFptpPXOvEWDrYkiMhyEH1+FB1GwtwX2tyXH4KtBO6g7oAoGCCqGSM49
13081487AwEHoUQDQgAE/BsIwagYc4YUjSSFyqcStj2qliAkdVGlMoJbMuXupzQ9Qs4TX5Pl
0 commit comments