SEBA-259
Added testing of username/password for xos

Change-Id: I9d2d3dd32d217d4f2c13bae843df427fddc631fb
diff --git a/api/abstract_olt_api.proto b/api/abstract_olt_api.proto
index 6604703..dd8fcea 100644
--- a/api/abstract_olt_api.proto
+++ b/api/abstract_olt_api.proto
@@ -25,14 +25,25 @@
 
 message AddChassisMessage{
    string CLLI =1;
-   string VCoreIP =2;
-   int32 VCorePort=3;
-   int32 Rack=4;
-   int32 Shelf=5;
+   string XOSIP =2;
+   int32 XOSPort=3;
+   string XOSUser=4;
+   string XOSPassword=5;
+   int32 Rack=6;
+   int32 Shelf=7;
 }
 message AddChassisReturn{
    string DeviceID = 1;
 }
+message ChangeXOSUserPasswordMessage{
+   string CLLI =1;
+   string XOSUser=2;
+   string XOSPassword=3;
+}
+message ChangeXOSUserPasswordReturn{
+   bool Success=1;
+}
+
 message AddOLTChassisMessage{
    string CLLI=1;
    string SlotIP=2;
@@ -100,6 +111,12 @@
 	 body:"*"
       };
    }
+   rpc ChangeXOSUserPassword(ChangeXOSUserPasswordMessage) returns(ChangeXOSUserPasswordReturn){
+      option(google.api.http)={
+        post:"/v1/ChangeXOSUserPassword"
+	body:"*"
+      };
+   }
    rpc CreateOLTChassis(AddOLTChassisMessage) returns (AddOLTChassisReturn) {
       option(google.api.http) = {
          post: "/v1/CreateOLTChassis"
diff --git a/api/handler.go b/api/handler.go
index 2e6b9cc..f6d4c5b 100644
--- a/api/handler.go
+++ b/api/handler.go
@@ -19,8 +19,10 @@
 import (
 	"errors"
 	"fmt"
+	"io/ioutil"
 	"log"
 	"net"
+	"net/http"
 	"os"
 	"strings"
 
@@ -52,14 +54,35 @@
 func (s *Server) CreateChassis(ctx context.Context, in *AddChassisMessage) (*AddChassisReturn, error) {
 	chassisMap := models.GetChassisMap()
 	clli := in.GetCLLI()
+
+	xosIP := net.ParseIP(in.GetXOSIP())
+	xosPort := int(in.GetXOSPort())
+	if xosIP == nil {
+		errStr := fmt.Sprintf("Invalid IP %s supplied for XOSIP", in.GetXOSIP())
+		return nil, errors.New(errStr)
+	}
+
+	xosAddress := net.TCPAddr{IP: xosIP, Port: xosPort}
+
+	xosUser := in.GetXOSUser()
+	xosPassword := in.GetXOSPassword()
+	if xosUser == "" || xosPassword == "" {
+		return nil, errors.New("Either XOSUser or XOSPassword supplied were empty")
+	}
+	loginWorked := testLogin(xosUser, xosPassword, xosIP, xosPort)
+	if !loginWorked {
+		return nil, errors.New("Unable to validate login not creating Abstract Chassis")
+	}
+	shelf := int(in.GetShelf())
+	rack := int(in.GetRack())
+
 	chassisHolder := (*chassisMap)[clli]
 	if chassisHolder != nil {
 		return &AddChassisReturn{DeviceID: chassisHolder.AbstractChassis.CLLI}, nil
 	}
 
 	abstractChassis := abstract.GenerateChassis(clli, int(in.GetRack()), int(in.GetShelf()))
-	phyChassis := physical.Chassis{CLLI: clli, VCoreAddress: net.TCPAddr{IP: net.ParseIP(in.GetVCoreIP()),
-		Port: int(in.GetVCorePort())}, Rack: int(in.GetRack()), Shelf: int(in.GetShelf())}
+	phyChassis := physical.Chassis{CLLI: clli, XOSAddress: xosAddress, Rack: rack, Shelf: shelf}
 
 	chassisHolder = &models.ChassisHolder{AbstractChassis: abstractChassis, PhysicalChassis: phyChassis}
 	if settings.GetDebug() {
@@ -72,6 +95,35 @@
 }
 
 /*
+ChangeXOSUserPassword - allows update of xos credentials
+*/
+func (s *Server) ChangeXOSUserPassword(ctx context.Context, in *ChangeXOSUserPasswordMessage) (*ChangeXOSUserPasswordReturn, error) {
+	clli := in.GetCLLI()
+	xosUser := in.GetXOSUser()
+	xosPassword := in.GetXOSPassword()
+	if xosUser == "" || xosPassword == "" {
+		return nil, errors.New("Either XOSUser or XOSPassword supplied were empty")
+	}
+	chassisMap := models.GetChassisMap()
+	chassisHolder := (*chassisMap)[clli]
+	if chassisHolder == nil {
+		errString := fmt.Sprintf("There is no chassis with CLLI of %s", clli)
+		return nil, errors.New(errString)
+	}
+	xosIP := chassisHolder.PhysicalChassis.XOSAddress.IP
+	xosPort := chassisHolder.PhysicalChassis.XOSAddress.Port
+	loginWorked := testLogin(xosUser, xosPassword, xosIP, xosPort)
+	if !loginWorked {
+		return nil, errors.New("Unable to validate login when changing password")
+	}
+
+	chassisHolder.PhysicalChassis.XOSUser = xosUser
+	chassisHolder.PhysicalChassis.XOSPassword = xosPassword
+	return &ChangeXOSUserPasswordReturn{Success: true}, nil
+
+}
+
+/*
 CreateOLTChassis adds an OLT chassis/line card to the Physical chassis
 */
 func (s *Server) CreateOLTChassis(ctx context.Context, in *AddOLTChassisMessage) (*AddOLTChassisReturn, error) {
@@ -152,3 +204,39 @@
 	return &OutputReturn{Success: true}, nil
 
 }
+func testLogin(xosUser string, xosPassword string, xosIP net.IP, xosPort int) bool {
+	var dummyYaml = `
+tosca_definitions_version: tosca_simple_yaml_1_0
+imports:
+  - custom_types/site.yaml
+description: anything
+topology_template:
+  node_templates:
+    mysite:
+      type: tosca.nodes.Site
+      properties:
+        must-exist: true
+        name: mysite
+`
+	client := &http.Client{}
+	requestList := fmt.Sprintf("http://%s:%d/run", xosIP, xosPort)
+	req, err := http.NewRequest("POST", requestList, strings.NewReader(dummyYaml))
+	req.Header.Add("xos-username", xosUser)
+	req.Header.Add("xos-password", xosPassword)
+	resp, err := client.Do(req)
+	log.Printf("testLogin resp:%v", resp)
+	if err != nil {
+		log.Printf("Unable to validate XOS Login Information %v", err)
+		return false
+	}
+	defer resp.Body.Close()
+
+	if resp.StatusCode == http.StatusOK {
+		bodyBytes, _ := ioutil.ReadAll(resp.Body)
+		bodyString := string(bodyBytes)
+		fmt.Println(bodyString)
+		return true
+	}
+	return false
+
+}
diff --git a/client/main.go b/client/main.go
index 8d8ea4c..12697f1 100644
--- a/client/main.go
+++ b/client/main.go
@@ -35,12 +35,15 @@
 	echo := flag.Bool("e", false, "echo")
 	message := flag.String("message", "ping", "message to be echoed back")
 	create := flag.Bool("c", false, "create?")
+	update := flag.Bool("u", false, "update?")
 	addOlt := flag.Bool("s", false, "addOlt?")
 	provOnt := flag.Bool("o", false, "provisionOnt?")
 	deleteOnt := flag.Bool("d", false, "deleteOnt")
 	/* END COMMAND FLAGS */
 
 	/* CREATE CHASSIS FLAGS */
+	xosUser := flag.String("xos_user", "", "xos_user")
+	xosPassword := flag.String("xos_password", "", "xos_password")
 	xosAddress := flag.String("xos_address", "", "xos address")
 	xosPort := flag.Uint("xos_port", 0, "xos port")
 	rack := flag.Uint("rack", 1, "rack number for chassis")
@@ -80,7 +83,7 @@
 		}
 	}
 
-	cmdFlags := []*bool{echo, addOlt, create, provOnt, deleteOnt, output}
+	cmdFlags := []*bool{echo, addOlt, update, create, provOnt, deleteOnt, output}
 	cmdCount := 0
 	for _, flag := range cmdFlags {
 		if *flag {
@@ -131,7 +134,9 @@
 
 	c := api.NewAbstractOLTClient(conn)
 	if *create {
-		createChassis(c, clli, xosAddress, xosPort, rack, shelf)
+		createChassis(c, clli, xosUser, xosPassword, xosAddress, xosPort, rack, shelf)
+	} else if *update {
+		updateXOSUserPassword(c, clli, xosUser, xosPassword)
 	} else if *addOlt {
 		addOltChassis(c, clli, oltAddress, oltPort, name, driver, oltType)
 	} else if *provOnt {
@@ -185,14 +190,17 @@
 	return nil
 }
 
-func createChassis(c api.AbstractOLTClient, clli *string, xosAddress *string, xosPort *uint, rack *uint, shelf *uint) error {
+func createChassis(c api.AbstractOLTClient, clli *string, xosUser *string, xosPassword *string, xosAddress *string, xosPort *uint, rack *uint, shelf *uint) error {
 	fmt.Println("Calling Create Chassis")
 	fmt.Println("clli", *clli)
+	fmt.Println("xos_user", *xosUser)
+	fmt.Println("xos_password", *xosPassword)
 	fmt.Println("xos_address", *xosAddress)
 	fmt.Println("xos_port", *xosPort)
 	fmt.Println("rack", *rack)
 	fmt.Println("shelf", *shelf)
-	response, err := c.CreateChassis(context.Background(), &api.AddChassisMessage{CLLI: *clli, VCoreIP: *xosAddress, VCorePort: int32(*xosPort), Rack: int32(*rack), Shelf: int32(*shelf)})
+	response, err := c.CreateChassis(context.Background(), &api.AddChassisMessage{CLLI: *clli, XOSUser: *xosUser, XOSPassword: *xosPassword,
+		XOSIP: *xosAddress, XOSPort: int32(*xosPort), Rack: int32(*rack), Shelf: int32(*shelf)})
 	if err != nil {
 		fmt.Printf("Error when calling CreateChassis: %s", err)
 		return err
@@ -200,6 +208,20 @@
 	log.Printf("Response from server: %s", response.GetDeviceID())
 	return nil
 }
+func updateXOSUserPassword(c api.AbstractOLTClient, clli *string, xosUser *string, xosPassword *string) error {
+	fmt.Println("Calling Update XOS USER/PASSWORD")
+	fmt.Println("clli", *clli)
+	fmt.Println("xos_user", *xosUser)
+	fmt.Println("xos_password", *xosPassword)
+	response, err := c.ChangeXOSUserPassword(context.Background(), &api.ChangeXOSUserPasswordMessage{CLLI: *clli, XOSUser: *xosUser, XOSPassword: *xosPassword})
+	if err != nil {
+		fmt.Printf("Error when calling UpdateXOSUserPassword: %s", err)
+		return err
+	}
+	log.Printf("Response from server: %s", response.GetSuccess())
+	return nil
+}
+
 func addOltChassis(c api.AbstractOLTClient, clli *string, oltAddress *string, oltPort *uint, name *string, driver *string, oltType *string) error {
 	fmt.Println("clli", *clli)
 	fmt.Println("olt_address", *oltAddress)
@@ -275,11 +297,18 @@
    -c create chassis
       params:
          -clli CLLI_NAME
+	 -xos_user XOS_USER
+	 -xos_password XOS_PASSWORD
 	 -xos_address XOS_TOSCA_IP
 	 -xos_port XOS_TOSCA_LISTEN_PORT
 	 -rack [optional default 1]
 	 -shelf [optional default 1]
-	 e.g. ./client -server=localhost:7777 -c -clli MY_CLLI -xos_address 192.168.0.1 -xos_port 30007 -rack 1 -shelf 1
+	 e.g. ./client -server=localhost:7777 -c -clli MY_CLLI -xos_user foundry -xos_password password -xos_address 192.168.0.1 -xos_port 30007 -rack 1 -shelf 1
+   -u update xos user/password
+         -clli CLLI_NAME
+	 -xos_user XOS_USER
+	 -xos_password XOS_PASSWORD
+	 e.g. ./client -server=localhost:7777 -u -clli MY_CLLI -xos_user NEW_USER -xos_password NEW_PASSWORD
    -s add physical olt chassis to chassis
       params:
          -clli CLLI_NAME - identifies abstract chassis to assign olt chassis to
diff --git a/models/physical/chassis.go b/models/physical/chassis.go
index 4392a10..0c164e9 100644
--- a/models/physical/chassis.go
+++ b/models/physical/chassis.go
@@ -31,12 +31,13 @@
 Chassis is a model that takes up to 16 discreet OLT chassis as if it is a 16 slot OLT chassis
 */
 type Chassis struct {
-	CLLI         string
-	VCoreAddress net.TCPAddr
-	//	Dataswitch   DataSwitch
-	Linecards []SimpleOLT
-	Rack      int
-	Shelf     int
+	CLLI        string
+	XOSAddress  net.TCPAddr
+	XOSUser     string
+	XOSPassword string
+	Linecards   []SimpleOLT
+	Rack        int
+	Shelf       int
 }
 type UnprovisionedSlotError struct {
 	CLLI       string
@@ -71,10 +72,10 @@
 		return
 	}
 	client := &http.Client{}
-	requestList := fmt.Sprintf("http://%s:%d/run", chassis.VCoreAddress.IP.String(), chassis.VCoreAddress.Port)
+	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", "admin@opencord.org")
-	req.Header.Add("xos-password", "letmein")
+	req.Header.Add("xos-username", chassis.XOSUser)
+	req.Header.Add("xos-password", chassis.XOSPassword)
 	resp, err := client.Do(req)
 	if err != nil {
 		//TODO
@@ -99,10 +100,10 @@
 		return
 	}
 	client := &http.Client{}
-	requestList := fmt.Sprintf("http://%s:%d/run", chassis.VCoreAddress.IP.String(), chassis.VCoreAddress.Port)
+	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", "admin@opencord.org")
-	req.Header.Add("xos-password", "letmein")
+	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)
@@ -114,8 +115,8 @@
 	yaml, _ = subStruct.ToYaml()
 	log.Printf("yaml:%s\n", yaml)
 	req, err = http.NewRequest("POST", requestList, strings.NewReader(yaml))
-	req.Header.Add("xos-username", "admin@opencord.org")
-	req.Header.Add("xos-password", "letmein")
+	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)