1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package physicalmachine
17
18 import (
19 "context"
20 "fmt"
21
22 "github.com/pkg/errors"
23 "github.com/spf13/cobra"
24 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
25 "sigs.k8s.io/controller-runtime/pkg/client"
26
27 "github.com/chaos-mesh/chaos-mesh/api/v1alpha1"
28 "github.com/chaos-mesh/chaos-mesh/pkg/chaosctl/common"
29 "github.com/chaos-mesh/chaos-mesh/pkg/label"
30 )
31
32 type PhysicalMachineCreateOptions struct {
33 namespace string
34 labels string
35 remoteIP string
36 chaosdPort int
37 secure bool
38 }
39
40 func NewPhysicalMachineCreateCmd() (*cobra.Command, error) {
41 createOption := &PhysicalMachineCreateOptions{}
42
43 createCmd := &cobra.Command{
44 Use: `create (PHYSICALMACHINE_NAME) [-n NAMESPACE]`,
45 Short: `Create PhysicalMachine CustomResource in Kubernetes cluster`,
46 Long: `Create PhysicalMachine CustomResource in Kubernetes cluster`,
47 SilenceErrors: true,
48 SilenceUsage: true,
49 RunE: func(cmd *cobra.Command, args []string) error {
50 if err := createOption.Validate(); err != nil {
51 return err
52 }
53 return createOption.Run(args)
54 },
55 }
56 createCmd.PersistentFlags().StringVarP(&createOption.namespace, "namespace", "n", "default", "namespace of the certain physical machine")
57 createCmd.PersistentFlags().StringVarP(&createOption.labels, "labels", "l", "", "labels of the certain physical machine (e.g. -l key1=value1,key2=value2)")
58 createCmd.PersistentFlags().StringVar(&createOption.remoteIP, "ip", "", "ip of the remote physical machine")
59 createCmd.PersistentFlags().IntVar(&createOption.chaosdPort, "chaosd-port", 31768, "port of the remote chaosd server listen")
60 createCmd.PersistentFlags().BoolVar(&createOption.secure, "secure", true, "if true, represent that the remote chaosd serve HTTPS")
61
62 return createCmd, nil
63 }
64
65 func (o *PhysicalMachineCreateOptions) Validate() error {
66 if len(o.remoteIP) == 0 {
67 return errors.New("--ip must be specified")
68 }
69 return nil
70 }
71
72 func (o *PhysicalMachineCreateOptions) Run(args []string) error {
73 if len(args) < 1 {
74 return errors.New("physical machine name is required")
75 }
76 physicalMachineName := args[0]
77
78 labels, err := label.ParseLabel(o.labels)
79 if err != nil {
80 return err
81 }
82 address := formatAddress(o.remoteIP, o.chaosdPort, o.secure)
83
84 clientset, err := common.InitClientSet()
85 if err != nil {
86 return err
87 }
88
89 ctx := context.Background()
90 return CreatePhysicalMachine(ctx, clientset.CtrlCli, o.namespace, physicalMachineName, address, labels)
91 }
92
93 func CreatePhysicalMachine(ctx context.Context, c client.Client,
94 namespace, name, address string, labels map[string]string) error {
95 pm := v1alpha1.PhysicalMachine{
96 ObjectMeta: metav1.ObjectMeta{
97 Namespace: namespace,
98 Name: name,
99 Labels: labels,
100 },
101 Spec: v1alpha1.PhysicalMachineSpec{
102 Address: address,
103 },
104 }
105
106 return c.Create(ctx, &pm)
107 }
108
109 func formatAddress(ip string, port int, secure bool) string {
110 protocol := "http"
111 if secure {
112 protocol = "https"
113 }
114 return fmt.Sprintf("%s://%s:%d", protocol, ip, port)
115 }
116