@@ -2,6 +2,7 @@ use crate::api::resource::{
2
2
ResourceList ,
3
3
WatchEvent ,
4
4
ApiResource ,
5
+ QueryParams ,
5
6
} ;
6
7
use crate :: client:: APIClient ;
7
8
use crate :: { Result } ;
@@ -31,48 +32,85 @@ pub struct Informer<T, U> where
31
32
version : Arc < RwLock < String > > ,
32
33
client : APIClient ,
33
34
resource : ApiResource ,
35
+ params : QueryParams ,
34
36
}
35
37
36
38
impl < T , U > Informer < T , U > where
37
39
T : Clone + DeserializeOwned ,
38
40
U : Clone + DeserializeOwned ,
39
41
{
40
42
/// Create a reflector with a kube client on a kube resource
41
- ///
42
- /// Initializes resourceVersion with a 1 limit list call
43
- pub fn new ( client : APIClient , r : ApiResource ) -> Result < Self > {
44
- info ! ( "Creating Informer for {:?}" , r) ;
45
- let initial = get_resource_version ( & client, & r) ?;
46
- Ok ( Informer {
43
+ pub fn new ( client : APIClient , r : ApiResource ) -> Self {
44
+ Informer {
47
45
client,
48
46
resource : r,
47
+ params : QueryParams :: default ( ) ,
49
48
events : Arc :: new ( RwLock :: new ( VecDeque :: new ( ) ) ) ,
50
- version : Arc :: new ( RwLock :: new ( initial ) ) ,
51
- } )
49
+ version : Arc :: new ( RwLock :: new ( 0 . to_string ( ) ) ) ,
50
+ }
52
51
}
53
52
54
- /// Create a reflector with a kube client on a kube resource
53
+ /// Configure the timeout for the list/watch call.
55
54
///
56
- /// Initializes resourceVersion from a passed in value
57
- pub fn from_version ( client : APIClient , r : ApiResource , v : String ) -> Result < Self > {
58
- info ! ( "Creating Informer for {:?}" , r) ;
59
- Ok ( Informer {
60
- client,
61
- resource : r,
62
- events : Arc :: new ( RwLock :: new ( VecDeque :: new ( ) ) ) ,
63
- version : Arc :: new ( RwLock :: new ( v) ) ,
64
- } )
55
+ /// This limits the duration of the call, regardless of any activity or inactivity.
56
+ /// Defaults to 10s
57
+ pub fn timeout ( mut self , timeout_secs : u32 ) -> Self {
58
+ self . params . timeout = Some ( timeout_secs) ;
59
+ self
60
+ }
61
+
62
+ /// Configure the selector to restrict the list of returned objects by their fields.
63
+ ///
64
+ /// Defaults to everything.
65
+ /// Supports '=', '==', and '!=', and can comma separate: key1=value1,key2=value2
66
+ /// The server only supports a limited number of field queries per type.
67
+ pub fn fields ( mut self , field_selector : & str ) -> Self {
68
+ self . params . field_selector = Some ( field_selector. to_string ( ) ) ;
69
+ self
70
+ }
71
+
72
+ /// Configure the selector to restrict the list of returned objects by their labels.
73
+ ///
74
+ /// Defaults to everything.
75
+ /// Supports '=', '==', and '!=', and can comma separate: key1=value1,key2=value2
76
+ pub fn labels ( mut self , label_selector : & str ) -> Self {
77
+ self . params . label_selector = Some ( label_selector. to_string ( ) ) ;
78
+ self
79
+ }
80
+
81
+ /// If called, partially initialized resources are included in watch/list responses.
82
+ pub fn include_uninitialized ( mut self ) -> Self {
83
+ self . params . include_uninitialized = true ;
84
+ self
85
+ }
86
+
87
+
88
+ /// Initialize without a prior version
89
+ ///
90
+ /// Will seed resourceVersion with a 1 limit list call to the resource
91
+ pub fn init ( self ) -> Result < Self > {
92
+ let initial = self . get_resource_version ( ) ?;
93
+ info ! ( "Starting Informer for {:?}" , self . resource) ;
94
+ * self . version . write ( ) . unwrap ( ) = initial;
95
+ Ok ( self )
96
+ }
97
+
98
+ /// Initialize from a prior version
99
+ pub fn init_from ( self , v : String ) -> Self {
100
+ info ! ( "Recreating Informer for {:?} at {}" , self . resource, v) ;
101
+ * self . version . write ( ) . unwrap ( ) = v;
102
+ self
65
103
}
66
104
105
+
67
106
/// Run a single watch poll
68
107
///
69
108
/// If this returns an error, it resets the resourceVersion.
70
109
/// This is meant to be run continually and events are meant to be handled between.
71
110
/// If handling all the events is too time consuming, you probably need a queue.
72
111
pub fn poll ( & self ) -> Result < ( ) > {
73
112
trace ! ( "Watching {:?}" , self . resource) ;
74
- let oldver = self . version ( ) ;
75
- match watch_for_resource_updates ( & self . client , & self . resource , & oldver) {
113
+ match self . single_watch ( ) {
76
114
Ok ( ( events, newver) ) => {
77
115
* self . version . write ( ) . unwrap ( ) = newver;
78
116
for e in events {
@@ -97,7 +135,7 @@ impl<T, U> Informer<T, U> where
97
135
/// Reset the resourceVersion to current and clear the event queue
98
136
pub fn reset ( & self ) -> Result < ( ) > {
99
137
// Fetch a new initial version:
100
- let initial = get_resource_version ( & self . client , & self . resource ) ?;
138
+ let initial = self . get_resource_version ( ) ?;
101
139
* self . version . write ( ) . unwrap ( ) = initial;
102
140
self . events . write ( ) . unwrap ( ) . clear ( ) ;
103
141
Ok ( ( ) )
@@ -107,42 +145,40 @@ impl<T, U> Informer<T, U> where
107
145
pub fn version ( & self ) -> String {
108
146
self . version . read ( ) . unwrap ( ) . clone ( )
109
147
}
110
- }
111
148
112
- fn get_resource_version ( client : & APIClient , rg : & ApiResource ) -> Result < String >
113
- {
114
- let req = rg. list_zero_resource_entries ( ) ?;
115
149
116
- // parse to void a ResourceList into void except for Metadata
117
- #[ derive( Clone , Deserialize ) ]
118
- struct Discard { } // ffs
119
- let res = client. request :: < ResourceList < Option < Discard > > > ( req) ?;
150
+ /// Init helper
151
+ fn get_resource_version ( & self ) -> Result < String > {
152
+ let req = self . resource . list_zero_resource_entries ( & self . params ) ?;
120
153
121
- let version = res . metadata . resourceVersion . unwrap_or_else ( || "0" . into ( ) ) ;
122
- debug ! ( "Got fresh resourceVersion={} for {}" , version , rg . resource ) ;
123
- Ok ( version )
124
- }
154
+ // parse to void a ResourceList into void except for Metadata
155
+ # [ derive ( Clone , Deserialize ) ]
156
+ struct Discard { } // ffs
157
+ let res = self . client . request :: < ResourceList < Option < Discard > > > ( req ) ? ;
125
158
159
+ let version = res. metadata . resourceVersion . unwrap_or_else ( || "0" . into ( ) ) ;
160
+ debug ! ( "Got fresh resourceVersion={} for {}" , version, self . resource. resource) ;
161
+ Ok ( version )
162
+ }
126
163
127
- fn watch_for_resource_updates < T , U > ( client : & APIClient , rg : & ApiResource , ver : & str )
128
- -> Result < ( Vec < WatchEvent < T , U > > , String ) > where
129
- T : Clone + DeserializeOwned ,
130
- U : Clone + DeserializeOwned ,
131
- {
132
- let req = rg. watch_resource_entries_after ( ver) ?;
133
- let events = client. request_events :: < WatchEvent < T , U > > ( req) ?;
134
-
135
- // Follow docs conventions and store the last resourceVersion
136
- // https://kubernetes.io/docs/reference/using-api/api-concepts/#efficient-detection-of-changes
137
- let newver = events. iter ( ) . filter_map ( |e| {
138
- match e {
139
- WatchEvent :: Added ( o) => o. metadata . resourceVersion . clone ( ) ,
140
- WatchEvent :: Modified ( o) => o. metadata . resourceVersion . clone ( ) ,
141
- WatchEvent :: Deleted ( o) => o. metadata . resourceVersion . clone ( ) ,
142
- _ => None
143
- }
144
- } ) . last ( ) . unwrap_or_else ( || ver. into ( ) ) ;
145
- debug ! ( "Got {} {} events, resourceVersion={}" , events. len( ) , rg. resource, newver) ;
164
+ /// Watch helper
165
+ fn single_watch ( & self ) -> Result < ( Vec < WatchEvent < T , U > > , String ) > {
166
+ let oldver = self . version ( ) ;
167
+ let req = self . resource . watch_resource_entries_after ( & self . params , & oldver) ?;
168
+ let events = self . client . request_events :: < WatchEvent < T , U > > ( req) ?;
169
+
170
+ // Follow docs conventions and store the last resourceVersion
171
+ // https://kubernetes.io/docs/reference/using-api/api-concepts/#efficient-detection-of-changes
172
+ let newver = events. iter ( ) . filter_map ( |e| {
173
+ match e {
174
+ WatchEvent :: Added ( o) => o. metadata . resourceVersion . clone ( ) ,
175
+ WatchEvent :: Modified ( o) => o. metadata . resourceVersion . clone ( ) ,
176
+ WatchEvent :: Deleted ( o) => o. metadata . resourceVersion . clone ( ) ,
177
+ _ => None
178
+ }
179
+ } ) . last ( ) . unwrap_or_else ( || oldver. into ( ) ) ;
180
+ debug ! ( "Got {} {} events, resourceVersion={}" , events. len( ) , self . resource. resource, newver) ;
146
181
147
- Ok ( ( events, newver) )
182
+ Ok ( ( events, newver) )
183
+ }
148
184
}
0 commit comments