@@ -20,14 +20,12 @@ package client
2020import (
2121 "bytes"
2222 "context"
23- "crypto/tls"
2423 "encoding/json"
2524 "errors"
2625 "fmt"
2726 "io"
2827 "net"
2928 "net/http"
30- "net/url"
3129 "os"
3230 "strings"
3331 "time"
@@ -86,7 +84,7 @@ type ADCServerOpts struct {
8684
8785type ADCValidateResult struct {
8886 Success * bool `json:"success,omitempty"`
89- ErrorMessage string `json:"errorMessage ,omitempty"`
87+ ErrorMessage string `json:"message ,omitempty"`
9088 Errors []types.ADCValidationDetail `json:"errors,omitempty"`
9189}
9290
@@ -254,21 +252,12 @@ func (e *HTTPADCExecutor) runHTTPValidateForSingleServer(ctx context.Context, se
254252 return fmt .Errorf ("failed to load resources from file %s: %w" , filePath , err )
255253 }
256254
257- var (
258- req * http.Request
259- httpClient = e .httpClient
260- )
261- if config .BackendType == "apisix-standalone" {
262- req , err = e .buildAPISIXValidateRequest (ctx , serverAddr , config , resources )
263- httpClient = e .newBackendHTTPClient (config )
264- } else {
265- req , err = e .buildHTTPRequest (ctx , serverAddr , config , labels , types , resources , http .MethodPost , "/validate" )
266- }
255+ req , err := e .buildHTTPRequest (ctx , serverAddr , config , labels , types , resources , http .MethodPost , "/validate" )
267256 if err != nil {
268257 return fmt .Errorf ("failed to build validate request: %w" , err )
269258 }
270259
271- resp , err := httpClient .Do (req )
260+ resp , err := e . httpClient .Do (req )
272261 if err != nil {
273262 return fmt .Errorf ("failed to send HTTP request: %w" , err )
274263 }
@@ -281,230 +270,6 @@ func (e *HTTPADCExecutor) runHTTPValidateForSingleServer(ctx context.Context, se
281270 return e .handleHTTPValidateResponse (resp , serverAddr )
282271}
283272
284- type apisixValidateRequest struct {
285- Routes []map [string ]any `json:"routes,omitempty"`
286- Services []map [string ]any `json:"services,omitempty"`
287- Consumers []map [string ]any `json:"consumers,omitempty"`
288- SSLs []map [string ]any `json:"ssls,omitempty"`
289- GlobalRules []map [string ]any `json:"global_rules,omitempty"`
290- StreamRoutes []map [string ]any `json:"stream_routes,omitempty"`
291- PluginMetadata []map [string ]any `json:"plugin_metadata,omitempty"`
292- Upstreams []map [string ]any `json:"upstreams,omitempty"`
293- }
294-
295- func (e * HTTPADCExecutor ) buildAPISIXValidateRequest (ctx context.Context , serverAddr string , config adctypes.Config , resources * adctypes.Resources ) (* http.Request , error ) {
296- body , err := buildAPISIXValidatePayload (resources )
297- if err != nil {
298- return nil , err
299- }
300-
301- jsonData , err := json .Marshal (body )
302- if err != nil {
303- return nil , fmt .Errorf ("failed to marshal APISIX validate request body: %w" , err )
304- }
305-
306- validateURL , err := url .JoinPath (serverAddr , "/apisix/admin/configs/validate" )
307- if err != nil {
308- return nil , fmt .Errorf ("failed to build APISIX validate URL: %w" , err )
309- }
310-
311- e .log .V (1 ).Info ("sending APISIX validate request" ,
312- "url" , validateURL ,
313- "server" , serverAddr ,
314- "cacheKey" , config .Name ,
315- "bodyLen" , len (jsonData ),
316- )
317-
318- req , err := http .NewRequestWithContext (ctx , http .MethodPost , validateURL , bytes .NewBuffer (jsonData ))
319- if err != nil {
320- return nil , fmt .Errorf ("failed to create APISIX validate request: %w" , err )
321- }
322-
323- req .Header .Set ("Content-Type" , "application/json" )
324- req .Header .Set ("X-API-KEY" , config .Token )
325- return req , nil
326- }
327-
328- func (e * HTTPADCExecutor ) newBackendHTTPClient (config adctypes.Config ) * http.Client {
329- transport := http .DefaultTransport .(* http.Transport ).Clone ()
330- if transport .TLSClientConfig == nil {
331- transport .TLSClientConfig = & tls.Config {}
332- }
333- transport .TLSClientConfig .MinVersion = tls .VersionTLS12
334- if ! config .TlsVerify {
335- transport .TLSClientConfig .InsecureSkipVerify = true
336- }
337-
338- return & http.Client {
339- Timeout : e .httpClient .Timeout ,
340- Transport : transport ,
341- }
342- }
343-
344- func buildAPISIXValidatePayload (resources * adctypes.Resources ) (* apisixValidateRequest , error ) {
345- body := & apisixValidateRequest {}
346-
347- for _ , service := range resources .Services {
348- if service == nil {
349- continue
350- }
351-
352- serviceMap , err := toMap (service )
353- if err != nil {
354- return nil , err
355- }
356- delete (serviceMap , "routes" )
357- delete (serviceMap , "stream_routes" )
358- delete (serviceMap , "upstreams" )
359-
360- body .Services = append (body .Services , serviceMap )
361-
362- for _ , upstream := range service .Upstreams {
363- upstreamMap , err := toMap (upstream )
364- if err != nil {
365- return nil , err
366- }
367- body .Upstreams = append (body .Upstreams , upstreamMap )
368- }
369-
370- for _ , route := range service .Routes {
371- routeMap , err := buildAPISIXRouteValidateObject (route )
372- if err != nil {
373- return nil , err
374- }
375- if service .ID != "" {
376- routeMap ["service_id" ] = service .ID
377- }
378- body .Routes = append (body .Routes , routeMap )
379- }
380-
381- for _ , streamRoute := range service .StreamRoutes {
382- streamRouteMap , err := toMap (streamRoute )
383- if err != nil {
384- return nil , err
385- }
386- body .StreamRoutes = append (body .StreamRoutes , streamRouteMap )
387- }
388- }
389-
390- for _ , consumer := range resources .Consumers {
391- consumerMap , err := buildAPISIXConsumerValidateObject (consumer )
392- if err != nil {
393- return nil , err
394- }
395- body .Consumers = append (body .Consumers , consumerMap )
396- }
397-
398- for _ , ssl := range resources .SSLs {
399- sslMap , err := buildAPISIXSSLValidateObject (ssl )
400- if err != nil {
401- return nil , err
402- }
403- body .SSLs = append (body .SSLs , sslMap )
404- }
405-
406- if len (resources .GlobalRules ) > 0 {
407- globalRuleMap , err := toMap (& adctypes.GlobalRuleItem {
408- Metadata : adctypes.Metadata {ID : "validation-global-rule" },
409- Plugins : adctypes .Plugins (resources .GlobalRules ),
410- })
411- if err != nil {
412- return nil , err
413- }
414- body .GlobalRules = append (body .GlobalRules , globalRuleMap )
415- }
416-
417- for pluginName , pluginConfig := range resources .PluginMetadata {
418- m := map [string ]any {"id" : pluginName }
419- if cfg , ok := pluginConfig .(map [string ]any ); ok {
420- for k , v := range cfg {
421- m [k ] = v
422- }
423- }
424- body .PluginMetadata = append (body .PluginMetadata , m )
425- }
426-
427- return body , nil
428- }
429-
430- func buildAPISIXRouteValidateObject (route * adctypes.Route ) (map [string ]any , error ) {
431- routeMap , err := toMap (route )
432- if err != nil {
433- return nil , err
434- }
435-
436- delete (routeMap , "description" )
437- return routeMap , nil
438- }
439-
440- func buildAPISIXConsumerValidateObject (consumer * adctypes.Consumer ) (map [string ]any , error ) {
441- consumerMap , err := toMap (consumer )
442- if err != nil {
443- return nil , err
444- }
445-
446- if len (consumer .Credentials ) == 0 {
447- return consumerMap , nil
448- }
449-
450- plugins , ok := consumerMap ["plugins" ].(map [string ]any )
451- if ! ok || plugins == nil {
452- plugins = make (map [string ]any , len (consumer .Credentials ))
453- }
454-
455- for _ , credential := range consumer .Credentials {
456- plugins [credential .Type ] = credential .Config
457- }
458-
459- consumerMap ["plugins" ] = plugins
460- delete (consumerMap , "credentials" )
461- return consumerMap , nil
462- }
463-
464- func buildAPISIXSSLValidateObject (ssl * adctypes.SSL ) (map [string ]any , error ) {
465- sslMap , err := toMap (ssl )
466- if err != nil {
467- return nil , err
468- }
469-
470- delete (sslMap , "certificates" )
471-
472- switch len (ssl .Certificates ) {
473- case 0 :
474- return sslMap , nil
475- case 1 :
476- sslMap ["cert" ] = ssl .Certificates [0 ].Certificate
477- sslMap ["key" ] = ssl .Certificates [0 ].Key
478- default :
479- sslMap ["cert" ] = ssl .Certificates [0 ].Certificate
480- sslMap ["key" ] = ssl .Certificates [0 ].Key
481-
482- certs := make ([]string , 0 , len (ssl .Certificates )- 1 )
483- keys := make ([]string , 0 , len (ssl .Certificates )- 1 )
484- for _ , certificate := range ssl .Certificates [1 :] {
485- certs = append (certs , certificate .Certificate )
486- keys = append (keys , certificate .Key )
487- }
488- sslMap ["certs" ] = certs
489- sslMap ["keys" ] = keys
490- }
491-
492- return sslMap , nil
493- }
494-
495- func toMap (obj any ) (map [string ]any , error ) {
496- data , err := json .Marshal (obj )
497- if err != nil {
498- return nil , fmt .Errorf ("failed to marshal validation object: %w" , err )
499- }
500-
501- var out map [string ]any
502- if err := json .Unmarshal (data , & out ); err != nil {
503- return nil , fmt .Errorf ("failed to unmarshal validation object: %w" , err )
504- }
505- return out , nil
506- }
507-
508273// parseArgs parses the command line arguments to extract labels, types, and file path
509274func (e * HTTPADCExecutor ) parseArgs (args []string ) (map [string ]string , []string , string , error ) {
510275 labels := make (map [string ]string )
0 commit comments