diff --git a/internal/pkg/commands/backup.go b/internal/pkg/commands/backup.go
new file mode 100644
index 0000000..84df5a9
--- /dev/null
+++ b/internal/pkg/commands/backup.go
@@ -0,0 +1,255 @@
+/*
+ * 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"
+	flags "github.com/jessevdk/go-flags"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+	"time"
+)
+
+const (
+	DEFAULT_BACKUP_FORMAT = "table{{ .Status }}\t{{ .Checksum }}\t{{ .Chunks }}\t{{ .Bytes }}"
+)
+
+type BackupOutput struct {
+	Status   string `json:"status"`
+	Checksum string `json:"checksum"`
+	Chunks   int    `json:"chunks"`
+	Bytes    int    `json:"bytes"`
+}
+
+type BackupCreate struct {
+	OutputOptions
+	ChunkSize int `short:"h" long:"chunksize" default:"65536" description:"Chunk size for streaming transfer"`
+	Args      struct {
+		LocalFileName string
+	} `positional-args:"yes" required:"yes"`
+}
+
+type BackupRestore struct {
+	OutputOptions
+	ChunkSize int `short:"h" long:"chunksize" default:"65536" description:"Chunk size for streaming transfer"`
+	Args      struct {
+		LocalFileName string
+	} `positional-args:"yes" required:"yes"`
+	CreateURIFunc func() (string, string) // allow override of CreateURIFunc for easy unit testing
+}
+
+type BackupOpts struct {
+	Create  BackupCreate  `command:"create"`
+	Restore BackupRestore `command:"restore"`
+}
+
+var backupOpts = BackupOpts{}
+
+func RegisterBackupCommands(parser *flags.Parser) {
+	parser.AddCommand("backup", "backup management commands", "Commands to create backups and restore backups", &backupOpts)
+}
+
+func (options *BackupCreate) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	ctx := context.Background() // TODO: Implement a sync timeout
+
+	// We might close and reopen the connection befor we do the DownloadFile,
+	// so make sure we've downloaded the service descriptor.
+	_, err = descriptor.FindSymbol("xos.filetransfer")
+	if err != nil {
+		return err
+	}
+
+	local_name := options.Args.LocalFileName
+
+	// STEP 1: Create backup operation
+
+	backupop := make(map[string]interface{})
+	backupop["operation"] = "create"
+	err = CreateModel(conn, descriptor, "BackupOperation", backupop)
+	if err != nil {
+		return err
+	}
+	conditional_printf(!options.Quiet, "Created backup-create operation id=%d uuid=%s\n", backupop["id"], backupop["uuid"])
+	conditional_printf(!options.Quiet, "Waiting for sync ")
+
+	// STEP 2: Wait for the operation to complete
+
+	flags := GM_UNTIL_ENACTED | GM_UNTIL_FOUND | Ternary_uint32(options.Quiet, GM_QUIET, 0)
+	conn, completed_backupop, err := GetModelWithRetry(ctx, conn, descriptor, "BackupOperation", backupop["id"].(int32), flags)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	status := completed_backupop.GetFieldByName("status").(string)
+	conditional_printf(!options.Quiet, "\nStatus: %s\n", status)
+
+	// we've failed. leave.
+	if status != "created" {
+		return corderrors.NewInternalError("BackupOp status is %s", status)
+	}
+
+	// STEP 3: Retrieve URI
+	backupfile_id := completed_backupop.GetFieldByName("file_id").(int32)
+	if backupfile_id == 0 {
+		return corderrors.NewInternalError("BackupOp.file_id is not set")
+	}
+
+	completed_backupfile, err := GetModel(ctx, conn, descriptor, "BackupFile", backupfile_id)
+	if err != nil {
+		return err
+	}
+
+	uri := completed_backupfile.GetFieldByName("uri").(string)
+	conditional_printf(!options.Quiet, "URI %s\n", uri)
+
+	// STEP 4: Download the file
+
+	conditional_printf(!options.Quiet, "Downloading %s\n", local_name)
+
+	h, err := DownloadFile(conn, descriptor, uri, local_name)
+	if err != nil {
+		return err
+	}
+
+	// STEP 5: Verify checksum
+
+	if completed_backupfile.GetFieldByName("checksum").(string) != h.GetChecksum() {
+		return corderrors.WithStackTrace(&corderrors.ChecksumMismatchError{
+			Actual:   h.GetChecksum(),
+			Expected: completed_backupfile.GetFieldByName("checksum").(string)})
+	}
+
+	// STEP 6: Show results
+
+	data := make([]BackupOutput, 1)
+	data[0].Chunks = h.chunks
+	data[0].Bytes = h.bytes
+	data[0].Status = h.status
+	data[0].Checksum = h.GetChecksum()
+
+	FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_BACKUP_FORMAT, "{{.Status}}", data)
+
+	return nil
+}
+
+// Create a file:/// URI to use for storing the file in the core
+func CreateDynamicURI() (string, string) {
+	remote_name := "cordctl-restore-" + time.Now().Format("20060102T150405Z")
+	uri := "file:///var/run/xos/backup/local/" + remote_name
+	return remote_name, uri
+}
+
+func (options *BackupRestore) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	ctx := context.Background() // TODO: Implement a sync timeout
+
+	local_name := options.Args.LocalFileName
+
+	var remote_name, uri string
+	if options.CreateURIFunc != nil {
+		remote_name, uri = options.CreateURIFunc()
+	} else {
+		remote_name, uri = CreateDynamicURI()
+	}
+
+	// STEP 1: Upload the file
+
+	h, upload_result, err := UploadFile(conn, descriptor, local_name, uri, options.ChunkSize)
+	if err != nil {
+		return err
+	}
+
+	upload_status := GetEnumValue(upload_result, "status")
+	if upload_status != "SUCCESS" {
+		return corderrors.NewInternalError("Upload status was %s", upload_status)
+	}
+
+	// STEP 2: Verify checksum
+
+	if upload_result.GetFieldByName("checksum").(string) != h.GetChecksum() {
+		return corderrors.WithStackTrace(&corderrors.ChecksumMismatchError{
+			Expected: h.GetChecksum(),
+			Actual:   upload_result.GetFieldByName("checksum").(string)})
+	}
+
+	// STEP 2: Create a BackupFile object
+
+	backupfile := make(map[string]interface{})
+	backupfile["name"] = remote_name
+	backupfile["uri"] = uri
+	backupfile["checksum"] = h.GetChecksum()
+	err = CreateModel(conn, descriptor, "BackupFile", backupfile)
+	if err != nil {
+		return err
+	}
+	conditional_printf(!options.Quiet, "Created backup file %d\n", backupfile["id"])
+
+	// STEP 3: Create a BackupOperation object
+
+	backupop := make(map[string]interface{})
+	backupop["operation"] = "restore"
+	backupop["file_id"] = backupfile["id"]
+	err = CreateModel(conn, descriptor, "BackupOperation", backupop)
+	if err != nil {
+		return err
+	}
+	conditional_printf(!options.Quiet, "Created backup-restore operation id=%d uuid=%s\n", backupop["id"], backupop["uuid"])
+
+	conditional_printf(!options.Quiet, "Waiting for completion ")
+
+	// STEP 4: Wait for completion
+
+	flags := GM_UNTIL_ENACTED | GM_UNTIL_FOUND | GM_UNTIL_STATUS | Ternary_uint32(options.Quiet, GM_QUIET, 0)
+	queries := map[string]string{"uuid": backupop["uuid"].(string)}
+	conn, completed_backupop, err := FindModelWithRetry(ctx, conn, descriptor, "BackupOperation", queries, flags)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	conditional_printf(!options.Quiet, "\n")
+
+	// STEP 5: Show results
+
+	data := make([]BackupOutput, 1)
+	data[0].Checksum = upload_result.GetFieldByName("checksum").(string)
+	data[0].Chunks = int(upload_result.GetFieldByName("chunks_received").(int32))
+	data[0].Bytes = int(upload_result.GetFieldByName("bytes_received").(int32))
+
+	if completed_backupop.GetFieldByName("status") == "restored" {
+		data[0].Status = "SUCCESS"
+	} else {
+		data[0].Status = "FAILURE"
+	}
+
+	FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_BACKUP_FORMAT, "{{.Status}}", data)
+
+	return nil
+}
diff --git a/internal/pkg/commands/backup_test.go b/internal/pkg/commands/backup_test.go
new file mode 100644
index 0000000..4d78a11
--- /dev/null
+++ b/internal/pkg/commands/backup_test.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 (
+	"bytes"
+	"github.com/opencord/cordctl/pkg/testutils"
+	"io/ioutil"
+	"testing"
+)
+
+func TestBackupCreate(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"bytes": 6,
+			"checksum": "sha256:e9c0f8b575cbfcb42ab3b78ecc87efa3b011d9a5d10b09fa4e96f240bf6a82f5",
+			"chunks": 2,
+			"status": "SUCCESS"
+		}
+	]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options BackupOpts
+	options.Create.OutputAs = "json"
+	options.Create.Args.LocalFileName = "/tmp/transfer.down"
+	options.Create.ChunkSize = 3
+	err := options.Create.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+// Mock the CreateURI function in the Restore code to use file:///tmp/transfer.up
+func CreateURI() (string, string) {
+	remote_name := "transfer.up"
+	uri := "file:///tmp/" + remote_name
+	return remote_name, uri
+}
+
+func TestBackupRestore(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"bytes": 6,
+			"checksum": "sha256:e9c0f8b575cbfcb42ab3b78ecc87efa3b011d9a5d10b09fa4e96f240bf6a82f5",
+			"chunks": 2,
+			"status": "SUCCESS"
+		}
+	]`
+
+	err := ioutil.WriteFile("/tmp/transfer.up", []byte("ABCDEF"), 0644)
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options BackupRestore
+	options.OutputAs = "json"
+	options.Args.LocalFileName = "/tmp/transfer.up"
+	options.ChunkSize = 3
+	options.CreateURIFunc = CreateURI
+	err = options.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
diff --git a/internal/pkg/commands/command.go b/internal/pkg/commands/command.go
new file mode 100644
index 0000000..45ccd5d
--- /dev/null
+++ b/internal/pkg/commands/command.go
@@ -0,0 +1,277 @@
+/*
+ * 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 (
+	"encoding/json"
+	"fmt"
+	"github.com/opencord/cordctl/pkg/format"
+	"github.com/opencord/cordctl/pkg/order"
+	"google.golang.org/grpc"
+	"gopkg.in/yaml.v2"
+	"io"
+	"io/ioutil"
+	"log"
+	"os"
+	"strings"
+	"time"
+	"net"
+)
+
+type OutputType uint8
+
+const (
+	OUTPUT_TABLE OutputType = iota
+	OUTPUT_JSON
+	OUTPUT_YAML
+
+	CORE_VERSION_CONSTRAINT = ">= 3, < 4" // Support XOS major version 3
+)
+
+// Make it easy to override output stream for testing
+var OutputStream io.Writer = os.Stdout
+
+var CharReplacer = strings.NewReplacer("\\t", "\t", "\\n", "\n")
+
+type GrpcConfigSpec struct {
+	Timeout time.Duration `yaml:"timeout"`
+}
+
+type TlsConfigSpec struct {
+	UseTls bool   `yaml:"useTls"`
+	CACert string `yaml:"caCert"`
+	Cert   string `yaml:"cert"`
+	Key    string `yaml:"key"`
+	Verify string `yaml:"verify"`
+}
+
+type GlobalConfigSpec struct {
+	Server   string        `yaml:"server"`
+	Username string        `yaml:"username"`
+	Password string        `yaml:"password"`
+	Protoset string        `yaml:"protoset"`
+	Tls      TlsConfigSpec `yaml:"tls"`
+	Grpc     GrpcConfigSpec
+}
+
+var GlobalConfig = GlobalConfigSpec{
+	Server: "localhost",
+	Tls: TlsConfigSpec{
+		UseTls: false,
+	},
+	Grpc: GrpcConfigSpec{
+		Timeout: time.Second * 10,
+	},
+}
+
+var GlobalOptions struct {
+	Config   string `short:"c" long:"config" env:"CORDCONFIG" value-name:"FILE" default:"" description:"Location of client config file"`
+	Server   string `short:"s" long:"server" default:"" value-name:"SERVER:PORT" description:"IP/Host and port of XOS"`
+	Username string `short:"u" long:"username" value-name:"USERNAME" default:"" description:"Username to authenticate with XOS"`
+	Password string `short:"p" long:"password" value-name:"PASSWORD" default:"" description:"Password to authenticate with XOS"`
+	Protoset string `long:"protoset" value-name:"FILENAME" description:"Load protobuf definitions from protoset instead of reflection api"`
+	Debug    bool   `short:"d" long:"debug" description:"Enable debug mode"`
+	UseTLS   bool   `long:"tls" description:"Use TLS"`
+	CACert   string `long:"tlscacert" value-name:"CA_CERT_FILE" description:"Trust certs signed only by this CA"`
+	Cert     string `long:"tlscert" value-name:"CERT_FILE" description:"Path to TLS vertificate file"`
+	Key      string `long:"tlskey" value-name:"KEY_FILE" description:"Path to TLS key file"`
+	Verify   bool   `long:"tlsverify" description:"Use TLS and verify the remote"`
+	Yes      bool   `short:"y" long:"yes" description:"answer yes to any confirmation prompts"`
+}
+
+type OutputOptions struct {
+	Format   string `long:"format" value-name:"FORMAT" default:"" description:"Format to use to output structured data"`
+	Quiet    bool   `short:"q" long:"quiet" description:"Output only the IDs of the objects"`
+	OutputAs string `short:"o" long:"outputas" default:"table" choice:"table" choice:"json" choice:"yaml" description:"Type of output to generate"`
+}
+
+type ListOutputOptions struct {
+	OutputOptions
+	OrderBy string `short:"r" long:"orderby" default:"" description:"Specify the sort order of the results"`
+}
+
+func toOutputType(in string) OutputType {
+	switch in {
+	case "table":
+		fallthrough
+	default:
+		return OUTPUT_TABLE
+	case "json":
+		return OUTPUT_JSON
+	case "yaml":
+		return OUTPUT_YAML
+	}
+}
+
+type CommandResult struct {
+	Format   format.Format
+	OrderBy  string
+	OutputAs OutputType
+	Data     interface{}
+}
+
+type config struct {
+	Server string `yaml:"server"`
+}
+
+func ProcessGlobalOptions() {
+	if len(GlobalOptions.Config) == 0 {
+		home, err := os.UserHomeDir()
+		if err != nil {
+			log.Printf("Unable to discover the users home directory: %s\n", err)
+		}
+		GlobalOptions.Config = fmt.Sprintf("%s/.cord/config", home)
+	}
+
+	info, err := os.Stat(GlobalOptions.Config)
+	if err == nil && !info.IsDir() {
+		configFile, err := ioutil.ReadFile(GlobalOptions.Config)
+		if err != nil {
+			log.Printf("configFile.Get err   #%v ", err)
+		}
+		err = yaml.Unmarshal(configFile, &GlobalConfig)
+		if err != nil {
+			log.Fatalf("Unmarshal: %v", err)
+		}
+	}
+
+	// Override from environment
+	//    in particualr, for passing env vars via `go test`
+	env_server, present := os.LookupEnv("CORDCTL_SERVER")
+	if present {
+		GlobalConfig.Server = env_server
+	}
+	env_username, present := os.LookupEnv("CORDCTL_USERNAME")
+	if present {
+		GlobalConfig.Username = env_username
+	}
+	env_password, present := os.LookupEnv("CORDCTL_PASSWORD")
+	if present {
+		GlobalConfig.Password = env_password
+	}
+	env_protoset, present := os.LookupEnv("CORDCTL_PROTOSET")
+	if present {
+		GlobalConfig.Protoset = env_protoset
+	}
+
+	// Override from command line
+	if GlobalOptions.Server != "" {
+		GlobalConfig.Server = GlobalOptions.Server
+	}
+	if GlobalOptions.Username != "" {
+		GlobalConfig.Username = GlobalOptions.Username
+	}
+	if GlobalOptions.Password != "" {
+		GlobalConfig.Password = GlobalOptions.Password
+	}
+	if GlobalOptions.Protoset != "" {
+		GlobalConfig.Protoset = GlobalOptions.Protoset
+	}
+
+	// Generate error messages for required settings
+	if GlobalConfig.Server == "" {
+		log.Fatal("Server is not set. Please update config file or use the -s option")
+	}
+	if GlobalConfig.Username == "" {
+		log.Fatal("Username is not set. Please update config file or use the -u option")
+	}
+	if GlobalConfig.Password == "" {
+		log.Fatal("Password is not set. Please update config file or use the -p option")
+	}
+	//Try to resolve hostname if provided for the server
+	if host, port, err := net.SplitHostPort(GlobalConfig.Server); err == nil {
+		if addrs, err := net.LookupHost(host); err == nil {
+			GlobalConfig.Server = net.JoinHostPort(addrs[0], port)
+		}
+	}
+}
+
+func NewConnection() (*grpc.ClientConn, error) {
+	ProcessGlobalOptions()
+	return grpc.Dial(GlobalConfig.Server, grpc.WithInsecure())
+}
+
+func GenerateOutput(result *CommandResult) {
+	if result != nil && result.Data != nil {
+		data := result.Data
+		if result.OrderBy != "" {
+			s, err := order.Parse(result.OrderBy)
+			if err != nil {
+				panic(err)
+			}
+			data, err = s.Process(data)
+			if err != nil {
+				panic(err)
+			}
+		}
+		if result.OutputAs == OUTPUT_TABLE {
+			tableFormat := format.Format(result.Format)
+			tableFormat.Execute(OutputStream, true, data)
+		} else if result.OutputAs == OUTPUT_JSON {
+			asJson, err := json.Marshal(&data)
+			if err != nil {
+				panic(err)
+			}
+			fmt.Fprintf(OutputStream, "%s", asJson)
+		} else if result.OutputAs == OUTPUT_YAML {
+			asYaml, err := yaml.Marshal(&data)
+			if err != nil {
+				panic(err)
+			}
+			fmt.Fprintf(OutputStream, "%s", asYaml)
+		}
+	}
+}
+
+// Applies common output options to format and generate output
+func FormatAndGenerateOutput(options *OutputOptions, default_format string, quiet_format string, data interface{}) {
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = default_format
+	}
+	if options.Quiet {
+		outputFormat = quiet_format
+	}
+
+	result := CommandResult{
+		Format:   format.Format(outputFormat),
+		OutputAs: toOutputType(options.OutputAs),
+		Data:     data,
+	}
+
+	GenerateOutput(&result)
+}
+
+// Applies common output options to format and generate output
+func FormatAndGenerateListOutput(options *ListOutputOptions, default_format string, quiet_format string, data interface{}) {
+	outputFormat := CharReplacer.Replace(options.Format)
+	if outputFormat == "" {
+		outputFormat = default_format
+	}
+	if options.Quiet {
+		outputFormat = quiet_format
+	}
+
+	result := CommandResult{
+		Format:   format.Format(outputFormat),
+		OutputAs: toOutputType(options.OutputAs),
+		Data:     data,
+		OrderBy:  options.OrderBy,
+	}
+
+	GenerateOutput(&result)
+}
diff --git a/internal/pkg/commands/common.go b/internal/pkg/commands/common.go
new file mode 100644
index 0000000..6f795e4
--- /dev/null
+++ b/internal/pkg/commands/common.go
@@ -0,0 +1,168 @@
+/*
+ * Copyright 2019-present Open Networking Foundation
+ *
+ * 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 (
+	"bufio"
+	b64 "encoding/base64"
+	"fmt"
+	"github.com/fullstorydev/grpcurl"
+	versionUtils "github.com/hashicorp/go-version"
+	"github.com/jhump/protoreflect/dynamic"
+	"github.com/jhump/protoreflect/grpcreflect"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	reflectpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
+	"log"
+	"os"
+	"strings"
+)
+
+// Flags for calling the InitReflectionClient Method
+const (
+	INIT_DEFAULT          = 0
+	INIT_NO_VERSION_CHECK = 1 // Do not check whether server is allowed version
+)
+
+func GenerateHeaders() []string {
+	username := GlobalConfig.Username
+	password := GlobalConfig.Password
+	sEnc := b64.StdEncoding.EncodeToString([]byte(username + ":" + password))
+	headers := []string{"authorization: basic " + sEnc}
+	return headers
+}
+
+// Perform the GetVersion API call on the core to get the version
+func GetVersion(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource) (*dynamic.Message, error) {
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	h := &RpcEventHandler{}
+	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.utility.GetVersion", headers, h, h.GetParams)
+	if err != nil {
+		return nil, corderrors.RpcErrorToCordError(err)
+	}
+
+	if h.Status != nil && h.Status.Err() != nil {
+		return nil, corderrors.RpcErrorToCordError(h.Status.Err())
+	}
+
+	d, err := dynamic.AsDynamicMessage(h.Response)
+
+	return d, err
+}
+
+// Initialize client connection
+//    flags is a set of optional flags that may influence how the connection is setup
+//        INIT_DEFAULT - default behavior (0)
+//        INIT_NO_VERSION_CHECK - do not perform core version check
+
+func InitClient(flags uint32) (*grpc.ClientConn, grpcurl.DescriptorSource, error) {
+	conn, err := NewConnection()
+	if err != nil {
+		return nil, nil, err
+	}
+
+	refClient := grpcreflect.NewClient(context.Background(), reflectpb.NewServerReflectionClient(conn))
+	defer refClient.Reset()
+
+	// Intended method of use is to download the protos via reflection API. Loading the
+	// protos from a file is supported for unit testing, as the mock server does not
+	// support the reflection API.
+
+	var descriptor grpcurl.DescriptorSource
+	if GlobalConfig.Protoset != "" {
+		descriptor, err = grpcurl.DescriptorSourceFromProtoSets(GlobalConfig.Protoset)
+		if err != nil {
+			return nil, nil, err
+		}
+	} else {
+		descriptor = grpcurl.DescriptorSourceFromServer(context.Background(), refClient)
+	}
+
+	if flags&INIT_NO_VERSION_CHECK == 0 {
+		d, err := GetVersion(conn, descriptor)
+		if err != nil {
+			return nil, nil, err
+		}
+		// Note: NewVersion doesn't like the `-dev` suffix, so strip it off.
+		serverVersion, err := versionUtils.NewVersion(strings.Split(d.GetFieldByName("version").(string), "-")[0])
+		if err != nil {
+			return nil, nil, err
+		}
+
+		constraint, err := versionUtils.NewConstraint(CORE_VERSION_CONSTRAINT)
+		if err != nil {
+			return nil, nil, err
+		}
+
+		if !constraint.Check(serverVersion) {
+			return nil, nil, corderrors.WithStackTrace(&corderrors.VersionConstraintError{
+				Name:       "xos-core",
+				Version:    serverVersion.String(),
+				Constraint: CORE_VERSION_CONSTRAINT})
+		}
+
+	}
+
+	return conn, descriptor, nil
+}
+
+// A makeshift substitute for C's Ternary operator
+func Ternary_uint32(condition bool, value_true uint32, value_false uint32) uint32 {
+	if condition {
+		return value_true
+	} else {
+		return value_false
+	}
+}
+
+// call printf only if visible is True
+func conditional_printf(visible bool, format string, args ...interface{}) {
+	if visible {
+		fmt.Printf(format, args...)
+	}
+}
+
+// Print a confirmation prompt and get a response from the user
+func Confirmf(format string, args ...interface{}) bool {
+	if GlobalOptions.Yes {
+		return true
+	}
+
+	reader := bufio.NewReader(os.Stdin)
+
+	for {
+		msg := fmt.Sprintf(format, args...)
+		fmt.Print(msg)
+
+		response, err := reader.ReadString('\n')
+		if err != nil {
+			log.Fatal(err)
+		}
+
+		response = strings.ToLower(strings.TrimSpace(response))
+
+		if response == "y" || response == "yes" {
+			return true
+		} else if response == "n" || response == "no" {
+			return false
+		}
+	}
+}
diff --git a/internal/pkg/commands/completion.go b/internal/pkg/commands/completion.go
new file mode 100644
index 0000000..74e7cfa
--- /dev/null
+++ b/internal/pkg/commands/completion.go
@@ -0,0 +1,37 @@
+/*
+ * 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 (
+	"fmt"
+	flags "github.com/jessevdk/go-flags"
+	"github.com/opencord/cordctl/internal/pkg/completion"
+)
+
+type BashOptions struct{}
+
+type CompletionOptions struct {
+	BashOptions `command:"bash"`
+}
+
+func RegisterCompletionCommands(parent *flags.Parser) {
+	parent.AddCommand("completion", "generate shell compleition", "Commands to generate shell completion information", &CompletionOptions{})
+}
+
+func (options *BashOptions) Execute(args []string) error {
+	fmt.Fprintln(OutputStream, completion.Bash)
+	return nil
+}
diff --git a/internal/pkg/commands/completion_test.go b/internal/pkg/commands/completion_test.go
new file mode 100644
index 0000000..b7b25c8
--- /dev/null
+++ b/internal/pkg/commands/completion_test.go
@@ -0,0 +1,39 @@
+/*
+ * 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/internal/pkg/completion"
+	"github.com/opencord/cordctl/pkg/testutils"
+	"testing"
+)
+
+func TestCompletion(t *testing.T) {
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options CompletionOptions
+	err := options.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertStringEqual(t, got.String(), completion.Bash+"\n")
+}
diff --git a/internal/pkg/commands/config.go b/internal/pkg/commands/config.go
new file mode 100644
index 0000000..81875a5
--- /dev/null
+++ b/internal/pkg/commands/config.go
@@ -0,0 +1,60 @@
+/*
+ * 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 (
+	"fmt"
+	flags "github.com/jessevdk/go-flags"
+	"gopkg.in/yaml.v2"
+)
+
+const copyrightNotice = `
+# 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.
+#
+`
+
+type ConfigOptions struct {
+}
+
+func RegisterConfigCommands(parent *flags.Parser) {
+	parent.AddCommand("config", "generate cordctl configuration", "Commands to generate cordctl configuration", &ConfigOptions{})
+}
+
+func (options *ConfigOptions) Execute(args []string) error {
+	//GlobalConfig
+	ProcessGlobalOptions()
+	b, err := yaml.Marshal(GlobalConfig)
+	if err != nil {
+		return err
+	}
+	fmt.Println(copyrightNotice)
+	fmt.Println(string(b))
+	return nil
+}
diff --git a/internal/pkg/commands/funcmap.go b/internal/pkg/commands/funcmap.go
new file mode 100644
index 0000000..7a2bdf2
--- /dev/null
+++ b/internal/pkg/commands/funcmap.go
@@ -0,0 +1,80 @@
+/*
+ * 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 (
+	"fmt"
+	"github.com/fullstorydev/grpcurl"
+	"github.com/jhump/protoreflect/dynamic"
+	"github.com/jhump/protoreflect/grpcreflect"
+	"golang.org/x/net/context"
+	"google.golang.org/grpc"
+	reflectpb "google.golang.org/grpc/reflection/grpc_reflection_v1alpha"
+)
+
+type MethodNotFoundError struct {
+	Name string
+}
+
+func (e *MethodNotFoundError) Error() string {
+	return fmt.Sprintf("Method '%s' not found in function map", e.Name)
+}
+
+type MethodVersionNotFoundError struct {
+	Name    string
+	Version string
+}
+
+func (e *MethodVersionNotFoundError) Error() string {
+	return fmt.Sprintf("Method '%s' does not have a verison for '%s' specfied in function map", e.Name, e.Version)
+}
+
+type DescriptorNotFoundError struct {
+	Version string
+}
+
+func (e *DescriptorNotFoundError) Error() string {
+	return fmt.Sprintf("Protocol buffer descriptor for API version '%s' not found", e.Version)
+}
+
+type UnableToParseDescriptorErrror struct {
+	err     error
+	Version string
+}
+
+func (e *UnableToParseDescriptorErrror) Error() string {
+	return fmt.Sprintf("Unable to parse protocal buffer descriptor for version '%s': %s", e.Version, e.err)
+}
+
+func GetReflectionMethod(conn *grpc.ClientConn, name string) (grpcurl.DescriptorSource, string, error) {
+	refClient := grpcreflect.NewClient(context.Background(), reflectpb.NewServerReflectionClient(conn))
+	defer refClient.Reset()
+
+	desc := grpcurl.DescriptorSourceFromServer(context.Background(), refClient)
+
+	return desc, name, nil
+}
+
+func GetEnumValue(msg *dynamic.Message, name string) string {
+	return msg.FindFieldDescriptorByName(name).GetEnumType().
+		FindValueByNumber(msg.GetFieldByName(name).(int32)).GetName()
+}
+
+func SetEnumValue(msg *dynamic.Message, name string, value string) {
+	eValue := msg.FindFieldDescriptorByName(name).GetEnumType().FindValueByName(value)
+	msg.SetFieldByName(name, eValue.GetNumber())
+}
diff --git a/internal/pkg/commands/handler.go b/internal/pkg/commands/handler.go
new file mode 100644
index 0000000..678883d
--- /dev/null
+++ b/internal/pkg/commands/handler.go
@@ -0,0 +1,85 @@
+/*
+ * 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 (
+	"github.com/golang/protobuf/proto"
+	"github.com/jhump/protoreflect/desc"
+	"github.com/jhump/protoreflect/dynamic"
+	"google.golang.org/grpc/metadata"
+	"google.golang.org/grpc/status"
+	"io"
+)
+
+type RpcEventHandler struct {
+	Response proto.Message
+	Status   *status.Status
+	Data     []byte
+	Fields   map[string]map[string]interface{}
+}
+
+func (h *RpcEventHandler) OnResolveMethod(*desc.MethodDescriptor) {
+}
+
+func (h *RpcEventHandler) OnSendHeaders(metadata.MD) {
+}
+
+func (h *RpcEventHandler) OnReceiveHeaders(metadata.MD) {
+}
+
+func (h *RpcEventHandler) OnReceiveResponse(m proto.Message) {
+	h.Response = m
+}
+
+func (h *RpcEventHandler) OnReceiveTrailers(s *status.Status, m metadata.MD) {
+	h.Status = s
+}
+
+func (h *RpcEventHandler) GetParams(msg proto.Message) error {
+	dmsg, err := dynamic.AsDynamicMessage(msg)
+	if err != nil {
+		return err
+	}
+
+	//fmt.Printf("MessageName: %s\n", dmsg.XXX_MessageName())
+
+	if h.Fields == nil || len(h.Fields) == 0 {
+		//fmt.Println("EOF")
+		return io.EOF
+	}
+
+	fields, ok := h.Fields[dmsg.XXX_MessageName()]
+	if !ok {
+		//fmt.Println("nil")
+		return nil
+	}
+
+	for k, v := range fields {
+		// _json is a special field name that indicates we should unmarshal json data
+		if k == "_json" {
+			err = dmsg.UnmarshalMergeJSON(v.([]byte))
+			if err != nil {
+				return err
+			}
+		} else {
+			dmsg.SetFieldByName(k, v)
+		}
+	}
+	delete(h.Fields, dmsg.XXX_MessageName())
+
+	return nil
+}
diff --git a/internal/pkg/commands/models.go b/internal/pkg/commands/models.go
new file mode 100644
index 0000000..c39d1df
--- /dev/null
+++ b/internal/pkg/commands/models.go
@@ -0,0 +1,609 @@
+/*
+ * 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"
+	"fmt"
+	"github.com/fullstorydev/grpcurl"
+	flags "github.com/jessevdk/go-flags"
+	"github.com/jhump/protoreflect/dynamic"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+	"google.golang.org/grpc"
+	"sort"
+	"strings"
+	"time"
+)
+
+const (
+	DEFAULT_CREATE_FORMAT = "table{{ .Id }}\t{{ .Message }}"
+	DEFAULT_DELETE_FORMAT = "table{{ .Id }}\t{{ .Message }}"
+	DEFAULT_UPDATE_FORMAT = "table{{ .Id }}\t{{ .Message }}"
+	DEFAULT_SYNC_FORMAT   = "table{{ .Id }}\t{{ .Message }}"
+)
+
+type ModelNameString string
+
+type ModelList struct {
+	ListOutputOptions
+	ShowHidden      bool   `long:"showhidden" description:"Show hidden fields in default output"`
+	ShowFeedback    bool   `long:"showfeedback" description:"Show feedback fields in default output"`
+	ShowBookkeeping bool   `long:"showbookkeeping" description:"Show bookkeeping fields in default output"`
+	Filter          string `short:"f" long:"filter" description:"Comma-separated list of filters"`
+	State           string `short:"s" long:"state" description:"Filter model state [DEFAULT | ALL | DIRTY | DELETED | DIRTYPOL | DELETEDPOL]"`
+	Args            struct {
+		ModelName ModelNameString
+	} `positional-args:"yes" required:"yes"`
+}
+
+type ModelUpdate struct {
+	OutputOptions
+	Unbuffered  bool          `short:"u" long:"unbuffered" description:"Do not buffer console output and suppress default output processor"`
+	Filter      string        `short:"f" long:"filter" description:"Comma-separated list of filters"`
+	SetFields   string        `long:"set-field" description:"Comma-separated list of field=value to set"`
+	SetJSON     string        `long:"set-json" description:"JSON dictionary to use for settings fields"`
+	Sync        bool          `long:"sync" description:"Synchronize before returning"`
+	SyncTimeout time.Duration `long:"synctimeout" default:"600s" description:"Timeout for --sync option"`
+	Args        struct {
+		ModelName ModelNameString
+	} `positional-args:"yes" required:"yes"`
+	IDArgs struct {
+		ID []int32
+	} `positional-args:"yes" required:"no"`
+}
+
+type ModelDelete struct {
+	OutputOptions
+	Unbuffered bool   `short:"u" long:"unbuffered" description:"Do not buffer console output and suppress default output processor"`
+	Filter     string `short:"f" long:"filter" description:"Comma-separated list of filters"`
+	All        bool   `short:"a" long:"all" description:"Operate on all models"`
+	Args       struct {
+		ModelName ModelNameString
+	} `positional-args:"yes" required:"yes"`
+	IDArgs struct {
+		ID []int32
+	} `positional-args:"yes" required:"no"`
+}
+
+type ModelCreate struct {
+	OutputOptions
+	Unbuffered  bool          `short:"u" long:"unbuffered" description:"Do not buffer console output"`
+	SetFields   string        `long:"set-field" description:"Comma-separated list of field=value to set"`
+	SetJSON     string        `long:"set-json" description:"JSON dictionary to use for settings fields"`
+	Sync        bool          `long:"sync" description:"Synchronize before returning"`
+	SyncTimeout time.Duration `long:"synctimeout" default:"600s" description:"Timeout for --sync option"`
+	Args        struct {
+		ModelName ModelNameString
+	} `positional-args:"yes" required:"yes"`
+}
+
+type ModelSync struct {
+	OutputOptions
+	Unbuffered  bool          `short:"u" long:"unbuffered" description:"Do not buffer console output and suppress default output processor"`
+	Filter      string        `short:"f" long:"filter" description:"Comma-separated list of filters"`
+	SyncTimeout time.Duration `long:"synctimeout" default:"600s" description:"Timeout for synchronization"`
+	All         bool          `short:"a" long:"all" description:"Operate on all models"`
+	Args        struct {
+		ModelName ModelNameString
+	} `positional-args:"yes" required:"yes"`
+	IDArgs struct {
+		ID []int32
+	} `positional-args:"yes" required:"no"`
+}
+
+type ModelSetDirty struct {
+	OutputOptions
+	Unbuffered bool   `short:"u" long:"unbuffered" description:"Do not buffer console output and suppress default output processor"`
+	Filter     string `short:"f" long:"filter" description:"Comma-separated list of filters"`
+	All        bool   `short:"a" long:"all" description:"Operate on all models"`
+	Args       struct {
+		ModelName ModelNameString
+	} `positional-args:"yes" required:"yes"`
+	IDArgs struct {
+		ID []int32
+	} `positional-args:"yes" required:"no"`
+}
+
+type ModelOpts struct {
+	List     ModelList     `command:"list"`
+	Update   ModelUpdate   `command:"update"`
+	Delete   ModelDelete   `command:"delete"`
+	Create   ModelCreate   `command:"create"`
+	Sync     ModelSync     `command:"sync"`
+	SetDirty ModelSetDirty `command:"setdirty"`
+}
+
+type ModelStatusOutputRow struct {
+	Id      interface{} `json:"id"`
+	Message string      `json:"message"`
+}
+
+type ModelStatusOutput struct {
+	Rows       []ModelStatusOutputRow
+	Unbuffered bool
+}
+
+var modelOpts = ModelOpts{}
+
+func RegisterModelCommands(parser *flags.Parser) {
+	parser.AddCommand("model", "model commands", "Commands to query and manipulate XOS models", &modelOpts)
+}
+
+// Initialize ModelStatusOutput structure, creating a row for each model that will be output
+func InitModelStatusOutput(unbuffered bool, count int) ModelStatusOutput {
+	return ModelStatusOutput{Rows: make([]ModelStatusOutputRow, count), Unbuffered: unbuffered}
+}
+
+// Update model status output row for the model
+//    If unbuffered is set then we will output directly to the console. Regardless of the unbuffered
+//    setting, we always update the row, as callers may check that row for status.
+// Args:
+//    output - ModelStatusOutput struct to update
+//    i - index of row to update
+//    id - id of model, <nil> if no model exists
+//    status - status text to set if there is no error
+//    errror - if non-nil, then apply error text instead of status text
+//    final - true if successful status should be reported, false if successful status is yet to come
+
+func UpdateModelStatusOutput(output *ModelStatusOutput, i int, id interface{}, status string, err error, final bool) {
+	if err != nil {
+		if output.Unbuffered {
+			fmt.Printf("%v: %s\n", id, err)
+		}
+		output.Rows[i] = ModelStatusOutputRow{Id: id, Message: err.Error()}
+	} else {
+		if output.Unbuffered && final {
+			fmt.Println(id)
+		}
+		output.Rows[i] = ModelStatusOutputRow{Id: id, Message: status}
+	}
+}
+
+// Convert a user-supplied state filter argument to the appropriate enum name
+func GetFilterKind(kindArg string) (string, error) {
+	kindMap := map[string]string{
+		"default":   FILTER_DEFAULT,
+		"all":       FILTER_ALL,
+		"dirty":     FILTER_DIRTY,
+		"deleted":   FILTER_DELETED,
+		"dirtypol":  FILTER_DIRTYPOL,
+		"deletedpo": FILTER_DELETEDPOL,
+	}
+
+	// If no arg then use default
+	if kindArg == "" {
+		return kindMap["default"], nil
+	}
+
+	val, ok := kindMap[strings.ToLower(kindArg)]
+	if !ok {
+		return "", corderrors.WithStackTrace(&corderrors.UnknownModelStateError{Name: kindArg})
+	}
+
+	return val, nil
+}
+
+// Common processing for commands that take a modelname and a list of ids or a filter
+func GetIDList(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, ids []int32, filter string, all bool) ([]int32, error) {
+	err := CheckModelName(descriptor, modelName)
+	if err != nil {
+		return nil, err
+	}
+
+	// we require exactly one of ID, --filter, or --all
+	exclusiveCount := 0
+	if len(ids) > 0 {
+		exclusiveCount++
+	}
+	if filter != "" {
+		exclusiveCount++
+	}
+	if all {
+		exclusiveCount++
+	}
+
+	if (exclusiveCount == 0) || (exclusiveCount > 1) {
+		return nil, corderrors.WithStackTrace(&corderrors.FilterRequiredError{})
+	}
+
+	queries, err := CommaSeparatedQueryToMap(filter, true)
+	if err != nil {
+		return nil, err
+	}
+
+	if len(ids) > 0 {
+		// do nothing
+	} else {
+		models, err := ListOrFilterModels(context.Background(), conn, descriptor, modelName, FILTER_DEFAULT, queries)
+		if err != nil {
+			return nil, err
+		}
+		ids = make([]int32, len(models))
+		for i, model := range models {
+			ids[i] = model.GetFieldByName("id").(int32)
+		}
+		if len(ids) == 0 {
+			return nil, corderrors.WithStackTrace(&corderrors.NoMatchError{})
+		} else if len(ids) > 1 {
+			if !Confirmf("Filter matches %d objects. Continue [y/n] ? ", len(models)) {
+				return nil, corderrors.WithStackTrace(&corderrors.AbortedError{})
+			}
+		}
+	}
+
+	return ids, nil
+}
+
+func (options *ModelList) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	err = CheckModelName(descriptor, string(options.Args.ModelName))
+	if err != nil {
+		return err
+	}
+
+	filterKind, err := GetFilterKind(options.State)
+	if err != nil {
+		return err
+	}
+
+	queries, err := CommaSeparatedQueryToMap(options.Filter, true)
+	if err != nil {
+		return err
+	}
+
+	models, err := ListOrFilterModels(context.Background(), conn, descriptor, string(options.Args.ModelName), filterKind, queries)
+	if err != nil {
+		return err
+	}
+
+	var field_names []string
+	data := make([]map[string]interface{}, len(models))
+	for i, val := range models {
+		data[i] = make(map[string]interface{})
+		for _, field_desc := range val.GetKnownFields() {
+			field_name := field_desc.GetName()
+
+			isGuiHidden := strings.Contains(field_desc.GetFieldOptions().String(), "1005:1")
+			isFeedback := strings.Contains(field_desc.GetFieldOptions().String(), "1006:1")
+			isBookkeeping := strings.Contains(field_desc.GetFieldOptions().String(), "1007:1")
+
+			if isGuiHidden && (!options.ShowHidden) {
+				continue
+			}
+
+			if isFeedback && (!options.ShowFeedback) {
+				continue
+			}
+
+			if isBookkeeping && (!options.ShowBookkeeping) {
+				continue
+			}
+
+			if field_desc.IsRepeated() {
+				continue
+			}
+
+			data[i][field_name] = val.GetFieldByName(field_name)
+
+			// Every row has the same set of known field names, so it suffices to use the names
+			// from the first row.
+			if i == 0 {
+				field_names = append(field_names, field_name)
+			}
+		}
+	}
+
+	// Sort field names, making sure "id" appears first
+	sort.SliceStable(field_names, func(i, j int) bool {
+		if field_names[i] == "id" {
+			return true
+		} else if field_names[j] == "id" {
+			return false
+		} else {
+			return (field_names[i] < field_names[j])
+		}
+	})
+
+	var default_format strings.Builder
+	default_format.WriteString("table")
+	for i, field_name := range field_names {
+		if i == 0 {
+			fmt.Fprintf(&default_format, "{{ .%s }}", field_name)
+		} else {
+			fmt.Fprintf(&default_format, "\t{{ .%s }}", field_name)
+		}
+	}
+
+	FormatAndGenerateListOutput(&options.ListOutputOptions, default_format.String(), "{{.id}}", data)
+
+	return nil
+}
+
+func (options *ModelUpdate) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	err = CheckModelName(descriptor, string(options.Args.ModelName))
+	if err != nil {
+		return err
+	}
+
+	if (len(options.IDArgs.ID) == 0 && len(options.Filter) == 0) ||
+		(len(options.IDArgs.ID) != 0 && len(options.Filter) != 0) {
+		return corderrors.WithStackTrace(&corderrors.FilterRequiredError{})
+	}
+
+	queries, err := CommaSeparatedQueryToMap(options.Filter, true)
+	if err != nil {
+		return err
+	}
+
+	updates, err := CommaSeparatedQueryToMap(options.SetFields, true)
+	if err != nil {
+		return err
+	}
+
+	modelName := string(options.Args.ModelName)
+
+	var models []*dynamic.Message
+
+	if len(options.IDArgs.ID) > 0 {
+		models = make([]*dynamic.Message, len(options.IDArgs.ID))
+		for i, id := range options.IDArgs.ID {
+			models[i], err = GetModel(context.Background(), conn, descriptor, modelName, id)
+			if err != nil {
+				return err
+			}
+		}
+	} else {
+		models, err = ListOrFilterModels(context.Background(), conn, descriptor, modelName, FILTER_DEFAULT, queries)
+		if err != nil {
+			return err
+		}
+	}
+
+	if len(models) == 0 {
+		return corderrors.WithStackTrace(&corderrors.NoMatchError{})
+	} else if len(models) > 1 {
+		if !Confirmf("Filter matches %d objects. Continue [y/n] ? ", len(models)) {
+			return corderrors.WithStackTrace(&corderrors.AbortedError{})
+		}
+	}
+
+	fields := make(map[string]interface{})
+
+	if len(options.SetJSON) > 0 {
+		fields["_json"] = []byte(options.SetJSON)
+	}
+
+	for fieldName, value := range updates {
+		value = value[1:]
+		proto_value, err := TypeConvert(descriptor, modelName, fieldName, value)
+		if err != nil {
+			return err
+		}
+		fields[fieldName] = proto_value
+	}
+
+	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, len(models))
+	for i, model := range models {
+		id := model.GetFieldByName("id").(int32)
+		fields["id"] = id
+		err := UpdateModel(conn, descriptor, modelName, fields)
+
+		UpdateModelStatusOutput(&modelStatusOutput, i, id, "Updated", err, !options.Sync)
+	}
+
+	if options.Sync {
+		ctx, cancel := context.WithTimeout(context.Background(), options.SyncTimeout)
+		defer cancel()
+		for i, model := range models {
+			id := model.GetFieldByName("id").(int32)
+			if modelStatusOutput.Rows[i].Message == "Updated" {
+				conditional_printf(!options.Quiet, "Wait for sync: %d ", id)
+				conn, _, err = GetModelWithRetry(ctx, conn, descriptor, modelName, id, GM_UNTIL_ENACTED|Ternary_uint32(options.Quiet, GM_QUIET, 0))
+				conditional_printf(!options.Quiet, "\n")
+				UpdateModelStatusOutput(&modelStatusOutput, i, id, "Enacted", err, true)
+			}
+		}
+	}
+
+	if !options.Unbuffered {
+		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_UPDATE_FORMAT, DEFAULT_UPDATE_FORMAT, modelStatusOutput.Rows)
+	}
+
+	return nil
+}
+
+func (options *ModelDelete) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	modelName := string(options.Args.ModelName)
+	ids, err := GetIDList(conn, descriptor, modelName, options.IDArgs.ID, options.Filter, options.All)
+	if err != nil {
+		return err
+	}
+
+	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, len(ids))
+	for i, id := range ids {
+		err = DeleteModel(conn, descriptor, modelName, id)
+		UpdateModelStatusOutput(&modelStatusOutput, i, id, "Deleted", err, true)
+	}
+
+	if !options.Unbuffered {
+		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_DELETE_FORMAT, DEFAULT_DELETE_FORMAT, modelStatusOutput.Rows)
+	}
+
+	return nil
+}
+
+func (options *ModelCreate) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	err = CheckModelName(descriptor, string(options.Args.ModelName))
+	if err != nil {
+		return err
+	}
+
+	updates, err := CommaSeparatedQueryToMap(options.SetFields, true)
+	if err != nil {
+		return err
+	}
+
+	modelName := string(options.Args.ModelName)
+
+	fields := make(map[string]interface{})
+
+	if len(options.SetJSON) > 0 {
+		fields["_json"] = []byte(options.SetJSON)
+	}
+
+	for fieldName, value := range updates {
+		value = value[1:]
+		proto_value, err := TypeConvert(descriptor, modelName, fieldName, value)
+		if err != nil {
+			return err
+		}
+		fields[fieldName] = proto_value
+	}
+
+	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, 1)
+
+	err = CreateModel(conn, descriptor, modelName, fields)
+	UpdateModelStatusOutput(&modelStatusOutput, 0, fields["id"], "Created", err, !options.Sync)
+
+	if options.Sync {
+		ctx, cancel := context.WithTimeout(context.Background(), options.SyncTimeout)
+		defer cancel()
+		if modelStatusOutput.Rows[0].Message == "Created" {
+			id := fields["id"].(int32)
+			conditional_printf(!options.Quiet, "Wait for sync: %d ", id)
+			conn, _, err = GetModelWithRetry(ctx, conn, descriptor, modelName, id, GM_UNTIL_ENACTED|Ternary_uint32(options.Quiet, GM_QUIET, 0))
+			conditional_printf(!options.Quiet, "\n")
+			UpdateModelStatusOutput(&modelStatusOutput, 0, id, "Enacted", err, true)
+		}
+	}
+
+	if !options.Unbuffered {
+		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_CREATE_FORMAT, DEFAULT_CREATE_FORMAT, modelStatusOutput.Rows)
+	}
+
+	return nil
+}
+
+func (options *ModelSync) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	modelName := string(options.Args.ModelName)
+	ids, err := GetIDList(conn, descriptor, modelName, options.IDArgs.ID, options.Filter, options.All)
+	if err != nil {
+		return err
+	}
+
+	ctx, cancel := context.WithTimeout(context.Background(), options.SyncTimeout)
+	defer cancel()
+
+	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, len(ids))
+	for i, id := range ids {
+		conditional_printf(!options.Quiet, "Wait for sync: %d ", id)
+		conn, _, err = GetModelWithRetry(ctx, conn, descriptor, modelName, id, GM_UNTIL_ENACTED|Ternary_uint32(options.Quiet, GM_QUIET, 0))
+		conditional_printf(!options.Quiet, "\n")
+		UpdateModelStatusOutput(&modelStatusOutput, i, id, "Enacted", err, true)
+	}
+
+	if !options.Unbuffered {
+		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_SYNC_FORMAT, DEFAULT_SYNC_FORMAT, modelStatusOutput.Rows)
+	}
+
+	return nil
+}
+
+func (options *ModelSetDirty) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	modelName := string(options.Args.ModelName)
+	ids, err := GetIDList(conn, descriptor, modelName, options.IDArgs.ID, options.Filter, options.All)
+	if err != nil {
+		return err
+	}
+
+	modelStatusOutput := InitModelStatusOutput(options.Unbuffered, len(ids))
+	for i, id := range ids {
+		updateMap := map[string]interface{}{"id": id}
+		err := UpdateModel(conn, descriptor, modelName, updateMap)
+		UpdateModelStatusOutput(&modelStatusOutput, i, id, "Dirtied", err, true)
+	}
+
+	if !options.Unbuffered {
+		FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_SYNC_FORMAT, DEFAULT_SYNC_FORMAT, modelStatusOutput.Rows)
+	}
+
+	return nil
+}
+
+func (modelName *ModelNameString) Complete(match string) []flags.Completion {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return nil
+	}
+
+	defer conn.Close()
+
+	models, err := GetModelNames(descriptor)
+	if err != nil {
+		return nil
+	}
+
+	list := make([]flags.Completion, 0)
+	for k := range models {
+		if strings.HasPrefix(k, match) {
+			list = append(list, flags.Completion{Item: k})
+		}
+	}
+
+	return list
+}
diff --git a/internal/pkg/commands/models_test.go b/internal/pkg/commands/models_test.go
new file mode 100644
index 0000000..40e25ea
--- /dev/null
+++ b/internal/pkg/commands/models_test.go
@@ -0,0 +1,446 @@
+/*
+ * Portions copyright 2019-present Open Networking Foundation
+ * Original copyright 2019-present Ciena Corporation
+ *
+ * Licensed under the Apache License, Version 2.0 (the"github.com/stretchr/testify/assert" "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"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+	"github.com/opencord/cordctl/pkg/testutils"
+	"github.com/stretchr/testify/assert"
+	"testing"
+	"time"
+)
+
+func TestModelList(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"controller_kind": "",
+			"controller_replica_count": 0,
+			"creator_id": 0,
+			"default_flavor_id": 0,
+			"default_image_id": 0,
+			"default_isolation": "",
+			"default_node_id": 0,
+			"description": "",
+			"enabled": false,
+			"exposed_ports": "",
+			"id": 1,
+			"max_instances": 0,
+			"mount_data_sets": "",
+			"name": "mockslice1",
+			"network": "",
+			"principal_id": 0,
+			"service_id": 0,
+			"site_id": 1,
+			"trust_domain_id": 0
+		},
+		{
+			"controller_kind": "",
+			"controller_replica_count": 0,
+			"creator_id": 0,
+			"default_flavor_id": 0,
+			"default_image_id": 0,
+			"default_isolation": "",
+			"default_node_id": 0,
+			"description": "",
+			"enabled": false,
+			"exposed_ports": "",
+			"id": 2,
+			"max_instances": 0,
+			"mount_data_sets": "",
+			"name": "mockslice2",
+			"network": "",
+			"principal_id": 0,
+			"service_id": 0,
+			"site_id": 1,
+			"trust_domain_id": 0
+		}
+	]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.List.Args.ModelName = "Slice"
+	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)
+}
+
+func TestModelListFilterID(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"controller_kind": "",
+			"controller_replica_count": 0,
+			"creator_id": 0,
+			"default_flavor_id": 0,
+			"default_image_id": 0,
+			"default_isolation": "",
+			"default_node_id": 0,
+			"description": "",
+			"enabled": false,
+			"exposed_ports": "",
+			"id": 1,
+			"max_instances": 0,
+			"mount_data_sets": "",
+			"name": "mockslice1",
+			"network": "",
+			"principal_id": 0,
+			"service_id": 0,
+			"site_id": 1,
+			"trust_domain_id": 0
+		}
+	]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.List.Args.ModelName = "Slice"
+	options.List.OutputAs = "json"
+	options.List.Filter = "id=1"
+	err := options.List.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelListFilterName(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"controller_kind": "",
+			"controller_replica_count": 0,
+			"creator_id": 0,
+			"default_flavor_id": 0,
+			"default_image_id": 0,
+			"default_isolation": "",
+			"default_node_id": 0,
+			"description": "",
+			"enabled": false,
+			"exposed_ports": "",
+			"id": 2,
+			"max_instances": 0,
+			"mount_data_sets": "",
+			"name": "mockslice2",
+			"network": "",
+			"principal_id": 0,
+			"service_id": 0,
+			"site_id": 1,
+			"trust_domain_id": 0
+		}
+	]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.List.Args.ModelName = "Slice"
+	options.List.OutputAs = "json"
+	options.List.Filter = "name=mockslice2"
+	err := options.List.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelListDirty(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"controller_kind": "",
+			"controller_replica_count": 0,
+			"creator_id": 0,
+			"default_flavor_id": 0,
+			"default_image_id": 0,
+			"default_isolation": "",
+			"default_node_id": 0,
+			"description": "",
+			"enabled": false,
+			"exposed_ports": "",
+			"id": 2,
+			"max_instances": 0,
+			"mount_data_sets": "",
+			"name": "mockslice2",
+			"network": "",
+			"principal_id": 0,
+			"service_id": 0,
+			"site_id": 1,
+			"trust_domain_id": 0
+		}
+	]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.List.Args.ModelName = "Slice"
+	options.List.OutputAs = "json"
+	options.List.State = "dirty"
+	err := options.List.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelUpdate(t *testing.T) {
+	expected := `[{"id":1, "message":"Updated"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Update.Args.ModelName = "Slice"
+	options.Update.OutputAs = "json"
+	options.Update.IDArgs.ID = []int32{1}
+	options.Update.SetFields = "name=mockslice1_newname"
+	err := options.Update.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelUpdateUsingFilter(t *testing.T) {
+	expected := `[{"id":1, "message":"Updated"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Update.Args.ModelName = "Slice"
+	options.Update.OutputAs = "json"
+	options.Update.Filter = "id=1"
+	options.Update.SetFields = "name=mockslice1_newname"
+	err := options.Update.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelUpdateNoExist(t *testing.T) {
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Update.Args.ModelName = "Slice"
+	options.Update.OutputAs = "json"
+	options.Update.IDArgs.ID = []int32{77}
+	options.Update.SetFields = "name=mockslice1_newname"
+	err := options.Update.Execute([]string{})
+
+	_, matched := err.(*corderrors.ModelNotFoundError)
+	assert.True(t, matched)
+}
+
+func TestModelUpdateUsingFilterNoExist(t *testing.T) {
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Update.Args.ModelName = "Slice"
+	options.Update.OutputAs = "json"
+	options.Update.Filter = "id=77"
+	options.Update.SetFields = "name=mockslice1_newname"
+	err := options.Update.Execute([]string{})
+
+	_, matched := err.(*corderrors.NoMatchError)
+	assert.True(t, matched)
+}
+
+func TestModelCreate(t *testing.T) {
+	expected := `[{"id":3, "message":"Created"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Create.Args.ModelName = "Slice"
+	options.Create.OutputAs = "json"
+	options.Create.SetFields = "name=mockslice3,site_id=1"
+	err := options.Create.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelDelete(t *testing.T) {
+	expected := `[{"id":1, "message":"Deleted"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Delete.Args.ModelName = "Slice"
+	options.Delete.OutputAs = "json"
+	options.Delete.IDArgs.ID = []int32{1}
+	err := options.Delete.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelDeleteUsingFilter(t *testing.T) {
+	expected := `[{"id":1, "message":"Deleted"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Delete.Args.ModelName = "Slice"
+	options.Delete.OutputAs = "json"
+	options.Delete.Filter = "id=1"
+	err := options.Delete.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelDeleteNoExist(t *testing.T) {
+	expected := `[{"id":77, "message":"Not Found [on model Slice <id=77>]"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Delete.Args.ModelName = "Slice"
+	options.Delete.OutputAs = "json"
+	options.Delete.IDArgs.ID = []int32{77}
+	err := options.Delete.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelDeleteFilterNoExist(t *testing.T) {
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Delete.Args.ModelName = "Slice"
+	options.Delete.OutputAs = "json"
+	options.Delete.Filter = "id=77"
+	err := options.Delete.Execute([]string{})
+
+	_, matched := err.(*corderrors.NoMatchError)
+	assert.True(t, matched)
+}
+
+func TestModelSync(t *testing.T) {
+	expected := `[{"id":1, "message":"Enacted"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Sync.Args.ModelName = "Slice"
+	options.Sync.OutputAs = "json"
+	options.Sync.IDArgs.ID = []int32{1}
+	options.Sync.SyncTimeout = 5 * time.Second
+	err := options.Sync.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelSyncTimeout(t *testing.T) {
+	expected := `[{"id":2, "message":"context deadline exceeded"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.Sync.Args.ModelName = "Slice"
+	options.Sync.OutputAs = "json"
+	options.Sync.IDArgs.ID = []int32{2}
+	options.Sync.SyncTimeout = 5 * time.Second
+	err := options.Sync.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestModelSetDirty(t *testing.T) {
+	expected := `[{"id":1, "message":"Dirtied"}]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelOpts
+	options.SetDirty.Args.ModelName = "Slice"
+	options.SetDirty.OutputAs = "json"
+	options.SetDirty.IDArgs.ID = []int32{1}
+	err := options.SetDirty.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
diff --git a/internal/pkg/commands/modeltypes.go b/internal/pkg/commands/modeltypes.go
new file mode 100644
index 0000000..e24a57a
--- /dev/null
+++ b/internal/pkg/commands/modeltypes.go
@@ -0,0 +1,69 @@
+/*
+ * 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 (
+	flags "github.com/jessevdk/go-flags"
+	"sort"
+)
+
+const (
+	DEFAULT_MODELTYPE_LIST_FORMAT = "{{ . }}"
+)
+
+type ModelTypeList struct {
+	OutputOptions
+}
+
+type ModelTypeOpts struct {
+	List ModelTypeList `command:"list"`
+}
+
+var modelTypeOpts = ModelTypeOpts{}
+
+func RegisterModelTypeCommands(parser *flags.Parser) {
+	parser.AddCommand("modeltype", "model type commands", "Commands to query the types of models", &modelTypeOpts)
+}
+
+func (options *ModelTypeList) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+
+	defer conn.Close()
+
+	models, err := GetModelNames(descriptor)
+	if err != nil {
+		return err
+	}
+
+	model_names := []string{}
+	for k := range models {
+		model_names = append(model_names, k)
+	}
+
+	sort.Strings(model_names)
+
+	FormatAndGenerateOutput(
+		&options.OutputOptions,
+		DEFAULT_MODELTYPE_LIST_FORMAT,
+		DEFAULT_MODELTYPE_LIST_FORMAT,
+		model_names)
+
+	return nil
+}
diff --git a/internal/pkg/commands/modeltypes_test.go b/internal/pkg/commands/modeltypes_test.go
new file mode 100644
index 0000000..e18c2db
--- /dev/null
+++ b/internal/pkg/commands/modeltypes_test.go
@@ -0,0 +1,111 @@
+/*
+ * 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/pkg/testutils"
+	"testing"
+)
+
+func TestModelTypeList(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `ANIPort
+AddressPool
+AttWorkflowDriverService
+AttWorkflowDriverServiceInstance
+AttWorkflowDriverWhiteListEntry
+BNGPortMapping
+BackupFile
+BackupOperation
+BandwidthProfile
+ComputeServiceInstance
+FabricCrossconnectService
+FabricCrossconnectServiceInstance
+FabricIpAddress
+FabricService
+Flavor
+Image
+InterfaceType
+KubernetesConfigMap
+KubernetesConfigVolumeMount
+KubernetesData
+KubernetesResourceInstance
+KubernetesSecret
+KubernetesSecretVolumeMount
+KubernetesService
+KubernetesServiceInstance
+NNIPort
+Network
+NetworkParameter
+NetworkParameterType
+NetworkSlice
+NetworkTemplate
+Node
+NodeLabel
+NodeToSwitchPort
+OLTDevice
+ONOSApp
+ONOSService
+ONUDevice
+PONPort
+Port
+PortBase
+PortInterface
+Principal
+Privilege
+RCORDIpAddress
+RCORDService
+RCORDSubscriber
+Role
+Service
+ServiceAttribute
+ServiceDependency
+ServiceGraphConstraint
+ServiceInstance
+ServiceInstanceAttribute
+ServiceInstanceLink
+ServiceInterface
+ServicePort
+Site
+Slice
+Switch
+SwitchPort
+Tag
+TechnologyProfile
+TrustDomain
+UNIPort
+User
+VOLTService
+VOLTServiceInstance
+XOSCore
+XOSGuiExtension
+`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ModelTypeOpts
+	err := options.List.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertStringEqual(t, got.String(), expected)
+}
diff --git a/internal/pkg/commands/orm.go b/internal/pkg/commands/orm.go
new file mode 100644
index 0000000..0ac846a
--- /dev/null
+++ b/internal/pkg/commands/orm.go
@@ -0,0 +1,658 @@
+/*
+ * 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"
+	"fmt"
+	"github.com/fullstorydev/grpcurl"
+	"github.com/golang/protobuf/proto"
+	"github.com/golang/protobuf/protoc-gen-go/descriptor"
+	"github.com/jhump/protoreflect/desc"
+	"github.com/jhump/protoreflect/dynamic"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+	"google.golang.org/grpc"
+	"io"
+	"strconv"
+	"strings"
+	"time"
+)
+
+// Flags for calling the *WithRetry methods
+const (
+	GM_QUIET         = 1
+	GM_UNTIL_FOUND   = 2
+	GM_UNTIL_ENACTED = 4
+	GM_UNTIL_STATUS  = 8
+)
+
+// Valid choices for FilterModels `Kind` argument
+const (
+	FILTER_DEFAULT    = "DEFAULT"
+	FILTER_ALL        = "ALL"
+	FILTER_DIRTY      = "SYNCHRONIZER_DIRTY_OBJECTS"
+	FILTER_DELETED    = "SYNCHRONIZER_DELETED_OBJECTS"
+	FILTER_DIRTYPOL   = "SYNCHRONIZER_DIRTY_POLICIES"
+	FILTER_DELETEDPOL = "SYNCHRONIZER_DELETED_POLICIES"
+)
+
+type QueryEventHandler struct {
+	RpcEventHandler
+	Elements map[string]string
+	Model    *desc.MessageDescriptor
+	Kind     string
+	EOF      bool
+}
+
+// Separate the operator from the query value.
+// For example,
+//    "==foo"  --> "EQUAL", "foo"
+func DecodeOperator(query string) (string, string, bool, error) {
+	if strings.HasPrefix(query, "!=") {
+		return strings.TrimSpace(query[2:]), "EQUAL", true, nil
+	} else if strings.HasPrefix(query, "==") {
+		return "", "", false, corderrors.NewInvalidInputError("Operator == is now allowed. Suggest using = instead.")
+	} else if strings.HasPrefix(query, "=") {
+		return strings.TrimSpace(query[1:]), "EQUAL", false, nil
+	} else if strings.HasPrefix(query, ">=") {
+		return strings.TrimSpace(query[2:]), "GREATER_THAN_OR_EQUAL", false, nil
+	} else if strings.HasPrefix(query, ">") {
+		return strings.TrimSpace(query[1:]), "GREATER_THAN", false, nil
+	} else if strings.HasPrefix(query, "<=") {
+		return strings.TrimSpace(query[2:]), "LESS_THAN_OR_EQUAL", false, nil
+	} else if strings.HasPrefix(query, "<") {
+		return strings.TrimSpace(query[1:]), "LESS_THAN", false, nil
+	} else {
+		return strings.TrimSpace(query), "EQUAL", false, nil
+	}
+}
+
+// Generate the parameters for Query messages.
+func (h *QueryEventHandler) GetParams(msg proto.Message) error {
+	dmsg, err := dynamic.AsDynamicMessage(msg)
+	if err != nil {
+		return err
+	}
+
+	//fmt.Printf("MessageName: %s\n", dmsg.XXX_MessageName())
+
+	if h.EOF {
+		return io.EOF
+	}
+
+	// Get the MessageType for the `elements` field
+	md := dmsg.GetMessageDescriptor()
+	elements_fld := md.FindFieldByName("elements")
+	elements_mt := elements_fld.GetMessageType()
+
+	for field_name, element := range h.Elements {
+		value, operator, invert, err := DecodeOperator(element)
+		if err != nil {
+			return err
+		}
+
+		nm := dynamic.NewMessage(elements_mt)
+
+		field_descriptor := h.Model.FindFieldByName(field_name)
+		if field_descriptor == nil {
+			return corderrors.WithStackTrace(&corderrors.FieldDoesNotExistError{ModelName: h.Model.GetName(), FieldName: field_name})
+		}
+
+		field_type := field_descriptor.GetType()
+		switch field_type {
+		case descriptor.FieldDescriptorProto_TYPE_INT32:
+			var i int64
+			i, err = strconv.ParseInt(value, 10, 32)
+			nm.SetFieldByName("iValue", int32(i))
+		case descriptor.FieldDescriptorProto_TYPE_UINT32:
+			var i int64
+			i, err = strconv.ParseInt(value, 10, 32)
+			nm.SetFieldByName("iValue", uint32(i))
+		case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+			err = corderrors.NewInvalidInputError("Floating point filters are unsupported")
+		case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+			err = corderrors.NewInvalidInputError("Floating point filters are unsupported")
+		default:
+			nm.SetFieldByName("sValue", value)
+			err = nil
+		}
+
+		if err != nil {
+			return err
+		}
+
+		nm.SetFieldByName("name", field_name)
+		nm.SetFieldByName("invert", invert)
+		SetEnumValue(nm, "operator", operator)
+		dmsg.AddRepeatedFieldByName("elements", nm)
+	}
+
+	SetEnumValue(dmsg, "kind", h.Kind)
+
+	h.EOF = true
+
+	return nil
+}
+
+// Take a string list of queries and turns it into a map of queries
+func QueryStringsToMap(query_args []string, allow_inequality bool) (map[string]string, error) {
+	queries := make(map[string]string)
+	for _, query_str := range query_args {
+		query_str := strings.TrimSpace(query_str)
+		operator_pos := -1
+		for i, ch := range query_str {
+			if allow_inequality {
+				if (ch == '!') || (ch == '=') || (ch == '>') || (ch == '<') {
+					operator_pos = i
+					break
+				}
+			} else {
+				if ch == '=' {
+					operator_pos = i
+					break
+				}
+			}
+		}
+		if operator_pos == -1 {
+			return nil, corderrors.WithStackTrace(&corderrors.IllegalQueryError{Query: query_str})
+		}
+		queries[strings.TrimSpace(query_str[:operator_pos])] = query_str[operator_pos:]
+	}
+	return queries, nil
+}
+
+// Take a string of comma-separated queries and turn it into a map of queries
+func CommaSeparatedQueryToMap(query_str string, allow_inequality bool) (map[string]string, error) {
+	if query_str == "" {
+		return nil, nil
+	}
+
+	query_strings := strings.Split(query_str, ",")
+	return QueryStringsToMap(query_strings, allow_inequality)
+}
+
+// Convert a string into the appropriate gRPC type for a given field
+func TypeConvert(source grpcurl.DescriptorSource, modelName string, field_name string, v string) (interface{}, error) {
+	model_descriptor, err := source.FindSymbol("xos." + modelName)
+	if err != nil {
+		return nil, err
+	}
+	model_md, ok := model_descriptor.(*desc.MessageDescriptor)
+	if !ok {
+		return nil, corderrors.WithStackTrace(&corderrors.TypeConversionError{Source: modelName, Destination: "messageDescriptor"})
+	}
+	field_descriptor := model_md.FindFieldByName(field_name)
+	if field_descriptor == nil {
+		return nil, corderrors.WithStackTrace(&corderrors.FieldDoesNotExistError{ModelName: modelName, FieldName: field_name})
+	}
+	field_type := field_descriptor.GetType()
+
+	var result interface{}
+
+	switch field_type {
+	case descriptor.FieldDescriptorProto_TYPE_INT32:
+		var i int64
+		i, err = strconv.ParseInt(v, 10, 32)
+		result = int32(i)
+	case descriptor.FieldDescriptorProto_TYPE_UINT32:
+		var i int64
+		i, err = strconv.ParseInt(v, 10, 32)
+		result = uint32(i)
+	case descriptor.FieldDescriptorProto_TYPE_FLOAT:
+		var f float64
+		f, err = strconv.ParseFloat(v, 32)
+		result = float32(f)
+	case descriptor.FieldDescriptorProto_TYPE_DOUBLE:
+		var f float64
+		f, err = strconv.ParseFloat(v, 64)
+		result = f
+	default:
+		result = v
+		err = nil
+	}
+
+	return result, err
+}
+
+// Return a list of all available model names
+func GetModelNames(source grpcurl.DescriptorSource) (map[string]bool, error) {
+	models := make(map[string]bool)
+	methods, err := grpcurl.ListMethods(source, "xos.xos")
+
+	if err != nil {
+		return nil, err
+	}
+
+	for _, method := range methods {
+		if strings.HasPrefix(method, "xos.xos.Get") {
+			models[method[11:]] = true
+		}
+	}
+
+	return models, nil
+}
+
+// Check to see if a model name is valid
+func CheckModelName(source grpcurl.DescriptorSource, name string) error {
+	models, err := GetModelNames(source)
+	if err != nil {
+		return err
+	}
+	_, present := models[name]
+	if !present {
+		return corderrors.WithStackTrace(&corderrors.UnknownModelTypeError{Name: name})
+	}
+	return nil
+}
+
+// Create a model in XOS given a map of fields
+func CreateModel(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, fields map[string]interface{}) error {
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	h := &RpcEventHandler{
+		Fields: map[string]map[string]interface{}{"xos." + modelName: fields},
+	}
+	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.Create"+modelName, headers, h, h.GetParams)
+	if err != nil {
+		return corderrors.RpcErrorWithModelNameToCordError(err, modelName)
+	} else if h.Status != nil && h.Status.Err() != nil {
+		return corderrors.RpcErrorWithModelNameToCordError(h.Status.Err(), modelName)
+	}
+
+	resp, err := dynamic.AsDynamicMessage(h.Response)
+	if err != nil {
+		return err
+	}
+
+	fields["id"] = resp.GetFieldByName("id").(int32)
+
+	if resp.HasFieldName("uuid") {
+		fields["uuid"] = resp.GetFieldByName("uuid").(string)
+	}
+
+	return nil
+}
+
+// Update a model in XOS given a map of fields
+func UpdateModel(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, fields map[string]interface{}) error {
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	h := &RpcEventHandler{
+		Fields: map[string]map[string]interface{}{"xos." + modelName: fields},
+	}
+	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.Update"+modelName, headers, h, h.GetParams)
+	if err != nil {
+		return corderrors.RpcErrorWithModelNameToCordError(err, modelName)
+	} else if h.Status != nil && h.Status.Err() != nil {
+		return corderrors.RpcErrorWithModelNameToCordError(h.Status.Err(), modelName)
+	}
+
+	resp, err := dynamic.AsDynamicMessage(h.Response)
+	if err != nil {
+		return err
+	}
+
+	// TODO: Do we need to do anything with the response?
+	_ = resp
+
+	return nil
+}
+
+// Get a model from XOS given its ID
+func GetModel(ctx context.Context, conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, id int32) (*dynamic.Message, error) {
+	ctx, cancel := context.WithTimeout(ctx, GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	h := &RpcEventHandler{
+		Fields: map[string]map[string]interface{}{"xos.ID": map[string]interface{}{"id": id}},
+	}
+	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.Get"+modelName, headers, h, h.GetParams)
+	if err != nil {
+		return nil, corderrors.RpcErrorWithIdToCordError(err, modelName, id)
+	}
+
+	if h.Status != nil && h.Status.Err() != nil {
+		return nil, corderrors.RpcErrorWithIdToCordError(h.Status.Err(), modelName, id) //h.Status.Err()
+	}
+
+	d, err := dynamic.AsDynamicMessage(h.Response)
+	if err != nil {
+		return nil, err
+	}
+
+	return d, nil
+}
+
+// Get a model, but retry under a variety of circumstances
+func GetModelWithRetry(ctx context.Context, conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, id int32, flags uint32) (*grpc.ClientConn, *dynamic.Message, error) {
+	quiet := (flags & GM_QUIET) != 0
+	until_found := (flags & GM_UNTIL_FOUND) != 0
+	until_enacted := (flags & GM_UNTIL_ENACTED) != 0
+	until_status := (flags & GM_UNTIL_STATUS) != 0
+
+	for {
+		var err error
+
+		if conn == nil {
+			conn, err = NewConnection()
+			if err != nil {
+				return nil, nil, err
+			}
+		}
+
+		model, err := GetModel(ctx, conn, descriptor, modelName, id)
+		if err != nil {
+			if strings.Contains(err.Error(), "rpc error: code = Unavailable") ||
+				strings.Contains(err.Error(), "rpc error: code = Internal desc = stream terminated by RST_STREAM") {
+				if !quiet {
+					fmt.Print(".")
+				}
+				select {
+				case <-time.After(100 * time.Millisecond):
+				case <-ctx.Done():
+					return nil, nil, ctx.Err()
+				}
+				conn.Close()
+				conn = nil
+				continue
+			}
+
+			_, is_not_found_error := err.(*corderrors.ModelNotFoundError)
+			if until_found && is_not_found_error {
+				if !quiet {
+					fmt.Print("x")
+				}
+				select {
+				case <-time.After(100 * time.Millisecond):
+				case <-ctx.Done():
+					return nil, nil, ctx.Err()
+				}
+				continue
+			}
+			return nil, nil, err
+		}
+
+		if until_enacted && !IsEnacted(model) {
+			if !quiet {
+				fmt.Print("o")
+			}
+			select {
+			case <-time.After(100 * time.Millisecond):
+			case <-ctx.Done():
+				return nil, nil, ctx.Err()
+			}
+			continue
+		}
+
+		if until_status && model.GetFieldByName("status") == nil {
+			if !quiet {
+				fmt.Print("O")
+			}
+			select {
+			case <-time.After(100 * time.Millisecond):
+			case <-ctx.Done():
+				return nil, nil, ctx.Err()
+			}
+			continue
+		}
+
+		return conn, model, nil
+	}
+}
+
+func ItemsToDynamicMessageList(items interface{}) []*dynamic.Message {
+	result := make([]*dynamic.Message, len(items.([]interface{})))
+	for i, item := range items.([]interface{}) {
+		result[i] = item.(*dynamic.Message)
+	}
+	return result
+}
+
+// List all objects of a given model
+func ListModels(ctx context.Context, conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string) ([]*dynamic.Message, error) {
+	ctx, cancel := context.WithTimeout(ctx, GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	h := &RpcEventHandler{}
+	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.List"+modelName, headers, h, h.GetParams)
+	if err != nil {
+		return nil, corderrors.RpcErrorWithModelNameToCordError(err, modelName)
+	}
+
+	if h.Status != nil && h.Status.Err() != nil {
+		return nil, corderrors.RpcErrorWithModelNameToCordError(h.Status.Err(), modelName)
+	}
+
+	d, err := dynamic.AsDynamicMessage(h.Response)
+	if err != nil {
+		return nil, err
+	}
+
+	items, err := d.TryGetFieldByName("items")
+	if err != nil {
+		return nil, err
+	}
+
+	return ItemsToDynamicMessageList(items), nil
+}
+
+// Filter models based on field values
+//   queries is a map of <field_name> to <operator><query>
+//   For example,
+//     map[string]string{"name": "==mysite"}
+func FilterModels(ctx context.Context, conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, kind string, queries map[string]string) ([]*dynamic.Message, error) {
+	ctx, cancel := context.WithTimeout(ctx, GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	model_descriptor, err := descriptor.FindSymbol("xos." + modelName)
+	if err != nil {
+		return nil, err
+	}
+	model_md, ok := model_descriptor.(*desc.MessageDescriptor)
+	if !ok {
+		return nil, corderrors.WithStackTrace(&corderrors.TypeConversionError{Source: modelName, Destination: "messageDescriptor"})
+	}
+
+	h := &QueryEventHandler{
+		RpcEventHandler: RpcEventHandler{
+			Fields: map[string]map[string]interface{}{"xos.Query": map[string]interface{}{"kind": 0}},
+		},
+		Elements: queries,
+		Model:    model_md,
+		Kind:     kind,
+	}
+	err = grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.Filter"+modelName, headers, h, h.GetParams)
+	if err != nil {
+		return nil, corderrors.RpcErrorWithQueriesToCordError(err, modelName, queries)
+	}
+
+	if h.Status != nil && h.Status.Err() != nil {
+		return nil, corderrors.RpcErrorWithQueriesToCordError(h.Status.Err(), modelName, queries)
+	}
+
+	d, err := dynamic.AsDynamicMessage(h.Response)
+	if err != nil {
+		return nil, err
+	}
+
+	items, err := d.TryGetFieldByName("items")
+	if err != nil {
+		return nil, err
+	}
+
+	return ItemsToDynamicMessageList(items), nil
+}
+
+// Call ListModels or FilterModels as appropriate
+func ListOrFilterModels(ctx context.Context, conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, kind string, queries map[string]string) ([]*dynamic.Message, error) {
+	if (len(queries) == 0) && (kind == FILTER_DEFAULT) {
+		return ListModels(ctx, conn, descriptor, modelName)
+	} else {
+		return FilterModels(ctx, conn, descriptor, modelName, kind, queries)
+	}
+}
+
+// Get a model from XOS given a fieldName/fieldValue
+func FindModel(ctx context.Context, conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, queries map[string]string) (*dynamic.Message, error) {
+	models, err := FilterModels(ctx, conn, descriptor, modelName, FILTER_DEFAULT, queries)
+	if err != nil {
+		return nil, err
+	}
+
+	if len(models) == 0 {
+		cordError := &corderrors.ModelNotFoundError{}
+		cordError.Obj = corderrors.ObjectReference{ModelName: modelName, Queries: queries}
+		return nil, corderrors.WithStackTrace(cordError)
+	}
+
+	return models[0], nil
+}
+
+// Find a model, but retry under a variety of circumstances
+func FindModelWithRetry(ctx context.Context, conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, queries map[string]string, flags uint32) (*grpc.ClientConn, *dynamic.Message, error) {
+	quiet := (flags & GM_QUIET) != 0
+	until_found := (flags & GM_UNTIL_FOUND) != 0
+	until_enacted := (flags & GM_UNTIL_ENACTED) != 0
+	until_status := (flags & GM_UNTIL_STATUS) != 0
+
+	for {
+		var err error
+
+		if conn == nil {
+			conn, err = NewConnection()
+			if err != nil {
+				return nil, nil, err
+			}
+		}
+
+		model, err := FindModel(ctx, conn, descriptor, modelName, queries)
+		if err != nil {
+			if strings.Contains(err.Error(), "rpc error: code = Unavailable") ||
+				strings.Contains(err.Error(), "rpc error: code = Internal desc = stream terminated by RST_STREAM") {
+				if !quiet {
+					fmt.Print(".")
+				}
+				select {
+				case <-time.After(100 * time.Millisecond):
+				case <-ctx.Done():
+					return nil, nil, ctx.Err()
+				}
+				conn.Close()
+				conn = nil
+				continue
+			}
+
+			_, is_not_found_error := err.(*corderrors.ModelNotFoundError)
+			if until_found && is_not_found_error {
+				if !quiet {
+					fmt.Print("x")
+				}
+				select {
+				case <-time.After(100 * time.Millisecond):
+				case <-ctx.Done():
+					return nil, nil, ctx.Err()
+				}
+				continue
+			}
+			return nil, nil, err
+		}
+
+		if until_enacted && !IsEnacted(model) {
+			if !quiet {
+				fmt.Print("o")
+			}
+			select {
+			case <-time.After(100 * time.Millisecond):
+			case <-ctx.Done():
+				return nil, nil, ctx.Err()
+			}
+			continue
+		}
+
+		if until_status && model.GetFieldByName("status") == nil {
+			if !quiet {
+				fmt.Print("O")
+			}
+			select {
+			case <-time.After(100 * time.Millisecond):
+			case <-ctx.Done():
+				return nil, nil, ctx.Err()
+			}
+			continue
+		}
+
+		return conn, model, nil
+	}
+}
+
+// Get a model from XOS given its ID
+func DeleteModel(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, modelName string, id int32) error {
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	h := &RpcEventHandler{
+		Fields: map[string]map[string]interface{}{"xos.ID": map[string]interface{}{"id": id}},
+	}
+	err := grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.xos.Delete"+modelName, headers, h, h.GetParams)
+	if err != nil {
+		return corderrors.RpcErrorWithIdToCordError(err, modelName, id)
+	}
+
+	if h.Status != nil && h.Status.Err() != nil {
+		return corderrors.RpcErrorWithIdToCordError(h.Status.Err(), modelName, id)
+	}
+
+	_, err = dynamic.AsDynamicMessage(h.Response)
+	if err != nil {
+		return err
+	}
+
+	return nil
+}
+
+// Takes a *dynamic.Message and turns it into a map of fields to interfaces
+//    TODO: Might be more useful to convert the values to strings and ints
+func MessageToMap(d *dynamic.Message) map[string]interface{} {
+	fields := make(map[string]interface{})
+	for _, field_desc := range d.GetKnownFields() {
+		field_name := field_desc.GetName()
+		fields[field_name] = d.GetFieldByName(field_name)
+	}
+	return fields
+}
+
+// Returns True if a message has been enacted
+func IsEnacted(d *dynamic.Message) bool {
+	enacted := d.GetFieldByName("enacted").(float64)
+	updated := d.GetFieldByName("updated").(float64)
+
+	return (enacted >= updated)
+}
diff --git a/internal/pkg/commands/orm_test.go b/internal/pkg/commands/orm_test.go
new file mode 100644
index 0000000..2d8db62
--- /dev/null
+++ b/internal/pkg/commands/orm_test.go
@@ -0,0 +1,243 @@
+/*
+ * 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"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+	"github.com/stretchr/testify/assert"
+	"testing"
+)
+
+func TestDecodeOperator(t *testing.T) {
+	value, operator, invert, err := DecodeOperator("=something")
+	assert.Equal(t, value, "something")
+	assert.Equal(t, operator, "EQUAL")
+	assert.Equal(t, invert, false)
+	assert.Equal(t, err, nil)
+
+	value, operator, invert, err = DecodeOperator("!=something")
+	assert.Equal(t, value, "something")
+	assert.Equal(t, operator, "EQUAL")
+	assert.Equal(t, invert, true)
+	assert.Equal(t, err, nil)
+
+	value, operator, invert, err = DecodeOperator(">3")
+	assert.Equal(t, value, "3")
+	assert.Equal(t, operator, "GREATER_THAN")
+	assert.Equal(t, invert, false)
+	assert.Equal(t, err, nil)
+
+	value, operator, invert, err = DecodeOperator(">=3")
+	assert.Equal(t, value, "3")
+	assert.Equal(t, operator, "GREATER_THAN_OR_EQUAL")
+	assert.Equal(t, invert, false)
+	assert.Equal(t, err, nil)
+
+	value, operator, invert, err = DecodeOperator("<3")
+	assert.Equal(t, value, "3")
+	assert.Equal(t, operator, "LESS_THAN")
+	assert.Equal(t, invert, false)
+	assert.Equal(t, err, nil)
+
+	value, operator, invert, err = DecodeOperator("<=3")
+	assert.Equal(t, value, "3")
+	assert.Equal(t, operator, "LESS_THAN_OR_EQUAL")
+	assert.Equal(t, invert, false)
+	assert.Equal(t, err, nil)
+}
+
+func TestCommaSeparatedQueryToMap(t *testing.T) {
+	m, err := CommaSeparatedQueryToMap("foo=7,bar!=stuff, x = 5, y= 27", true)
+	assert.Equal(t, err, nil)
+	assert.Equal(t, m["foo"], "=7")
+	assert.Equal(t, m["bar"], "!=stuff")
+	assert.Equal(t, m["x"], "= 5")
+	assert.Equal(t, m["y"], "= 27")
+}
+
+func TestCommaSeparatedQueryToMapIllegal(t *testing.T) {
+	// Query string missing operator
+	_, err := CommaSeparatedQueryToMap("foo", true)
+
+	_, matched := err.(*corderrors.IllegalQueryError)
+	assert.True(t, matched)
+
+	// Query string is contains an empty element
+	_, err = CommaSeparatedQueryToMap(",foo=bar", true)
+
+	_, matched = err.(*corderrors.IllegalQueryError)
+	assert.True(t, matched)
+}
+
+func TestCommaSeparatedQueryToMapEmpty(t *testing.T) {
+	// Query string missing operator
+	m, err := CommaSeparatedQueryToMap("", true)
+
+	assert.Equal(t, err, nil)
+	assert.Equal(t, len(m), 0)
+}
+
+func TestTypeConvert(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	v, err := TypeConvert(descriptor, "Site", "id", "7")
+	assert.Equal(t, err, nil)
+	assert.Equal(t, v, int32(7))
+
+	v, err = TypeConvert(descriptor, "Site", "name", "foo")
+	assert.Equal(t, err, nil)
+	assert.Equal(t, v, "foo")
+
+	v, err = TypeConvert(descriptor, "Site", "enacted", "123.4")
+	assert.Equal(t, err, nil)
+	assert.Equal(t, v, 123.4)
+}
+
+func TestCheckModelName(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	err = CheckModelName(descriptor, "Slice")
+	assert.Equal(t, err, nil)
+
+	err = CheckModelName(descriptor, "DoesNotExist")
+	_, matched := err.(*corderrors.UnknownModelTypeError)
+	assert.True(t, matched)
+}
+
+func TestCreateModel(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	m := make(map[string]interface{})
+	m["name"] = "mockslice3"
+	m["site_id"] = int32(1)
+
+	err = CreateModel(conn, descriptor, "Slice", m)
+	assert.Equal(t, err, nil)
+
+	assert.Equal(t, m["id"], int32(3))
+}
+
+func TestUpdateModel(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	m := make(map[string]interface{})
+	m["id"] = int32(1)
+	m["name"] = "mockslice1_newname"
+
+	err = UpdateModel(conn, descriptor, "Slice", m)
+	assert.Equal(t, err, nil)
+}
+
+func TestGetModel(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	m, err := GetModel(context.Background(), conn, descriptor, "Slice", int32(1))
+	assert.Equal(t, err, nil)
+
+	assert.Equal(t, m.GetFieldByName("id").(int32), int32(1))
+	assert.Equal(t, m.GetFieldByName("name").(string), "mockslice1")
+}
+
+func TestGetModelNoExist(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	_, err = GetModel(context.Background(), conn, descriptor, "Slice", int32(77))
+	assert.NotEqual(t, err, nil)
+
+	_, matched := err.(*corderrors.ModelNotFoundError)
+	assert.True(t, matched)
+}
+
+func TestListModels(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	m, err := ListModels(context.Background(), conn, descriptor, "Slice")
+	assert.Equal(t, err, nil)
+
+	assert.Equal(t, len(m), 2)
+	assert.Equal(t, m[0].GetFieldByName("id").(int32), int32(1))
+	assert.Equal(t, m[0].GetFieldByName("name").(string), "mockslice1")
+	assert.Equal(t, m[1].GetFieldByName("id").(int32), int32(2))
+	assert.Equal(t, m[1].GetFieldByName("name").(string), "mockslice2")
+}
+
+func TestFilterModels(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	qm := map[string]string{"id": "=1"}
+
+	m, err := FilterModels(context.Background(), conn, descriptor, "Slice", FILTER_DEFAULT, qm)
+	assert.Equal(t, err, nil)
+
+	assert.Equal(t, len(m), 1)
+	assert.Equal(t, m[0].GetFieldByName("id").(int32), int32(1))
+	assert.Equal(t, m[0].GetFieldByName("name").(string), "mockslice1")
+}
+
+func TestFindModel(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	qm := map[string]string{"id": "=1"}
+
+	m, err := FindModel(context.Background(), conn, descriptor, "Slice", qm)
+	assert.Equal(t, err, nil)
+
+	assert.Equal(t, m.GetFieldByName("id").(int32), int32(1))
+	assert.Equal(t, m.GetFieldByName("name").(string), "mockslice1")
+}
+
+func TestFindModelNoExist(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	qm := map[string]string{"id": "=77"}
+
+	_, err = FindModel(context.Background(), conn, descriptor, "Slice", qm)
+	assert.NotEqual(t, err, nil)
+
+	_, matched := err.(*corderrors.ModelNotFoundError)
+	assert.True(t, matched)
+}
+
+func TestDeleteModel(t *testing.T) {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	assert.Equal(t, err, nil)
+	defer conn.Close()
+
+	err = DeleteModel(conn, descriptor, "Slice", int32(1))
+	assert.Equal(t, err, nil)
+}
diff --git a/internal/pkg/commands/services.go b/internal/pkg/commands/services.go
new file mode 100644
index 0000000..d199ee9
--- /dev/null
+++ b/internal/pkg/commands/services.go
@@ -0,0 +1,95 @@
+/*
+ * 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"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+)
+
+const (
+	DEFAULT_SERVICE_FORMAT = "table{{ .Name }}\t{{.Version}}\t{{.State}}"
+)
+
+type ServiceList struct {
+	ListOutputOptions
+}
+
+type ServiceListOutput struct {
+	Name    string `json:"name"`
+	Version string `json:"version"`
+	State   string `json:"state"`
+}
+
+type ServiceOpts struct {
+	List ServiceList `command:"list"`
+}
+
+var serviceOpts = ServiceOpts{}
+
+func RegisterServiceCommands(parser *flags.Parser) {
+	parser.AddCommand("service", "service commands", "Commands to query and manipulate dynamically loaded XOS Services", &serviceOpts)
+}
+
+func (options *ServiceList) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	h := &RpcEventHandler{}
+	err = grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.dynamicload.GetLoadStatus", headers, h, h.GetParams)
+	if err != nil {
+		return corderrors.RpcErrorToCordError(err)
+	}
+
+	if h.Status != nil && h.Status.Err() != nil {
+		return corderrors.RpcErrorToCordError(h.Status.Err())
+	}
+
+	d, err := dynamic.AsDynamicMessage(h.Response)
+	if err != nil {
+		return err
+	}
+
+	items, err := d.TryGetFieldByName("services")
+	if err != nil {
+		return err
+	}
+
+	data := make([]ServiceListOutput, len(items.([]interface{})))
+
+	for i, item := range items.([]interface{}) {
+		val := item.(*dynamic.Message)
+		data[i].Name = val.GetFieldByName("name").(string)
+		data[i].Version = val.GetFieldByName("version").(string)
+		data[i].State = val.GetFieldByName("state").(string)
+	}
+
+	FormatAndGenerateListOutput(&options.ListOutputOptions, DEFAULT_SERVICE_FORMAT, "{{.Name}}", data)
+
+	return nil
+}
diff --git a/internal/pkg/commands/services_test.go b/internal/pkg/commands/services_test.go
new file mode 100644
index 0000000..721b6dc
--- /dev/null
+++ b/internal/pkg/commands/services_test.go
@@ -0,0 +1,101 @@
+/*
+ * 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/pkg/testutils"
+	"testing"
+)
+
+func TestServicesList(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"name": "onos",
+			"state": "present",
+			"version": "2.1.1-dev"
+		},
+		{
+			"name": "kubernetes",
+			"state": "present",
+			"version": "1.2.1"
+		}
+	]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ServiceOpts
+	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)
+}
+
+func TestServicesListTable(t *testing.T) {
+	// We'll use the ServicesList command to be our end-to-end test for
+	// table formatted commands, as the output is relatively simple.
+	expected := `NAME          VERSION      STATE
+onos          2.1.1-dev    present
+kubernetes    1.2.1        present
+`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ServiceOpts
+	err := options.List.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertStringEqual(t, got.String(), expected)
+}
+
+func TestServicesListYaml(t *testing.T) {
+	// We'll use the ServicesList command to be our end-to-end test for
+	// yaml formatted commands, as the output is relatively simple.
+	expected := `- name: onos
+  version: 2.1.1-dev
+  state: present
+- name: kubernetes
+  version: 1.2.1
+  state: present
+`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options ServiceOpts
+	options.List.OutputAs = "yaml"
+	err := options.List.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertStringEqual(t, got.String(), expected)
+}
diff --git a/internal/pkg/commands/setup_test.go b/internal/pkg/commands/setup_test.go
new file mode 100644
index 0000000..3b1dc7b
--- /dev/null
+++ b/internal/pkg/commands/setup_test.go
@@ -0,0 +1,35 @@
+/*
+ * 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 (
+	"fmt"
+	"github.com/opencord/cordctl/pkg/testutils"
+	"os"
+	"testing"
+)
+
+// This TestMain is global to all tests in the `commands` package
+
+func TestMain(m *testing.M) {
+	err := testutils.StartMockServer("data.json")
+	if err != nil {
+		fmt.Printf("Error when initializing mock server %v", err)
+		os.Exit(-1)
+	}
+	os.Exit(m.Run())
+}
diff --git a/internal/pkg/commands/status.go b/internal/pkg/commands/status.go
new file mode 100644
index 0000000..802720a
--- /dev/null
+++ b/internal/pkg/commands/status.go
@@ -0,0 +1,91 @@
+/*
+ * 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"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+	"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 := InitClient(INIT_DEFAULT)
+	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 corderrors.RpcErrorToCordError(err)
+		}
+
+		if h.Status != nil && h.Status.Err() != nil {
+			return corderrors.RpcErrorToCordError(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/internal/pkg/commands/status_test.go b/internal/pkg/commands/status_test.go
new file mode 100644
index 0000000..a7662fb
--- /dev/null
+++ b/internal/pkg/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/pkg/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/internal/pkg/commands/transfer.go b/internal/pkg/commands/transfer.go
new file mode 100644
index 0000000..c8fa89d
--- /dev/null
+++ b/internal/pkg/commands/transfer.go
@@ -0,0 +1,143 @@
+/*
+ * 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 (
+	flags "github.com/jessevdk/go-flags"
+	corderrors "github.com/opencord/cordctl/internal/pkg/error"
+	"strings"
+)
+
+const (
+	DEFAULT_TRANSFER_FORMAT = "table{{ .Status }}\t{{ .Checksum }}\t{{ .Chunks }}\t{{ .Bytes }}"
+)
+
+type TransferOutput struct {
+	Status   string `json:"status"`
+	Checksum string `json:"checksum"`
+	Chunks   int    `json:"chunks"`
+	Bytes    int    `json:"bytes"`
+}
+
+type TransferUpload struct {
+	OutputOptions
+	ChunkSize int `short:"h" long:"chunksize" default:"65536" description:"Host and port"`
+	Args      struct {
+		LocalFileName string
+		URI           string
+	} `positional-args:"yes" required:"yes"`
+}
+
+type TransferDownload struct {
+	OutputOptions
+	Args struct {
+		URI           string
+		LocalFileName string
+	} `positional-args:"yes" required:"yes"`
+}
+
+type TransferOpts struct {
+	Upload   TransferUpload   `command:"upload"`
+	Download TransferDownload `command:"download"`
+}
+
+var transferOpts = TransferOpts{}
+
+func RegisterTransferCommands(parser *flags.Parser) {
+	parser.AddCommand("transfer", "file transfer commands", "Commands to transfer files to and from XOS", &transferOpts)
+}
+
+/* Command processors */
+
+func (options *TransferUpload) Execute(args []string) error {
+
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	local_name := options.Args.LocalFileName
+	uri := options.Args.URI
+
+	if IsFileUri(local_name) {
+		return corderrors.NewInvalidInputError("local_name argument should not be a uri")
+	}
+
+	if !IsFileUri(uri) {
+		return corderrors.NewInvalidInputError("uri argument should be a file:// uri")
+	}
+
+	h, upload_result, err := UploadFile(conn, descriptor, local_name, uri, options.ChunkSize)
+	if err != nil {
+		return err
+	}
+
+	if upload_result.GetFieldByName("checksum").(string) != h.GetChecksum() {
+		return corderrors.WithStackTrace(&corderrors.ChecksumMismatchError{
+			Expected: h.GetChecksum(),
+			Actual:   upload_result.GetFieldByName("checksum").(string)})
+	}
+
+	data := make([]TransferOutput, 1)
+	data[0].Checksum = upload_result.GetFieldByName("checksum").(string)
+	data[0].Chunks = int(upload_result.GetFieldByName("chunks_received").(int32))
+	data[0].Bytes = int(upload_result.GetFieldByName("bytes_received").(int32))
+	data[0].Status = GetEnumValue(upload_result, "status")
+
+	FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_TRANSFER_FORMAT, "{{.Status}}", data)
+
+	return nil
+}
+
+func IsFileUri(s string) bool {
+	return strings.HasPrefix(s, "file://")
+}
+
+func (options *TransferDownload) Execute(args []string) error {
+	conn, descriptor, err := InitClient(INIT_DEFAULT)
+	if err != nil {
+		return err
+	}
+	defer conn.Close()
+
+	local_name := options.Args.LocalFileName
+	uri := options.Args.URI
+
+	if IsFileUri(local_name) {
+		return corderrors.NewInvalidInputError("local_name argument should not be a uri")
+	}
+
+	if !IsFileUri(uri) {
+		return corderrors.NewInvalidInputError("uri argument should be a file:// uri")
+	}
+
+	h, err := DownloadFile(conn, descriptor, uri, local_name)
+	if err != nil {
+		return err
+	}
+
+	data := make([]TransferOutput, 1)
+	data[0].Chunks = h.chunks
+	data[0].Bytes = h.bytes
+	data[0].Status = h.status
+	data[0].Checksum = h.GetChecksum()
+
+	FormatAndGenerateOutput(&options.OutputOptions, DEFAULT_TRANSFER_FORMAT, "{{.Status}}", data)
+
+	return nil
+}
diff --git a/internal/pkg/commands/transfer_handler.go b/internal/pkg/commands/transfer_handler.go
new file mode 100644
index 0000000..cc18f1b
--- /dev/null
+++ b/internal/pkg/commands/transfer_handler.go
@@ -0,0 +1,167 @@
+/*
+ * 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"
+	"crypto/sha256"
+	"fmt"
+	"github.com/fullstorydev/grpcurl"
+	"github.com/golang/protobuf/proto"
+	"github.com/jhump/protoreflect/dynamic"
+	"google.golang.org/grpc"
+	"hash"
+	"io"
+	"os"
+)
+
+/* Handlers for streaming upload and download */
+
+type DownloadHandler struct {
+	RpcEventHandler
+	f      *os.File
+	chunks int
+	bytes  int
+	status string
+	hash   hash.Hash
+}
+
+type UploadHandler struct {
+	RpcEventHandler
+	chunksize int
+	f         *os.File
+	uri       string
+	hash      hash.Hash
+}
+
+func (h *DownloadHandler) OnReceiveResponse(m proto.Message) {
+	d, err := dynamic.AsDynamicMessage(m)
+	if err != nil {
+		h.status = "ERROR"
+		// TODO(smbaker): How to raise an exception?
+		return
+	}
+	chunk := d.GetFieldByName("chunk").(string)
+	io.WriteString(h.hash, chunk)
+	h.f.Write([]byte(chunk))
+	h.chunks += 1
+	h.bytes += len(chunk)
+}
+
+func (h *DownloadHandler) GetChecksum() string {
+	return fmt.Sprintf("sha256:%x", h.hash.Sum(nil))
+}
+
+func (h *UploadHandler) GetParams(msg proto.Message) error {
+	dmsg, err := dynamic.AsDynamicMessage(msg)
+	if err != nil {
+		return err
+	}
+
+	//fmt.Printf("streamer, MessageName: %s\n", dmsg.XXX_MessageName())
+
+	block := make([]byte, h.chunksize)
+	bytes_read, err := h.f.Read(block)
+
+	if err == io.EOF {
+		h.f.Close()
+		//fmt.Print("EOF\n")
+		return err
+	}
+
+	if err != nil {
+		//fmt.Print("ERROR!\n")
+		return err
+	}
+
+	chunk := string(block[:bytes_read])
+	io.WriteString(h.hash, chunk)
+
+	dmsg.TrySetFieldByName("uri", h.uri)
+	dmsg.TrySetFieldByName("chunk", chunk)
+
+	return nil
+}
+
+func (h *UploadHandler) GetChecksum() string {
+	return fmt.Sprintf("sha256:%x", h.hash.Sum(nil))
+}
+
+func UploadFile(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, local_name string, uri string, chunkSize int) (*UploadHandler, *dynamic.Message, error) {
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	f, err := os.Open(local_name)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	h := &UploadHandler{uri: uri,
+		f:         f,
+		chunksize: chunkSize,
+		hash:      sha256.New()}
+
+	err = grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.filetransfer/Upload", headers, h, h.GetParams)
+	if err != nil {
+		return nil, nil, err
+	}
+	if h.Status.Err() != nil {
+		return nil, nil, h.Status.Err()
+	}
+	d, err := dynamic.AsDynamicMessage(h.Response)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	return h, d, err
+}
+
+func DownloadFile(conn *grpc.ClientConn, descriptor grpcurl.DescriptorSource, uri string, local_name string) (*DownloadHandler, error) {
+	ctx, cancel := context.WithTimeout(context.Background(), GlobalConfig.Grpc.Timeout)
+	defer cancel()
+
+	headers := GenerateHeaders()
+
+	f, err := os.Create(local_name)
+	if err != nil {
+		return nil, err
+	}
+
+	dm := make(map[string]interface{})
+	dm["uri"] = uri
+
+	h := &DownloadHandler{
+		RpcEventHandler: RpcEventHandler{
+			Fields: map[string]map[string]interface{}{"xos.FileRequest": dm},
+		},
+		f:      f,
+		hash:   sha256.New(),
+		status: "SUCCESS"}
+
+	err = grpcurl.InvokeRPC(ctx, descriptor, conn, "xos.filetransfer/Download", headers, h, h.GetParams)
+	if err != nil {
+		return nil, err
+	}
+
+	if h.Status.Err() != nil {
+		return nil, h.Status.Err()
+	}
+
+	return h, err
+}
diff --git a/internal/pkg/commands/transfer_test.go b/internal/pkg/commands/transfer_test.go
new file mode 100644
index 0000000..b6a4dd2
--- /dev/null
+++ b/internal/pkg/commands/transfer_test.go
@@ -0,0 +1,83 @@
+/*
+ * 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/pkg/testutils"
+	"io/ioutil"
+	"testing"
+)
+
+func TestDownload(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"bytes": 6,
+			"checksum": "sha256:e9c0f8b575cbfcb42ab3b78ecc87efa3b011d9a5d10b09fa4e96f240bf6a82f5",
+			"chunks": 2,
+			"status": "SUCCESS"
+		}
+	]`
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options TransferOpts
+	options.Download.OutputAs = "json"
+	options.Download.Args.LocalFileName = "/tmp/transfer.down"
+	options.Download.Args.URI = "file:///tmp/transfer.down"
+	err := options.Download.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
+
+func TestUpload(t *testing.T) {
+	// use `python -m json.tool` to pretty-print json
+	expected := `[
+		{
+			"bytes": 6,
+			"checksum": "sha256:e9c0f8b575cbfcb42ab3b78ecc87efa3b011d9a5d10b09fa4e96f240bf6a82f5",
+			"chunks": 2,
+			"status": "SUCCESS"
+		}
+	]`
+
+	err := ioutil.WriteFile("/tmp/transfer.up", []byte("ABCDEF"), 0644)
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options TransferOpts
+	options.Upload.OutputAs = "json"
+	options.Upload.Args.LocalFileName = "/tmp/transfer.up"
+	options.Upload.Args.URI = "file:///tmp/transfer.up"
+	options.Upload.ChunkSize = 3
+	err = options.Upload.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	testutils.AssertJSONEqual(t, got.String(), expected)
+}
diff --git a/internal/pkg/commands/version.go b/internal/pkg/commands/version.go
new file mode 100644
index 0000000..c207d55
--- /dev/null
+++ b/internal/pkg/commands/version.go
@@ -0,0 +1,143 @@
+/*
+ * 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 (
+	flags "github.com/jessevdk/go-flags"
+	"github.com/opencord/cordctl/internal/pkg/cli/version"
+	"github.com/opencord/cordctl/pkg/format"
+)
+
+type VersionDetails struct {
+	Version   string `json:"version"`
+	GoVersion string `json:"goversion"`
+	GitCommit string `json:"gitcommit"`
+	GitDirty  string `json:"gitdirty"`
+	BuildTime string `json:"buildtime"`
+	Os        string `json:"os"`
+	Arch      string `json:"arch"`
+}
+
+type CoreVersionDetails struct {
+	Version       string `json:"version"`
+	PythonVersion string `json:"goversion"`
+	GitCommit     string `json:"gitcommit"`
+	BuildTime     string `json:"buildtime"`
+	Os            string `json:"os"`
+	Arch          string `json:"arch"`
+	DjangoVersion string `json:"djangoversion"`
+}
+
+type VersionOutput struct {
+	Client VersionDetails     `json:"client"`
+	Server CoreVersionDetails `json:"server"`
+}
+
+type VersionOpts struct {
+	OutputAs   string `short:"o" long:"outputas" default:"table" choice:"table" choice:"json" choice:"yaml" description:"Type of output to generate"`
+	ClientOnly bool   `short:"c" long:"client-only" description:"Print only client version"`
+}
+
+var versionOpts = VersionOpts{}
+
+var versionInfo = VersionOutput{
+	Client: VersionDetails{
+		Version:   version.Version,
+		GoVersion: version.GoVersion,
+		GitCommit: version.GitCommit,
+		GitDirty:  version.GitDirty,
+		Os:        version.Os,
+		Arch:      version.Arch,
+		BuildTime: version.BuildTime,
+	},
+	Server: CoreVersionDetails{
+		Version:       "unknown",
+		PythonVersion: "unknown",
+		GitCommit:     "unknown",
+		Os:            "unknown",
+		Arch:          "unknown",
+		BuildTime:     "unknown",
+		DjangoVersion: "unknown",
+	},
+}
+
+func RegisterVersionCommands(parent *flags.Parser) {
+	parent.AddCommand("version", "display version", "Display client version", &versionOpts)
+}
+
+const ClientFormat = `Client:
+ Version         {{.Client.Version}}
+ Go version:     {{.Client.GoVersion}}
+ Git commit:     {{.Client.GitCommit}}
+ Git dirty:      {{.Client.GitDirty}}
+ Built:          {{.Client.BuildTime}}
+ OS/Arch:        {{.Client.Os}}/{{.Client.Arch}}
+`
+const ServerFormat = `
+Server:
+ Version         {{.Server.Version}}
+ Python version: {{.Server.PythonVersion}}
+ Django version: {{.Server.DjangoVersion}}
+ Git commit:     {{.Server.GitCommit}}
+ Built:          {{.Server.BuildTime}}
+ OS/Arch:        {{.Server.Os}}/{{.Server.Arch}}
+`
+
+const DefaultFormat = ClientFormat + ServerFormat
+
+func (options *VersionOpts) Execute(args []string) error {
+	if !options.ClientOnly {
+		conn, descriptor, err := InitClient(INIT_NO_VERSION_CHECK)
+		if err != nil {
+			return err
+		}
+		defer conn.Close()
+
+		d, err := GetVersion(conn, descriptor)
+		if err != nil {
+			return err
+		}
+
+		versionInfo.Server.Version = d.GetFieldByName("version").(string)
+		versionInfo.Server.PythonVersion = d.GetFieldByName("pythonVersion").(string)
+		versionInfo.Server.GitCommit = d.GetFieldByName("gitCommit").(string)
+		versionInfo.Server.BuildTime = d.GetFieldByName("buildTime").(string)
+		versionInfo.Server.Os = d.GetFieldByName("os").(string)
+		versionInfo.Server.Arch = d.GetFieldByName("arch").(string)
+
+		// djangoVersion was added to GetVersion() in xos-core 3.3.1-dev
+		djangoVersion, err := d.TryGetFieldByName("djangoVersion")
+		if err == nil {
+			versionInfo.Server.DjangoVersion = djangoVersion.(string)
+		}
+	}
+
+	result := CommandResult{
+		// Format:   format.Format(DefaultFormat),
+		OutputAs: toOutputType(options.OutputAs),
+		Data:     versionInfo,
+	}
+
+	if options.ClientOnly {
+		result.Format = format.Format(ClientFormat)
+	} else {
+		result.Format = format.Format(DefaultFormat)
+	}
+
+	GenerateOutput(&result)
+	return nil
+}
diff --git a/internal/pkg/commands/version_test.go b/internal/pkg/commands/version_test.go
new file mode 100644
index 0000000..e37b6d1
--- /dev/null
+++ b/internal/pkg/commands/version_test.go
@@ -0,0 +1,89 @@
+/*
+ * 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"
+	"testing"
+)
+
+func TestVersionClientOnly(t *testing.T) {
+	expected := "" +
+		"Client:\n" +
+		" Version         unknown-version\n" +
+		" Go version:     unknown-goversion\n" +
+		" Git commit:     unknown-gitcommit\n" +
+		" Git dirty:      unknown-gitdirty\n" +
+		" Built:          unknown-buildtime\n" +
+		" OS/Arch:        unknown-os/unknown-arch\n" +
+		"\n"
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options VersionOpts
+	options.ClientOnly = true
+	err := options.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	if got.String() != expected {
+		t.Logf("RECEIVED:\n%s\n", got.String())
+		t.Logf("EXPECTED:\n%s\n", expected)
+		t.Errorf("%s: expected and received did not match", t.Name())
+	}
+}
+
+func TestVersionClientAndServer(t *testing.T) {
+	expected := "" +
+		"Client:\n" +
+		" Version         unknown-version\n" +
+		" Go version:     unknown-goversion\n" +
+		" Git commit:     unknown-gitcommit\n" +
+		" Git dirty:      unknown-gitdirty\n" +
+		" Built:          unknown-buildtime\n" +
+		" OS/Arch:        unknown-os/unknown-arch\n" +
+		"\n" +
+		"Server:\n" +
+		" Version         3.2.6\n" +
+		" Python version: 2.7.16 (default, May  6 2019, 19:35:26)\n" +
+		" Django version: unknown\n" +
+		" Git commit:     b0df1bf6ed1698285eda6a6725c5da0c80aa4aee\n" +
+		" Built:          2019-05-20T17:04:14Z\n" +
+		" OS/Arch:        linux/x86_64\n" +
+		"\n"
+
+	got := new(bytes.Buffer)
+	OutputStream = got
+
+	var options VersionOpts
+	err := options.Execute([]string{})
+
+	if err != nil {
+		t.Errorf("%s: Received error %v", t.Name(), err)
+		return
+	}
+
+	if got.String() != expected {
+		t.Logf("RECEIVED:\n%s\n", got.String())
+		t.Logf("EXPECTED:\n%s\n", expected)
+		t.Errorf("%s: expected and received did not match", t.Name())
+	}
+}
