SEBA-38 implement status command

Change-Id: I23a513d8190a4b83ffdf35c91b50aa6955c35b8d
diff --git a/cmd/cordctl.go b/cmd/cordctl.go
index 11d221b..19a27c7 100644
--- a/cmd/cordctl.go
+++ b/cmd/cordctl.go
@@ -38,6 +38,7 @@
 	commands.RegisterVersionCommands(parser)
 	commands.RegisterCompletionCommands(parser)
 	commands.RegisterConfigCommands(parser)
+	commands.RegisterStatusCommands(parser)
 
 	_, err = parser.ParseArgs(os.Args[1:])
 	if err != nil {
diff --git a/commands/modeltypes_test.go b/commands/modeltypes_test.go
index 678afba..abdc305 100644
--- a/commands/modeltypes_test.go
+++ b/commands/modeltypes_test.go
@@ -24,7 +24,8 @@
 
 func TestModelTypeList(t *testing.T) {
 	// use `python -m json.tool` to pretty-print json
-	expected := `AddressPool
+	expected := `ANIPort
+AddressPool
 AttWorkflowDriverService
 AttWorkflowDriverServiceInstance
 AttWorkflowDriverWhiteListEntry
@@ -61,7 +62,6 @@
 ONOSApp
 ONOSService
 ONUDevice
-PONONUPort
 PONPort
 Port
 PortBase
@@ -86,6 +86,7 @@
 Switch
 SwitchPort
 Tag
+TechnologyProfile
 TrustDomain
 UNIPort
 User
diff --git a/commands/status.go b/commands/status.go
new file mode 100644
index 0000000..215d1bb
--- /dev/null
+++ b/commands/status.go
@@ -0,0 +1,90 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed 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 commands
+
+import (
+	"context"
+	"github.com/fullstorydev/grpcurl"
+	flags "github.com/jessevdk/go-flags"
+	"github.com/jhump/protoreflect/dynamic"
+	"strings"
+)
+
+const StatusListFormat = "table{{ .Component }}\t{{ .Name }}\t{{ .Version }}\t{{ .Connection }}\t{{ .Status }}"
+
+type StatusListOpts struct {
+	ListOutputOptions
+	Filter string `short:"f" long:"filter" description:"Comma-separated list of filters"`
+}
+
+type StatusOpts struct {
+	List StatusListOpts `command:"list"`
+}
+
+var statusOpts = StatusOpts{}
+
+func RegisterStatusCommands(parser *flags.Parser) {
+	parser.AddCommand("status", "status commands", "Commands to query status of various subsystems", &statusOpts)
+}
+
+func (options *StatusListOpts) Execute(args []string) error {
+	conn, descriptor, err := InitReflectionClient()
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	var components []map[string]string
+
+	// TODO(smbaker): Consider using David's client-side filtering can be used so we get filtering
+	// by other fields (status, etc) for free.
+
+	if options.Filter == "" || strings.Contains(strings.ToLower(options.Filter), "database") {
+		h := &RpcEventHandler{}
+		err = grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.utility.GetDatabaseInfo", headers, h, h.GetParams)
+		if err != nil {
+			return err
+		}
+
+		if h.Status != nil && h.Status.Err() != nil {
+			return h.Status.Err()
+		}
+
+		d, err := dynamic.AsDynamicMessage(h.Response)
+		if err != nil {
+			return err
+		}
+
+		db_map := make(map[string]string)
+		db_map["Component"] = "Database"
+		db_map["Name"] = d.GetFieldByName("name").(string)
+		db_map["Version"] = d.GetFieldByName("version").(string)
+		db_map["Connection"] = d.GetFieldByName("connection").(string)
+		db_map["Status"] = GetEnumValue(d, "status")
+
+		components = append(components, db_map)
+	}
+
+	FormatAndGenerateListOutput(&options.ListOutputOptions, StatusListFormat, StatusListFormat, components)
+
+	return nil
+}
diff --git a/commands/status_test.go b/commands/status_test.go
new file mode 100644
index 0000000..46c0040
--- /dev/null
+++ b/commands/status_test.go
@@ -0,0 +1,50 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed 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 commands
+
+import (
+	"bytes"
+	"github.com/opencord/cordctl/testutils"
+	"testing"
+)
+
+func TestStatusList(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"Component": "Database",
+			"Connection": "xos-db:5432",
+			"Name": "xos",
+			"Status": "OPERATIONAL",
+			"Version": "10.3"
+		}
+	]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options StatusOpts
+	options.List.OutputAs = "json"
+	err := options.List.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
diff --git a/mock/data.json b/mock/data.json
index fd1bb03..4e1e7ee 100644
--- a/mock/data.json
+++ b/mock/data.json
@@ -12,6 +12,16 @@
         }
     },
     {
+        "method": "GetDatabaseInfo",
+        "input": ".*",
+        "output": {
+          "name": "xos",
+          "connection": "xos-db:5432",
+          "version": "10.3",
+          "status": 1
+        }
+    },
+    {
         "method": "GetSlice",
         "input": {"id": 1},
         "output": {
diff --git a/mock/xos-core.protoset b/mock/xos-core.protoset
index 1515ded..6320190 100644
--- a/mock/xos-core.protoset
+++ b/mock/xos-core.protoset
Binary files differ