diff --git a/go.mod b/go.mod index 2eafba6..61213f1 100644 --- a/go.mod +++ b/go.mod @@ -3,6 +3,7 @@ module github.com/opiproject/goopicsi go 1.19 require ( + github.com/google/uuid v1.1.2 github.com/opiproject/opi-api v0.0.0-20221129180238-b10361a9c119 github.com/stretchr/testify v1.8.1 google.golang.org/grpc v1.51.0 diff --git a/go.sum b/go.sum index cdce6e7..d26d021 100644 --- a/go.sum +++ b/go.sum @@ -6,8 +6,8 @@ github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY= github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= -github.com/opiproject/opi-api v0.0.0-20221121200811-5d2289de810a h1:dFFDDQez4aCsKEkvEnQ+yFnMu5/yZ/VWBxbIRmAvgd4= -github.com/opiproject/opi-api v0.0.0-20221121200811-5d2289de810a/go.mod h1:92pv4ulvvPMuxCJ9ND3aYbmBfEMLx0VCjpkiR7ZTqPY= +github.com/google/uuid v1.1.2 h1:EVhdT+1Kseyi1/pUmXKaFxYsDNy9RQYkMWRH68J/W7Y= +github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= github.com/opiproject/opi-api v0.0.0-20221129180238-b10361a9c119 h1:exwxNwGuwQtA9IRs2I/Eh22IWeeReAf3uzExgblLytY= github.com/opiproject/opi-api v0.0.0-20221129180238-b10361a9c119/go.mod h1:92pv4ulvvPMuxCJ9ND3aYbmBfEMLx0VCjpkiR7ZTqPY= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= diff --git a/goopicsi.go b/goopicsi.go index 3f67583..16cac06 100644 --- a/goopicsi.go +++ b/goopicsi.go @@ -8,10 +8,13 @@ import ( "context" "errors" "flag" + "fmt" "log" "strings" "time" + "github.com/google/uuid" + pbc "github.com/opiproject/opi-api/common/v1/gen/go" pb "github.com/opiproject/opi-api/storage/v1alpha1/gen/go" "google.golang.org/grpc" @@ -101,7 +104,7 @@ func ConnectToRemoteAndExpose(addr string) error { } // NVMeControllerConnect Connects to remote NVMf controller -func NVMeControllerConnect(id int64, trAddr string, subnqn string, trSvcID int64) error { +func NVMeControllerConnect(id int64, trAddr string, subnqn string, trSvcID int64, hostnqn string) error { if conn == nil { err := dialConnection() if err != nil { @@ -126,6 +129,7 @@ func NVMeControllerConnect(id int64, trAddr string, subnqn string, trSvcID int64 Traddr: trAddr, Subnqn: subnqn, Trsvcid: trSvcID, + Hostnqn: hostnqn, }} response, err := client.NVMfRemoteControllerConnect(ctx, request) if err != nil { @@ -137,7 +141,6 @@ func NVMeControllerConnect(id int64, trAddr string, subnqn string, trSvcID int64 } log.Printf("Remote NVMf controller is already connected with SubNQN: %v", data.GetCtrl().Subnqn) - defer disconnectConnection() return nil } @@ -227,11 +230,11 @@ func NVMeControllerDisconnect(id int64) error { } // ExposeRemoteNVMe creates a new NVMe Subsystem and NVMe controller -func ExposeRemoteNVMe(subsystemID string, subsystemNQN string, maxNamespaces int64, controllerID string) error { +func ExposeRemoteNVMe(subsystemNQN string, maxNamespaces int64) (string, string, error) { if conn == nil { err := dialConnection() if err != nil { - return err + return "", "", err } } @@ -239,6 +242,7 @@ func ExposeRemoteNVMe(subsystemID string, subsystemNQN string, maxNamespaces int defer cancel() client := pb.NewFrontendNvmeServiceClient(conn) + subsystemID := uuid.New().String() data1, err := client.GetNVMeSubsystem(ctx, &pb.GetNVMeSubsystemRequest{SubsystemId: &pbc.ObjectKey{Value: subsystemID}}) if err != nil { log.Printf("No existing NVMe Subsystem found with subsystemID: %v", subsystemID) @@ -256,16 +260,17 @@ func ExposeRemoteNVMe(subsystemID string, subsystemNQN string, maxNamespaces int }) if err != nil { log.Println(err) - return err + return "", "", err } log.Printf("NVMe Subsytem created: %v", response1) } else { log.Printf("NVMe Subsystem is already present with the subsytemID: %v", subsystemID) } + controllerID := uuid.New().String() data2, err := client.GetNVMeController(ctx, &pb.GetNVMeControllerRequest{ControllerId: &pbc.ObjectKey{Value: controllerID}}) if err != nil { - log.Printf("No existing NVMe Controller found with controllerID %v:", controllerID) + log.Printf("No existing NVMe Controller found with controllerID: %v", controllerID) } if data2 == nil { response2, err := client.CreateNVMeController(ctx, &pb.CreateNVMeControllerRequest{ @@ -279,13 +284,13 @@ func ExposeRemoteNVMe(subsystemID string, subsystemNQN string, maxNamespaces int }) if err != nil { log.Println(err) - return err + return subsystemID, "", err } log.Printf("NVMe Controller created: %v", response2) - return nil + return subsystemID, controllerID, nil } log.Printf("NVMe Controller is already present with the controllerID: %v", controllerID) - return nil + return subsystemID, controllerID, nil } // CreateNVMeNamespace Creates a new NVMe namespace @@ -361,6 +366,16 @@ func DeleteNVMeNamespace(id string) error { return nil } +// GenerateHostNQN generates a new hostNQN +func GenerateHostNQN() string { + // Sample of NVMe Qualified Name in UUID-based format - nqn.2014-08.org.nvmexpress:uuid:a11a1111-11a1-111a-a111-1a111aaa1a11 + nqnConst := "nqn.2014-08.org.nvmexpress:uuid:" + nqnUUID := uuid.New().String() + + hostNQN := fmt.Sprintf("%s%s", nqnConst, nqnUUID) + return hostNQN +} + func dialConnection() error { var err error conn, err = grpc.Dial(address, grpc.WithTransportCredentials(insecure.NewCredentials())) diff --git a/goopicsi_test.go b/goopicsi_test.go index d7ac84b..82456d0 100644 --- a/goopicsi_test.go +++ b/goopicsi_test.go @@ -11,7 +11,7 @@ import ( ) func TestNVMeControllerConnect(t *testing.T) { - err := NVMeControllerConnect(12, "", "", 44565) + err := NVMeControllerConnect(12, "", "", 44565, "") if err != nil { log.Println(err) } @@ -57,8 +57,15 @@ func TestDeleteNVMeNamespace(t *testing.T) { } func TestExposeRemoteNVMe(t *testing.T) { - err := ExposeRemoteNVMe("subsystem1", "nqn.2022-09.io.spdk:test", 10, "controller1") + subsystemID, controllerID, err := ExposeRemoteNVMe("nqn.2022-09.io.spdk:test", 10) if err != nil { log.Println(err) } + log.Printf("Subsystem ID: %s", subsystemID) + log.Printf("Controller Id: %s", controllerID) +} + +func TestGenerateHostNQN(t *testing.T) { + hostNQN := GenerateHostNQN() + log.Println(hostNQN) }