@@ -5,12 +5,15 @@ import (
55 "fmt"
66 "os"
77 "strings"
8+ "time"
89
10+ "github.com/google/uuid"
911 "github.com/spf13/cobra"
1012 "github.com/spf13/pflag"
1113 searchapiserver "go.miloapis.net/search/internal/apiserver"
1214 "go.miloapis.net/search/internal/version"
1315 searchv1alpha1 "go.miloapis.net/search/pkg/apis/search/v1alpha1"
16+ "k8s.io/apimachinery/pkg/runtime"
1417 utilruntime "k8s.io/apimachinery/pkg/util/runtime"
1518 apiopenapi "k8s.io/apiserver/pkg/endpoints/openapi"
1619 genericapiserver "k8s.io/apiserver/pkg/server"
@@ -22,9 +25,13 @@ import (
2225 logsapi "k8s.io/component-base/logs/api/v1"
2326 "k8s.io/klog/v2"
2427 "k8s.io/kube-openapi/pkg/common"
28+ runtimecache "sigs.k8s.io/controller-runtime/pkg/cache"
29+ ctrllog "sigs.k8s.io/controller-runtime/pkg/log"
2530
2631 "go.miloapis.net/search/cmd/search/indexer"
2732 "go.miloapis.net/search/cmd/search/manager"
33+ internalindexer "go.miloapis.net/search/internal/indexer"
34+ "go.miloapis.net/search/pkg/meilisearch"
2835
2936 // Register JSON logging format
3037 _ "k8s.io/component-base/logs/json/register"
@@ -140,8 +147,14 @@ func NewVersionCommand() *cobra.Command {
140147
141148// SearchServerOptions contains configuration for the search server.
142149type SearchServerOptions struct {
143- RecommendedOptions * options.RecommendedOptions
144- Logs * logsapi.LoggingConfiguration
150+ RecommendedOptions * options.RecommendedOptions
151+ Logs * logsapi.LoggingConfiguration
152+ MeilisearchDomain string
153+ MeilisearchHTTPTimeout time.Duration
154+ MeilisearchTaskWaitTimeout time.Duration
155+ MaxSearchLimit int
156+ DefaultSearchLimit int
157+ PagingTimeout time.Duration
145158}
146159
147160// NewSearchServerOptions creates options with default values.
@@ -151,14 +164,23 @@ func NewSearchServerOptions() *SearchServerOptions {
151164 "/registry/search.miloapis.com" ,
152165 searchapiserver .Codecs .LegacyCodec (searchapiserver .Scheme .PrioritizedVersionsAllGroups ()... ),
153166 ),
154- Logs : logsapi .NewLoggingConfiguration (),
167+ Logs : logsapi .NewLoggingConfiguration (),
168+ MeilisearchDomain : "http://meilisearch.meilisearch-system.svc.cluster.local:7700" ,
169+ MeilisearchHTTPTimeout : 60 * time .Second ,
170+ MaxSearchLimit : 100 ,
171+ DefaultSearchLimit : 10 ,
172+ PagingTimeout : 24 * time .Hour ,
155173 }
156174
157175 return o
158176}
159177
160178func (o * SearchServerOptions ) AddFlags (fs * pflag.FlagSet ) {
161179 o .RecommendedOptions .AddFlags (fs )
180+ fs .StringVar (& o .MeilisearchDomain , "meilisearch-domain" , o .MeilisearchDomain , "Domain of the Meilisearch instance." )
181+ fs .IntVar (& o .MaxSearchLimit , "max-search-limit" , o .MaxSearchLimit , "The maximum number of results a SearchQuery can return in a single request." )
182+ fs .IntVar (& o .DefaultSearchLimit , "default-search-limit" , o .DefaultSearchLimit , "The default number of results a SearchQuery returns when no limit is specified." )
183+ fs .DurationVar (& o .PagingTimeout , "paging-timeout" , o .PagingTimeout , "The duration for which a paging (continue) token is valid." )
162184}
163185
164186func (o * SearchServerOptions ) Complete () error {
@@ -197,9 +219,53 @@ func (o *SearchServerOptions) Config() (*searchapiserver.Config, error) {
197219 return nil , fmt .Errorf ("failed to apply recommended options: %w" , err )
198220 }
199221
222+ meiliClient , err := meilisearch .NewSDKClient (meilisearch.SDKConfig {
223+ Domain : o .MeilisearchDomain ,
224+ APIKey : os .Getenv ("MEILISEARCH_API_KEY" ),
225+ WaitTimeout : o .MeilisearchTaskWaitTimeout ,
226+ HTTPTimeout : o .MeilisearchHTTPTimeout ,
227+ })
228+ if err != nil {
229+ return nil , fmt .Errorf ("failed to initialize meilisearch client: %w" , err )
230+ }
231+
232+ // Create a dedicated scheme for the policy cache that only contains versioned types.
233+ // This avoids ambiguity when the main scheme registers the same type for both
234+ // v1alpha1 and __internal versions.
235+ policyScheme := runtime .NewScheme ()
236+ if err := searchv1alpha1 .AddToScheme (policyScheme ); err != nil {
237+ return nil , fmt .Errorf ("failed to add v1alpha1 to policy scheme: %w" , err )
238+ }
239+
240+ // Create a controller-runtime cache that uses a watch stream (informer)
241+ // to keep ResourceIndexPolicies in-sync.
242+ k8sCache , err := runtimecache .New (genericConfig .LoopbackClientConfig , runtimecache.Options {Scheme : policyScheme })
243+ if err != nil {
244+ return nil , fmt .Errorf ("failed to create controller-runtime cache: %w" , err )
245+ }
246+
247+ // Create the policy cache (strict ready checking enabled)
248+ indexPolicyCache , err := internalindexer .NewPolicyCache (k8sCache , true )
249+ if err != nil {
250+ return nil , fmt .Errorf ("failed to create policy cache: %w" , err )
251+ }
252+
253+ pagingSecret := []byte (os .Getenv ("SEARCH_PAGING_SECRET" ))
254+ if len (pagingSecret ) == 0 {
255+ klog .Info ("SEARCH_PAGING_SECRET not set, generating a random one" )
256+ pagingSecret = []byte (uuid .New ().String ())
257+ }
258+
200259 serverConfig := & searchapiserver.Config {
201260 GenericConfig : genericConfig ,
202- ExtraConfig : searchapiserver.ExtraConfig {},
261+ ExtraConfig : searchapiserver.ExtraConfig {
262+ MeiliClient : meiliClient ,
263+ PolicyCache : indexPolicyCache ,
264+ MaxSearchLimit : o .MaxSearchLimit ,
265+ DefaultSearchLimit : o .DefaultSearchLimit ,
266+ PagingSecret : pagingSecret ,
267+ PagingTimeout : o .PagingTimeout ,
268+ },
203269 }
204270
205271 return serverConfig , nil
@@ -211,6 +277,8 @@ func Run(options *SearchServerOptions, ctx context.Context) error {
211277 return fmt .Errorf ("failed to apply logging configuration: %w" , err )
212278 }
213279
280+ ctrllog .SetLogger (klog .NewKlogr ())
281+
214282 config , err := options .Config ()
215283 if err != nil {
216284 return err
0 commit comments