Skip to content

Commit b68293b

Browse files
committed
Initial oVirt provisioning support.
1 parent 1089770 commit b68293b

20 files changed

Lines changed: 10782 additions & 2 deletions

config/crds/hive.openshift.io_clusterdeployments.yaml

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -423,6 +423,27 @@ spec:
423423
- cloud
424424
- credentialsSecretRef
425425
type: object
426+
ovirt:
427+
description: Ovirt is the configuration used when installing on
428+
oVirt
429+
properties:
430+
credentialsSecretRef:
431+
description: 'CredentialsSecretRef refers to a secret that contains
432+
the oVirt account access credentials with fields: ovirt_url,
433+
ovirt_username, ovirt_password, ovirt_ca_bundle'
434+
properties:
435+
name:
436+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
437+
TODO: Add other useful fields. apiVersion, kind, uid?'
438+
type: string
439+
type: object
440+
ovirt_cluster_id:
441+
description: The target cluster under which all VMs will run
442+
type: string
443+
required:
444+
- credentialsSecretRef
445+
- ovirt_cluster_id
446+
type: object
426447
vsphere:
427448
description: VSphere is the configuration used when installing on
428449
vSphere

config/crds/hive.openshift.io_clusterdeprovisions.yaml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,25 @@ spec:
127127
required:
128128
- cloud
129129
type: object
130+
ovirt:
131+
description: Ovirt contains oVirt-specific deprovision settings
132+
properties:
133+
credentialsSecretRef:
134+
description: CredentialsSecretRef is the oVirt account credentials
135+
to use for deprovisioning the cluster
136+
properties:
137+
name:
138+
description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names
139+
TODO: Add other useful fields. apiVersion, kind, uid?'
140+
type: string
141+
type: object
142+
ovirt_cluster_id:
143+
description: The oVirt cluster ID
144+
type: string
145+
required:
146+
- credentialsSecretRef
147+
- ovirt_cluster_id
148+
type: object
130149
vsphere:
131150
description: VSphere contains VMWare vSphere-specific deprovision
132151
settings

config/crds/hive.openshift.io_machinepools.yaml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,10 @@ spec:
201201
required:
202202
- flavor
203203
type: object
204+
ovirt:
205+
description: Ovirt is the configuration used when installing on
206+
oVirt.
207+
type: object
204208
vsphere:
205209
description: VSphere is the configuration used when installing on
206210
vSphere

contrib/pkg/createcluster/create.go

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ import (
2828
azurecredutil "github.com/openshift/hive/contrib/pkg/utils/azure"
2929
gcputils "github.com/openshift/hive/contrib/pkg/utils/gcp"
3030
openstackutils "github.com/openshift/hive/contrib/pkg/utils/openstack"
31+
ovirtutils "github.com/openshift/hive/contrib/pkg/utils/ovirt"
3132
"github.com/openshift/hive/pkg/apis"
3233
hivev1 "github.com/openshift/hive/pkg/apis/hive/v1"
3334
"github.com/openshift/hive/pkg/clusterresource"
@@ -92,6 +93,7 @@ const (
9293
cloudGCP = "gcp"
9394
cloudOpenStack = "openstack"
9495
cloudVSphere = "vsphere"
96+
cloudOVirt = "ovirt"
9597

9698
testFailureManifest = `apiVersion: v1
9799
kind: NotARealSecret
@@ -109,6 +111,7 @@ var (
109111
cloudGCP: true,
110112
cloudOpenStack: true,
111113
cloudVSphere: true,
114+
cloudOVirt: true,
112115
}
113116
)
114117

@@ -172,6 +175,14 @@ type Options struct {
172175
VSphereNetwork string
173176
VSphereCACerts string
174177

178+
// Ovirt
179+
OvirtClusterID string
180+
OvirtStorageDomainID string
181+
OvirtNetworkName string
182+
OvirtAPIVIP string
183+
OvirtDNSVIP string
184+
OvirtIngressVIP string
185+
175186
homeDir string
176187
}
177188

@@ -199,7 +210,8 @@ create-cluster CLUSTER_DEPLOYMENT_NAME --cloud=aws
199210
create-cluster CLUSTER_DEPLOYMENT_NAME --cloud=azure --azure-base-domain-resource-group-name=RESOURCE_GROUP_NAME
200211
create-cluster CLUSTER_DEPLOYMENT_NAME --cloud=gcp
201212
create-cluster CLUSTER_DEPLOYMENT_NAME --cloud=openstack --openstack-api-floating-ip=192.168.1.2 --openstack-cloud=mycloud
202-
create-cluster CLUSTER_DEPLOYMENT_NAME --cloud=vsphere --vsphere-vcenter=vmware.devcluster.com --vsphere-datacenter=dc1 --vsphere-default-datastore=nvme-ds1 --vsphere-api-vip=192.168.1.2 --vsphere-ingress-vip=192.168.1.3 --vsphere-cluster=devel --vsphere-network="VM Network" --vsphere-ca-certs=/path/to/cert`,
213+
create-cluster CLUSTER_DEPLOYMENT_NAME --cloud=vsphere --vsphere-vcenter=vmware.devcluster.com --vsphere-datacenter=dc1 --vsphere-default-datastore=nvme-ds1 --vsphere-api-vip=192.168.1.2 --vsphere-ingress-vip=192.168.1.3 --vsphere-cluster=devel --vsphere-network="VM Network" --vsphere-ca-certs=/path/to/cert
214+
create-cluster CLUSTER_DEPLOYMENT_NAME --cloud=ovirt`,
203215
Short: "Creates a new Hive cluster deployment",
204216
Long: fmt.Sprintf(longDesc, defaultSSHPublicKeyFile, defaultPullSecretFile),
205217
Args: cobra.ExactArgs(1),
@@ -279,6 +291,14 @@ create-cluster CLUSTER_DEPLOYMENT_NAME --cloud=vsphere --vsphere-vcenter=vmware.
279291
flags.StringVar(&opt.VSphereNetwork, "vsphere-network", "", "Name of the network to be used by the cluster")
280292
flags.StringVar(&opt.VSphereCACerts, "vsphere-ca-certs", "", "Path to vSphere CA certificate, multiple CA paths can be : delimited")
281293

294+
// oVirt flags
295+
flags.StringVar(&opt.OvirtClusterID, "ovirt-cluster-id", "", "The oVirt cluster under which all VMs will run")
296+
flags.StringVar(&opt.OvirtStorageDomainID, "ovirt-storage-domain-id", "", "oVirt storage domain under which all VM disk would be created")
297+
flags.StringVar(&opt.OvirtNetworkName, "ovirt-network-name", "ovirtmgmt", "oVirt network of all the network interfaces of the nodes")
298+
flags.StringVar(&opt.OvirtAPIVIP, "ovirt-api-vip", "", "IP which will be served by bootstrap and then pivoted masters, using keepalived")
299+
flags.StringVar(&opt.OvirtDNSVIP, "ovirt-dns-vip", "", "IP of the internal DNS which will be operated by the cluster")
300+
flags.StringVar(&opt.OvirtIngressVIP, "ovirt-ingress-vip", "", "External IP which routes to the default ingress controller")
301+
282302
return cmd
283303
}
284304

@@ -595,6 +615,22 @@ func (o *Options) GenerateObjects() ([]runtime.Object, error) {
595615
CACert: bytes.Join(caCerts, []byte("\n")),
596616
}
597617
builder.CloudBuilder = vsphereProvider
618+
case cloudOVirt:
619+
oVirtConfigYAMLContent, err := ovirtutils.GetCreds(o.CredsFile)
620+
if err != nil {
621+
return nil, err
622+
}
623+
oVirtProvider := &clusterresource.OvirtCloudBuilder{
624+
OVirtConfigYAMLContent: oVirtConfigYAMLContent,
625+
ClusterID: o.OvirtClusterID,
626+
StorageDomainID: o.OvirtStorageDomainID,
627+
NetworkName: o.OvirtNetworkName,
628+
APIVIP: o.OvirtAPIVIP,
629+
DNSVIP: o.OvirtDNSVIP,
630+
IngressVIP: o.OvirtIngressVIP,
631+
}
632+
builder.CloudBuilder = oVirtProvider
633+
builder.SkipMachinePoolGeneration = true
598634
}
599635

600636
if len(o.ServingCert) != 0 {

contrib/pkg/deprovision/deprovision.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,5 +17,6 @@ func NewDeprovisionCommand() *cobra.Command {
1717
cmd.AddCommand(NewDeprovisionGCPCommand())
1818
cmd.AddCommand(NewDeprovisionOpenStackCommand())
1919
cmd.AddCommand(NewDeprovisionvSphereCommand())
20+
cmd.AddCommand(NewDeprovisionOvirtCommand())
2021
return cmd
2122
}

contrib/pkg/deprovision/ovirt.go

Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
package deprovision
2+
3+
import (
4+
"errors"
5+
"os"
6+
7+
log "github.com/sirupsen/logrus"
8+
"github.com/spf13/cobra"
9+
10+
"github.com/openshift/installer/pkg/destroy/ovirt"
11+
"github.com/openshift/installer/pkg/types"
12+
typesovirt "github.com/openshift/installer/pkg/types/ovirt"
13+
)
14+
15+
// oVirtOptions is the set of options to deprovision an oVirt cluster
16+
type oVirtOptions struct {
17+
logLevel string
18+
infraID string
19+
clusterID string
20+
}
21+
22+
// NewDeprovisionOvirtCommand is the entrypoint to create the oVirt deprovision subcommand
23+
func NewDeprovisionOvirtCommand() *cobra.Command {
24+
opt := &oVirtOptions{}
25+
cmd := &cobra.Command{
26+
Use: "ovirt INFRAID",
27+
Short: "Deprovision oVirt assets (as created by openshift-installer)",
28+
Args: cobra.ExactArgs(1),
29+
Run: func(cmd *cobra.Command, args []string) {
30+
if err := opt.Complete(cmd, args); err != nil {
31+
log.WithError(err).Fatal("failed to complete options")
32+
}
33+
if err := opt.Validate(cmd); err != nil {
34+
log.WithError(err).Fatal("validation failed")
35+
}
36+
if err := opt.Run(); err != nil {
37+
log.WithError(err).Fatal("Runtime error")
38+
}
39+
},
40+
}
41+
flags := cmd.Flags()
42+
flags.StringVar(&opt.logLevel, "loglevel", "info", "log level, one of: debug, info, warn, error, fatal, panic")
43+
flags.StringVar(&opt.clusterID, "ovirt-cluster-id", "", "oVirt cluster ID")
44+
return cmd
45+
}
46+
47+
// Complete finishes parsing arguments for the command
48+
func (o *oVirtOptions) Complete(cmd *cobra.Command, args []string) error {
49+
o.infraID = args[0]
50+
return nil
51+
}
52+
53+
// Validate ensures that option values make sense
54+
func (o *oVirtOptions) Validate(cmd *cobra.Command) error {
55+
if o.clusterID == "" {
56+
return errors.New("must provide --ovirt-cluster-id or set")
57+
}
58+
return nil
59+
}
60+
61+
// Run executes the command
62+
func (o *oVirtOptions) Run() error {
63+
// Set log level
64+
level, err := log.ParseLevel(o.logLevel)
65+
if err != nil {
66+
log.WithError(err).Error("cannot parse log level")
67+
return err
68+
}
69+
70+
logger := log.NewEntry(&log.Logger{
71+
Out: os.Stdout,
72+
Formatter: &log.TextFormatter{
73+
FullTimestamp: true,
74+
},
75+
Hooks: make(log.LevelHooks),
76+
Level: level,
77+
})
78+
79+
metadata := &types.ClusterMetadata{
80+
InfraID: o.infraID,
81+
ClusterPlatformMetadata: types.ClusterPlatformMetadata{
82+
Ovirt: &typesovirt.Metadata{
83+
ClusterID: o.clusterID,
84+
},
85+
},
86+
}
87+
88+
destroyer, err := ovirt.New(logger, metadata)
89+
if err != nil {
90+
return err
91+
}
92+
93+
return destroyer.Run()
94+
}

contrib/pkg/utils/ovirt/ovirt.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
package ovirt
2+
3+
import (
4+
"io/ioutil"
5+
"os"
6+
"path/filepath"
7+
8+
"k8s.io/client-go/util/homedir"
9+
10+
"github.com/openshift/hive/pkg/constants"
11+
)
12+
13+
// GetCreds reads oVirt credentials either from the specified credentials file,
14+
// or ~/.ovirt/ovirt-config.yaml
15+
func GetCreds(credsFile string) ([]byte, error) {
16+
if credsFile == "" {
17+
for _, filePath := range []string{filepath.Join(homedir.HomeDir(), ".ovirt", constants.OvirtCredentialsName)} {
18+
19+
_, err := os.Stat(filePath)
20+
if err != nil && !os.IsNotExist(err) {
21+
return nil, err
22+
}
23+
if os.IsNotExist(err) {
24+
continue
25+
}
26+
credsFile = filePath
27+
break
28+
}
29+
}
30+
// log.WithField("credsFile", credsFile).Info("Loading oVirt creds")
31+
return ioutil.ReadFile(credsFile)
32+
}

pkg/apis/hive/v1/clusterdeployment_types.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"github.com/openshift/hive/pkg/apis/hive/v1/baremetal"
1111
"github.com/openshift/hive/pkg/apis/hive/v1/gcp"
1212
"github.com/openshift/hive/pkg/apis/hive/v1/openstack"
13+
"github.com/openshift/hive/pkg/apis/hive/v1/ovirt"
1314
"github.com/openshift/hive/pkg/apis/hive/v1/vsphere"
1415
)
1516

@@ -334,6 +335,9 @@ type Platform struct {
334335

335336
// VSphere is the configuration used when installing on vSphere
336337
VSphere *vsphere.Platform `json:"vsphere,omitempty"`
338+
339+
// Ovirt is the configuration used when installing on oVirt
340+
Ovirt *ovirt.Platform `json:"ovirt,omitempty"`
337341
}
338342

339343
// ClusterIngress contains the configurable pieces for any ClusterIngress objects

pkg/apis/hive/v1/clusterdeprovision_types.go

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,8 @@ type ClusterDeprovisionPlatform struct {
3636
OpenStack *OpenStackClusterDeprovision `json:"openstack,omitempty"`
3737
// VSphere contains VMWare vSphere-specific deprovision settings
3838
VSphere *VSphereClusterDeprovision `json:"vsphere,omitempty"`
39+
// Ovirt contains oVirt-specific deprovision settings
40+
Ovirt *OvirtClusterDeprovision `json:"ovirt,omitempty"`
3941
}
4042

4143
// AWSClusterDeprovision contains AWS-specific configuration for a ClusterDeprovision
@@ -80,6 +82,14 @@ type VSphereClusterDeprovision struct {
8082
VCenter string `json:"vCenter"`
8183
}
8284

85+
// OvirtClusterDeprovision contains oVirt-specific configuration for a ClusterDeprovision
86+
type OvirtClusterDeprovision struct {
87+
// The oVirt cluster ID
88+
ClusterID string `json:"ovirt_cluster_id"`
89+
// CredentialsSecretRef is the oVirt account credentials to use for deprovisioning the cluster
90+
CredentialsSecretRef corev1.LocalObjectReference `json:"credentialsSecretRef"`
91+
}
92+
8393
// +genclient
8494
// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object
8595

pkg/apis/hive/v1/machinepool_types.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"github.com/openshift/hive/pkg/apis/hive/v1/azure"
99
"github.com/openshift/hive/pkg/apis/hive/v1/gcp"
1010
"github.com/openshift/hive/pkg/apis/hive/v1/openstack"
11+
"github.com/openshift/hive/pkg/apis/hive/v1/ovirt"
1112
"github.com/openshift/hive/pkg/apis/hive/v1/vsphere"
1213
)
1314

@@ -77,6 +78,8 @@ type MachinePoolPlatform struct {
7778
OpenStack *openstack.MachinePool `json:"openstack,omitempty"`
7879
// VSphere is the configuration used when installing on vSphere
7980
VSphere *vsphere.MachinePool `json:"vsphere,omitempty"`
81+
// Ovirt is the configuration used when installing on oVirt.
82+
Ovirt *ovirt.MachinePool `json:"ovirt,omitempty"`
8083
}
8184

8285
// MachinePoolStatus defines the observed state of MachinePool

0 commit comments

Comments
 (0)