@@ -17,6 +17,7 @@ limitations under the License.
17
17
package discovery
18
18
19
19
import (
20
+ "context"
20
21
"net/http"
21
22
"sync"
22
23
@@ -33,12 +34,21 @@ import (
33
34
// GroupManager is an interface that allows dynamic mutation of the existing webservice to handle
34
35
// API groups being added or removed.
35
36
type GroupManager interface {
37
+ GroupLister
38
+
36
39
AddGroup (apiGroup metav1.APIGroup )
37
40
RemoveGroup (groupName string )
38
41
ServeHTTP (resp http.ResponseWriter , req * http.Request )
39
42
WebService () * restful.WebService
40
43
}
41
44
45
+ // GroupLister knows how to list APIGroups for discovery.
46
+ type GroupLister interface {
47
+ // Groups returns APIGroups for discovery, filling in ServerAddressByClientCIDRs
48
+ // based on data in req.
49
+ Groups (ctx context.Context , req * http.Request ) ([]metav1.APIGroup , error )
50
+ }
51
+
42
52
// rootAPIsHandler creates a webservice serving api group discovery.
43
53
// The list of APIGroups may change while the server is running because additional resources
44
54
// are registered or removed. It is not safe to cache the values.
@@ -94,24 +104,40 @@ func (s *rootAPIsHandler) RemoveGroup(groupName string) {
94
104
}
95
105
}
96
106
97
- func (s * rootAPIsHandler ) ServeHTTP ( resp http. ResponseWriter , req * http.Request ) {
107
+ func (s * rootAPIsHandler ) Groups ( ctx context. Context , req * http.Request ) ([]metav1. APIGroup , error ) {
98
108
s .lock .RLock ()
99
109
defer s .lock .RUnlock ()
100
110
111
+ return s .groupsLocked (ctx , req ), nil
112
+ }
113
+
114
+ // groupsLocked returns the APIGroupList discovery information for this handler.
115
+ // The caller must hold the lock before invoking this method to avoid data races.
116
+ func (s * rootAPIsHandler ) groupsLocked (ctx context.Context , req * http.Request ) []metav1.APIGroup {
117
+ clientIP := utilnet .GetClientIP (req )
118
+ serverCIDR := s .addresses .ServerAddressByClientCIDRs (clientIP )
119
+
101
120
orderedGroups := []metav1.APIGroup {}
102
121
for _ , groupName := range s .apiGroupNames {
103
122
orderedGroups = append (orderedGroups , s .apiGroups [groupName ])
104
123
}
105
124
106
- clientIP := utilnet .GetClientIP (req )
107
- serverCIDR := s .addresses .ServerAddressByClientCIDRs (clientIP )
108
125
groups := make ([]metav1.APIGroup , len (orderedGroups ))
109
126
for i := range orderedGroups {
110
127
groups [i ] = orderedGroups [i ]
111
128
groups [i ].ServerAddressByClientCIDRs = serverCIDR
112
129
}
113
130
114
- responsewriters .WriteObjectNegotiated (s .serializer , negotiation .DefaultEndpointRestrictions , schema.GroupVersion {}, resp , req , http .StatusOK , & metav1.APIGroupList {Groups : groups }, false )
131
+ return groups
132
+ }
133
+
134
+ func (s * rootAPIsHandler ) ServeHTTP (resp http.ResponseWriter , req * http.Request ) {
135
+ s .lock .RLock ()
136
+ defer s .lock .RUnlock ()
137
+
138
+ groupList := metav1.APIGroupList {Groups : s .groupsLocked (req .Context (), req )}
139
+
140
+ responsewriters .WriteObjectNegotiated (s .serializer , negotiation .DefaultEndpointRestrictions , schema.GroupVersion {}, resp , req , http .StatusOK , & groupList , false )
115
141
}
116
142
117
143
func (s * rootAPIsHandler ) restfulHandle (req * restful.Request , resp * restful.Response ) {
0 commit comments