@@ -2,7 +2,10 @@ package auth
2
2
3
3
import (
4
4
"fmt"
5
+ operatorv1 "github.com/openshift/api/operator/v1"
6
+ "k8s.io/apimachinery/pkg/util/sets"
5
7
"net/url"
8
+ "sort"
6
9
"strings"
7
10
8
11
"k8s.io/klog/v2"
@@ -33,31 +36,28 @@ func ObserveServiceAccountIssuer(
33
36
) (map [string ]interface {}, []error ) {
34
37
35
38
listers := genericListers .(configobservation.Listers )
36
- ret , errs := observedConfig (existingConfig , listers .AuthConfigLister .Get , listers .InfrastructureLister ().Get , recorder )
39
+ ret , errs := observedConfig (existingConfig , listers .KubeAPIServerOperatorLister () .Get , listers .InfrastructureLister ().Get , recorder )
37
40
return configobserver .Pruned (ret , serviceAccountIssuerPath , audiencesPath , jwksURIPath ), errs
38
41
}
39
42
40
43
// observedConfig returns an unstructured fragment of KubeAPIServerConfig that may
41
44
// include an override of the default service account issuer if one was set in the
42
45
// Authentication resource.
43
- func observedConfig (
44
- existingConfig map [string ]interface {},
45
- getAuthConfig func (string ) (* configv1.Authentication , error ),
46
- getInfrastructureConfig func (string ) (* configv1.Infrastructure , error ),
47
- recorder events.Recorder ,
48
- ) (map [string ]interface {}, []error ) {
46
+ func observedConfig (existingConfig map [string ]interface {},
47
+ getOperator func (name string ) (* operatorv1.KubeAPIServer , error ),
48
+ getInfrastructureConfig func (string ) (* configv1.Infrastructure , error ), recorder events.Recorder ) (map [string ]interface {}, []error ) {
49
49
50
50
errs := []error {}
51
51
var issuerChanged bool
52
- var existingIssuer , newIssuer string
52
+ var existingActiveIssuer , newActiveIssuer string
53
53
// when the issuer will change, indicate that by setting `issuerChanged` to true
54
54
// to emit the informative event
55
55
defer func () {
56
56
if issuerChanged {
57
57
recorder .Eventf (
58
58
"ObserveServiceAccountIssuer" ,
59
59
"ServiceAccount issuer changed from %v to %v" ,
60
- existingIssuer , newIssuer ,
60
+ existingActiveIssuer , newActiveIssuer ,
61
61
)
62
62
}
63
63
}()
@@ -68,34 +68,38 @@ func observedConfig(
68
68
}
69
69
70
70
if len (existingIssuers ) > 0 {
71
- existingIssuer = existingIssuers [0 ]
71
+ existingActiveIssuer = existingIssuers [0 ]
72
72
}
73
73
74
- authConfig , err := getAuthConfig ("cluster" )
74
+ operator , err := getOperator ("cluster" )
75
75
if apierrors .IsNotFound (err ) {
76
- klog .Warningf ("authentications.config.openshift.io/cluster: not found" )
77
- // No issuer if the auth config is missing
78
- authConfig = & configv1.Authentication {}
76
+ klog .Warningf ("kubeapiserver.operators.openshift.io/cluster: not found" )
77
+ operator = & operatorv1.KubeAPIServer {}
79
78
} else if err != nil {
80
79
return existingConfig , append (errs , err )
81
80
}
82
81
83
- newIssuer = authConfig . Spec . ServiceAccountIssuer
84
- if err := checkIssuer (newIssuer ); err != nil {
82
+ newActiveIssuer = getActiveServiceAccountIssuer ( operator . Status . ServiceAccountIssuers )
83
+ if err := checkIssuer (newActiveIssuer ); err != nil {
85
84
return existingConfig , append (errs , err )
86
85
}
87
86
88
- if len (newIssuer ) != 0 {
89
- issuerChanged = existingIssuer != newIssuer
87
+ if len (newActiveIssuer ) > 0 {
88
+ currentTrustedServiceAccountIssuers := getTrustedServiceAccountIssuers (operator .Status .ServiceAccountIssuers )
89
+ issuerChanged = issuersChanged (
90
+ existingIssuers ,
91
+ append ([]string {newActiveIssuer }, currentTrustedServiceAccountIssuers ... )... ,
92
+ )
93
+
94
+ value := []interface {}{newActiveIssuer }
95
+ for _ , i := range currentTrustedServiceAccountIssuers {
96
+ value = append (value , i )
97
+ }
90
98
// configure the issuer if set by the user and is a valid issuer
91
99
return map [string ]interface {}{
92
100
"apiServerArguments" : map [string ]interface {}{
93
- "service-account-issuer" : []interface {}{
94
- newIssuer ,
95
- },
96
- "api-audiences" : []interface {}{
97
- newIssuer ,
98
- },
101
+ "service-account-issuer" : value ,
102
+ "api-audiences" : value ,
99
103
},
100
104
}, errs
101
105
}
@@ -113,7 +117,7 @@ func observedConfig(
113
117
return existingConfig , append (errs , fmt .Errorf ("APIServerInternalURL missing from infrastructure/cluster" ))
114
118
}
115
119
116
- issuerChanged = existingIssuer != newIssuer
120
+ issuerChanged = existingActiveIssuer != newActiveIssuer
117
121
return map [string ]interface {}{
118
122
"apiServerArguments" : map [string ]interface {}{
119
123
"service-account-jwks-uri" : []interface {}{
@@ -123,6 +127,34 @@ func observedConfig(
123
127
}, errs
124
128
}
125
129
130
+ // issuersChanged compares the command line flags used for KAS and the operator status service account issuers.
131
+ // if these two sets are different, we have a change and we need to update the KAS.
132
+ func issuersChanged (kasIssuers []string , trustedOperatorIssuers ... string ) bool {
133
+ sort .Strings (kasIssuers )
134
+ operatorAllIssuers := trustedOperatorIssuers
135
+ sort .Strings (operatorAllIssuers )
136
+ return ! sets .NewString (kasIssuers ... ).Equal (sets .NewString (operatorAllIssuers ... ))
137
+ }
138
+
139
+ func getTrustedServiceAccountIssuers (issuers []operatorv1.ServiceAccountIssuerStatus ) []string {
140
+ result := []string {}
141
+ for i := range issuers {
142
+ if issuers [i ].ExpirationTime != nil {
143
+ result = append (result , issuers [i ].Name )
144
+ }
145
+ }
146
+ return result
147
+ }
148
+
149
+ func getActiveServiceAccountIssuer (issuers []operatorv1.ServiceAccountIssuerStatus ) string {
150
+ for i := range issuers {
151
+ if issuers [i ].ExpirationTime == nil {
152
+ return issuers [i ].Name
153
+ }
154
+ }
155
+ return ""
156
+ }
157
+
126
158
// checkIssuer validates the issuer in the same way that it will be validated by
127
159
// kube-apiserver
128
160
func checkIssuer (issuer string ) error {
0 commit comments