-
Notifications
You must be signed in to change notification settings - Fork 30
Expand file tree
/
Copy pathopenstackops.go
More file actions
151 lines (136 loc) · 5.08 KB
/
openstackops.go
File metadata and controls
151 lines (136 loc) · 5.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
// Copyright © 2024 The vjailbreak authors
package openstack
import (
"crypto/tls"
"crypto/x509"
"fmt"
"net/http"
"net/url"
"os"
"time"
"github.com/platform9/vjailbreak/v2v-helper/pkg/constants"
"github.com/platform9/vjailbreak/v2v-helper/pkg/utils"
"github.com/platform9/vjailbreak/v2v-helper/pkg/utils/migrateutils"
"github.com/platform9/vjailbreak/v2v-helper/vm"
"github.com/gophercloud/gophercloud"
"github.com/gophercloud/gophercloud/openstack"
"github.com/gophercloud/gophercloud/openstack/blockstorage/v3/volumes"
"github.com/gophercloud/gophercloud/openstack/compute/v2/flavors"
"github.com/gophercloud/gophercloud/openstack/compute/v2/servers"
"github.com/gophercloud/gophercloud/openstack/networking/v2/networks"
"github.com/gophercloud/gophercloud/openstack/networking/v2/ports"
)
//go:generate mockgen -source=../openstack/openstackops.go -destination=../openstack/openstackops_mock.go -package=openstack
type OpenstackOperations interface {
CreateVolume(name string, size int64, ostype string, uefi bool, volumetype string) (*volumes.Volume, error)
WaitForVolume(volumeID string) error
AttachVolumeToVM(volumeID string) error
WaitForVolumeAttachment(volumeID string) error
DetachVolumeFromVM(volumeID string) error
SetVolumeUEFI(volume *volumes.Volume) error
EnableQGA(volume *volumes.Volume) error
SetVolumeImageMetadata(volume *volumes.Volume) error
SetVolumeBootable(volume *volumes.Volume) error
GetClosestFlavour(cpu int32, memory int32) (*flavors.Flavor, error)
GetFlavor(flavorId string) (*flavors.Flavor, error)
GetNetwork(networkname string) (*networks.Network, error)
GetPort(portID string) (*ports.Port, error)
CreatePort(networkid *networks.Network, mac, ip, vmname string, securityGroups []string) (*ports.Port, error)
CreateVM(flavor *flavors.Flavor, networkIDs, portIDs []string, vminfo vm.VMInfo, availabilityZone string, securityGroups []string, vjailbreakSettings utils.VjailbreakSettings, useFlavorless bool) (*servers.Server, error)
GetSecurityGroupIDs(groupNames []string, projectName string) ([]string, error)
DeleteVolume(volumeID string) error
FindDevice(volumeID string) (string, error)
WaitUntilVMActive(vmID string) (bool, error)
CinderManage(rdmDisk vm.RDMDisk, openstackAPIVersion string) (*volumes.Volume, error)
}
func getCert(endpoint string) (*x509.Certificate, error) {
conf := &tls.Config{
InsecureSkipVerify: true,
}
parsedURL, err := url.Parse(endpoint)
if err != nil {
return nil, fmt.Errorf("error parsing URL: %w", err)
}
hostname := parsedURL.Hostname()
conn, err := tls.Dial("tcp", hostname+":443", conf)
if err != nil {
return nil, fmt.Errorf("error connecting to %s: %w", hostname, err)
}
defer conn.Close()
cert := conn.ConnectionState().PeerCertificates[0]
return cert, nil
}
func validateOpenStack(insecure bool) (*migrateutils.OpenStackClients, error) {
opts, err := openstack.AuthOptionsFromEnv()
if err != nil {
return nil, fmt.Errorf("failed to get OpenStack auth options: %s", err)
}
opts.AllowReauth = true
providerClient, err := openstack.NewClient(opts.IdentityEndpoint)
if err != nil {
return nil, fmt.Errorf("failed to create provider client: %s", err)
}
tlsConfig := &tls.Config{
MinVersion: tls.VersionTLS12,
}
if insecure {
tlsConfig.InsecureSkipVerify = true
} else {
// Get the certificate for the Openstack endpoint
caCert, err := getCert(opts.IdentityEndpoint)
if err != nil {
return nil, fmt.Errorf("failed to get certificate: %s", err)
}
caCertPool, _ := x509.SystemCertPool()
if caCertPool == nil {
caCertPool = x509.NewCertPool()
}
caCertPool.AddCert(caCert)
tlsConfig.RootCAs = caCertPool
}
transport := &http.Transport{
TLSClientConfig: tlsConfig,
}
providerClient.HTTPClient = http.Client{
Transport: transport,
}
// Connection Retry Block
for i := 0; i < constants.MaxIntervalCount; i++ {
err = openstack.Authenticate(providerClient, opts)
if err == nil {
break
}
time.Sleep(5 * time.Second) // Wait for 5 seconds before checking again
}
if err != nil {
return nil, fmt.Errorf("failed to authenticate OpenStack client: %s", err)
}
endpoint := gophercloud.EndpointOpts{
Region: os.Getenv("OS_REGION_NAME"),
}
blockStorageClient, err := openstack.NewBlockStorageV3(providerClient, endpoint)
if err != nil {
return nil, fmt.Errorf("failed to create block storage client: %s", err)
}
computeClient, err := openstack.NewComputeV2(providerClient, endpoint)
if err != nil {
return nil, fmt.Errorf("failed to create compute client: %s", err)
}
networkingClient, err := openstack.NewNetworkV2(providerClient, endpoint)
if err != nil {
return nil, fmt.Errorf("failed to create networking client: %s", err)
}
return &migrateutils.OpenStackClients{
BlockStorageClient: blockStorageClient,
ComputeClient: computeClient,
NetworkingClient: networkingClient,
K8sClient: nil,
}, nil
}
func NewOpenStackClients(insecure bool) (*migrateutils.OpenStackClients, error) {
ostackclients, err := validateOpenStack(insecure)
if err != nil {
return nil, fmt.Errorf("failed to validate OpenStack connection: %s", err)
}
return ostackclients, nil
}