diff --git a/cmd/create/create.go b/cmd/create/create.go new file mode 100644 index 00000000..d8c09486 --- /dev/null +++ b/cmd/create/create.go @@ -0,0 +1,34 @@ +// Copyright 2021 IBM Corp +// +// 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 create + +import ( + "github.com/spf13/cobra" + + "github.com/ppc64le-cloud/pvsadm/cmd/create/port" + "github.com/ppc64le-cloud/pvsadm/pkg" +) + +var Cmd = &cobra.Command{ + Use: "create", + Short: "Create the resources", + Long: `Create the resources`, +} + +func init() { + Cmd.AddCommand(port.Cmd) + Cmd.PersistentFlags().StringVarP(&pkg.Options.InstanceID, "instance-id", "i", "", "Instance ID of the PowerVS instance") + _ = Cmd.MarkPersistentFlagRequired("instance-id") +} diff --git a/cmd/create/port/port.go b/cmd/create/port/port.go new file mode 100644 index 00000000..10ddfd5f --- /dev/null +++ b/cmd/create/port/port.go @@ -0,0 +1,102 @@ +// Copyright 2021 IBM Corp +// +// 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 port + +import ( + "fmt" + "strings" + + "github.com/IBM-Cloud/power-go-client/power/client/p_cloud_networks" + "github.com/IBM-Cloud/power-go-client/power/models" + "github.com/spf13/cobra" + "k8s.io/klog/v2" + + "github.com/ppc64le-cloud/pvsadm/pkg" + "github.com/ppc64le-cloud/pvsadm/pkg/client" + "github.com/ppc64le-cloud/pvsadm/pkg/utils" +) + +var ( + network, ipaddress, description string +) + +var Cmd = &cobra.Command{ + Use: "port", + Short: "Create PowerVS network port", + Long: `Create PowerVS network port`, + RunE: func(cmd *cobra.Command, args []string) error { + opt := pkg.Options + + c, err := client.NewClientWithEnv(opt.APIKey, opt.Environment, opt.Debug) + if err != nil { + klog.Errorf("failed to create a session with IBM cloud: %v", err) + return err + } + + pvmclient, err := client.NewPVMClientWithEnv(c, opt.InstanceID, opt.InstanceName, opt.Environment) + if err != nil { + return err + } + + networks, err := pvmclient.NetworkClient.GetAll() + if err != nil { + return fmt.Errorf("failed to get the networks, err: %v", err) + } + + var networkNames, networkIDs []string + for _, net := range networks.Networks { + networkIDs = append(networkIDs, *net.NetworkID) + networkNames = append(networkNames, *net.Name) + } + + var netID string + + if utils.Contains(networkIDs, network) { + netID = network + } else if utils.Contains(networkNames, network) { + for _, n := range networks.Networks { + if *n.Name == network { + netID = *n.NetworkID + } + } + } else { + return fmt.Errorf("not able to find network: \"%s\" by ID or name in the list: ids:[%s], names: [%s]", network, strings.Join(networkIDs, ","), strings.Join(networkNames, ",")) + } + + params := &p_cloud_networks.PcloudNetworksPortsPostParams{ + Body: &models.NetworkPortCreate{ + Description: description, + IPAddress: ipaddress, + }, + } + + port, err := pvmclient.NetworkClient.CreatePort(netID, params) + if err != nil { + return fmt.Errorf("failed to create a port, err: %v", err) + } + klog.Infof("Successfully created a port, id: %s", *port.PortID) + + table := utils.NewTable() + table.Render([]*models.NetworkPort{port}, []string{}) + return nil + }, +} + +func init() { + Cmd.Flags().StringVar(&network, "network", "", "Network ID or Name(preference will be given to the ID over Name)") + Cmd.Flags().StringVar(&ipaddress, "ip-address", "", "The requested ip address of this port") + Cmd.Flags().StringVar(&description, "description", "", "Description of the port") + _ = Cmd.MarkFlagRequired("network") +} diff --git a/cmd/delete/delete.go b/cmd/delete/delete.go new file mode 100644 index 00000000..af8a3b73 --- /dev/null +++ b/cmd/delete/delete.go @@ -0,0 +1,34 @@ +// Copyright 2021 IBM Corp +// +// 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 delete + +import ( + "github.com/spf13/cobra" + + "github.com/ppc64le-cloud/pvsadm/cmd/delete/port" + "github.com/ppc64le-cloud/pvsadm/pkg" +) + +var Cmd = &cobra.Command{ + Use: "delete", + Short: "Delete the resources", + Long: `Delete the resources`, +} + +func init() { + Cmd.AddCommand(port.Cmd) + Cmd.PersistentFlags().StringVarP(&pkg.Options.InstanceID, "instance-id", "i", "", "Instance ID of the PowerVS instance") + _ = Cmd.MarkPersistentFlagRequired("instance-id") +} diff --git a/cmd/delete/port/port.go b/cmd/delete/port/port.go new file mode 100644 index 00000000..fa0ae908 --- /dev/null +++ b/cmd/delete/port/port.go @@ -0,0 +1,90 @@ +// Copyright 2021 IBM Corp +// +// 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 port + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + "k8s.io/klog/v2" + + "github.com/ppc64le-cloud/pvsadm/pkg" + "github.com/ppc64le-cloud/pvsadm/pkg/client" + "github.com/ppc64le-cloud/pvsadm/pkg/utils" +) + +var ( + network, portID string +) + +var Cmd = &cobra.Command{ + Use: "port", + Short: "Delete PowerVS network port", + Long: `Delete PowerVS network port`, + RunE: func(cmd *cobra.Command, args []string) error { + opt := pkg.Options + + c, err := client.NewClientWithEnv(opt.APIKey, opt.Environment, opt.Debug) + if err != nil { + klog.Errorf("failed to create a session with IBM cloud: %v", err) + return err + } + + pvmclient, err := client.NewPVMClientWithEnv(c, opt.InstanceID, opt.InstanceName, opt.Environment) + if err != nil { + return err + } + + networks, err := pvmclient.NetworkClient.GetAll() + if err != nil { + return fmt.Errorf("failed to get the networks, err: %v", err) + } + + var networkNames, networkIDs []string + for _, net := range networks.Networks { + networkIDs = append(networkIDs, *net.NetworkID) + networkNames = append(networkNames, *net.Name) + } + + var netID string + + if utils.Contains(networkIDs, network) { + netID = network + } else if utils.Contains(networkNames, network) { + for _, n := range networks.Networks { + if *n.Name == network { + netID = *n.NetworkID + } + } + } else { + return fmt.Errorf("not able to find network: \"%s\" by ID or name in the list: ids:[%s], names: [%s]", network, strings.Join(networkIDs, ","), strings.Join(networkNames, ",")) + } + + _, err = pvmclient.NetworkClient.DeletePort(netID, portID) + if err != nil { + return fmt.Errorf("failed to delete a port, err: %v", err) + } + klog.Infof("Successfully deleted a port, id: %s", portID) + return nil + }, +} + +func init() { + Cmd.Flags().StringVar(&network, "network", "", "Network ID or Name(preference will be given to the ID over Name)") + Cmd.Flags().StringVar(&portID, "port-id", "", "Port ID to be deleted") + _ = Cmd.MarkFlagRequired("network") + _ = Cmd.MarkFlagRequired("port-id") +} diff --git a/cmd/get/get.go b/cmd/get/get.go index 02bcb7aa..4e199a83 100644 --- a/cmd/get/get.go +++ b/cmd/get/get.go @@ -15,9 +15,11 @@ package get import ( + "github.com/spf13/cobra" + "github.com/ppc64le-cloud/pvsadm/cmd/get/events" + "github.com/ppc64le-cloud/pvsadm/cmd/get/ports" "github.com/ppc64le-cloud/pvsadm/pkg" - "github.com/spf13/cobra" ) var Cmd = &cobra.Command{ @@ -28,6 +30,7 @@ var Cmd = &cobra.Command{ func init() { Cmd.AddCommand(events.Cmd) + Cmd.AddCommand(ports.Cmd) Cmd.PersistentFlags().StringVarP(&pkg.Options.InstanceID, "instance-id", "i", "", "Instance ID of the PowerVS instance") Cmd.PersistentFlags().StringVarP(&pkg.Options.InstanceName, "instance-name", "n", "", "Instance name of the PowerVS") } diff --git a/cmd/get/ports/ports.go b/cmd/get/ports/ports.go new file mode 100644 index 00000000..24c92ee7 --- /dev/null +++ b/cmd/get/ports/ports.go @@ -0,0 +1,96 @@ +// Copyright 2021 IBM Corp +// +// 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 ports + +import ( + "fmt" + "strings" + + "github.com/spf13/cobra" + "k8s.io/klog/v2" + + "github.com/ppc64le-cloud/pvsadm/pkg" + "github.com/ppc64le-cloud/pvsadm/pkg/client" + "github.com/ppc64le-cloud/pvsadm/pkg/utils" +) + +var ( + network string +) + +var Cmd = &cobra.Command{ + Use: "ports", + Short: "Get PowerVS network ports", + Long: `Get PowerVS network ports`, + PreRunE: func(cmd *cobra.Command, args []string) error { + if pkg.Options.InstanceID == "" && pkg.Options.InstanceName == "" { + return fmt.Errorf("--instance-id or --instance-name required") + } + return nil + }, + RunE: func(cmd *cobra.Command, args []string) error { + opt := pkg.Options + + c, err := client.NewClientWithEnv(opt.APIKey, opt.Environment, opt.Debug) + if err != nil { + klog.Errorf("failed to create a session with IBM cloud: %v", err) + return err + } + + pvmclient, err := client.NewPVMClientWithEnv(c, opt.InstanceID, opt.InstanceName, opt.Environment) + if err != nil { + return err + } + + networks, err := pvmclient.NetworkClient.GetAll() + if err != nil { + return fmt.Errorf("failed to get the networks, err: %v", err) + } + + var networkNames, networkIDs []string + for _, net := range networks.Networks { + networkIDs = append(networkIDs, *net.NetworkID) + networkNames = append(networkNames, *net.Name) + } + + var netID string + + if utils.Contains(networkIDs, network) { + netID = network + } else if utils.Contains(networkNames, network) { + for _, n := range networks.Networks { + if *n.Name == network { + netID = *n.NetworkID + } + } + } else { + return fmt.Errorf("not able to find network: \"%s\" by ID or name in the list: ids:[%s], names: [%s]", network, strings.Join(networkIDs, ","), strings.Join(networkNames, ",")) + } + + ports, err := pvmclient.NetworkClient.GetAllPort(netID) + if err != nil { + return fmt.Errorf("failed to get the ports, err: %v", err) + } + + table := utils.NewTable() + table.Render(ports.Ports, []string{"href", "pvminstance"}) + return nil + }, +} + +func init() { + Cmd.Flags().StringVar(&network, "network", "", "Network ID or Name(preference will be given to the ID over Name)") + _ = Cmd.MarkFlagRequired("network") +} diff --git a/cmd/root.go b/cmd/root.go index 65602600..e4fb73ca 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,7 +17,6 @@ package cmd import ( goflag "flag" "fmt" - "github.com/ppc64le-cloud/pvsadm/pkg/client" "os" "strings" @@ -25,12 +24,15 @@ import ( flag "github.com/spf13/pflag" "k8s.io/klog/v2" + "github.com/ppc64le-cloud/pvsadm/cmd/create" + deletecmd "github.com/ppc64le-cloud/pvsadm/cmd/delete" "github.com/ppc64le-cloud/pvsadm/cmd/get" "github.com/ppc64le-cloud/pvsadm/cmd/image" "github.com/ppc64le-cloud/pvsadm/cmd/purge" "github.com/ppc64le-cloud/pvsadm/cmd/version" "github.com/ppc64le-cloud/pvsadm/pkg" "github.com/ppc64le-cloud/pvsadm/pkg/audit" + "github.com/ppc64le-cloud/pvsadm/pkg/client" ) var rootCmd = &cobra.Command{ @@ -63,6 +65,8 @@ func init() { rootCmd.AddCommand(get.Cmd) rootCmd.AddCommand(version.Cmd) rootCmd.AddCommand(image.Cmd) + rootCmd.AddCommand(create.Cmd) + rootCmd.AddCommand(deletecmd.Cmd) rootCmd.PersistentFlags().StringVarP(&pkg.Options.APIKey, "api-key", "k", "", "IBMCLOUD API Key(env name: IBMCLOUD_API_KEY)") rootCmd.PersistentFlags().StringVar(&pkg.Options.Environment, "env", client.DefaultEnv, "IBM Cloud Environments, supported are: ["+strings.Join(client.ListEnvironments(), ", ")+"]") rootCmd.PersistentFlags().BoolVar(&pkg.Options.Debug, "debug", false, "Enable PowerVS debug option(ATTENTION: dev only option, may print sensitive data from APIs)") diff --git a/pkg/client/network/network.go b/pkg/client/network/network.go index b33fc427..e44a361b 100644 --- a/pkg/client/network/network.go +++ b/pkg/client/network/network.go @@ -83,3 +83,19 @@ func (c *Client) GetAllPurgeable(before, since time.Duration, expr string) ([]*m } return candidates, nil } + +func (c *Client) CreatePort(id string, params *p_cloud_networks.PcloudNetworksPortsPostParams) (*models.NetworkPort, error) { + return c.client.CreatePort(id, c.instanceID, params, pkg.TIMEOUT) +} + +func (c *Client) DeletePort(id, portID string) (*models.Object, error) { + return c.client.DeletePort(id, c.instanceID, portID, pkg.TIMEOUT) +} + +func (c *Client) GetPort(id, portID string) (*models.NetworkPort, error) { + return c.client.GetPort(id, c.instanceID, portID, pkg.TIMEOUT) +} + +func (c *Client) GetAllPort(id string) (*models.NetworkPorts, error) { + return c.client.GetAllPort(id, c.instanceID, pkg.TIMEOUT) +}