mirror of
https://github.com/openshift/installer.git
synced 2026-02-05 15:47:14 +01:00
oVirt: update ovirt terraform provider anf cluster-api-provider-ovirt
Updates the oVirt terraform and cluster api providers to get ovirt affinity group abilities
This commit is contained in:
4
go.mod
4
go.mod
@@ -61,12 +61,12 @@ require (
|
||||
github.com/openshift/cluster-api-provider-gcp v0.0.1-0.20201203141909-4dc702fd57a5
|
||||
github.com/openshift/cluster-api-provider-kubevirt v0.0.0-20201214114543-e5aed9c73f1f
|
||||
github.com/openshift/cluster-api-provider-libvirt v0.2.1-0.20191219173431-2336783d4603
|
||||
github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210315122142-893a4db3909a
|
||||
github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210406154451-1ea59ab6b543
|
||||
github.com/openshift/library-go v0.0.0-20201215165635-4ee79b1caed5
|
||||
github.com/openshift/machine-api-operator v0.2.1-0.20210104142355-8e6ae0acdfcf
|
||||
github.com/openshift/machine-config-operator v0.0.0
|
||||
github.com/ovirt/go-ovirt v0.0.0-20210308100159-ac0bcbc88d7c
|
||||
github.com/ovirt/terraform-provider-ovirt v0.99.1-0.20210326142716-4545f80e61cd
|
||||
github.com/ovirt/terraform-provider-ovirt v0.99.1-0.20210419101841-5d3f6567ce90
|
||||
github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db // indirect
|
||||
github.com/pborman/uuid v1.2.0
|
||||
github.com/pkg/errors v0.9.1
|
||||
|
||||
9
go.sum
9
go.sum
@@ -1237,8 +1237,8 @@ github.com/openshift/cluster-api-provider-libvirt v0.2.1-0.20191219173431-233678
|
||||
github.com/openshift/cluster-api-provider-libvirt v0.2.1-0.20191219173431-2336783d4603/go.mod h1:7pQ9Bzha+ug/5zd+0ufbDEcnn2OnNlPwRwYrzhXk4NM=
|
||||
github.com/openshift/cluster-api-provider-openstack v0.0.0-20210302164104-8498241fa4bd h1:5mq9/JftiO9u/RknQ5iR9Nkd09R1XFfUPS1nO11Wth0=
|
||||
github.com/openshift/cluster-api-provider-openstack v0.0.0-20210302164104-8498241fa4bd/go.mod h1:ONl4R7ziQtgnsBjR59fcZbOLjBEPVeZ69C1TPKevynw=
|
||||
github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210315122142-893a4db3909a h1:ZVGkVxyKM00gzdJRC7LYEBGgL4CfK8W50uOjj0fX1/E=
|
||||
github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210315122142-893a4db3909a/go.mod h1:pqKflzzmag/YrCHzJw5rpjk9o+rArgPn9qEVEe4ULP8=
|
||||
github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210406154451-1ea59ab6b543 h1:rzPiPUccXtMbXuOlgIXU8Qhhn9zQpTLeuyDcOfZc2MA=
|
||||
github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210406154451-1ea59ab6b543/go.mod h1:PDoRQIKJb/XT14ebzBoNH0I6ZV2yA7G+jJCk1gCsXB0=
|
||||
github.com/openshift/cluster-autoscaler-operator v0.0.0-20190521201101-62768a6ba480/go.mod h1:/XmV44Fh28Vo3Ye93qFrxAbcFJ/Uy+7LPD+jGjmfJYc=
|
||||
github.com/openshift/custom-resource-status v0.0.0-20190822192428-e62f2f3b79f3 h1:XuAys09+XqT5/FjdR23G/UtbBLII89dFe9XIi73EKIQ=
|
||||
github.com/openshift/custom-resource-status v0.0.0-20190822192428-e62f2f3b79f3/go.mod h1:GDjWl0tX6FNIj82vIxeudWeSx2Ff6nDZ8uJn0ohUFvo=
|
||||
@@ -1278,11 +1278,10 @@ github.com/operator-framework/operator-sdk v0.5.1-0.20190301204940-c2efe6f74e7b/
|
||||
github.com/oracle/oci-go-sdk v7.0.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
|
||||
github.com/ory/dockertest v3.3.4+incompatible/go.mod h1:1vX4m9wsvi00u5bseYwXaSnhNrne+V0E6LAcBILJdPs=
|
||||
github.com/ostreedev/ostree-go v0.0.0-20190702140239-759a8c1ac913/go.mod h1:J6OG6YJVEWopen4avK3VNQSnALmmjvniMmni/YFYAwc=
|
||||
github.com/ovirt/go-ovirt v0.0.0-20210112072624-e4d3b104de71/go.mod h1:fLDxPk1Sf64DBYtwIYxrnx3gPZ1q0xPdWdI1y9vxUaw=
|
||||
github.com/ovirt/go-ovirt v0.0.0-20210308100159-ac0bcbc88d7c h1:2SbYZedeIawU8sGFnohfrdEcEMBA4V8SDouG6hly+H4=
|
||||
github.com/ovirt/go-ovirt v0.0.0-20210308100159-ac0bcbc88d7c/go.mod h1:fLDxPk1Sf64DBYtwIYxrnx3gPZ1q0xPdWdI1y9vxUaw=
|
||||
github.com/ovirt/terraform-provider-ovirt v0.99.1-0.20210326142716-4545f80e61cd h1:dG/VniPIWmJbiCunCA2S85QULDPQhXkUhlKo1T3MOYo=
|
||||
github.com/ovirt/terraform-provider-ovirt v0.99.1-0.20210326142716-4545f80e61cd/go.mod h1:xiMZ4bXb5VDorJN++WoqRbxLQ6k4sSlw59jqs5R08JQ=
|
||||
github.com/ovirt/terraform-provider-ovirt v0.99.1-0.20210419101841-5d3f6567ce90 h1:7URZwDm8pcQukU2VH69h8eI1DQDLZtfCKkKtuvQ9/DA=
|
||||
github.com/ovirt/terraform-provider-ovirt v0.99.1-0.20210419101841-5d3f6567ce90/go.mod h1:wnTGn9+USQJ51TMV5brymzjxUfmYmnOQZuNfYeuqky8=
|
||||
github.com/oxtoacart/bpool v0.0.0-20150712133111-4e1c5567d7c2/go.mod h1:L3UMQOThbttwfYRNFOWLLVXMhk5Lkio4GGOtw5UrxS0=
|
||||
github.com/packer-community/winrmcp v0.0.0-20180102160824-81144009af58/go.mod h1:f6Izs6JvFTdnRbziASagjZ2vmf55NSIkC/weStxCHqk=
|
||||
github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db h1:9uViuKtx1jrlXLBW/pMnhOfzn3iSEdLase/But/IZRU=
|
||||
|
||||
@@ -8,7 +8,7 @@ import (
|
||||
func init() {
|
||||
exec := func() {
|
||||
plugin.Serve(&plugin.ServeOpts{
|
||||
ProviderFunc: ovirt.Provider,
|
||||
ProviderFunc: ovirt.ProviderContext(),
|
||||
})
|
||||
}
|
||||
KnownPlugins["terraform-provider-ovirt"] = exec
|
||||
|
||||
@@ -75,7 +75,12 @@ type OvirtMachineProviderSpec struct {
|
||||
|
||||
// VMAffinityGroup contains the name of the OpenShift cluster affinity groups
|
||||
// It will be used to add the newly created machine to the affinity groups
|
||||
AffinityGroupsNames []string `json:"affinity_groups_names,omitempty`
|
||||
AffinityGroupsNames []string `json:"affinity_groups_names,omitempty"`
|
||||
|
||||
// AutoPinningPolicy defines the policy to automatically set the CPU
|
||||
// and NUMA including pinning to the host for the instance.
|
||||
// One of "disabled, existing, adjust"
|
||||
AutoPinningPolicy string `json:"auto_pinning_policy,omitempty"`
|
||||
}
|
||||
|
||||
// CPU defines the VM cpu, made of (Sockets * Cores * Threads)
|
||||
|
||||
49
vendor/github.com/ovirt/terraform-provider-ovirt/ovirt/provider.go
generated
vendored
49
vendor/github.com/ovirt/terraform-provider-ovirt/ovirt/provider.go
generated
vendored
@@ -9,14 +9,26 @@ package ovirt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sync"
|
||||
|
||||
"github.com/hashicorp/terraform-plugin-sdk/helper/schema"
|
||||
"github.com/hashicorp/terraform-plugin-sdk/terraform"
|
||||
ovirtsdk4 "github.com/ovirt/go-ovirt"
|
||||
)
|
||||
|
||||
type providerContext struct {
|
||||
semaphores *semaphoreProvider
|
||||
}
|
||||
|
||||
func ProviderContext() func() terraform.ResourceProvider {
|
||||
c := &providerContext{
|
||||
semaphores: newSemaphoreProvider(),
|
||||
}
|
||||
return c.Provider
|
||||
}
|
||||
|
||||
// Provider returns oVirt provider configuration
|
||||
func Provider() terraform.ResourceProvider {
|
||||
func (c *providerContext) Provider() terraform.ResourceProvider {
|
||||
return &schema.Provider{
|
||||
Schema: map[string]*schema.Schema{
|
||||
"username": {
|
||||
@@ -72,7 +84,7 @@ func Provider() terraform.ResourceProvider {
|
||||
ConfigureFunc: ConfigureProvider,
|
||||
ResourcesMap: map[string]*schema.Resource{
|
||||
"ovirt_affinity_group": resourceOvirtAffinityGroup(),
|
||||
"ovirt_vm": resourceOvirtVM(),
|
||||
"ovirt_vm": resourceOvirtVM(c),
|
||||
"ovirt_template": resourceOvirtTemplate(),
|
||||
"ovirt_disk": resourceOvirtDisk(),
|
||||
"ovirt_disk_attachment": resourceOvirtDiskAttachment(),
|
||||
@@ -136,3 +148,36 @@ func ConfigureProvider(d *schema.ResourceData) (interface{}, error) {
|
||||
|
||||
return connBuilder.Build()
|
||||
}
|
||||
|
||||
func newSemaphoreProvider() *semaphoreProvider {
|
||||
return &semaphoreProvider{
|
||||
lock: &sync.Mutex{},
|
||||
semaphores: map[string]chan struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
type semaphoreProvider struct {
|
||||
lock *sync.Mutex
|
||||
semaphores map[string]chan struct{}
|
||||
}
|
||||
|
||||
func (s *semaphoreProvider) Lock(semName string, capacity uint) {
|
||||
if capacity < 1 {
|
||||
panic(fmt.Sprintf("Invalid semaphoreProvider capacity %d for sem %s", capacity, semName))
|
||||
}
|
||||
s.lock.Lock()
|
||||
if _, ok := s.semaphores[semName]; !ok {
|
||||
s.semaphores[semName] = make(chan struct{}, capacity)
|
||||
}
|
||||
s.lock.Unlock()
|
||||
s.semaphores[semName] <- struct{}{}
|
||||
}
|
||||
|
||||
func (s *semaphoreProvider) Unlock(semName string) {
|
||||
s.lock.Lock()
|
||||
if _, ok := s.semaphores[semName]; !ok {
|
||||
panic(fmt.Sprintf("semaphoreProvider unlock called before lock: %s", semName))
|
||||
}
|
||||
s.lock.Unlock()
|
||||
<-s.semaphores[semName]
|
||||
}
|
||||
|
||||
26
vendor/github.com/ovirt/terraform-provider-ovirt/ovirt/resource_ovirt_affinity_group.go
generated
vendored
26
vendor/github.com/ovirt/terraform-provider-ovirt/ovirt/resource_ovirt_affinity_group.go
generated
vendored
@@ -106,23 +106,29 @@ func resourceOvirtAffinityGroupCreate(d *schema.ResourceData, meta interface{})
|
||||
}
|
||||
|
||||
vmRuleBuilder := ovirtsdk4.NewAffinityRuleBuilder()
|
||||
if _, ok := d.GetOk("vm_list"); ok {
|
||||
vmRuleBuilder.Enabled(false)
|
||||
if vmPositive, ok := d.GetOkExists("vm_positive"); ok {
|
||||
vmRuleBuilder.Enabled(true)
|
||||
vmRuleBuilder.Positive(d.Get("vm_positive").(bool))
|
||||
vmRuleBuilder.Enforcing(d.Get("vm_enforcing").(bool))
|
||||
} else {
|
||||
vmRuleBuilder.Enabled(false)
|
||||
vmRuleBuilder.Positive(vmPositive.(bool))
|
||||
}
|
||||
if vmEnforcing, ok := d.GetOk("vm_enforcing"); ok {
|
||||
vmRuleBuilder.Enabled(true)
|
||||
vmRuleBuilder.Enforcing(vmEnforcing.(bool))
|
||||
}
|
||||
|
||||
agBuilder.VmsRule(vmRuleBuilder.MustBuild())
|
||||
|
||||
hostRuleBuilder := ovirtsdk4.NewAffinityRuleBuilder()
|
||||
if _, ok := d.GetOk("host_list"); ok {
|
||||
hostRuleBuilder.Enabled(false)
|
||||
if hostPositive, ok := d.GetOkExists("host_positive"); ok {
|
||||
hostRuleBuilder.Enabled(true)
|
||||
hostRuleBuilder.Positive(d.Get("host_positive").(bool))
|
||||
hostRuleBuilder.Enforcing(d.Get("host_enforcing").(bool))
|
||||
} else {
|
||||
hostRuleBuilder.Enabled(false)
|
||||
hostRuleBuilder.Positive(hostPositive.(bool))
|
||||
}
|
||||
if hostEnforcing, ok := d.GetOk("host_enforcing"); ok {
|
||||
hostRuleBuilder.Enabled(true)
|
||||
hostRuleBuilder.Enforcing(hostEnforcing.(bool))
|
||||
}
|
||||
|
||||
agBuilder.HostsRule(hostRuleBuilder.MustBuild())
|
||||
|
||||
log.Printf("Creating %#v", agBuilder.MustBuild())
|
||||
|
||||
103
vendor/github.com/ovirt/terraform-provider-ovirt/ovirt/resource_ovirt_vm.go
generated
vendored
103
vendor/github.com/ovirt/terraform-provider-ovirt/ovirt/resource_ovirt_vm.go
generated
vendored
@@ -8,6 +8,7 @@
|
||||
package ovirt
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
@@ -22,9 +23,9 @@ import (
|
||||
// BlankTemplateID indicates the ID of default blank template in oVirt
|
||||
const BlankTemplateID = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
func resourceOvirtVM() *schema.Resource {
|
||||
func resourceOvirtVM(c *providerContext) *schema.Resource {
|
||||
return &schema.Resource{
|
||||
Create: resourceOvirtVMCreate,
|
||||
Create: c.resourceOvirtVMCreate,
|
||||
Read: resourceOvirtVMRead,
|
||||
Update: resourceOvirtVMUpdate,
|
||||
Delete: resourceOvirtVMDelete,
|
||||
@@ -361,11 +362,28 @@ func resourceOvirtVM() *schema.Resource {
|
||||
string(ovirtsdk4.AUTOPINNINGPOLICY_ADJUST),
|
||||
}, false),
|
||||
},
|
||||
"affinity_groups": {
|
||||
Type: schema.TypeSet,
|
||||
Optional: true,
|
||||
Description: "The name of the Affinity Groups that the VM will join",
|
||||
Elem: &schema.Schema{
|
||||
Type: schema.TypeString,
|
||||
},
|
||||
},
|
||||
"hugepages": {
|
||||
Type: schema.TypeInt,
|
||||
Optional: true,
|
||||
Description: "The size of hugepage to use in KiB, One of 2048 or 1048576",
|
||||
ValidateFunc: validation.IntInSlice([]int{
|
||||
2048,
|
||||
1048576,
|
||||
}),
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func resourceOvirtVMCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
func (c *providerContext) resourceOvirtVMCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
conn := meta.(*ovirtsdk4.Connection)
|
||||
|
||||
// template with disks attached is conflicted with block_device
|
||||
@@ -407,8 +425,9 @@ func resourceOvirtVMCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
memoryPolicyBuilder.Max(int64(maximumMemory.(int)) * int64(math.Pow(2, 20)))
|
||||
}
|
||||
|
||||
clusterId := d.Get("cluster_id").(string)
|
||||
cluster, err := ovirtsdk4.NewClusterBuilder().
|
||||
Id(d.Get("cluster_id").(string)).Build()
|
||||
Id(clusterId).Build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -623,6 +642,17 @@ func resourceOvirtVMCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
}
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("hugepages"); ok {
|
||||
customProp, err := ovirtsdk4.NewCustomPropertyBuilder().
|
||||
Name("hugepages").
|
||||
Value(fmt.Sprint(v)).
|
||||
Build()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
vmBuilder.CustomPropertiesOfAny(customProp)
|
||||
}
|
||||
|
||||
if v, ok := d.GetOk("instance_type_id"); ok {
|
||||
vmBuilder.InstanceTypeBuilder(
|
||||
ovirtsdk4.NewInstanceTypeBuilder().Id(v.(string)))
|
||||
@@ -714,6 +744,22 @@ func resourceOvirtVMCreate(d *schema.ResourceData, meta interface{}) error {
|
||||
}
|
||||
}
|
||||
|
||||
affinityGroups, affinityGroupsOk := d.GetOk("affinity_groups")
|
||||
if affinityGroupsOk {
|
||||
agStr, err := convInterfaceArrToStringArr(affinityGroups.(*schema.Set).List())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
ag, err := getAffinityGroups(conn, clusterId, agStr)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = c.addVmToAffinityGroups(conn, newVM, clusterId, ag)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
autoStart := d.Get("auto_start").(bool)
|
||||
if autoStart {
|
||||
// Try to start VM
|
||||
@@ -1609,3 +1655,52 @@ func getTemplateDiskAttachments(templateID string, meta interface{}) ([]*ovirtsd
|
||||
}
|
||||
return nil, nil
|
||||
}
|
||||
|
||||
func getAffinityGroups(conn *ovirtsdk4.Connection, cID string, agNames []string) (ag []*ovirtsdk4.AffinityGroup, err error) {
|
||||
var ags []*ovirtsdk4.AffinityGroup
|
||||
var notFoundAGs []string
|
||||
|
||||
res, err := conn.SystemService().ClustersService().
|
||||
ClusterService(cID).AffinityGroupsService().
|
||||
List().Send()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
agNamesMap := make(map[string]*ovirtsdk4.AffinityGroup)
|
||||
for _, af := range res.MustGroups().Slice() {
|
||||
agNamesMap[af.MustName()] = af
|
||||
}
|
||||
for _, agName := range agNames {
|
||||
if _, ok := agNamesMap[agName]; !ok {
|
||||
notFoundAGs = append(notFoundAGs, agName)
|
||||
} else {
|
||||
ags = append(ags, agNamesMap[agName])
|
||||
}
|
||||
}
|
||||
if len(notFoundAGs) > 0 {
|
||||
return nil, fmt.Errorf("affinity groups %v were not found on cluster %s", notFoundAGs, cID)
|
||||
}
|
||||
return ags, nil
|
||||
}
|
||||
|
||||
func (c *providerContext) addVmToAffinityGroups(conn *ovirtsdk4.Connection, vm *ovirtsdk4.Vm, cID string, ags []*ovirtsdk4.AffinityGroup) error {
|
||||
// TODO: Remove lock once BZ#1950767 is resolved
|
||||
c.semaphores.Lock("vm-ag", 1)
|
||||
defer c.semaphores.Unlock("vm-ag")
|
||||
|
||||
for _, ag := range ags {
|
||||
log.Printf("Adding machine %s to affinity group %s", vm.MustName(), ag.MustName())
|
||||
_, err := conn.SystemService().ClustersService().
|
||||
ClusterService(cID).AffinityGroupsService().
|
||||
GroupService(ag.MustId()).VmsService().Add().Vm(vm).Send()
|
||||
// TODO: Remove error handling workaround when BZ#1931932 is resolved and backported
|
||||
if err != nil && !errors.Is(err, ovirtsdk4.XMLTagNotMatchError{ActualTag: "action", ExpectedTag: "vm"}) {
|
||||
return fmt.Errorf(
|
||||
"failed to add VM %s to AffinityGroup %s, error: %v",
|
||||
vm.MustName(),
|
||||
ag.MustName(),
|
||||
err)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
16
vendor/github.com/ovirt/terraform-provider-ovirt/ovirt/utils.go
generated
vendored
16
vendor/github.com/ovirt/terraform-provider-ovirt/ovirt/utils.go
generated
vendored
@@ -64,3 +64,19 @@ func parseResourceID(id string, count int) ([]string, error) {
|
||||
}
|
||||
return parts, nil
|
||||
}
|
||||
|
||||
//Converts an array of type []interface{} to []string, notice that all the interface elements needs to be strings
|
||||
func convInterfaceArrToStringArr(arr []interface{}) ([]string, error) {
|
||||
var newArr []string
|
||||
for _, val := range arr {
|
||||
if s, ok := val.(string); ok {
|
||||
newArr = append(newArr, s)
|
||||
} else {
|
||||
return nil, fmt.Errorf(
|
||||
"error converting []interface{} to []string, "+
|
||||
"provided interface array %v contains non string elements %v",
|
||||
arr, val)
|
||||
}
|
||||
}
|
||||
return newArr, nil
|
||||
}
|
||||
|
||||
4
vendor/modules.txt
vendored
4
vendor/modules.txt
vendored
@@ -1131,7 +1131,7 @@ github.com/openshift/cluster-api-provider-kubevirt/pkg/utils
|
||||
## explicit
|
||||
github.com/openshift/cluster-api-provider-libvirt/pkg/apis
|
||||
github.com/openshift/cluster-api-provider-libvirt/pkg/apis/libvirtproviderconfig/v1beta1
|
||||
# github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210315122142-893a4db3909a
|
||||
# github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210406154451-1ea59ab6b543
|
||||
## explicit
|
||||
github.com/openshift/cluster-api-provider-ovirt/pkg/apis
|
||||
github.com/openshift/cluster-api-provider-ovirt/pkg/apis/ovirtprovider/v1beta1
|
||||
@@ -1153,7 +1153,7 @@ github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.opens
|
||||
# github.com/ovirt/go-ovirt v0.0.0-20210308100159-ac0bcbc88d7c
|
||||
## explicit
|
||||
github.com/ovirt/go-ovirt
|
||||
# github.com/ovirt/terraform-provider-ovirt v0.99.1-0.20210326142716-4545f80e61cd
|
||||
# github.com/ovirt/terraform-provider-ovirt v0.99.1-0.20210419101841-5d3f6567ce90
|
||||
## explicit
|
||||
github.com/ovirt/terraform-provider-ovirt/ovirt
|
||||
# github.com/packer-community/winrmcp v0.0.0-20180921211025-c76d91c1e7db
|
||||
|
||||
Reference in New Issue
Block a user