seba-260 get inventory

Change-Id: Icd3f955d55ed71ab18cbab6f669ce244ab7c47da
diff --git a/api/abstract_olt_api.proto b/api/abstract_olt_api.proto
index 7a8cb69..6c5304b 100644
--- a/api/abstract_olt_api.proto
+++ b/api/abstract_olt_api.proto
@@ -104,7 +104,6 @@
    bool Success=1;
 }
 message ReflowMessage{
-
 }
 message ReflowReturn{
     bool Success=1;
@@ -115,6 +114,14 @@
 message OutputReturn{
    bool Success=1;
 }
+message FullInventoryMessage{
+}
+message InventoryMessage{
+   string Clli=1;
+}
+message InventoryReturn{
+   string JsonDump=1;
+}
 service AbstractOLT{
    rpc Echo(EchoMessage) returns (EchoReplyMessage){
       option(google.api.http)={
@@ -171,5 +178,17 @@
 	    body:"*"
       };
    }
+   rpc GetFullInventory(FullInventoryMessage)returns(InventoryReturn){
+      option(google.api.http)={
+        post:"/v1/FullInventory"
+	    body:"*"
+      };
+   }
+   rpc GetInventory(InventoryMessage)returns(InventoryReturn){
+      option(google.api.http)={
+        post:"/v1/Inventory"
+	    body:"*"
+      };
+   }
 }
 
diff --git a/api/handler.go b/api/handler.go
index ee70d74..f2e832e 100644
--- a/api/handler.go
+++ b/api/handler.go
@@ -23,6 +23,7 @@
 	"sync"
 
 	"gerrit.opencord.org/abstract-olt/internal/pkg/impl"
+	"gerrit.opencord.org/abstract-olt/models/inventory"
 	context "golang.org/x/net/context"
 )
 
@@ -130,7 +131,7 @@
 }
 
 /*
-ProvsionOntFull - provisions ont using sTag,cTag,NasPortID, and CircuitID passed in
+ProvisionOntFull - provisions ont using sTag,cTag,NasPortID, and CircuitID passed in
 */
 func (s *Server) ProvisionOntFull(ctx context.Context, in *AddOntFullMessage) (*AddOntReturn, error) {
 	clli := in.GetCLLI()
@@ -159,13 +160,36 @@
 	return &DeleteOntReturn{Success: success}, err
 }
 
+/*
+Reflow - iterates through provisioning to rebuild Seba-Pod
+*/
 func (s *Server) Reflow(ctx context.Context, in *ReflowMessage) (*ReflowReturn, error) {
 	success, err := impl.Reflow()
 	return &ReflowReturn{Success: success}, err
 
 }
+
+/*
+Output - causes an immediate backup to be created
+*/
 func (s *Server) Output(ctx context.Context, in *OutputMessage) (*OutputReturn, error) {
 	success, err := impl.DoOutput()
 	return &OutputReturn{Success: success}, err
 
 }
+
+/*
+GetFullInventory - gets a full json dump of the currently provisioned equipment
+*/
+func (s *Server) GetFullInventory(ctx context.Context, in *FullInventoryMessage) (*InventoryReturn, error) {
+	json := inventory.GatherAllInventory()
+	return &InventoryReturn{JsonDump: json}, nil
+}
+
+/*
+GetInventory - returns a json dump of a particular seba-pod
+*/
+func (s *Server) GetInventory(ctx context.Context, in *InventoryMessage) (*InventoryReturn, error) {
+	json := inventory.GatherInventory(in.GetClli())
+	return &InventoryReturn{JsonDump: json}, nil
+}
diff --git a/client/main.go b/client/main.go
index abecae7..a91b22a 100644
--- a/client/main.go
+++ b/client/main.go
@@ -40,6 +40,8 @@
 	deleteOnt := flag.Bool("d", false, "deleteOnt")
 	output := flag.Bool("output", false, "dump output")
 	reflow := flag.Bool("reflow", false, "reflow provisioning tosca")
+	fullInventory := flag.Bool("full_inventory", false, "pull full inventory json")
+	inventory := flag.Bool("inventory", false, "pull json inventory for a specific clli")
 	/* END COMMAND FLAGS */
 
 	/* CREATE CHASSIS FLAGS */
@@ -95,7 +97,7 @@
 		}
 	}
 
-	cmdFlags := []*bool{echo, addOlt, update, create, provOnt, provOntFull, deleteOnt, output, reflow}
+	cmdFlags := []*bool{echo, addOlt, update, create, provOnt, provOntFull, deleteOnt, output, reflow, fullInventory, inventory}
 	cmdCount := 0
 	for _, flag := range cmdFlags {
 		if *flag {
@@ -163,6 +165,10 @@
 		deleteONT(c, clli, slot, port, ont, serial)
 	} else if *reflow {
 		reflowTosca(c)
+	} else if *fullInventory {
+		getFullInventory(c)
+	} else if *inventory {
+		getInventory(c, clli)
 	}
 
 }
@@ -325,6 +331,26 @@
 	log.Printf("Response from server: %t", res.GetSuccess())
 	return nil
 }
+func getFullInventory(c api.AbstractOLTClient) error {
+	res, err := c.GetFullInventory(context.Background(), &api.FullInventoryMessage{})
+	if err != nil {
+		debug.PrintStack()
+		fmt.Printf("Error when calling Reflow %s", err)
+		return err
+	}
+	log.Println(res.GetJsonDump())
+	return nil
+}
+func getInventory(c api.AbstractOLTClient, clli *string) error {
+	res, err := c.GetInventory(context.Background(), &api.InventoryMessage{Clli: *clli})
+	if err != nil {
+		debug.PrintStack()
+		fmt.Printf("Error when calling Reflow %s", err)
+		return err
+	}
+	log.Println(res.GetJsonDump())
+	return nil
+}
 
 func usage() {
 	var output = `
diff --git a/models/inventory/gather.go b/models/inventory/gather.go
new file mode 100644
index 0000000..9f2bd21
--- /dev/null
+++ b/models/inventory/gather.go
@@ -0,0 +1,129 @@
+/*
+ Copyright 2017 the original author or authors.
+
+ 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 inventory
+
+import (
+	"encoding/json"
+	"net"
+
+	"gerrit.opencord.org/abstract-olt/models"
+	"gerrit.opencord.org/abstract-olt/models/physical"
+)
+
+type Chassis struct {
+	Clli      string
+	Rack      int
+	Shelf     int
+	XOSAddr   net.TCPAddr
+	LineCards []LineCard
+}
+type LineCard struct {
+	Number int
+	Olts   []PhysicalOlt
+}
+type PhysicalOlt struct {
+	Address  net.TCPAddr
+	Hostname string
+	Ports    []Port
+}
+type Port struct {
+	AbstractNumber int
+	PhysicalNumber int
+	Onts           []Ont
+}
+type Ont struct {
+	Number       int
+	SVlan        uint32
+	CVlan        uint32
+	SerialNumber string
+	NasPortID    string
+	CircuitID    string
+}
+
+func GatherAllInventory() string {
+	chassisMap := models.GetChassisMap()
+	chassis_s := []Chassis{}
+	for clli, chassisHolder := range *chassisMap {
+		chassis := parseClli(clli, chassisHolder)
+		chassis_s = append(chassis_s, chassis)
+	}
+	bytes, _ := json.Marshal(chassis_s)
+	return string(bytes)
+}
+
+func GatherInventory(clli string) string {
+	chassisMap := models.GetChassisMap()
+	chassisHolder := (*chassisMap)[clli]
+	chassis := parseClli(clli, chassisHolder)
+	bytes, _ := json.Marshal(chassis)
+	return string(bytes)
+}
+
+func parseClli(clli string, chassisHolder *models.ChassisHolder) Chassis {
+	abstract := chassisHolder.AbstractChassis
+	chassis := Chassis{}
+	chassis.Clli = clli
+	chassis.Rack = abstract.Rack
+	chassis.Shelf = abstract.Shelf
+	chassis.XOSAddr = chassisHolder.PhysicalChassis.XOSAddress
+
+	lineCards := []LineCard{}
+	for index, slot := range abstract.Slots {
+		if slot.Ports[0].PhysPort != nil {
+			lineCard := LineCard{Number: index + 1}
+			var currentOLT *physical.SimpleOLT
+			var physicalOLT PhysicalOlt
+			var ports []Port
+			olts := []PhysicalOlt{}
+			for i := 0; i < 16; i++ {
+				ponPort := slot.Ports[i].PhysPort
+				if ponPort != nil {
+					parentOLT := ponPort.Parent
+					if currentOLT != parentOLT {
+						if currentOLT != nil {
+							physicalOLT.Ports = ports
+							olts = append(olts, physicalOLT)
+						}
+						physicalOLT = PhysicalOlt{Address: parentOLT.Address, Hostname: parentOLT.Hostname}
+						currentOLT = parentOLT
+						ports = []Port{}
+
+					}
+					port := Port{AbstractNumber: i + 1, PhysicalNumber: ponPort.Number}
+					onts := []Ont{}
+					for _, physicalONT := range ponPort.Onts {
+						if physicalONT.Active {
+							ont := Ont{Number: physicalONT.Number, SVlan: physicalONT.Svlan, CVlan: physicalONT.Cvlan, SerialNumber: physicalONT.SerialNumber,
+								NasPortID: physicalONT.NasPortID, CircuitID: physicalONT.CircuitID}
+							onts = append(onts, ont)
+						}
+					}
+					port.Onts = onts
+					ports = append(ports, port)
+				}
+
+				if i == 15 { // last one
+					physicalOLT.Ports = ports
+					olts = append(olts, physicalOLT)
+				}
+			}
+			lineCard.Olts = olts
+			lineCards = append(lineCards, lineCard)
+		}
+	}
+	chassis.LineCards = lineCards
+	return chassis
+}