diff --git a/applications/venv-manager/main.go b/applications/venv-manager/main.go index 3d6683a3fbcd36720dc4057e6823af461aeef1f8..4263464c32fcff5c9e057e23090c47e1fbeae7be 100644 --- a/applications/venv-manager/main.go +++ b/applications/venv-manager/main.go @@ -16,9 +16,11 @@ func main() { var yamlFilepath string var customContainerRegistryURL string var sdnConfigFilepath string + var mode string dialOption := grpc.WithTransportCredentials(insecure.NewCredentials()) + flag.StringVar(&mode, "mode", "extract", "") flag.StringVar(&dialConnectionURL, "controller", "localhost:55055", "") flag.StringVar(&yamlFilepath, "topology", "venv.clab.yaml", "") flag.StringVar(&customContainerRegistryURL, "registry", "", "") @@ -27,6 +29,7 @@ func main() { // Define own output of --help and parsing error, as some library also uses the flags library and adds there flags to ours, which is not intended. flag.Usage = func() { fmt.Printf("Usable flags of the venv-manager:\n\n") + fmt.Println("--mode string\n\t The mode of the venv-manager. use either 'extract' or 'deploy'. (Default: 'extract')") fmt.Println("--controller string\n\t Controller URL and Port. (Default: 'localhost:55055')") fmt.Println("--topology string\n\t Filename of the resulting topology file. (Default: 'venv.clab.yaml')") fmt.Println("--sdnconfig string\n\t Filename of the resulting SDN configuration file. (Default: 'sdn_config.json')") @@ -37,23 +40,34 @@ func main() { customContainerRegistryURL = ensureLastCharIsSlash(customContainerRegistryURL) - fmt.Println("I will try to connect to goSDN located at", dialConnectionURL) - venvManager := venvmanager.NewVenvManager(dialConnectionURL, dialOption, yamlFilepath, sdnConfigFilepath, customContainerRegistryURL) + if mode == "extract" { + fmt.Println("I will try to connect to goSDN located at", dialConnectionURL) + venvManager := venvmanager.NewVenvManager(dialConnectionURL, dialOption, yamlFilepath, sdnConfigFilepath, customContainerRegistryURL) - fmt.Println("Generating topology file...") - err := venvManager.CreateTopologyFile() - if err != nil { - fmt.Println(err) - fmt.Println("An error occurred, exiting.") - os.Exit(1) - } + fmt.Println("Generating topology file...") + err := venvManager.CreateTopologyFile() + if err != nil { + printErrAndAbort(err) + } + + fmt.Println("Generating SDN configuration file...") + err = venvManager.CreateSDNConfigFile() + if err != nil { + printErrAndAbort(err) + } + } else if mode == "deploy" { + fmt.Println("I will try to connect to goSDN located at", dialConnectionURL) + venvManager := venvmanager.NewVenvManager(dialConnectionURL, dialOption, yamlFilepath, sdnConfigFilepath, customContainerRegistryURL) + + //TODO: read topology file and tell containerlab to start environment. - fmt.Println("Generating SDN configuration file...") - err = venvManager.CreateSDNConfigFile() - if err != nil { - fmt.Println(err) - fmt.Println("An error occurred, exiting.") - os.Exit(1) + err := venvManager.ReadAndSendSDNConfig() + if err != nil { + printErrAndAbort(err) + } + + } else { + fmt.Println("No valid mode selected. Choose either 'extract' or 'deploy'.") } fmt.Println("All done!") @@ -72,3 +86,9 @@ func ensureLastCharIsSlash(inputString string) string { return inputString + "/" } + +func printErrAndAbort(err error) { + fmt.Println(err) + fmt.Println("An error occurred, exiting.") + os.Exit(1) +} diff --git a/applications/venv-manager/venv-manager/venv-manager.go b/applications/venv-manager/venv-manager/venv-manager.go index 005a1f01a33055426edaababe2bc21d4173d5b4f..4905be72b3d215379c41046fe400abcf0e9c4ede 100644 --- a/applications/venv-manager/venv-manager/venv-manager.go +++ b/applications/venv-manager/venv-manager/venv-manager.go @@ -49,7 +49,6 @@ func NewVenvManager(dialConnectionURL string, dialOption grpc.DialOption, yamlFi func (v *VenvManager) createConnection() (*grpc.ClientConn, error) { conn, err := grpc.Dial(v.dialConnectionURL, v.dialOption) - if err != nil { return nil, err } @@ -59,12 +58,54 @@ func (v *VenvManager) createConnection() (*grpc.ClientConn, error) { func (v *VenvManager) closeConnection(conn *grpc.ClientConn) { err := conn.Close() - if err != nil { fmt.Println(err) } } +// ReadAndSendSDNConfig gets the SDN config data and sends it to the controller. +func (v *VenvManager) ReadAndSendSDNConfig() error { + sdnConfigData, err := v.readSDNConfigFile() + if err != nil { + return err + } + + err = v.sendSDNConfigData(&sdnConfigData) + if err != nil { + return err + } + + return nil +} + +// getSDNConfigData gets the sDN configuration data. +func (v *VenvManager) sendSDNConfigData(sdnConfigData *string) error { + conn, err := v.createConnection() + if err != nil { + return err + } + defer v.closeConnection(conn) + + ctx := context.Background() + + //get PND, might remove later because we won't support PND in the future and it gets infored everywhere + coreService := corePb.NewCoreServiceClient(conn) + pndRes, err := coreService.GetPndList(ctx, &corePb.GetPndListRequest{Timestamp: getTimestamp()}) + if err != nil { + return err + } + v.pnd = pndRes.Pnd[0].Id + + configMgmtService := configMgmtPb.NewConfigurationManagementServiceClient(conn) + + _, err = configMgmtService.ImportSDNConfig(ctx, &configMgmtPb.ImportSDNConfigRequest{Timestamp: getTimestamp(), Pid: v.pnd, SdnConfigData: *sdnConfigData}) + if err != nil { + return err + } + + return nil +} + // CreateSDNConfigFile creates the SDN configuration file. func (v *VenvManager) CreateSDNConfigFile() error { sdnConfigReponse, err := v.getSDNConfigData() @@ -72,7 +113,7 @@ func (v *VenvManager) CreateSDNConfigFile() error { return err } - err = v.writeSDNConfigToFile(*sdnConfigReponse) + err = v.writeSDNConfigFile(*sdnConfigReponse) if err != nil { return err } @@ -105,11 +146,11 @@ func (v *VenvManager) getSDNConfigData() (*string, error) { return nil, err } - return &sdnConfigResponse.SdnConfig, nil + return &sdnConfigResponse.SdnConfigData, nil } -// writeSDNConfigToFile wriets the SDN configuration in a string to a file. -func (v *VenvManager) writeSDNConfigToFile(sdnConfigToWrite string) error { +// writeSDNConfigFile writes the SDN configuration in a string to a file. +func (v *VenvManager) writeSDNConfigFile(sdnConfigToWrite string) error { err := os.WriteFile(v.sdnConfigFilepath, []byte(sdnConfigToWrite), 0644) if err != nil { return err @@ -118,6 +159,16 @@ func (v *VenvManager) writeSDNConfigToFile(sdnConfigToWrite string) error { return nil } +// readSDNConfigToFile reads the SDN configuration from a file to a string. +func (v *VenvManager) readSDNConfigFile() (string, error) { + content, err := os.ReadFile(v.sdnConfigFilepath) + if err != nil { + return "", err + } + + return string(content), nil +} + // CreateTopologyFile creates the topology file. func (v *VenvManager) CreateTopologyFile() error { topologyData, err := v.getTopologyData()