SEBA-349 GRPC
added xos proto files
Change-Id: I59feae392782331d11e1ac506c18f772ccfb8898
diff --git a/models/inventory/gather.go b/models/inventory/gather.go
index 75e762f..573fcb2 100644
--- a/models/inventory/gather.go
+++ b/models/inventory/gather.go
@@ -48,6 +48,7 @@
}
type Ont struct {
Number int
+ Active bool
SVlan uint32
CVlan uint32
SerialNumber string
@@ -114,8 +115,8 @@
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,
+ if physicalONT.CircuitID != "" {
+ ont := Ont{Number: physicalONT.Number, Active: physicalONT.Active, SVlan: physicalONT.Svlan, CVlan: physicalONT.Cvlan, SerialNumber: physicalONT.SerialNumber,
NasPortID: physicalONT.NasPortID, CircuitID: physicalONT.CircuitID}
onts = append(onts, ont)
}
diff --git a/models/physical/chassis.go b/models/physical/chassis.go
index 943c830..7761bf6 100644
--- a/models/physical/chassis.go
+++ b/models/physical/chassis.go
@@ -17,16 +17,38 @@
package physical
import (
+ "context"
+ "encoding/base64"
+ "errors"
"fmt"
"log"
"net"
"net/http"
"strings"
+ "gerrit.opencord.org/abstract-olt/contrib/xos"
"gerrit.opencord.org/abstract-olt/internal/pkg/settings"
"gerrit.opencord.org/abstract-olt/models/tosca"
+ "google.golang.org/grpc"
)
+type basicAuth struct {
+ username string
+ password string
+}
+
+func (b basicAuth) GetRequestMetadata(ctx context.Context, in ...string) (map[string]string, error) {
+ auth := b.username + ":" + b.password
+ enc := base64.StdEncoding.EncodeToString([]byte(auth))
+ return map[string]string{
+ "authorization": "Basic " + enc,
+ }, nil
+}
+
+func (basicAuth) RequireTransportSecurity() bool {
+ return false
+}
+
/*
Chassis is a model that takes up to 16 discreet OLT chassis as if it is a 16 slot OLT chassis
*/
@@ -39,17 +61,15 @@
Rack int
Shelf int
}
+
+/*
+UnprovisionedSlotError - Error thrown when attempting to provision to a line card that hasn't been activated
+*/
type UnprovisionedSlotError struct {
CLLI string
SlotNumber int
}
-func (c *Chassis) Output() {
- for _, olt := range c.Linecards {
- olt.Output()
- }
-}
-
func (e *UnprovisionedSlotError) Error() string {
return fmt.Sprintf("SlotNumber %d in Chassis %s is currently unprovsioned", e.SlotNumber, e.CLLI)
}
@@ -60,51 +80,84 @@
func (chassis *Chassis) AddOLTChassis(olt SimpleOLT) {
olt.SetNumber((len(chassis.Linecards) + 1))
chassis.Linecards = append(chassis.Linecards, olt)
- chassis.SendOltTosca(olt)
-
+ if settings.GetGrpc() {
+ chassis.SendOltGRPC(olt)
+ } else {
+ chassis.SendOltTosca(olt)
+ }
}
/*
-SendOltTosca - Broke above method apart to support Reflow
+SendOltGRPC - provisions olt using grpc interface
*/
-func (chassis *Chassis) SendOltTosca(olt SimpleOLT) {
+func (chassis *Chassis) SendOltGRPC(olt SimpleOLT) error {
+ if settings.GetDummy() {
+ log.Println("Running in Dummy mode with GRPC in SendOltGRPC")
+ return nil
+ }
+ conn, err := grpc.Dial(chassis.XOSAddress.String(), grpc.WithInsecure(), grpc.WithPerRPCCredentials(basicAuth{
+ username: chassis.XOSUser,
+ password: chassis.XOSPassword,
+ }))
+ defer conn.Close()
+ if err != nil {
+ log.Println(err)
+ return err
+ }
+
+ xosClient := xos.NewXosClient(conn)
+ //queryElement := &xos.QueryElement{Operator: xos.QueryElement_EQUAL, Name: "volt_service_instances", Value: &xos.QueryElement_SValue{"volt"}}
+ queryElement := &xos.QueryElement{Operator: xos.QueryElement_EQUAL, Name: "name", Value: &xos.QueryElement_SValue{"volt"}}
+ queryElements := []*xos.QueryElement{queryElement}
+ query := &xos.Query{Kind: xos.Query_DEFAULT, Elements: queryElements}
+
+ voltResponse, err := xosClient.FilterVOLTService(context.Background(), query)
+ if err != nil {
+ log.Println(err)
+ return err
+ }
+ voltServices := voltResponse.GetItems()
+ if len(voltServices) == 0 {
+ return errors.New("xosClient.FilterVOLTService returned 0 entries with name \"volt\"")
+ }
+ voltService := voltServices[0]
+
+ response, err := xosClient.CreateOLTDevice(context.Background(), &xos.OLTDevice{
+ NamePresent: &xos.OLTDevice_Name{olt.Hostname},
+ DeviceTypePresent: &xos.OLTDevice_DeviceType{olt.Driver},
+ HostPresent: &xos.OLTDevice_Host{olt.GetAddress().IP.String()},
+ PortPresent: &xos.OLTDevice_Port{int32(olt.GetAddress().Port)},
+ OuterTpidPresent: &xos.OLTDevice_OuterTpid{"0x8100"},
+ UplinkPresent: &xos.OLTDevice_Uplink{"65536"},
+ NasIdPresent: &xos.OLTDevice_NasId{olt.CLLI},
+ SwitchDatapathIdPresent: &xos.OLTDevice_SwitchDatapathId{"of:0000000000000001"},
+ SwitchPortPresent: &xos.OLTDevice_SwitchPort{"1"},
+ VoltServicePresent: &xos.OLTDevice_VoltServiceId{voltService.GetId()},
+ })
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+ log.Printf("Response is %v\n", response)
+ return nil
+}
+
+/*
+SendOltTosca - Provision OLT using TOSCA Interface
+*/
+func (chassis *Chassis) SendOltTosca(olt SimpleOLT) error {
ipString := olt.GetAddress().IP.String()
webServerPort := olt.GetAddress().Port
oltStruct := tosca.NewOltProvision(chassis.CLLI, olt.GetHostname(), olt.Driver, ipString, webServerPort)
yaml, _ := oltStruct.ToYaml()
if settings.GetDummy() {
log.Printf("yaml:%s\n", yaml)
- log.Println("YAML IS NOT BEING SET TO XOS")
- return
+ log.Println("YAML IS NOT BEING SET TO XOS or DEBUG is Set")
+ return nil
}
- client := &http.Client{}
- requestList := fmt.Sprintf("http://%s:%d/run", chassis.XOSAddress.IP.String(), chassis.XOSAddress.Port)
- req, err := http.NewRequest("POST", requestList, strings.NewReader(yaml))
- req.Header.Add("xos-username", chassis.XOSUser)
- req.Header.Add("xos-password", chassis.XOSPassword)
- resp, err := client.Do(req)
- if err != nil {
- //TODO
- // handle error
- }
- log.Printf("Server response was %v\n", resp)
-}
-func (chassis *Chassis) provisionONT(ont Ont) {
- //TODO - api call to provison s/c vlans and ont serial number etc
- log.Printf("chassis.provisionONT(%s,SVlan:%d,CVlan:%d)\n", ont.SerialNumber, ont.Svlan, ont.Cvlan)
- chassis.SendOntTosca(ont)
- chassis.SendSubscriberTosca(ont)
-}
-func (chassis *Chassis) SendOntTosca(ont Ont) {
- ponPort := ont.Parent
- slot := ponPort.Parent
- ontStruct := tosca.NewOntProvision(ont.SerialNumber, slot.Address.IP, ponPort.Number)
- yaml, _ := ontStruct.ToYaml()
- if settings.GetDummy() {
+ if settings.GetDebug() {
log.Printf("yaml:%s\n", yaml)
- log.Println("YAML IS NOT BEING SET TO XOS")
- return
}
client := &http.Client{}
requestList := fmt.Sprintf("http://%s:%d/run", chassis.XOSAddress.IP.String(), chassis.XOSAddress.Port)
@@ -114,11 +167,171 @@
resp, err := client.Do(req)
if err != nil {
log.Printf("ERROR :) %v\n", err)
- // handle error
+ return err
+ }
+ log.Printf("Server response was %v\n", resp.Body)
+ return nil
+}
+func (chassis *Chassis) provisionONT(ont Ont) {
+ //TODO - api call to provison s/c vlans and ont serial number etc
+ log.Printf("chassis.provisionONT(%s,SVlan:%d,CVlan:%d)\n", ont.SerialNumber, ont.Svlan, ont.Cvlan)
+ if settings.GetGrpc() {
+ chassis.SendOntGRPC(ont)
+ chassis.SendSubscriberGRPC(ont)
+ } else {
+ chassis.SendOntTosca(ont)
+ chassis.SendSubscriberTosca(ont)
+ }
+}
+
+/*
+SendOntGRPC - Provision ONT on XOS using GRPC interface
+*/
+func (chassis *Chassis) SendOntGRPC(ont Ont) error {
+ if settings.GetDummy() {
+ log.Println("Running in Dummy mode with GRPC in SendOntGRPC")
+ return nil
+ }
+ ponPort := ont.Parent
+ slot := ponPort.Parent
+ ip := slot.Address.IP
+ ipNum := []byte(ip[12:16]) //only handling ipv4
+ ofID := fmt.Sprintf("of:00000000%0x", ipNum)
+
+ conn, err := grpc.Dial(chassis.XOSAddress.String(), grpc.WithInsecure(), grpc.WithPerRPCCredentials(basicAuth{
+ username: chassis.XOSUser,
+ password: chassis.XOSPassword,
+ },
+ ))
+ defer conn.Close()
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+ xosClient := xos.NewXosClient(conn)
+ queryElement := &xos.QueryElement{Operator: xos.QueryElement_EQUAL, Name: "name", Value: &xos.QueryElement_SValue{"att-workflow-driver"}}
+ queryElements := []*xos.QueryElement{queryElement}
+ query := &xos.Query{Kind: xos.Query_DEFAULT, Elements: queryElements}
+
+ attWorkFlowResponse, err := xosClient.FilterAttWorkflowDriverService(context.Background(), query)
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+
+ attWorkFlowServices := attWorkFlowResponse.GetItems()
+ if len(attWorkFlowServices) == 0 {
+ err := "xosClient.FilterAttWorkflowDriverService return zero attWorkFlowServices with name att-workflow-driver"
+ log.Print(err)
+ return errors.New(err)
+ }
+ log.Printf("FilterAttWorkflowDriver response is %s", attWorkFlowResponse)
+ attWorkFlowService := attWorkFlowServices[0]
+
+ newQueryElement := &xos.QueryElement{Operator: xos.QueryElement_EQUAL, Name: "serial_number", Value: &xos.QueryElement_SValue{ont.SerialNumber}}
+ newQueryElements := []*xos.QueryElement{newQueryElement}
+ query = &xos.Query{Kind: xos.Query_DEFAULT, Elements: newQueryElements}
+
+ onuResponse, err := xosClient.FilterONUDevice(context.Background(), query)
+ log.Printf("FilterONU response is %s", onuResponse)
+ onus := onuResponse.GetItems()
+ if len(onus) == 0 {
+ err := fmt.Sprintf("xosClient.FilterONUDevices return zero onus with serial number %s", ont.SerialNumber)
+ log.Print(err)
+ return errors.New(err)
+ }
+ deviceID := onus[0].GetDeviceId()
+
+ offset := 1 << 29
+ ponPortNumber := offset + (ponPort.Number - 1)
+ log.Printf("Calling xosClient.CreateAttWorkflowDriverWhiteListEntry with SerialNumberPresent: %s DeviceIdPresent: %s PonPortIdPresent: %d OwnerPresent: %d", ont.SerialNumber, deviceID, ponPortNumber, attWorkFlowService.GetId())
+ response, err := xosClient.CreateAttWorkflowDriverWhiteListEntry(context.Background(), &xos.AttWorkflowDriverWhiteListEntry{
+ SerialNumberPresent: &xos.AttWorkflowDriverWhiteListEntry_SerialNumber{ont.SerialNumber},
+ //DeviceIdPresent: &xos.AttWorkflowDriverWhiteListEntry_DeviceId{deviceID},
+ DeviceIdPresent: &xos.AttWorkflowDriverWhiteListEntry_DeviceId{ofID},
+ PonPortIdPresent: &xos.AttWorkflowDriverWhiteListEntry_PonPortId{int32(ponPortNumber)},
+ OwnerPresent: &xos.AttWorkflowDriverWhiteListEntry_OwnerId{attWorkFlowService.GetId()},
+ })
+
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+ log.Printf("Response is %v\n", response)
+ return nil
+}
+
+/*
+SendOntTosca - Provision ONT on XOS using Tosca interface
+*/
+func (chassis *Chassis) SendOntTosca(ont Ont) error {
+ ponPort := ont.Parent
+ slot := ponPort.Parent
+ ontStruct := tosca.NewOntProvision(ont.SerialNumber, slot.Address.IP, ponPort.Number)
+ yaml, _ := ontStruct.ToYaml()
+
+ if settings.GetDummy() {
+ log.Printf("yaml:%s\n", yaml)
+ log.Println("YAML IS NOT BEING SET TO XOS")
+ return nil
+ }
+ client := &http.Client{}
+ requestList := fmt.Sprintf("http://%s:%d/run", chassis.XOSAddress.IP.String(), chassis.XOSAddress.Port)
+ req, err := http.NewRequest("POST", requestList, strings.NewReader(yaml))
+ req.Header.Add("xos-username", chassis.XOSUser)
+ req.Header.Add("xos-password", chassis.XOSPassword)
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
}
log.Printf("Response is %v\n", resp)
+ return nil
}
-func (chassis *Chassis) SendSubscriberTosca(ont Ont) {
+
+/*
+SendSubscriberGRPC - Provisons a subscriber using the GRPC Interface
+*/
+func (chassis *Chassis) SendSubscriberGRPC(ont Ont) error {
+ if settings.GetDummy() {
+ log.Println("Running in Dummy mode with GRPC in SendSubscriberGRPC")
+ return nil
+ }
+ ponPort := ont.Parent
+ slot := ponPort.Parent
+ conn, err := grpc.Dial(chassis.XOSAddress.String(), grpc.WithInsecure(), grpc.WithPerRPCCredentials(basicAuth{
+ username: chassis.XOSUser,
+ password: chassis.XOSPassword,
+ }))
+ defer conn.Close()
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+
+ xosClient := xos.NewXosClient(conn)
+ rgName := fmt.Sprintf("%s_%d_%d_%d_RG", chassis.CLLI, slot.Number, ponPort.Number, ont.Number)
+ response, err := xosClient.CreateRCORDSubscriber(context.Background(), &xos.RCORDSubscriber{
+ NamePresent: &xos.RCORDSubscriber_Name{rgName},
+ CTagPresent: &xos.RCORDSubscriber_CTag{int32(ont.Cvlan)},
+ STagPresent: &xos.RCORDSubscriber_STag{int32(ont.Svlan)},
+ OnuDevicePresent: &xos.RCORDSubscriber_OnuDevice{ont.SerialNumber},
+ NasPortIdPresent: &xos.RCORDSubscriber_NasPortId{ont.NasPortID},
+ CircuitIdPresent: &xos.RCORDSubscriber_CircuitId{ont.CircuitID},
+ RemoteIdPresent: &xos.RCORDSubscriber_RemoteId{chassis.CLLI}})
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+ log.Println(response)
+ return nil
+
+}
+
+/*
+SendSubscriberTosca - Provisons a subscriber using the Tosca Interface
+*/
+func (chassis *Chassis) SendSubscriberTosca(ont Ont) error {
ponPort := ont.Parent
slot := ponPort.Parent
requestList := fmt.Sprintf("http://%s:%d/run", chassis.XOSAddress.IP.String(), chassis.XOSAddress.Port)
@@ -128,26 +341,79 @@
if settings.GetDummy() {
log.Printf("yaml:%s\n", yaml)
log.Println("YAML IS NOT BEING SET TO XOS")
- } else {
- req, err := http.NewRequest("POST", requestList, strings.NewReader(yaml))
- req.Header.Add("xos-username", chassis.XOSUser)
- req.Header.Add("xos-password", chassis.XOSPassword)
- client := &http.Client{}
- resp, err := client.Do(req)
- if err != nil {
- log.Printf("ERROR :) %v\n", err)
- // handle error
- }
- log.Printf("Response is %v\n", resp)
-
+ return nil
}
+ req, err := http.NewRequest("POST", requestList, strings.NewReader(yaml))
+ req.Header.Add("xos-username", chassis.XOSUser)
+ req.Header.Add("xos-password", chassis.XOSPassword)
+ client := &http.Client{}
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+ log.Printf("Response is %v\n", resp)
+
+ return nil
}
+
func (chassis *Chassis) deleteONT(ont Ont) {
log.Printf("chassis.deleteONT(%s,SVlan:%d,CVlan:%d)\n", ont.SerialNumber, ont.Svlan, ont.Cvlan)
+ if settings.GetGrpc() {
+ chassis.deleteOntWhitelistGRPC(ont)
+ } else {
+ chassis.deleteOntTosca(ont)
+ }
+}
+
+/*
+deleteOntGRPC - deletes ONT using XOS GRPC Interface
+*/
+func (chassis *Chassis) deleteOntWhitelistGRPC(ont Ont) error {
+ if settings.GetDummy() {
+ log.Println("Running in Dummy mode with GRPC in SendSubscriberGRPC")
+ return nil
+ }
+ conn, err := grpc.Dial(chassis.XOSAddress.String(), grpc.WithInsecure(), grpc.WithPerRPCCredentials(basicAuth{
+ username: chassis.XOSUser,
+ password: chassis.XOSPassword,
+ }))
+ defer conn.Close()
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+ xosClient := xos.NewXosClient(conn)
+ queryElement := &xos.QueryElement{Operator: xos.QueryElement_EQUAL, Name: "serial_number", Value: &xos.QueryElement_SValue{ont.SerialNumber}}
+ queryElements := []*xos.QueryElement{queryElement}
+ query := &xos.Query{Kind: xos.Query_DEFAULT, Elements: queryElements}
+ onuResponse, err := xosClient.FilterAttWorkflowDriverWhiteListEntry(context.Background(), query)
+ onus := onuResponse.GetItems()
+ if len(onus) == 0 {
+ errorMsg := fmt.Sprintf("Unable to find WhiteListEntry in XOS with SerialNumber %s", ont.SerialNumber)
+ return errors.New(errorMsg)
+ }
+ onu := onus[0]
+ log.Printf("DeleteAttWorkflowDriverWhiteListEntry ONU : %v\n", onu)
+
+ id := &xos.ID{Id: onu.GetId()}
+ log.Printf("DeleteAttWorkflowDriverWhiteListEntry XOSID:%v\n", id)
+ response, err := xosClient.DeleteAttWorkflowDriverWhiteListEntry(context.Background(), id)
+
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ return err
+ }
+ log.Printf("Response is %v\n", response)
+ return nil
+}
+
+/*
+deleteOntTosca - deletes ONT using XOS Tosca Interface
+*/
+func (chassis *Chassis) deleteOntTosca(ont Ont) {
ponPort := ont.Parent
slot := ponPort.Parent
-
- //func NewOntProvision(serialNumber string, oltIP net.IP, ponPortNumber int) OntProvision {
ontStruct := tosca.NewOntProvision(ont.SerialNumber, slot.Address.IP, ponPort.Number)
yaml, _ := ontStruct.ToYaml()
fmt.Println(yaml)
@@ -181,15 +447,14 @@
log.Printf("yaml:%s\n", yaml)
log.Println("YAML IS NOT BEING SET TO XOS")
return
- } else {
- req, err := http.NewRequest("POST", requestList, strings.NewReader(yaml))
- req.Header.Add("xos-username", chassis.XOSUser)
- req.Header.Add("xos-password", chassis.XOSPassword)
- resp, err := client.Do(req)
- if err != nil {
- log.Printf("ERROR :) %v\n", err)
- // handle error
- }
- log.Printf("Response is %v\n", resp)
}
+ req, err := http.NewRequest("POST", requestList, strings.NewReader(yaml))
+ req.Header.Add("xos-username", chassis.XOSUser)
+ req.Header.Add("xos-password", chassis.XOSPassword)
+ resp, err := client.Do(req)
+ if err != nil {
+ log.Printf("ERROR :) %v\n", err)
+ // handle error
+ }
+ log.Printf("Response is %v\n", resp)
}
diff --git a/models/physical/ponport.go b/models/physical/ponport.go
index 738d65e..5012fe1 100644
--- a/models/physical/ponport.go
+++ b/models/physical/ponport.go
@@ -68,6 +68,7 @@
PreProvisionOnt - passes ont information to chassis to make call to NEM to activate (whitelist) ont
*/
func (port *PONPort) PreProvisionOnt(number int, sVlan uint32, cVlan uint32, nasPortID string, circuitID string, techProfile string, speedProfile string) error {
+ fmt.Printf("PrPreProvisionOnt(number %d, sVlan %d, cVlan %d, nasPortID %s, circuitID %s, techProfile %s, speedProfile %s\n", number, sVlan, cVlan, nasPortID, circuitID, techProfile, speedProfile)
slot := port.Parent
chassis := slot.Parent
@@ -84,6 +85,7 @@
ont.CircuitID = circuitID
ont.TechProfile = techProfile
ont.SpeedProfile = speedProfile
+ fmt.Printf("ponPort PreProvision ont :%v\n", ont)
return nil
}
@@ -98,10 +100,10 @@
e := AllReadyActiveError{ontNumber: number, slotNum: slot.Number, ponportNum: port.Number, clli: chassis.CLLI}
return &e
}
- ont := port.Onts[number-1]
+ ont := &port.Onts[number-1]
ont.SerialNumber = serialNumber
fmt.Println(ont)
- port.Parent.Parent.provisionONT(ont)
+ port.Parent.Parent.provisionONT(*ont)
port.Onts[number-1].Active = true
return nil
@@ -130,6 +132,8 @@
DeleteOnt - passes ont information to chassis to make call to NEM to de-activate (de-whitelist) ont
*/
func (port *PONPort) DeleteOnt(number int, sVlan uint32, cVlan uint32, serialNumber string) error {
+
+ fmt.Printf("DeleteOnt(number %d, sVlan %d, cVlan %d, serialNumber %s)\n", number, sVlan, cVlan, serialNumber)
slot := port.Parent
chassis := slot.Parent
if port.Onts[number-1].Active != true {
diff --git a/models/tosca/addOlt.go b/models/tosca/addOlt.go
index 30e8d12..07bd997 100644
--- a/models/tosca/addOlt.go
+++ b/models/tosca/addOlt.go
@@ -44,10 +44,10 @@
host: test
port: 32
outer_tpid: "0x8100"
- uplink: "65536"
nas_id:
switch_datapath_id: of:0000000000000001
switch_port: "1"
+ uplink: "65536"
requirements:
- volt_service:
node: service#volt