@ -35,6 +35,8 @@ var defaultProxyClassAnnotations = map[string]string{
}
}
func TestProxyGroup ( t * testing . T ) {
func TestProxyGroup ( t * testing . T ) {
const initialCfgHash = "6632726be70cf224049580deb4d317bba065915b5fd415461d60ed621c91b196"
pc := & tsapi . ProxyClass {
pc := & tsapi . ProxyClass {
ObjectMeta : metav1 . ObjectMeta {
ObjectMeta : metav1 . ObjectMeta {
Name : "default-pc" ,
Name : "default-pc" ,
@ -80,6 +82,7 @@ func TestProxyGroup(t *testing.T) {
tsoperator . SetProxyGroupCondition ( pg , tsapi . ProxyGroupReady , metav1 . ConditionFalse , reasonProxyGroupCreating , "the ProxyGroup's ProxyClass default-pc is not yet in a ready state, waiting..." , 0 , cl , zl . Sugar ( ) )
tsoperator . SetProxyGroupCondition ( pg , tsapi . ProxyGroupReady , metav1 . ConditionFalse , reasonProxyGroupCreating , "the ProxyGroup's ProxyClass default-pc is not yet in a ready state, waiting..." , 0 , cl , zl . Sugar ( ) )
expectEqual ( t , fc , pg , nil )
expectEqual ( t , fc , pg , nil )
expectProxyGroupResources ( t , fc , pg , false , "" )
} )
} )
t . Run ( "observe_ProxyGroupCreating_status_reason" , func ( t * testing . T ) {
t . Run ( "observe_ProxyGroupCreating_status_reason" , func ( t * testing . T ) {
@ -100,10 +103,11 @@ func TestProxyGroup(t *testing.T) {
tsoperator . SetProxyGroupCondition ( pg , tsapi . ProxyGroupReady , metav1 . ConditionFalse , reasonProxyGroupCreating , "0/2 ProxyGroup pods running" , 0 , cl , zl . Sugar ( ) )
tsoperator . SetProxyGroupCondition ( pg , tsapi . ProxyGroupReady , metav1 . ConditionFalse , reasonProxyGroupCreating , "0/2 ProxyGroup pods running" , 0 , cl , zl . Sugar ( ) )
expectEqual ( t , fc , pg , nil )
expectEqual ( t , fc , pg , nil )
expectProxyGroupResources ( t , fc , pg , true , initialCfgHash )
if expected := 1 ; reconciler . proxyGroups . Len ( ) != expected {
if expected := 1 ; reconciler . proxyGroups . Len ( ) != expected {
t . Fatalf ( "expected %d recorders, got %d" , expected , reconciler . proxyGroups . Len ( ) )
t . Fatalf ( "expected %d recorders, got %d" , expected , reconciler . proxyGroups . Len ( ) )
}
}
expectProxyGroupResources ( t , fc , pg , true )
expectProxyGroupResources ( t , fc , pg , true , initialCfgHash )
keyReq := tailscale . KeyCapabilities {
keyReq := tailscale . KeyCapabilities {
Devices : tailscale . KeyDeviceCapabilities {
Devices : tailscale . KeyDeviceCapabilities {
Create : tailscale . KeyDeviceCreateCapabilities {
Create : tailscale . KeyDeviceCreateCapabilities {
@ -135,7 +139,7 @@ func TestProxyGroup(t *testing.T) {
}
}
tsoperator . SetProxyGroupCondition ( pg , tsapi . ProxyGroupReady , metav1 . ConditionTrue , reasonProxyGroupReady , reasonProxyGroupReady , 0 , cl , zl . Sugar ( ) )
tsoperator . SetProxyGroupCondition ( pg , tsapi . ProxyGroupReady , metav1 . ConditionTrue , reasonProxyGroupReady , reasonProxyGroupReady , 0 , cl , zl . Sugar ( ) )
expectEqual ( t , fc , pg , nil )
expectEqual ( t , fc , pg , nil )
expectProxyGroupResources ( t , fc , pg , true )
expectProxyGroupResources ( t , fc , pg , true , initialCfgHash )
} )
} )
t . Run ( "scale_up_to_3" , func ( t * testing . T ) {
t . Run ( "scale_up_to_3" , func ( t * testing . T ) {
@ -146,6 +150,7 @@ func TestProxyGroup(t *testing.T) {
expectReconciled ( t , reconciler , "" , pg . Name )
expectReconciled ( t , reconciler , "" , pg . Name )
tsoperator . SetProxyGroupCondition ( pg , tsapi . ProxyGroupReady , metav1 . ConditionFalse , reasonProxyGroupCreating , "2/3 ProxyGroup pods running" , 0 , cl , zl . Sugar ( ) )
tsoperator . SetProxyGroupCondition ( pg , tsapi . ProxyGroupReady , metav1 . ConditionFalse , reasonProxyGroupCreating , "2/3 ProxyGroup pods running" , 0 , cl , zl . Sugar ( ) )
expectEqual ( t , fc , pg , nil )
expectEqual ( t , fc , pg , nil )
expectProxyGroupResources ( t , fc , pg , true , initialCfgHash )
addNodeIDToStateSecrets ( t , fc , pg )
addNodeIDToStateSecrets ( t , fc , pg )
expectReconciled ( t , reconciler , "" , pg . Name )
expectReconciled ( t , reconciler , "" , pg . Name )
@ -155,7 +160,7 @@ func TestProxyGroup(t *testing.T) {
TailnetIPs : [ ] string { "1.2.3.4" , "::1" } ,
TailnetIPs : [ ] string { "1.2.3.4" , "::1" } ,
} )
} )
expectEqual ( t , fc , pg , nil )
expectEqual ( t , fc , pg , nil )
expectProxyGroupResources ( t , fc , pg , true )
expectProxyGroupResources ( t , fc , pg , true , initialCfgHash )
} )
} )
t . Run ( "scale_down_to_1" , func ( t * testing . T ) {
t . Run ( "scale_down_to_1" , func ( t * testing . T ) {
@ -163,11 +168,26 @@ func TestProxyGroup(t *testing.T) {
mustUpdate ( t , fc , "" , pg . Name , func ( p * tsapi . ProxyGroup ) {
mustUpdate ( t , fc , "" , pg . Name , func ( p * tsapi . ProxyGroup ) {
p . Spec = pg . Spec
p . Spec = pg . Spec
} )
} )
expectReconciled ( t , reconciler , "" , pg . Name )
expectReconciled ( t , reconciler , "" , pg . Name )
pg . Status . Devices = pg . Status . Devices [ : 1 ] // truncate to only the first device.
pg . Status . Devices = pg . Status . Devices [ : 1 ] // truncate to only the first device.
expectEqual ( t , fc , pg , nil )
expectEqual ( t , fc , pg , nil )
expectProxyGroupResources ( t , fc , pg , true , initialCfgHash )
} )
expectProxyGroupResources ( t , fc , pg , true )
t . Run ( "trigger_config_change_and_observe_new_config_hash" , func ( t * testing . T ) {
pc . Spec . TailscaleConfig = & tsapi . TailscaleConfig {
AcceptRoutes : true ,
}
mustUpdate ( t , fc , "" , pc . Name , func ( p * tsapi . ProxyClass ) {
p . Spec = pc . Spec
} )
expectReconciled ( t , reconciler , "" , pg . Name )
expectEqual ( t , fc , pg , nil )
expectProxyGroupResources ( t , fc , pg , true , "518a86e9fae64f270f8e0ec2a2ea6ca06c10f725035d3d6caca132cd61e42a74" )
} )
} )
t . Run ( "delete_and_cleanup" , func ( t * testing . T ) {
t . Run ( "delete_and_cleanup" , func ( t * testing . T ) {
@ -191,13 +211,13 @@ func TestProxyGroup(t *testing.T) {
} )
} )
}
}
func expectProxyGroupResources ( t * testing . T , fc client . WithWatch , pg * tsapi . ProxyGroup , shouldExist bool ) {
func expectProxyGroupResources ( t * testing . T , fc client . WithWatch , pg * tsapi . ProxyGroup , shouldExist bool , cfgHash string ) {
t . Helper ( )
t . Helper ( )
role := pgRole ( pg , tsNamespace )
role := pgRole ( pg , tsNamespace )
roleBinding := pgRoleBinding ( pg , tsNamespace )
roleBinding := pgRoleBinding ( pg , tsNamespace )
serviceAccount := pgServiceAccount ( pg , tsNamespace )
serviceAccount := pgServiceAccount ( pg , tsNamespace )
statefulSet , err := pgStatefulSet ( pg , tsNamespace , testProxyImage , "auto" , "" )
statefulSet , err := pgStatefulSet ( pg , tsNamespace , testProxyImage , "auto" , cfgHash )
if err != nil {
if err != nil {
t . Fatal ( err )
t . Fatal ( err )
}
}
@ -207,9 +227,7 @@ func expectProxyGroupResources(t *testing.T, fc client.WithWatch, pg *tsapi.Prox
expectEqual ( t , fc , role , nil )
expectEqual ( t , fc , role , nil )
expectEqual ( t , fc , roleBinding , nil )
expectEqual ( t , fc , roleBinding , nil )
expectEqual ( t , fc , serviceAccount , nil )
expectEqual ( t , fc , serviceAccount , nil )
expectEqual ( t , fc , statefulSet , func ( ss * appsv1 . StatefulSet ) {
expectEqual ( t , fc , statefulSet , nil )
ss . Spec . Template . Annotations [ podAnnotationLastSetConfigFileHash ] = ""
} )
} else {
} else {
expectMissing [ rbacv1 . Role ] ( t , fc , role . Namespace , role . Name )
expectMissing [ rbacv1 . Role ] ( t , fc , role . Namespace , role . Name )
expectMissing [ rbacv1 . RoleBinding ] ( t , fc , roleBinding . Namespace , roleBinding . Name )
expectMissing [ rbacv1 . RoleBinding ] ( t , fc , roleBinding . Namespace , roleBinding . Name )
@ -218,12 +236,14 @@ func expectProxyGroupResources(t *testing.T, fc client.WithWatch, pg *tsapi.Prox
}
}
var expectedSecrets [ ] string
var expectedSecrets [ ] string
if shouldExist {
for i := range pgReplicas ( pg ) {
for i := range pgReplicas ( pg ) {
expectedSecrets = append ( expectedSecrets ,
expectedSecrets = append ( expectedSecrets ,
fmt . Sprintf ( "%s-%d" , pg . Name , i ) ,
fmt . Sprintf ( "%s-%d" , pg . Name , i ) ,
fmt . Sprintf ( "%s-%d-config" , pg . Name , i ) ,
fmt . Sprintf ( "%s-%d-config" , pg . Name , i ) ,
)
)
}
}
}
expectSecrets ( t , fc , expectedSecrets )
expectSecrets ( t , fc , expectedSecrets )
}
}