Add health check command for bydbctl (#336)

* Add health check command for bydbctl

* Add insecure flag
diff --git a/CHANGES.md b/CHANGES.md
index 6331edf..1e2b6d8 100644
--- a/CHANGES.md
+++ b/CHANGES.md
@@ -8,6 +8,7 @@
 
 - Support etcd client authentication.
 - Implement Local file system.
+- Add health check command for bydbctl
 
 ### Bugs
 
@@ -31,7 +32,6 @@
 - Support for recovery buffer using wal.
 - Register the node role to the metadata registry.
 - Implement the remote queue to spreading data to data nodes.
-- Fix parse environment variables error
 - Implement the distributed query engine.
 - Add mod revision check to write requests.
 - Add TTL to the property.
@@ -46,6 +46,7 @@
 - BanyanDB ui misses fields when creating a group
 - Fix data duplicate writing
 - Syncing metadata change events from etcd instead of a local channel.
+- Fix parse environment variables error
 
 ### Chores
 
diff --git a/bydbctl/internal/cmd/group.go b/bydbctl/internal/cmd/group.go
index f2c32fd..b549fa7 100644
--- a/bydbctl/internal/cmd/group.go
+++ b/bydbctl/internal/cmd/group.go
@@ -61,7 +61,7 @@
 					fmt.Printf("group %s is created", reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -90,7 +90,7 @@
 					fmt.Printf("group %s is updated", reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindFileFlag(createCmd, updateCmd)
@@ -102,7 +102,7 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("group", request.group).Get(getPath("/api/v1/group/schema/{group}"))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -118,7 +118,7 @@
 					fmt.Printf("group %s is deleted", reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -129,10 +129,11 @@
 		RunE: func(cmd *cobra.Command, args []string) (err error) {
 			return rest(nil, func(request request) (*resty.Response, error) {
 				return request.req.Get(getPath("/api/v1/group/schema/lists"))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
+	bindTLSRelatedFlag(createCmd, updateCmd, listCmd, getCmd, deleteCmd)
 	groupCmd.AddCommand(createCmd, updateCmd, listCmd, getCmd, deleteCmd)
 	return groupCmd
 }
diff --git a/bydbctl/internal/cmd/health_check.go b/bydbctl/internal/cmd/health_check.go
new file mode 100644
index 0000000..a3f3b79
--- /dev/null
+++ b/bydbctl/internal/cmd/health_check.go
@@ -0,0 +1,79 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package cmd
+
+import (
+	"crypto/tls"
+	"crypto/x509"
+	"fmt"
+	"os"
+	"time"
+
+	"github.com/pkg/errors"
+	"github.com/spf13/cobra"
+	"google.golang.org/grpc"
+	"google.golang.org/grpc/credentials"
+	ins "google.golang.org/grpc/credentials/insecure"
+
+	"github.com/apache/skywalking-banyandb/pkg/test/helpers"
+	"github.com/apache/skywalking-banyandb/pkg/version"
+)
+
+var grpcAddr string
+
+func newHealthCheckCmd() *cobra.Command {
+	healthCheckCmd := &cobra.Command{
+		Use:           "health",
+		Version:       version.Build(),
+		Short:         "Health check",
+		SilenceErrors: true,
+		SilenceUsage:  true,
+		RunE: func(_ *cobra.Command, _ []string) (err error) {
+			opts := make([]grpc.DialOption, 0, 1)
+			if enableTLS {
+				// #nosec G402
+				config := &tls.Config{
+					InsecureSkipVerify: insecure,
+				}
+				if grpcCert != "" {
+					cert, errRead := os.ReadFile(grpcCert)
+					if errRead != nil {
+						return errRead
+					}
+					certPool := x509.NewCertPool()
+					if !certPool.AppendCertsFromPEM(cert) {
+						return errors.New("failed to add server's certificate")
+					}
+					config.RootCAs = certPool
+				}
+				creds := credentials.NewTLS(config)
+				opts = append(opts, grpc.WithTransportCredentials(creds))
+			} else {
+				opts = append(opts, grpc.WithTransportCredentials(ins.NewCredentials()))
+			}
+			err = helpers.HealthCheck(grpcAddr, 10*time.Second, 10*time.Second, opts...)()
+			if err == nil {
+				fmt.Println("connected")
+			}
+			return err
+		},
+	}
+	healthCheckCmd.Flags().StringVarP(&grpcAddr, "grpc-addr", "", "localhost:17912", "Grpc server's address, the format is Domain:Port")
+	bindTLSRelatedFlag(healthCheckCmd)
+	return healthCheckCmd
+}
diff --git a/bydbctl/internal/cmd/health_check_test.go b/bydbctl/internal/cmd/health_check_test.go
new file mode 100644
index 0000000..72628c7
--- /dev/null
+++ b/bydbctl/internal/cmd/health_check_test.go
@@ -0,0 +1,90 @@
+// Licensed to Apache Software Foundation (ASF) under one or more contributor
+// license agreements. See the NOTICE file distributed with
+// this work for additional information regarding copyright
+// ownership. Apache Software Foundation (ASF) licenses this file to you under
+// the Apache License, Version 2.0 (the "License"); you may
+// not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+//     http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+
+package cmd_test
+
+import (
+	"path/filepath"
+	"runtime"
+
+	. "github.com/onsi/ginkgo/v2"
+	. "github.com/onsi/gomega"
+	"github.com/spf13/cobra"
+	"github.com/zenizh/go-capturer"
+
+	"github.com/apache/skywalking-banyandb/bydbctl/internal/cmd"
+	"github.com/apache/skywalking-banyandb/pkg/test/setup"
+)
+
+var _ = Describe("health check after launching banyandb server", func() {
+	var deferFunc func()
+	var grpcAddr, certFile string
+	var rootCmd *cobra.Command
+	BeforeEach(func() {
+		_, basePath, _, _ := runtime.Caller(0)
+		for i := 0; i < 4; i++ {
+			basePath = filepath.Dir(basePath)
+		}
+		certFile = filepath.Join(basePath, "test/integration/standalone/other/testdata/server_cert.pem")
+		keyFile := filepath.Join(basePath, "test/integration/standalone/other/testdata/server_key.pem")
+		grpcAddr, _, deferFunc = setup.StandaloneWithTLS(certFile, keyFile)
+		rootCmd = &cobra.Command{Use: "root"}
+		cmd.RootCmdFlags(rootCmd)
+	})
+
+	It("should pass", func() {
+		rootCmd.SetArgs([]string{"health", "--grpc-addr", grpcAddr, "--grpc-cert", certFile, "--enable-tls", "true"})
+		out := capturer.CaptureStdout(func() {
+			err := rootCmd.Execute()
+			Expect(err).NotTo(HaveOccurred())
+		})
+		Expect(out).To(ContainSubstring("connected"))
+	})
+
+	It("should pass with insecure flag set", func() {
+		rootCmd.SetArgs([]string{"health", "--grpc-addr", grpcAddr, "--insecure", "true", "--enable-tls", "true"})
+		out := capturer.CaptureStdout(func() {
+			err := rootCmd.Execute()
+			Expect(err).NotTo(HaveOccurred())
+		})
+		Expect(out).To(ContainSubstring("connected"))
+	})
+
+	It("should fail without the proper cert", func() {
+		rootCmd.SetArgs([]string{"health", "--grpc-addr", grpcAddr, "--enable-tls", "true"})
+		err := rootCmd.Execute()
+		Expect(err).To(HaveOccurred())
+	})
+
+	AfterEach(func() {
+		deferFunc()
+	})
+})
+
+var _ = Describe("health check without launching banyandb server", func() {
+	var rootCmd *cobra.Command
+	BeforeEach(func() {
+		rootCmd = &cobra.Command{Use: "root"}
+		cmd.RootCmdFlags(rootCmd)
+	})
+
+	It("should fail", func() {
+		rootCmd.SetArgs([]string{"health"})
+		err := rootCmd.Execute()
+		Expect(err).To(HaveOccurred())
+	})
+})
diff --git a/bydbctl/internal/cmd/index_rule.go b/bydbctl/internal/cmd/index_rule.go
index fe2227c..ac18fd1 100644
--- a/bydbctl/internal/cmd/index_rule.go
+++ b/bydbctl/internal/cmd/index_rule.go
@@ -64,7 +64,7 @@
 					fmt.Printf("indexRule %s.%s is created", reqBody.group, reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -95,7 +95,7 @@
 					fmt.Printf("indexRule %s.%s is updated", reqBody.group, reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -106,7 +106,7 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("name", request.name).SetPathParam("group", request.group).Get(getPath(indexRuleSchemaPathWithParams))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -121,7 +121,7 @@
 				fmt.Printf("indexRule %s.%s is deleted", reqBody.group, reqBody.name)
 				fmt.Println()
 				return nil
-			})
+			}, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindNameFlag(getCmd, deleteCmd)
@@ -133,12 +133,13 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("group", request.group).Get(getPath("/api/v1/index-rule/schema/lists/{group}"))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
 	bindFileFlag(createCmd, updateCmd)
 
+	bindTLSRelatedFlag(getCmd, createCmd, deleteCmd, updateCmd, listCmd)
 	indexRuleCmd.AddCommand(getCmd, createCmd, deleteCmd, updateCmd, listCmd)
 	return indexRuleCmd
 }
diff --git a/bydbctl/internal/cmd/index_rule_binding.go b/bydbctl/internal/cmd/index_rule_binding.go
index 57fb17d..b26f346 100644
--- a/bydbctl/internal/cmd/index_rule_binding.go
+++ b/bydbctl/internal/cmd/index_rule_binding.go
@@ -64,7 +64,7 @@
 					fmt.Printf("indexRuleBinding %s.%s is created", reqBody.group, reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -95,7 +95,7 @@
 					fmt.Printf("indexRuleBinding %s.%s is updated", reqBody.group, reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -106,7 +106,7 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("name", request.name).SetPathParam("group", request.group).Get(getPath(indexRuleBindingSchemaPathWithParams))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -121,7 +121,7 @@
 				fmt.Printf("indexRuleBinding %s.%s is deleted", reqBody.group, reqBody.name)
 				fmt.Println()
 				return nil
-			})
+			}, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindNameFlag(getCmd, deleteCmd)
@@ -133,12 +133,13 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("group", request.group).Get(getPath("/api/v1/index-rule-binding/schema/lists/{group}"))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
 	bindFileFlag(createCmd, updateCmd)
 
+	bindTLSRelatedFlag(getCmd, createCmd, deleteCmd, updateCmd, listCmd)
 	indexRuleBindingCmd.AddCommand(getCmd, createCmd, deleteCmd, updateCmd, listCmd)
 	return indexRuleBindingCmd
 }
diff --git a/bydbctl/internal/cmd/measure.go b/bydbctl/internal/cmd/measure.go
index 9c3f76a..56ee928 100644
--- a/bydbctl/internal/cmd/measure.go
+++ b/bydbctl/internal/cmd/measure.go
@@ -64,7 +64,7 @@
 					fmt.Printf("measure %s.%s is created", reqBody.group, reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -95,7 +95,7 @@
 					fmt.Printf("measure %s.%s is updated", reqBody.group, reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -106,7 +106,7 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("name", request.name).SetPathParam("group", request.group).Get(getPath(measureSchemaPathWithParams))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -121,7 +121,7 @@
 				fmt.Printf("measure %s.%s is deleted", reqBody.group, reqBody.name)
 				fmt.Println()
 				return nil
-			})
+			}, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindNameFlag(getCmd, deleteCmd)
@@ -133,7 +133,7 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("group", request.group).Get(getPath("/api/v1/measure/schema/lists/{group}"))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -146,12 +146,13 @@
 			return rest(func() ([]reqBody, error) { return parseTimeRangeFromFlagAndYAML(cmd.InOrStdin()) },
 				func(request request) (*resty.Response, error) {
 					return request.req.SetBody(request.data).Post(getPath("/api/v1/measure/data"))
-				}, yamlPrinter)
+				}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindFileFlag(createCmd, updateCmd, queryCmd)
 	bindTimeRangeFlag(queryCmd)
 
+	bindTLSRelatedFlag(getCmd, createCmd, deleteCmd, updateCmd, listCmd, queryCmd)
 	measureCmd.AddCommand(getCmd, createCmd, deleteCmd, updateCmd, listCmd, queryCmd)
 	return measureCmd
 }
diff --git a/bydbctl/internal/cmd/property.go b/bydbctl/internal/cmd/property.go
index 529f68f..3f60872 100644
--- a/bydbctl/internal/cmd/property.go
+++ b/bydbctl/internal/cmd/property.go
@@ -69,7 +69,7 @@
 					}
 					return request.req.SetPathParam("group", request.group).SetPathParam("name", request.name).
 						SetPathParam("id", request.id).SetBody(b).Put(getPath(propertySchemaPathWithoutTagParams))
-				}, yamlPrinter)
+				}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindFileFlag(applyCmd)
@@ -83,7 +83,7 @@
 				return request.req.SetPathParam("name", request.name).SetPathParam("group", request.group).
 					SetPathParam("id", request.id).SetPathParam("tag", request.tags()).
 					Get(getPath(propertySchemaPathWithTagParams))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -95,7 +95,7 @@
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("name", request.name).SetPathParam("group", request.group).
 					SetPathParam("id", request.id).SetPathParam("tag", request.tags()).Delete(getPath(propertySchemaPathWithTagParams))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindNameAndIDAndTagsFlag(getCmd, deleteCmd)
@@ -111,7 +111,7 @@
 				}
 				return request.req.SetPathParam("name", request.name).SetPathParam("group", request.group).
 					SetPathParam("ids", request.ids()).SetPathParam("tags", request.tags()).Get(getPath(propertyListSchemaPathWithTagParams))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 	listCmd.Flags().StringVarP(&name, "name", "n", "", "the name of the resource")
@@ -132,11 +132,12 @@
 			}, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("lease_id", strconv.FormatInt(request.leaseID, 10)).
 					Put(getPath(propertySchemaPath + "/lease/{lease_id}"))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 	keepAliveCmd.Flags().Int64VarP(&leaseID, "lease_id", "i", 0, "the lease id of the property")
 
+	bindTLSRelatedFlag(getCmd, applyCmd, deleteCmd, listCmd, keepAliveCmd)
 	propertyCmd.AddCommand(getCmd, applyCmd, deleteCmd, listCmd, keepAliveCmd)
 	return propertyCmd
 }
diff --git a/bydbctl/internal/cmd/rest.go b/bydbctl/internal/cmd/rest.go
index 02e15e8..cd65970 100644
--- a/bydbctl/internal/cmd/rest.go
+++ b/bydbctl/internal/cmd/rest.go
@@ -18,9 +18,12 @@
 package cmd
 
 import (
+	"crypto/tls"
+	"crypto/x509"
 	"encoding/json"
 	"fmt"
 	"io"
+	"os"
 	"strings"
 	"time"
 
@@ -290,7 +293,7 @@
 	return nil
 }
 
-func rest(pfn paramsFn, fn reqFn, printer printer) (err error) {
+func rest(pfn paramsFn, fn reqFn, printer printer, enableTLS bool, insecure bool, grpcCert string) (err error) {
 	var requests []reqBody
 	if pfn == nil {
 		requests = []reqBody{{}}
@@ -302,7 +305,26 @@
 	}
 
 	for i, r := range requests {
-		req := resty.New().R()
+		client := resty.New()
+		if enableTLS {
+			// #nosec G402
+			config := tls.Config{
+				InsecureSkipVerify: insecure,
+			}
+			if grpcCert != "" {
+				cert, err := os.ReadFile(grpcCert)
+				if err != nil {
+					return err
+				}
+				certPool := x509.NewCertPool()
+				if !certPool.AppendCertsFromPEM(cert) {
+					return errors.New("failed to add server's certificate")
+				}
+				config.RootCAs = certPool
+			}
+			client.SetTLSClientConfig(&config)
+		}
+		req := client.R()
 		resp, err := fn(request{
 			reqBody: r,
 			req:     req,
diff --git a/bydbctl/internal/cmd/root.go b/bydbctl/internal/cmd/root.go
index 3750c49..9aff040 100644
--- a/bydbctl/internal/cmd/root.go
+++ b/bydbctl/internal/cmd/root.go
@@ -32,12 +32,15 @@
 const pathTemp = "/{group}/{name}"
 
 var (
-	filePath string
-	name     string
-	start    string
-	end      string
-	cfgFile  string
-	rootCmd  = &cobra.Command{
+	filePath  string
+	name      string
+	start     string
+	end       string
+	cfgFile   string
+	enableTLS bool
+	insecure  bool
+	grpcCert  string
+	rootCmd   = &cobra.Command{
 		DisableAutoGenTag: true,
 		Version:           version.Build(),
 		Short:             "bydbctl is the command line tool of BanyanDB",
@@ -66,7 +69,7 @@
 	_ = viper.BindPFlag("addr", command.PersistentFlags().Lookup("addr"))
 	viper.SetDefault("addr", "http://localhost:17913")
 
-	command.AddCommand(newGroupCmd(), newUserCmd(), newStreamCmd(), newMeasureCmd(), newIndexRuleCmd(), newIndexRuleBindingCmd(), newPropertyCmd())
+	command.AddCommand(newGroupCmd(), newUserCmd(), newStreamCmd(), newMeasureCmd(), newIndexRuleCmd(), newIndexRuleBindingCmd(), newPropertyCmd(), newHealthCheckCmd())
 }
 
 func init() {
@@ -138,3 +141,11 @@
 		_ = c.MarkFlagRequired("id")
 	}
 }
+
+func bindTLSRelatedFlag(commands ...*cobra.Command) {
+	for _, c := range commands {
+		c.Flags().BoolVarP(&enableTLS, "enable-tls", "", false, "Used to enable tls")
+		c.Flags().BoolVarP(&insecure, "insecure", "", false, "Used to skip server's cert")
+		c.Flags().StringVarP(&grpcCert, "grpc-cert", "", "", "Grpc certificate for tls")
+	}
+}
diff --git a/bydbctl/internal/cmd/stream.go b/bydbctl/internal/cmd/stream.go
index 59d6cd7..0189104 100644
--- a/bydbctl/internal/cmd/stream.go
+++ b/bydbctl/internal/cmd/stream.go
@@ -69,7 +69,7 @@
 					fmt.Printf("stream %s.%s is created", reqBody.group, reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -100,7 +100,7 @@
 					fmt.Printf("stream %s.%s is updated", reqBody.group, reqBody.name)
 					fmt.Println()
 					return nil
-				})
+				}, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -111,7 +111,7 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("name", request.name).SetPathParam("group", request.group).Get(getPath(streamSchemaPathWithParams))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -126,7 +126,7 @@
 				fmt.Printf("stream %s.%s is deleted", reqBody.group, reqBody.name)
 				fmt.Println()
 				return nil
-			})
+			}, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindNameFlag(getCmd, deleteCmd)
@@ -138,7 +138,7 @@
 		RunE: func(_ *cobra.Command, _ []string) (err error) {
 			return rest(parseFromFlags, func(request request) (*resty.Response, error) {
 				return request.req.SetPathParam("group", request.group).Get(getPath("/api/v1/stream/schema/lists/{group}"))
-			}, yamlPrinter)
+			}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 
@@ -151,12 +151,13 @@
 			return rest(func() ([]reqBody, error) { return parseTimeRangeFromFlagAndYAML(cmd.InOrStdin()) },
 				func(request request) (*resty.Response, error) {
 					return request.req.SetBody(request.data).Post(getPath("/api/v1/stream/data"))
-				}, yamlPrinter)
+				}, yamlPrinter, enableTLS, insecure, grpcCert)
 		},
 	}
 	bindFileFlag(createCmd, updateCmd, queryCmd)
 	bindTimeRangeFlag(queryCmd)
 
+	bindTLSRelatedFlag(getCmd, createCmd, deleteCmd, updateCmd, listCmd, queryCmd)
 	streamCmd.AddCommand(getCmd, createCmd, deleteCmd, updateCmd, listCmd, queryCmd)
 	return streamCmd
 }
diff --git a/pkg/test/helpers/http_health.go b/pkg/test/helpers/http_health.go
index 365338c..bce8b48 100644
--- a/pkg/test/helpers/http_health.go
+++ b/pkg/test/helpers/http_health.go
@@ -30,7 +30,6 @@
 func HTTPHealthCheck(addr string) func() error {
 	return func() error {
 		client := resty.New()
-
 		resp, err := client.R().
 			SetHeader("Accept", "application/json").
 			Get(fmt.Sprintf("http://%s/api/healthz", addr))