go-duck-cli 1.2.1 → 1.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -400,6 +400,502 @@ jobs:
400
400
  ]
401
401
  }, null, 4);
402
402
 
403
+ const pushScript = `#!/usr/bin/env bash
404
+ # Exit immediately if a command exits with a non-zero status
405
+ set -e
406
+
407
+ # --- CONFIGURATION ---
408
+ # Edit these variables to hardcode your values, or leave them to fallback to environment variables.
409
+ DOCKER_USER="\${DOCKER_USER:-your-dockerhub-username}"
410
+ IMAGE_NAME="\${IMAGE_NAME:-${appName}}"
411
+ VERSION="\${VERSION:-1.0.0}"
412
+ # ---------------------
413
+
414
+ # Build the full image tag
415
+ TAG="\${DOCKER_USER}/\${IMAGE_NAME}:\${VERSION}"
416
+
417
+ echo "========================================="
418
+ echo "Building Docker image: \$TAG"
419
+ echo "========================================="
420
+ docker build -f devops/Dockerfile -t "\$TAG" .
421
+
422
+ echo "========================================="
423
+ echo "Pushing Docker image: \$TAG"
424
+ echo "========================================="
425
+ docker push "\$TAG"
426
+
427
+ echo "========================================="
428
+ echo "Successfully built and published \$TAG"
429
+ echo "========================================="
430
+ `;
431
+
432
+ const k8sAppYaml = `apiVersion: apps/v1
433
+ kind: Deployment
434
+ metadata:
435
+ name: ${appName}
436
+ labels:
437
+ app: ${appName}
438
+ spec:
439
+ replicas: 1
440
+ selector:
441
+ matchLabels:
442
+ app: ${appName}
443
+ template:
444
+ metadata:
445
+ labels:
446
+ app: ${appName}
447
+ spec:
448
+ containers:
449
+ - name: ${appName}
450
+ image: ${appName}:latest
451
+ env:
452
+ - name: GO_PROFILE
453
+ value: prod
454
+ - name: GO_DUCK_SERVER_REST_PORT
455
+ value: "${appPort}"
456
+ - name: GO_DUCK_DATASOURCE_HOST
457
+ value: postgres
458
+ - name: GO_DUCK_DATASOURCE_USERNAME
459
+ value: "${config.datasource?.username || 'postgres'}"
460
+ - name: GO_DUCK_DATASOURCE_PASSWORD
461
+ value: "${config.datasource?.password || 'password'}"
462
+ - name: GO_DUCK_DATASOURCE_DATABASE
463
+ value: "${config.datasource?.database || 'go_duck_master'}"
464
+ - name: GO_DUCK_DATASOURCE_PORT
465
+ value: "5432"
466
+ - name: GO_DUCK_CACHE_REDIS_HOST
467
+ value: redis:6379
468
+ - name: GO_DUCK_MESSAGING_MQTT_BROKER
469
+ value: tcp://mosquitto:1883
470
+ - name: GO_DUCK_MESSAGING_NATS_URL
471
+ value: nats://nats:4222
472
+ - name: GO_DUCK_TELEMETRY_OTEL_ENDPOINT
473
+ value: otel-collector:4317
474
+ - name: GO_DUCK_ELASTICSEARCH_ADDRESSES
475
+ value: http://elasticsearch:9200
476
+ - name: GO_DUCK_SECURITY_KEYCLOAK_HOST
477
+ value: http://keycloak:8080
478
+ ports:
479
+ - name: http
480
+ containerPort: ${appPort}
481
+ - name: grpc
482
+ containerPort: 9000
483
+ ---
484
+ apiVersion: v1
485
+ kind: Service
486
+ metadata:
487
+ name: ${appName}
488
+ spec:
489
+ ports:
490
+ - name: http
491
+ port: ${appPort}
492
+ targetPort: http
493
+ - name: grpc
494
+ port: 9000
495
+ targetPort: grpc
496
+ selector:
497
+ app: ${appName}
498
+ `;
499
+
500
+ const k8sPostgresYaml = `apiVersion: v1
501
+ kind: PersistentVolumeClaim
502
+ metadata:
503
+ name: postgres-pvc
504
+ spec:
505
+ accessModes:
506
+ - ReadWriteOnce
507
+ resources:
508
+ requests:
509
+ storage: 1Gi
510
+ ---
511
+ apiVersion: apps/v1
512
+ kind: Deployment
513
+ metadata:
514
+ name: postgres
515
+ labels:
516
+ app: postgres
517
+ spec:
518
+ replicas: 1
519
+ selector:
520
+ matchLabels:
521
+ app: postgres
522
+ template:
523
+ metadata:
524
+ labels:
525
+ app: postgres
526
+ spec:
527
+ containers:
528
+ - name: postgres
529
+ image: postgres:15.6-alpine
530
+ env:
531
+ - name: POSTGRES_USER
532
+ value: "${config.datasource?.username || 'postgres'}"
533
+ - name: POSTGRES_PASSWORD
534
+ value: "${config.datasource?.password || 'password'}"
535
+ - name: POSTGRES_DB
536
+ value: "${config.datasource?.database || 'go_duck_master'}"
537
+ ports:
538
+ - containerPort: 5432
539
+ volumeMounts:
540
+ - name: postgres-storage
541
+ mountPath: /var/lib/postgresql/data
542
+ volumes:
543
+ - name: postgres-storage
544
+ persistentVolumeClaim:
545
+ claimName: postgres-pvc
546
+ ---
547
+ apiVersion: v1
548
+ kind: Service
549
+ metadata:
550
+ name: postgres
551
+ spec:
552
+ ports:
553
+ - port: 5432
554
+ selector:
555
+ app: postgres
556
+ `;
557
+
558
+ const k8sRedisYaml = `apiVersion: apps/v1
559
+ kind: Deployment
560
+ metadata:
561
+ name: redis
562
+ labels:
563
+ app: redis
564
+ spec:
565
+ replicas: 1
566
+ selector:
567
+ matchLabels:
568
+ app: redis
569
+ template:
570
+ metadata:
571
+ labels:
572
+ app: redis
573
+ spec:
574
+ containers:
575
+ - name: redis
576
+ image: redis:7.2.4-alpine
577
+ ports:
578
+ - containerPort: 6379
579
+ ---
580
+ apiVersion: v1
581
+ kind: Service
582
+ metadata:
583
+ name: redis
584
+ spec:
585
+ ports:
586
+ - port: 6379
587
+ selector:
588
+ app: redis
589
+ `;
590
+
591
+ const k8sNatsYaml = `apiVersion: apps/v1
592
+ kind: Deployment
593
+ metadata:
594
+ name: nats
595
+ labels:
596
+ app: nats
597
+ spec:
598
+ replicas: 1
599
+ selector:
600
+ matchLabels:
601
+ app: nats
602
+ template:
603
+ metadata:
604
+ labels:
605
+ app: nats
606
+ spec:
607
+ containers:
608
+ - name: nats
609
+ image: nats:2.10.12-alpine
610
+ ports:
611
+ - containerPort: 4222
612
+ ---
613
+ apiVersion: v1
614
+ kind: Service
615
+ metadata:
616
+ name: nats
617
+ spec:
618
+ ports:
619
+ - port: 4222
620
+ selector:
621
+ app: nats
622
+ `;
623
+
624
+ const k8sMosquittoYaml = `apiVersion: v1
625
+ kind: ConfigMap
626
+ metadata:
627
+ name: mosquitto-config
628
+ data:
629
+ mosquitto.conf: |
630
+ listener 1883
631
+ listener 9001
632
+ protocol websockets
633
+ allow_anonymous true
634
+ ---
635
+ apiVersion: apps/v1
636
+ kind: Deployment
637
+ metadata:
638
+ name: mosquitto
639
+ labels:
640
+ app: mosquitto
641
+ spec:
642
+ replicas: 1
643
+ selector:
644
+ matchLabels:
645
+ app: mosquitto
646
+ template:
647
+ metadata:
648
+ labels:
649
+ app: mosquitto
650
+ spec:
651
+ containers:
652
+ - name: mosquitto
653
+ image: eclipse-mosquitto:2.0.18
654
+ ports:
655
+ - containerPort: 1883
656
+ - containerPort: 9001
657
+ volumeMounts:
658
+ - name: config-volume
659
+ mountPath: /mosquitto/config/mosquitto.conf
660
+ subPath: mosquitto.conf
661
+ volumes:
662
+ - name: config-volume
663
+ configMap:
664
+ name: mosquitto-config
665
+ ---
666
+ apiVersion: v1
667
+ kind: Service
668
+ metadata:
669
+ name: mosquitto
670
+ spec:
671
+ ports:
672
+ - name: mqtt
673
+ port: 1883
674
+ - name: ws
675
+ port: 9001
676
+ selector:
677
+ app: mosquitto
678
+ `;
679
+
680
+ const k8sElasticsearchYaml = `apiVersion: apps/v1
681
+ kind: Deployment
682
+ metadata:
683
+ name: elasticsearch
684
+ labels:
685
+ app: elasticsearch
686
+ spec:
687
+ replicas: 1
688
+ selector:
689
+ matchLabels:
690
+ app: elasticsearch
691
+ template:
692
+ metadata:
693
+ labels:
694
+ app: elasticsearch
695
+ spec:
696
+ containers:
697
+ - name: elasticsearch
698
+ image: docker.elastic.co/elasticsearch/elasticsearch:8.12.2
699
+ env:
700
+ - name: discovery.type
701
+ value: single-node
702
+ - name: xpack.security.enabled
703
+ value: "false"
704
+ - name: ES_JAVA_OPTS
705
+ value: "-Xms512m -Xmx512m"
706
+ ports:
707
+ - containerPort: 9200
708
+ ---
709
+ apiVersion: v1
710
+ kind: Service
711
+ metadata:
712
+ name: elasticsearch
713
+ spec:
714
+ ports:
715
+ - port: 9200
716
+ selector:
717
+ app: elasticsearch
718
+ `;
719
+
720
+ const k8sJaegerYaml = `apiVersion: apps/v1
721
+ kind: Deployment
722
+ metadata:
723
+ name: jaeger
724
+ labels:
725
+ app: jaeger
726
+ spec:
727
+ replicas: 1
728
+ selector:
729
+ matchLabels:
730
+ app: jaeger
731
+ template:
732
+ metadata:
733
+ labels:
734
+ app: jaeger
735
+ spec:
736
+ containers:
737
+ - name: jaeger
738
+ image: jaegertracing/all-in-one:1.55
739
+ ports:
740
+ - containerPort: 16686
741
+ - containerPort: 4317
742
+ env:
743
+ - name: COLLECTOR_OTLP_ENABLED
744
+ value: "true"
745
+ ---
746
+ apiVersion: v1
747
+ kind: Service
748
+ metadata:
749
+ name: jaeger
750
+ spec:
751
+ ports:
752
+ - name: ui
753
+ port: 16686
754
+ - name: otlp-grpc
755
+ port: 4317
756
+ selector:
757
+ app: jaeger
758
+ `;
759
+
760
+ const k8sOtelCollectorYaml = `apiVersion: v1
761
+ kind: ConfigMap
762
+ metadata:
763
+ name: otel-collector-config
764
+ data:
765
+ otel-collector.yaml: |
766
+ receivers:
767
+ otlp:
768
+ protocols:
769
+ grpc:
770
+ http:
771
+ processors:
772
+ batch:
773
+ resourcedetection:
774
+ detectors: [env, system]
775
+ exporters:
776
+ logging:
777
+ loglevel: debug
778
+ otlp:
779
+ endpoint: "jaeger:4317"
780
+ tls:
781
+ insecure: true
782
+ service:
783
+ pipelines:
784
+ traces:
785
+ receivers: [otlp]
786
+ processors: [batch, resourcedetection]
787
+ exporters: [logging, otlp]
788
+ ---
789
+ apiVersion: apps/v1
790
+ kind: Deployment
791
+ metadata:
792
+ name: otel-collector
793
+ labels:
794
+ app: otel-collector
795
+ spec:
796
+ replicas: 1
797
+ selector:
798
+ matchLabels:
799
+ app: otel-collector
800
+ template:
801
+ metadata:
802
+ labels:
803
+ app: otel-collector
804
+ spec:
805
+ containers:
806
+ - name: otel-collector
807
+ image: otel/opentelemetry-collector-contrib:0.96.0
808
+ command:
809
+ - --config=/etc/otel-collector-config.yaml
810
+ ports:
811
+ - containerPort: 4317
812
+ - containerPort: 4318
813
+ volumeMounts:
814
+ - name: config-volume
815
+ mountPath: /etc/otel-collector-config.yaml
816
+ subPath: otel-collector.yaml
817
+ volumes:
818
+ - name: config-volume
819
+ configMap:
820
+ name: otel-collector-config
821
+ ---
822
+ apiVersion: v1
823
+ kind: Service
824
+ metadata:
825
+ name: otel-collector
826
+ spec:
827
+ ports:
828
+ - name: otlp-grpc
829
+ port: 4317
830
+ - name: otlp-http
831
+ port: 4318
832
+ selector:
833
+ app: otel-collector
834
+ `;
835
+
836
+ const k8sKeycloakYaml = `apiVersion: v1
837
+ kind: ConfigMap
838
+ metadata:
839
+ name: keycloak-realm-config
840
+ data:
841
+ realm.json: |
842
+ ${realmJson.split('\n').map(l => ' ' + l).join('\n')}
843
+ ---
844
+ apiVersion: apps/v1
845
+ kind: Deployment
846
+ metadata:
847
+ name: keycloak
848
+ labels:
849
+ app: keycloak
850
+ spec:
851
+ replicas: 1
852
+ selector:
853
+ matchLabels:
854
+ app: keycloak
855
+ template:
856
+ metadata:
857
+ labels:
858
+ app: keycloak
859
+ spec:
860
+ containers:
861
+ - name: keycloak
862
+ image: quay.io/keycloak/keycloak:26.2.3
863
+ args: ["start-dev", "--import-realm"]
864
+ env:
865
+ - name: KEYCLOAK_ADMIN
866
+ value: admin
867
+ - name: KEYCLOAK_ADMIN_PASSWORD
868
+ value: admin
869
+ - name: KC_DB
870
+ value: postgres
871
+ - name: KC_DB_URL
872
+ value: jdbc:postgresql://postgres:5432/keycloak
873
+ - name: KC_DB_USERNAME
874
+ value: "${config.datasource?.username || 'postgres'}"
875
+ - name: KC_DB_PASSWORD
876
+ value: "${config.datasource?.password || 'password'}"
877
+ ports:
878
+ - containerPort: 8080
879
+ volumeMounts:
880
+ - name: realm-volume
881
+ mountPath: /opt/keycloak/data/import/realm.json
882
+ subPath: realm.json
883
+ volumes:
884
+ - name: realm-volume
885
+ configMap:
886
+ name: keycloak-realm-config
887
+ ---
888
+ apiVersion: v1
889
+ kind: Service
890
+ metadata:
891
+ name: keycloak
892
+ spec:
893
+ ports:
894
+ - port: 8080
895
+ selector:
896
+ app: keycloak
897
+ `;
898
+
403
899
  const realmConfigDir = path.join(devopsDir, 'keycloak', 'realm-config');
404
900
  await fs.ensureDir(realmConfigDir);
405
901
  await fs.writeFile(path.join(realmConfigDir, `${realmName}-realm.json`), realmJson);
@@ -413,8 +909,102 @@ jobs:
413
909
  await fs.writeFile(path.join(devopsDir, 'app.yml'), appYaml);
414
910
  await fs.writeFile(path.join(devopsDir, 'docker-compose.yml'), dockerCompose);
415
911
  await fs.writeFile(path.join(k8sDir, 'mosquitto.conf'), mosquittoConf);
912
+
913
+ // Write Kubernetes manifest assets
914
+ await fs.writeFile(path.join(k8sDir, 'app.yaml'), k8sAppYaml);
915
+ await fs.writeFile(path.join(k8sDir, 'postgres.yaml'), k8sPostgresYaml);
916
+ await fs.writeFile(path.join(k8sDir, 'redis.yaml'), k8sRedisYaml);
917
+ await fs.writeFile(path.join(k8sDir, 'nats.yaml'), k8sNatsYaml);
918
+ await fs.writeFile(path.join(k8sDir, 'mosquitto.yaml'), k8sMosquittoYaml);
919
+ await fs.writeFile(path.join(k8sDir, 'elasticsearch.yaml'), k8sElasticsearchYaml);
920
+ await fs.writeFile(path.join(k8sDir, 'jaeger.yaml'), k8sJaegerYaml);
921
+ await fs.writeFile(path.join(k8sDir, 'otel-collector-k8s.yaml'), k8sOtelCollectorYaml);
922
+ await fs.writeFile(path.join(k8sDir, 'keycloak.yaml'), k8sKeycloakYaml);
923
+
924
+ // Additional optional services manifests
925
+ const k8sMongoYaml = `apiVersion: apps/v1
926
+ kind: Deployment
927
+ metadata:
928
+ name: mongodb
929
+ labels:
930
+ app: mongodb
931
+ spec:
932
+ replicas: 1
933
+ selector:
934
+ matchLabels:
935
+ app: mongodb
936
+ template:
937
+ metadata:
938
+ labels:
939
+ app: mongodb
940
+ spec:
941
+ containers:
942
+ - name: mongodb
943
+ image: mongo:7.0.5
944
+ ports:
945
+ - containerPort: 27017
946
+ ---
947
+ apiVersion: v1
948
+ kind: Service
949
+ metadata:
950
+ name: mongodb
951
+ spec:
952
+ ports:
953
+ - port: 27017
954
+ selector:
955
+ app: mongodb`;
956
+ const k8sMinioYaml = `apiVersion: apps/v1
957
+ kind: Deployment
958
+ metadata:
959
+ name: minio
960
+ labels:
961
+ app: minio
962
+ spec:
963
+ replicas: 1
964
+ selector:
965
+ matchLabels:
966
+ app: minio
967
+ template:
968
+ metadata:
969
+ labels:
970
+ app: minio
971
+ spec:
972
+ containers:
973
+ - name: minio
974
+ image: minio/minio:RELEASE.2024-05-10T19-05-27Z
975
+ args:
976
+ - server
977
+ - /data
978
+ env:
979
+ - name: MINIO_ROOT_USER
980
+ value: "minioadmin"
981
+ - name: MINIO_ROOT_PASSWORD
982
+ value: "minioadmin"
983
+ ports:
984
+ - containerPort: 9000
985
+ ---
986
+ apiVersion: v1
987
+ kind: Service
988
+ metadata:
989
+ name: minio
990
+ spec:
991
+ ports:
992
+ - port: 9000
993
+ selector:
994
+ app: minio`;
995
+ await fs.writeFile(path.join(k8sDir, 'mongodb.yaml'), k8sMongoYaml);
996
+ await fs.writeFile(path.join(k8sDir, 'minio.yaml'), k8sMinioYaml);
997
+
416
998
  await fs.writeFile(path.join(githubDir, 'ci.yml'), ciWorkflow);
417
999
  await fs.writeFile(path.join(githubDir, 'cd.yml'), cdWorkflow);
418
1000
 
419
- console.log(chalk.gray(' Generated devops/Dockerfile, devops/services.yml, devops/app.yml, devops/docker-compose.yml & GitHub Actions CI/CD'));
1001
+ const pushScriptPath = path.join(projectRootDir, 'push.sh');
1002
+ await fs.writeFile(pushScriptPath, pushScript);
1003
+ try {
1004
+ await fs.chmod(pushScriptPath, 0o755);
1005
+ } catch (e) {
1006
+ // Safe fallback for OS environments where chmod is not supported
1007
+ }
1008
+
1009
+ console.log(chalk.gray(' Generated devops/Dockerfile, devops/services.yml, devops/app.yml, devops/docker-compose.yml, push.sh, Kubernetes manifests & GitHub Actions CI/CD'));
420
1010
  };
@@ -156,10 +156,9 @@ func ExecuteSearch(ctx context.Context, entityName string, queryStr string, cfg
156
156
  } else {
157
157
  query = map[string]interface{}{
158
158
  "query": map[string]interface{}{
159
- "multi_match": map[string]interface{}{
160
- "query": queryStr,
161
- "fields": []string{"*"},
162
- "fuzziness": "AUTO",
159
+ "query_string": map[string]interface{}{
160
+ "query": queryStr,
161
+ "analyze_wildcard": true,
163
162
  },
164
163
  },
165
164
  }