blob: d10d2d9282829e243e0d201865a9dbb6d34da7f8 [file] [log] [blame]
Adrià Vilanova Martíneze94112f2021-09-04 01:04:24 +02001package main
2
3import (
4 "context"
5 "encoding/json"
6 "flag"
7 "log"
8 "os"
9
10 "google.golang.org/grpc"
Adrià Vilanova Martínez34d806c2021-12-08 18:37:38 +010011 "google.golang.org/grpc/credentials"
Adrià Vilanova Martíneze94112f2021-09-04 01:04:24 +020012 "google.golang.org/grpc/metadata"
13
Adrià Vilanova Martínez34d806c2021-12-08 18:37:38 +010014 "github.com/johnsiilver/getcert"
15
Adrià Vilanova Martíneze94112f2021-09-04 01:04:24 +020016 pb "gomodules.avm99963.com/twpt-server/api_proto"
17)
18
19var (
20 grpcEndpoint = flag.String("grpcEndpoint", "", "gRPC endpoint address.")
21 jwt = flag.String("jwt", "", "JWT credentials.")
Adrià Vilanova Martínez34d806c2021-12-08 18:37:38 +010022 insecure = flag.Bool("insecure", false, "Set if the connection to the gRPC endpoint is insecure.")
Adrià Vilanova Martíneze94112f2021-09-04 01:04:24 +020023)
24
25type Features map[string]Feature
26
27type Feature struct {
28 DefaultValue interface{} `json:"defaultValue"`
29 Context string `json:"context"`
30 KillSwitchType string `json:"killSwitchType"`
31}
32
33func convertStringTypeToPb(context string) pb.Feature_Type {
34 switch context {
35 case "option":
36 return pb.Feature_TYPE_OPTION
37
38 case "experiment":
39 return pb.Feature_TYPE_EXPERIMENT
40
Adrià Vilanova Martínez20a3e8b2023-04-15 17:31:38 +020041 case "internalKillSwitch":
42 return pb.Feature_TYPE_INTERNAL_KILL_SWITCH
43
Adrià Vilanova Martíneze94112f2021-09-04 01:04:24 +020044 case "deprecated":
45 return pb.Feature_TYPE_DEPRECATED
46
47 default:
48 return pb.Feature_TYPE_UNKNOWN
49 }
50}
51
52func main() {
53 flag.Parse()
54
Adrià Vilanova Martínez34d806c2021-12-08 18:37:38 +010055 var err error
56 var conn *grpc.ClientConn
57
58 if *insecure {
59 conn, err = grpc.Dial(*grpcEndpoint, grpc.WithInsecure())
60 } else {
61 tlsCert, _, err2 := getcert.FromTLSServer(*grpcEndpoint, false)
62 if err2 != nil {
63 log.Fatalf("error while retrieving public certificate: %v\n", err2)
64 }
65 conn, err = grpc.Dial(*grpcEndpoint, grpc.WithTransportCredentials(credentials.NewServerTLSFromCert(&tlsCert)))
66 }
Adrià Vilanova Martíneze94112f2021-09-04 01:04:24 +020067 if err != nil {
68 log.Fatalf("error while connecting to gRPC endpoint: %v\n", err)
69 }
70 defer conn.Close()
71
72 client := pb.NewKillSwitchServiceClient(conn)
73 md := metadata.Pairs("authorization", *jwt)
74 ctx := metadata.NewOutgoingContext(context.Background(), md)
75
76 var jsonFeatures Features
77 err = json.NewDecoder(os.Stdin).Decode(&jsonFeatures)
78 if err != nil {
79 log.Fatalf("can't decode JSON file: %v\n", err)
80 }
81
82 features := make([]*pb.Feature, 0)
83 for codename, jsonFeature := range jsonFeatures {
Adrià Vilanova Martínez20a3e8b2023-04-15 17:31:38 +020084 if jsonFeature.Context == "internal" && jsonFeature.KillSwitchType != "internalKillSwitch" {
Adrià Vilanova Martíneze94112f2021-09-04 01:04:24 +020085 continue
86 }
87
88 feature := &pb.Feature{
89 Codename: codename,
90 Type: convertStringTypeToPb(jsonFeature.KillSwitchType),
91 }
92 features = append(features, feature)
93 }
94
95 request := &pb.SyncFeaturesRequest{
96 Features: features,
97 }
98 _, err = client.SyncFeatures(ctx, request)
99 if err != nil {
100 log.Fatalf("error syncing features: %v\n", err)
101 }
102
103 log.Println("Synced features successfully.")
104}