diff --git a/Gopkg.lock b/Gopkg.lock index 26af525c4ce..5f6389fb8e9 100644 --- a/Gopkg.lock +++ b/Gopkg.lock @@ -209,7 +209,7 @@ [[projects]] branch = "master" - digest = "1:ca30c5461de1d21c23dfd9ce86be573942b3f90019126d72079cb0acfb530fbe" + digest = "1:641224f7b8f1cea6916375f46c997c991902910af8860d4520642b7a69fe37a4" name = "github.com/gophercloud/gophercloud" packages = [ ".", @@ -223,7 +223,6 @@ "openstack/identity/v2/tokens", "openstack/identity/v3/regions", "openstack/identity/v3/tokens", - "openstack/imageservice/v2/images", "openstack/networking/v2/extensions", "openstack/networking/v2/extensions/layer3/floatingips", "openstack/networking/v2/extensions/layer3/routers", @@ -864,7 +863,6 @@ "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors", "github.com/gophercloud/gophercloud/openstack/compute/v2/servers", "github.com/gophercloud/gophercloud/openstack/identity/v3/regions", - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images", "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions", "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/floatingips", "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions/layer3/routers", diff --git a/docs/design/resource_dep.svg b/docs/design/resource_dep.svg index 4faf595a3bf..7a4f70526d7 100644 --- a/docs/design/resource_dep.svg +++ b/docs/design/resource_dep.svg @@ -1,1165 +1,1159 @@ - - + G - + installconfig.InstallConfig - -installconfig.InstallConfig + +installconfig.InstallConfig Target Install Config - -Target Install Config + +Target Install Config installconfig.InstallConfig->Target Install Config - - + + manifests.Manifests - -manifests.Manifests + +manifests.Manifests installconfig.InstallConfig->manifests.Manifests - - + + manifests.Ingress - -manifests.Ingress + +manifests.Ingress installconfig.InstallConfig->manifests.Ingress - - + + manifests.DNS - -manifests.DNS + +manifests.DNS installconfig.InstallConfig->manifests.DNS - - + + manifests.Networking - -manifests.Networking + +manifests.Networking installconfig.InstallConfig->manifests.Networking - - + + tls.IngressCertKey - -tls.IngressCertKey + +tls.IngressCertKey installconfig.InstallConfig->tls.IngressCertKey - - + + tls.MCSCertKey - -tls.MCSCertKey + +tls.MCSCertKey installconfig.InstallConfig->tls.MCSCertKey - - + + manifests.Openshift - -manifests.Openshift + +manifests.Openshift installconfig.InstallConfig->manifests.Openshift - - + + manifests.ClusterK8sIO - -manifests.ClusterK8sIO + +manifests.ClusterK8sIO installconfig.InstallConfig->manifests.ClusterK8sIO - - + + machines.Worker - -machines.Worker + +machines.Worker installconfig.InstallConfig->machines.Worker - - + + - + +rhcos.Image + +rhcos.Image + + + +installconfig.InstallConfig->rhcos.Image + + + + + machine.Worker - -machine.Worker + +machine.Worker - + installconfig.InstallConfig->machine.Worker - - + + - + machines.Master - -machines.Master + +machines.Master - + installconfig.InstallConfig->machines.Master - - + + - + machine.Master - -machine.Master + +machine.Master - + installconfig.InstallConfig->machine.Master - - + + - + bootstrap.Bootstrap - -bootstrap.Bootstrap + +bootstrap.Bootstrap - + installconfig.InstallConfig->bootstrap.Bootstrap - - + + - + tls.APIServerCertKey - -tls.APIServerCertKey + +tls.APIServerCertKey - + installconfig.InstallConfig->tls.APIServerCertKey - - + + kubeconfig.Admin - -kubeconfig.Admin + +kubeconfig.Admin - + installconfig.InstallConfig->kubeconfig.Admin - - + + kubeconfig.Kubelet - -kubeconfig.Kubelet + +kubeconfig.Kubelet - + installconfig.InstallConfig->kubeconfig.Kubelet - - + + cluster.TerraformVariables - -cluster.TerraformVariables + +cluster.TerraformVariables - + installconfig.InstallConfig->cluster.TerraformVariables - - + + - + cluster.Cluster - -cluster.Cluster + +cluster.Cluster installconfig.InstallConfig->cluster.Cluster - - + + installconfig.clusterID - -installconfig.clusterID + +installconfig.clusterID installconfig.clusterID->installconfig.InstallConfig - - + + installconfig.sshPublicKey - -installconfig.sshPublicKey + +installconfig.sshPublicKey installconfig.sshPublicKey->installconfig.InstallConfig - - + + installconfig.baseDomain - -installconfig.baseDomain + +installconfig.baseDomain installconfig.baseDomain->installconfig.InstallConfig - - + + installconfig.platform - -installconfig.platform + +installconfig.platform installconfig.platform->installconfig.InstallConfig - - + + installconfig.platform->installconfig.baseDomain - - + + installconfig.clusterName - -installconfig.clusterName + +installconfig.clusterName installconfig.clusterName->installconfig.InstallConfig - - + + installconfig.pullSecret - -installconfig.pullSecret + +installconfig.pullSecret installconfig.pullSecret->installconfig.InstallConfig - - + + templates.Templates - -templates.Templates + +templates.Templates Target Manifest templates - -Target Manifest templates + +Target Manifest templates templates.Templates->Target Manifest templates - - + + bootkube.KubeCloudConfig - -bootkube.KubeCloudConfig + +bootkube.KubeCloudConfig bootkube.KubeCloudConfig->templates.Templates - - + + bootkube.KubeCloudConfig->manifests.Manifests - - + + bootkube.MachineConfigServerTLSSecret - -bootkube.MachineConfigServerTLSSecret + +bootkube.MachineConfigServerTLSSecret bootkube.MachineConfigServerTLSSecret->templates.Templates - - + + bootkube.MachineConfigServerTLSSecret->manifests.Manifests - - + + bootkube.OpenshiftServiceCertSignerSecret - -bootkube.OpenshiftServiceCertSignerSecret + +bootkube.OpenshiftServiceCertSignerSecret bootkube.OpenshiftServiceCertSignerSecret->templates.Templates - - + + bootkube.OpenshiftServiceCertSignerSecret->manifests.Manifests - - + + bootkube.Pull - -bootkube.Pull + +bootkube.Pull bootkube.Pull->templates.Templates - - + + bootkube.Pull->manifests.Manifests - - + + bootkube.CVOOverrides - -bootkube.CVOOverrides + +bootkube.CVOOverrides bootkube.CVOOverrides->templates.Templates - - + + bootkube.CVOOverrides->manifests.Manifests - - + + bootkube.HostEtcdServiceEndpointsKubeSystem - -bootkube.HostEtcdServiceEndpointsKubeSystem + +bootkube.HostEtcdServiceEndpointsKubeSystem bootkube.HostEtcdServiceEndpointsKubeSystem->templates.Templates - - + + bootkube.HostEtcdServiceEndpointsKubeSystem->manifests.Manifests - - + + bootkube.KubeSystemConfigmapEtcdServingCA - -bootkube.KubeSystemConfigmapEtcdServingCA + +bootkube.KubeSystemConfigmapEtcdServingCA bootkube.KubeSystemConfigmapEtcdServingCA->templates.Templates - - + + bootkube.KubeSystemConfigmapEtcdServingCA->manifests.Manifests - - + + bootkube.KubeSystemConfigmapRootCA - -bootkube.KubeSystemConfigmapRootCA + +bootkube.KubeSystemConfigmapRootCA bootkube.KubeSystemConfigmapRootCA->templates.Templates - - + + bootkube.KubeSystemConfigmapRootCA->manifests.Manifests - - + + bootkube.KubeSystemSecretEtcdClient - -bootkube.KubeSystemSecretEtcdClient + +bootkube.KubeSystemSecretEtcdClient bootkube.KubeSystemSecretEtcdClient->templates.Templates - - + + bootkube.KubeSystemSecretEtcdClient->manifests.Manifests - - + + bootkube.OpenshiftMachineConfigOperator - -bootkube.OpenshiftMachineConfigOperator + +bootkube.OpenshiftMachineConfigOperator bootkube.OpenshiftMachineConfigOperator->templates.Templates - - + + bootkube.OpenshiftMachineConfigOperator->manifests.Manifests - - + + bootkube.OpenshiftClusterAPINamespace - -bootkube.OpenshiftClusterAPINamespace + +bootkube.OpenshiftClusterAPINamespace bootkube.OpenshiftClusterAPINamespace->templates.Templates - - + + bootkube.OpenshiftClusterAPINamespace->manifests.Manifests - - + + bootkube.OpenshiftServiceCertSignerNamespace - -bootkube.OpenshiftServiceCertSignerNamespace + +bootkube.OpenshiftServiceCertSignerNamespace bootkube.OpenshiftServiceCertSignerNamespace->templates.Templates - - + + bootkube.OpenshiftServiceCertSignerNamespace->manifests.Manifests - - + + bootkube.EtcdServiceKubeSystem - -bootkube.EtcdServiceKubeSystem + +bootkube.EtcdServiceKubeSystem bootkube.EtcdServiceKubeSystem->templates.Templates - - + + bootkube.EtcdServiceKubeSystem->manifests.Manifests - - + + bootkube.HostEtcdServiceKubeSystem - -bootkube.HostEtcdServiceKubeSystem + +bootkube.HostEtcdServiceKubeSystem bootkube.HostEtcdServiceKubeSystem->templates.Templates - - + + bootkube.HostEtcdServiceKubeSystem->manifests.Manifests - - + + openshift.BindingDiscovery - -openshift.BindingDiscovery + +openshift.BindingDiscovery openshift.BindingDiscovery->templates.Templates - - + + - + openshift.BindingDiscovery->manifests.Openshift - - + + openshift.CloudCredsSecret - -openshift.CloudCredsSecret + +openshift.CloudCredsSecret openshift.CloudCredsSecret->templates.Templates - - + + - + openshift.CloudCredsSecret->manifests.Openshift - - + + openshift.KubeadminPasswordSecret - -openshift.KubeadminPasswordSecret + +openshift.KubeadminPasswordSecret openshift.KubeadminPasswordSecret->templates.Templates - - + + - + openshift.KubeadminPasswordSecret->manifests.Openshift - - + + openshift.RoleCloudCredsSecretReader - -openshift.RoleCloudCredsSecretReader + +openshift.RoleCloudCredsSecretReader openshift.RoleCloudCredsSecretReader->templates.Templates - - + + - + openshift.RoleCloudCredsSecretReader->manifests.Openshift - - + + Target Manifests - -Target Manifests + +Target Manifests manifests.Manifests->Target Manifests - - + + - + manifests.Manifests->bootstrap.Bootstrap - - + + manifests.Ingress->manifests.Manifests - - + + manifests.DNS->manifests.Manifests - - + + manifests.Networking->manifests.Manifests - - + + manifests.Networking->manifests.ClusterK8sIO - - + + tls.RootCA - -tls.RootCA + +tls.RootCA tls.RootCA->manifests.Manifests - - + + tls.EtcdCA - -tls.EtcdCA + +tls.EtcdCA tls.RootCA->tls.EtcdCA - - + + tls.KubeCA - -tls.KubeCA + +tls.KubeCA tls.RootCA->tls.KubeCA - - + + tls.ServiceServingCA - -tls.ServiceServingCA + +tls.ServiceServingCA tls.RootCA->tls.ServiceServingCA - - + + tls.RootCA->tls.MCSCertKey - - + + - + tls.RootCA->machine.Worker - - + + - + tls.RootCA->machine.Master - - + + - + tls.RootCA->bootstrap.Bootstrap - - + + - + tls.AggregatorCA - -tls.AggregatorCA + +tls.AggregatorCA - + tls.RootCA->tls.AggregatorCA - - - - - -tls.JournalCA - -tls.JournalCA - - - -tls.RootCA->tls.JournalCA - - + + - + tls.RootCA->kubeconfig.Admin - - + + - + tls.RootCA->kubeconfig.Kubelet - - + + tls.EtcdCA->manifests.Manifests - - + + tls.EtcdClientCertKey - -tls.EtcdClientCertKey + +tls.EtcdClientCertKey tls.EtcdCA->tls.EtcdClientCertKey - - + + - + tls.EtcdCA->bootstrap.Bootstrap - - + + tls.IngressCertKey->manifests.Manifests - - + + tls.KubeCA->manifests.Manifests - - + + tls.KubeCA->tls.IngressCertKey - - + + tls.KubeletCertKey - -tls.KubeletCertKey + +tls.KubeletCertKey tls.KubeCA->tls.KubeletCertKey - - + + - + tls.KubeCA->bootstrap.Bootstrap - - + + - + tls.KubeCA->tls.APIServerCertKey - - + + - + tls.AdminCertKey - -tls.AdminCertKey + +tls.AdminCertKey - + tls.KubeCA->tls.AdminCertKey - - + + tls.ServiceServingCA->manifests.Manifests - - + + - + tls.ServiceServingCA->bootstrap.Bootstrap - - + + tls.EtcdClientCertKey->manifests.Manifests - - + + - + tls.EtcdClientCertKey->bootstrap.Bootstrap - - + + tls.MCSCertKey->manifests.Manifests - - + + - + tls.MCSCertKey->bootstrap.Bootstrap - - + + tls.KubeletCertKey->manifests.Manifests - - + + - + tls.KubeletCertKey->bootstrap.Bootstrap - - + + - + tls.KubeletCertKey->kubeconfig.Kubelet - - + + manifests.Openshift->Target Manifests - - + + - + manifests.Openshift->bootstrap.Bootstrap - - + + manifests.ClusterK8sIO->manifests.Openshift - - + + machines.Worker->manifests.Openshift - - + + - + +rhcos.Image->machines.Worker + + + + + +rhcos.Image->machines.Master + + + + + +rhcos.Image->cluster.TerraformVariables + + + + + machine.Worker->machines.Worker - - + + - + Target Ignition Configs - -Target Ignition Configs + +Target Ignition Configs - + machine.Worker->Target Ignition Configs - - + + - + machines.Master->manifests.Openshift - - + + - + machine.Master->machines.Master - - + + - + machine.Master->Target Ignition Configs - - + + - + machine.Master->cluster.TerraformVariables - - + + - + password.KubeadminPassword - -password.KubeadminPassword + +password.KubeadminPassword - + password.KubeadminPassword->manifests.Openshift - - + + password.KubeadminPassword->cluster.Cluster - - + + - + bootstrap.Bootstrap->Target Ignition Configs - - + + - + bootstrap.Bootstrap->cluster.TerraformVariables - - + + - + tls.AggregatorCA->bootstrap.Bootstrap - - + + - + tls.APIServerProxyCertKey - -tls.APIServerProxyCertKey + +tls.APIServerProxyCertKey - + tls.AggregatorCA->tls.APIServerProxyCertKey - - + + - + tls.APIServerCertKey->bootstrap.Bootstrap - - + + - + tls.APIServerProxyCertKey->bootstrap.Bootstrap - - + + - + tls.AdminCertKey->bootstrap.Bootstrap - - + + - + tls.AdminCertKey->kubeconfig.Admin - - + + - + tls.ServiceAccountKeyPair - -tls.ServiceAccountKeyPair + +tls.ServiceAccountKeyPair - + tls.ServiceAccountKeyPair->bootstrap.Bootstrap - - - - - -tls.JournalCA->bootstrap.Bootstrap - - - - - -tls.JournalCertKey - -tls.JournalCertKey - - - -tls.JournalCA->tls.JournalCertKey - - + + - + kubeconfig.Admin->bootstrap.Bootstrap - - + + Target Cluster - -Target Cluster + +Target Cluster - + kubeconfig.Admin->Target Cluster - - + + - + kubeconfig.Kubelet->bootstrap.Bootstrap - - + + - + cluster.TerraformVariables->Target Cluster - - + + cluster.TerraformVariables->cluster.Cluster - - - - - -tls.JournalCertKey->Target Cluster - - + + cluster.Cluster->Target Cluster - - + + diff --git a/pkg/asset/cluster/tfvars.go b/pkg/asset/cluster/tfvars.go index f8dd936fa8d..2e52253483e 100644 --- a/pkg/asset/cluster/tfvars.go +++ b/pkg/asset/cluster/tfvars.go @@ -7,6 +7,7 @@ import ( "github.com/openshift/installer/pkg/asset/ignition/bootstrap" "github.com/openshift/installer/pkg/asset/ignition/machine" "github.com/openshift/installer/pkg/asset/installconfig" + "github.com/openshift/installer/pkg/asset/rhcos" "github.com/openshift/installer/pkg/tfvars" "github.com/pkg/errors" ) @@ -34,6 +35,7 @@ func (t *TerraformVariables) Name() string { func (t *TerraformVariables) Dependencies() []asset.Asset { return []asset.Asset{ &installconfig.InstallConfig{}, + new(rhcos.Image), &bootstrap.Bootstrap{}, &machine.Master{}, } @@ -44,13 +46,13 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error { installConfig := &installconfig.InstallConfig{} bootstrap := &bootstrap.Bootstrap{} master := &machine.Master{} - parents.Get(installConfig, bootstrap, master) + rhcosImage := new(rhcos.Image) + parents.Get(installConfig, bootstrap, master, rhcosImage) bootstrapIgn := string(bootstrap.Files()[0].Data) - masterIgn := string(master.Files()[0].Data) - data, err := tfvars.TFVars(installConfig.Config, bootstrapIgn, masterIgn) + data, err := tfvars.TFVars(installConfig.Config, string(*rhcosImage), bootstrapIgn, masterIgn) if err != nil { return errors.Wrap(err, "failed to get Tfvars") } diff --git a/pkg/asset/installconfig/libvirt/libvirt.go b/pkg/asset/installconfig/libvirt/libvirt.go index 9c662e15a6a..d4fb8530ad7 100644 --- a/pkg/asset/installconfig/libvirt/libvirt.go +++ b/pkg/asset/installconfig/libvirt/libvirt.go @@ -2,13 +2,9 @@ package libvirt import ( - "context" - - "github.com/pkg/errors" survey "gopkg.in/AlecAivazis/survey.v1" "github.com/openshift/installer/pkg/ipnet" - "github.com/openshift/installer/pkg/rhcos" "github.com/openshift/installer/pkg/types/libvirt" "github.com/openshift/installer/pkg/validate" ) @@ -40,18 +36,10 @@ func Platform() (*libvirt.Platform, error) { return nil, err } - qcowImage, err := rhcos.QEMU(context.TODO(), rhcos.DefaultChannel) - if err != nil { - return nil, errors.Wrap(err, "failed to fetch QEMU image URL") - } - return &libvirt.Platform{ Network: libvirt.Network{ IfName: defaultNetworkIfName, }, - DefaultMachinePlatform: &libvirt.MachinePool{ - Image: qcowImage, - }, URI: uri, }, nil } diff --git a/pkg/asset/installconfig/openstack/openstack.go b/pkg/asset/installconfig/openstack/openstack.go index 88d3b2066a2..b58c6d91918 100644 --- a/pkg/asset/installconfig/openstack/openstack.go +++ b/pkg/asset/installconfig/openstack/openstack.go @@ -72,34 +72,6 @@ func Platform() (*openstack.Platform, error) { return nil, err } - imageNames, err := validValuesFetcher.GetImageNames(cloud) - if err != nil { - return nil, err - } - sort.Strings(imageNames) - var image string - err = survey.Ask([]*survey.Question{ - { - Prompt: &survey.Select{ - Message: "Image", - Help: "The OpenStack image name to be used for installation.", - Default: "rhcos", - Options: imageNames, - }, - Validate: survey.ComposeValidators(survey.Required, func(ans interface{}) error { - value := ans.(string) - i := sort.SearchStrings(imageNames, value) - if i == len(imageNames) || imageNames[i] != value { - return errors.Errorf("invalid image name %q, should be one of %+v", value, strings.Join(imageNames, ", ")) - } - return nil - }), - }, - }, &image) - if err != nil { - return nil, err - } - networkNames, err := validValuesFetcher.GetNetworkNames(cloud) if err != nil { return nil, err @@ -169,7 +141,6 @@ func Platform() (*openstack.Platform, error) { return &openstack.Platform{ Region: region, - BaseImage: image, Cloud: cloud, ExternalNetwork: extNet, FlavorName: flavor, diff --git a/pkg/asset/machines/aws/machines.go b/pkg/asset/machines/aws/machines.go index c117678ae69..f128c977c9a 100644 --- a/pkg/asset/machines/aws/machines.go +++ b/pkg/asset/machines/aws/machines.go @@ -18,7 +18,7 @@ import ( ) // Machines returns a list of machines for a machinepool. -func Machines(config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]clusterapi.Machine, error) { +func Machines(config *types.InstallConfig, pool *types.MachinePool, osImage, role, userDataSecret string) ([]clusterapi.Machine, error) { if configPlatform := config.Platform.Name(); configPlatform != aws.Name { return nil, fmt.Errorf("non-AWS configuration: %q", configPlatform) } @@ -37,7 +37,7 @@ func Machines(config *types.InstallConfig, pool *types.MachinePool, role, userDa var machines []clusterapi.Machine for idx := int64(0); idx < total; idx++ { azIndex := int(idx) % len(azs) - provider, err := provider(config.ClusterID, clustername, platform, mpool, azIndex, role, userDataSecret) + provider, err := provider(config.ClusterID, clustername, platform, mpool, osImage, azIndex, role, userDataSecret) if err != nil { return nil, errors.Wrap(err, "failed to create provider") } @@ -69,8 +69,9 @@ func Machines(config *types.InstallConfig, pool *types.MachinePool, role, userDa return machines, nil } -func provider(clusterID, clusterName string, platform *aws.Platform, mpool *aws.MachinePool, azIdx int, role, userDataSecret string) (*awsprovider.AWSMachineProviderConfig, error) { +func provider(clusterID, clusterName string, platform *aws.Platform, mpool *aws.MachinePool, osImage string, azIdx int, role, userDataSecret string) (*awsprovider.AWSMachineProviderConfig, error) { az := mpool.Zones[azIdx] + amiID := osImage tags, err := tagsFromUserTags(clusterID, clusterName, platform.UserTags) if err != nil { return nil, errors.Wrap(err, "failed to create awsprovider.TagSpecifications from UserTags") @@ -81,7 +82,7 @@ func provider(clusterID, clusterName string, platform *aws.Platform, mpool *aws. Kind: "AWSMachineProviderConfig", }, InstanceType: mpool.InstanceType, - AMI: awsprovider.AWSResourceReference{ID: &mpool.AMIID}, + AMI: awsprovider.AWSResourceReference{ID: &amiID}, Tags: tags, IAMInstanceProfile: &awsprovider.AWSResourceReference{ID: pointer.StringPtr(fmt.Sprintf("%s-%s-profile", clusterName, role))}, UserDataSecret: &corev1.LocalObjectReference{Name: userDataSecret}, diff --git a/pkg/asset/machines/aws/machinesets.go b/pkg/asset/machines/aws/machinesets.go index 1c93d498674..4cff392b68c 100644 --- a/pkg/asset/machines/aws/machinesets.go +++ b/pkg/asset/machines/aws/machinesets.go @@ -14,7 +14,7 @@ import ( ) // MachineSets returns a list of machinesets for a machinepool. -func MachineSets(config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]clusterapi.MachineSet, error) { +func MachineSets(config *types.InstallConfig, pool *types.MachinePool, osImage, role, userDataSecret string) ([]clusterapi.MachineSet, error) { if configPlatform := config.Platform.Name(); configPlatform != aws.Name { return nil, fmt.Errorf("non-AWS configuration: %q", configPlatform) } @@ -38,7 +38,7 @@ func MachineSets(config *types.InstallConfig, pool *types.MachinePool, role, use replicas++ } - provider, err := provider(config.ClusterID, clustername, platform, mpool, idx, role, userDataSecret) + provider, err := provider(config.ClusterID, clustername, platform, mpool, osImage, idx, role, userDataSecret) if err != nil { return nil, errors.Wrap(err, "failed to create provider") } diff --git a/pkg/asset/machines/libvirt/machines.go b/pkg/asset/machines/libvirt/machines.go index 9d3ccf66fb7..90ee78848c8 100644 --- a/pkg/asset/machines/libvirt/machines.go +++ b/pkg/asset/machines/libvirt/machines.go @@ -18,14 +18,11 @@ func Machines(config *types.InstallConfig, pool *types.MachinePool, role, userDa if configPlatform := config.Platform.Name(); configPlatform != libvirt.Name { return nil, fmt.Errorf("non-Libvirt configuration: %q", configPlatform) } - // FIXME: empty is a valid case for Libvirt as we don't use it. - if poolPlatform := pool.Platform.Name(); poolPlatform != "" && poolPlatform != libvirt.Name { + if poolPlatform := pool.Platform.Name(); poolPlatform != libvirt.Name { return nil, fmt.Errorf("non-Libvirt machine-pool: %q", poolPlatform) } clustername := config.ObjectMeta.Name platform := config.Platform.Libvirt - // FIXME: libvirt actuator does not support any options from machinepool. - // mpool := pool.Platform.Libvirt total := int64(1) if pool.Replicas != nil { diff --git a/pkg/asset/machines/master.go b/pkg/asset/machines/master.go index 7152f2d12c9..11070f8c831 100644 --- a/pkg/asset/machines/master.go +++ b/pkg/asset/machines/master.go @@ -1,9 +1,7 @@ package machines import ( - "context" "fmt" - "time" "github.com/ghodss/yaml" "github.com/pkg/errors" @@ -17,7 +15,7 @@ import ( "github.com/openshift/installer/pkg/asset/machines/aws" "github.com/openshift/installer/pkg/asset/machines/libvirt" "github.com/openshift/installer/pkg/asset/machines/openstack" - "github.com/openshift/installer/pkg/rhcos" + "github.com/openshift/installer/pkg/asset/rhcos" "github.com/openshift/installer/pkg/types" awstypes "github.com/openshift/installer/pkg/types/aws" libvirttypes "github.com/openshift/installer/pkg/types/libvirt" @@ -43,6 +41,7 @@ func (m *Master) Name() string { func (m *Master) Dependencies() []asset.Asset { return []asset.Asset{ &installconfig.InstallConfig{}, + new(rhcos.Image), &machine.Master{}, } } @@ -50,8 +49,9 @@ func (m *Master) Dependencies() []asset.Asset { // Generate generates the Master asset. func (m *Master) Generate(dependencies asset.Parents) error { installconfig := &installconfig.InstallConfig{} + rhcosImage := new(rhcos.Image) mign := &machine.Master{} - dependencies.Get(installconfig, mign) + dependencies.Get(installconfig, rhcosImage, mign) var err error userDataMap := map[string][]byte{"master-user-data": mign.File.Data} @@ -67,15 +67,6 @@ func (m *Master) Generate(dependencies asset.Parents) error { mpool := defaultAWSMachinePoolPlatform() mpool.Set(ic.Platform.AWS.DefaultMachinePlatform) mpool.Set(pool.Platform.AWS) - if mpool.AMIID == "" { - ctx, cancel := context.WithTimeout(context.TODO(), 60*time.Second) - defer cancel() - ami, err := rhcos.AMI(ctx, rhcos.DefaultChannel, ic.Platform.AWS.Region) - if err != nil { - return errors.Wrap(err, "failed to determine default AMI") - } - mpool.AMIID = ami - } if len(mpool.Zones) == 0 { azs, err := aws.AvailabilityZones(ic.Platform.AWS.Region) if err != nil { @@ -84,7 +75,7 @@ func (m *Master) Generate(dependencies asset.Parents) error { mpool.Zones = azs } pool.Platform.AWS = &mpool - machines, err := aws.Machines(ic, &pool, "master", "master-user-data") + machines, err := aws.Machines(ic, &pool, string(*rhcosImage), "master", "master-user-data") if err != nil { return errors.Wrap(err, "failed to create master machine objects") } @@ -97,6 +88,10 @@ func (m *Master) Generate(dependencies asset.Parents) error { } m.MachinesRaw = raw case libvirttypes.Name: + mpool := defaultLibvirtMachinePoolPlatform() + mpool.Set(ic.Platform.Libvirt.DefaultMachinePlatform) + mpool.Set(pool.Platform.Libvirt) + pool.Platform.Libvirt = &mpool machines, err := libvirt.Machines(ic, &pool, "master", "master-user-data") if err != nil { return errors.Wrap(err, "failed to create master machine objects") @@ -121,7 +116,7 @@ func (m *Master) Generate(dependencies asset.Parents) error { config := openstack.MasterConfig{ ClusterName: ic.ObjectMeta.Name, Instances: instances, - Image: ic.Platform.OpenStack.BaseImage, + Image: string(*rhcosImage), Region: ic.Platform.OpenStack.Region, Machine: defaultOpenStackMachinePoolPlatform(ic.Platform.OpenStack.FlavorName), Trunk: trunkSupportBoolean(ic.Platform.OpenStack.TrunkSupport), diff --git a/pkg/asset/machines/worker.go b/pkg/asset/machines/worker.go index 65519826bca..be8a95b472e 100644 --- a/pkg/asset/machines/worker.go +++ b/pkg/asset/machines/worker.go @@ -2,10 +2,8 @@ package machines import ( "bytes" - "context" "fmt" "text/template" - "time" "github.com/ghodss/yaml" "github.com/pkg/errors" @@ -19,7 +17,7 @@ import ( "github.com/openshift/installer/pkg/asset/machines/aws" "github.com/openshift/installer/pkg/asset/machines/libvirt" "github.com/openshift/installer/pkg/asset/machines/openstack" - "github.com/openshift/installer/pkg/rhcos" + "github.com/openshift/installer/pkg/asset/rhcos" "github.com/openshift/installer/pkg/types" awstypes "github.com/openshift/installer/pkg/types/aws" libvirttypes "github.com/openshift/installer/pkg/types/libvirt" @@ -33,6 +31,10 @@ func defaultAWSMachinePoolPlatform() awstypes.MachinePool { } } +func defaultLibvirtMachinePoolPlatform() libvirttypes.MachinePool { + return libvirttypes.MachinePool{} +} + func defaultOpenStackMachinePoolPlatform(flavor string) openstacktypes.MachinePool { return openstacktypes.MachinePool{ FlavorName: flavor, @@ -66,6 +68,7 @@ func (w *Worker) Name() string { func (w *Worker) Dependencies() []asset.Asset { return []asset.Asset{ &installconfig.InstallConfig{}, + new(rhcos.Image), &machine.Worker{}, } } @@ -73,8 +76,9 @@ func (w *Worker) Dependencies() []asset.Asset { // Generate generates the Worker asset. func (w *Worker) Generate(dependencies asset.Parents) error { installconfig := &installconfig.InstallConfig{} + rhcosImage := new(rhcos.Image) wign := &machine.Worker{} - dependencies.Get(installconfig, wign) + dependencies.Get(installconfig, rhcosImage, wign) var err error userDataMap := map[string][]byte{"worker-user-data": wign.File.Data} @@ -90,15 +94,6 @@ func (w *Worker) Generate(dependencies asset.Parents) error { mpool := defaultAWSMachinePoolPlatform() mpool.Set(ic.Platform.AWS.DefaultMachinePlatform) mpool.Set(pool.Platform.AWS) - if mpool.AMIID == "" { - ctx, cancel := context.WithTimeout(context.TODO(), 60*time.Second) - defer cancel() - ami, err := rhcos.AMI(ctx, rhcos.DefaultChannel, ic.Platform.AWS.Region) - if err != nil { - return errors.Wrap(err, "failed to determine default AMI") - } - mpool.AMIID = ami - } if len(mpool.Zones) == 0 { azs, err := aws.AvailabilityZones(ic.Platform.AWS.Region) if err != nil { @@ -107,7 +102,7 @@ func (w *Worker) Generate(dependencies asset.Parents) error { mpool.Zones = azs } pool.Platform.AWS = &mpool - sets, err := aws.MachineSets(ic, &pool, "worker", "worker-user-data") + sets, err := aws.MachineSets(ic, &pool, string(*rhcosImage), "worker", "worker-user-data") if err != nil { return errors.Wrap(err, "failed to create worker machine objects") } @@ -119,6 +114,10 @@ func (w *Worker) Generate(dependencies asset.Parents) error { } w.MachineSetRaw = raw case libvirttypes.Name: + mpool := defaultLibvirtMachinePoolPlatform() + mpool.Set(ic.Platform.Libvirt.DefaultMachinePlatform) + mpool.Set(pool.Platform.Libvirt) + pool.Platform.Libvirt = &mpool sets, err := libvirt.MachineSets(ic, &pool, "worker", "worker-user-data") if err != nil { return errors.Wrap(err, "failed to create worker machine objects") @@ -139,7 +138,7 @@ func (w *Worker) Generate(dependencies asset.Parents) error { config := openstack.Config{ ClusterName: ic.ObjectMeta.Name, Replicas: numOfWorkers, - Image: ic.Platform.OpenStack.BaseImage, + Image: string(*rhcosImage), Region: ic.Platform.OpenStack.Region, Machine: defaultOpenStackMachinePoolPlatform(ic.Platform.OpenStack.FlavorName), Trunk: trunkSupportBoolean(ic.Platform.OpenStack.TrunkSupport), diff --git a/pkg/asset/rhcos/image.go b/pkg/asset/rhcos/image.go new file mode 100644 index 00000000000..956b85bc320 --- /dev/null +++ b/pkg/asset/rhcos/image.go @@ -0,0 +1,72 @@ +// Package rhcos contains assets for RHCOS. +package rhcos + +import ( + "context" + "os" + "time" + + "github.com/pkg/errors" + "github.com/sirupsen/logrus" + + "github.com/openshift/installer/pkg/asset" + "github.com/openshift/installer/pkg/asset/installconfig" + "github.com/openshift/installer/pkg/rhcos" + "github.com/openshift/installer/pkg/types/aws" + "github.com/openshift/installer/pkg/types/libvirt" + "github.com/openshift/installer/pkg/types/none" + "github.com/openshift/installer/pkg/types/openstack" +) + +// Image is location of RHCOS image. +// This stores the location of the image based on the platform. +// eg. on AWS this contains ami-id, on Livirt this can be the URI for QEMU image etc. +type Image string + +var _ asset.Asset = (*Image)(nil) + +// Name returns the human-friendly name of the asset. +func (i *Image) Name() string { + return "Image" +} + +// Dependencies returns no dependencies. +func (i *Image) Dependencies() []asset.Asset { + return []asset.Asset{ + &installconfig.InstallConfig{}, + } +} + +// Generate the RHCOS image location. +func (i *Image) Generate(p asset.Parents) error { + if oi, ok := os.LookupEnv("OPENSHIFT_INSTALL_OS_IMAGE_OVERRIDE"); ok && oi != "" { + logrus.Warn("Found override for OS Image. Please be warned, this is not advised") + *i = Image(oi) + return nil + } + + ic := &installconfig.InstallConfig{} + p.Get(ic) + config := ic.Config + + var osimage string + var err error + ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) + defer cancel() + switch config.Platform.Name() { + case aws.Name: + osimage, err = rhcos.AMI(ctx, rhcos.DefaultChannel, config.Platform.AWS.Region) + case libvirt.Name: + osimage, err = rhcos.QEMU(ctx, rhcos.DefaultChannel) + case openstack.Name: + osimage = "rhcos" + case none.Name: + default: + return errors.New("invalid Platform") + } + if err != nil { + return err + } + *i = Image(osimage) + return nil +} diff --git a/pkg/tfvars/tfvars.go b/pkg/tfvars/tfvars.go index d0956151b90..5e1aab57587 100644 --- a/pkg/tfvars/tfvars.go +++ b/pkg/tfvars/tfvars.go @@ -2,11 +2,8 @@ package tfvars import ( - "context" "encoding/json" - "time" - "github.com/openshift/installer/pkg/rhcos" "github.com/openshift/installer/pkg/tfvars/aws" "github.com/openshift/installer/pkg/tfvars/libvirt" "github.com/openshift/installer/pkg/tfvars/openstack" @@ -31,7 +28,7 @@ type config struct { // TFVars converts the InstallConfig and Ignition content to // terraform.tfvar JSON. -func TFVars(cfg *types.InstallConfig, bootstrapIgn, masterIgn string) ([]byte, error) { +func TFVars(cfg *types.InstallConfig, osImage, bootstrapIgn, masterIgn string) ([]byte, error) { config := &config{ ClusterID: cfg.ClusterID, Name: cfg.ObjectMeta.Name, @@ -76,17 +73,10 @@ func TFVars(cfg *types.InstallConfig, bootstrapIgn, masterIgn string) ([]byte, e } if cfg.Platform.AWS != nil { - ctx, cancel := context.WithTimeout(context.TODO(), 30*time.Second) - defer cancel() - ami, err := rhcos.AMI(ctx, rhcos.DefaultChannel, cfg.Platform.AWS.Region) - if err != nil { - return nil, errors.Wrap(err, "failed to determine default AMI") - } - config.AWS = aws.AWS{ Region: cfg.Platform.AWS.Region, ExtraTags: cfg.Platform.AWS.UserTags, - EC2AMIOverride: ami, + EC2AMIOverride: osImage, } } else if cfg.Platform.Libvirt != nil { masterIPs := make([]string, len(cfg.Platform.Libvirt.MasterIPs)) @@ -98,7 +88,7 @@ func TFVars(cfg *types.InstallConfig, bootstrapIgn, masterIgn string) ([]byte, e Network: libvirt.Network{ IfName: cfg.Platform.Libvirt.Network.IfName, }, - Image: cfg.Platform.Libvirt.DefaultMachinePlatform.Image, + Image: osImage, MasterIPs: masterIPs, } if err := config.Libvirt.TFVars(&cfg.Networking.MachineCIDR.IPNet, config.Masters); err != nil { @@ -110,7 +100,7 @@ func TFVars(cfg *types.InstallConfig, bootstrapIgn, masterIgn string) ([]byte, e } else if cfg.Platform.OpenStack != nil { config.OpenStack = openstack.OpenStack{ Region: cfg.Platform.OpenStack.Region, - BaseImage: cfg.Platform.OpenStack.BaseImage, + BaseImage: osImage, } config.OpenStack.Credentials.Cloud = cfg.Platform.OpenStack.Cloud config.OpenStack.ExternalNetwork = cfg.Platform.OpenStack.ExternalNetwork diff --git a/pkg/types/aws/machinepool.go b/pkg/types/aws/machinepool.go index b19dcea1ad2..ba872b1635c 100644 --- a/pkg/types/aws/machinepool.go +++ b/pkg/types/aws/machinepool.go @@ -6,9 +6,6 @@ type MachinePool struct { // Zones is list of availability zones that can be used. Zones []string `json:"zones,omitempty"` - // AMIID defines the AMI that should be used. - AMIID string `json:"amiID,omitempty"` - // InstanceType defines the ec2 instance type. // eg. m4-large InstanceType string `json:"type"` @@ -30,9 +27,7 @@ func (a *MachinePool) Set(required *MachinePool) { if len(required.Zones) > 0 { a.Zones = required.Zones } - if required.AMIID != "" { - a.AMIID = required.AMIID - } + if required.InstanceType != "" { a.InstanceType = required.InstanceType } diff --git a/pkg/types/libvirt/machinepool.go b/pkg/types/libvirt/machinepool.go index 00dadb5e609..5470f85159d 100644 --- a/pkg/types/libvirt/machinepool.go +++ b/pkg/types/libvirt/machinepool.go @@ -3,16 +3,6 @@ package libvirt // MachinePool stores the configuration for a machine pool installed // on libvirt. type MachinePool struct { - // ImagePool is the name of the libvirt storage pool to which the storage - // volume containing the OS image belongs. - ImagePool string `json:"imagePool,omitempty"` - // ImageVolume is the name of the libvirt storage volume containing the OS - // image. - ImageVolume string `json:"imageVolume,omitempty"` - - // Image is the URL to the OS image. - // E.g. "http://aos-ostree.rhev-ci-vms.eng.rdu2.redhat.com/rhcos/images/cloud/latest/rhcos-qemu.qcow2.gz" - Image string `json:"image"` } // Set sets the values from `required` to `a`. @@ -20,14 +10,4 @@ func (l *MachinePool) Set(required *MachinePool) { if required == nil || l == nil { return } - - if required.ImagePool != "" { - l.ImagePool = required.ImagePool - } - if required.ImageVolume != "" { - l.ImageVolume = required.ImageVolume - } - if required.Image != "" { - l.Image = required.Image - } } diff --git a/pkg/types/libvirt/validation/machinepool.go b/pkg/types/libvirt/validation/machinepool.go index 42c330a7668..f372b889578 100644 --- a/pkg/types/libvirt/validation/machinepool.go +++ b/pkg/types/libvirt/validation/machinepool.go @@ -4,16 +4,9 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" "github.com/openshift/installer/pkg/types/libvirt" - "github.com/openshift/installer/pkg/validate" ) // ValidateMachinePool checks that the specified machine pool is valid. func ValidateMachinePool(p *libvirt.MachinePool, fldPath *field.Path) field.ErrorList { - allErrs := field.ErrorList{} - if p.Image != "" { - if err := validate.URI(p.Image); err != nil { - allErrs = append(allErrs, field.Invalid(fldPath.Child("image"), p.Image, err.Error())) - } - } - return allErrs + return field.ErrorList{} } diff --git a/pkg/types/libvirt/validation/machinepool_test.go b/pkg/types/libvirt/validation/machinepool_test.go index 1984c89eb2a..a613bfb2744 100644 --- a/pkg/types/libvirt/validation/machinepool_test.go +++ b/pkg/types/libvirt/validation/machinepool_test.go @@ -20,20 +20,6 @@ func TestValidateMachinePool(t *testing.T) { pool: &libvirt.MachinePool{}, valid: true, }, - { - name: "valid image", - pool: &libvirt.MachinePool{ - Image: "https://example.com/rhcos-qemu.qcow2", - }, - valid: true, - }, - { - name: "invalid image", - pool: &libvirt.MachinePool{ - Image: "bad-image", - }, - valid: false, - }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/types/libvirt/validation/platform_test.go b/pkg/types/libvirt/validation/platform_test.go index 036085ed67e..67377269f2f 100644 --- a/pkg/types/libvirt/validation/platform_test.go +++ b/pkg/types/libvirt/validation/platform_test.go @@ -56,17 +56,6 @@ func TestValidatePlatform(t *testing.T) { }(), valid: true, }, - { - name: "invalid machine pool", - platform: func() *libvirt.Platform { - p := validPlatform() - p.DefaultMachinePlatform = &libvirt.MachinePool{ - Image: "bad-image", - } - return p - }(), - valid: false, - }, } for _, tc := range cases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/types/openstack/platform.go b/pkg/types/openstack/platform.go index 1c7c0d8abc7..ca474845121 100644 --- a/pkg/types/openstack/platform.go +++ b/pkg/types/openstack/platform.go @@ -11,10 +11,6 @@ type Platform struct { // platform configuration. DefaultMachinePlatform *MachinePool `json:"defaultMachinePlatform,omitempty"` - // BaseImage - // Name of image to use from OpenStack cloud - BaseImage string `json:"baseImage"` - // Cloud // Name of OpenStack cloud to use from clouds.yaml Cloud string `json:"cloud"` diff --git a/pkg/types/openstack/validation/mock/validvaluesfetcher_generated.go b/pkg/types/openstack/validation/mock/validvaluesfetcher_generated.go index 52959bcebbc..7735b302e76 100644 --- a/pkg/types/openstack/validation/mock/validvaluesfetcher_generated.go +++ b/pkg/types/openstack/validation/mock/validvaluesfetcher_generated.go @@ -62,21 +62,6 @@ func (mr *MockValidValuesFetcherMockRecorder) GetRegionNames(cloud interface{}) return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetRegionNames", reflect.TypeOf((*MockValidValuesFetcher)(nil).GetRegionNames), cloud) } -// GetImageNames mocks base method -func (m *MockValidValuesFetcher) GetImageNames(cloud string) ([]string, error) { - m.ctrl.T.Helper() - ret := m.ctrl.Call(m, "GetImageNames", cloud) - ret0, _ := ret[0].([]string) - ret1, _ := ret[1].(error) - return ret0, ret1 -} - -// GetImageNames indicates an expected call of GetImageNames -func (mr *MockValidValuesFetcherMockRecorder) GetImageNames(cloud interface{}) *gomock.Call { - mr.mock.ctrl.T.Helper() - return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "GetImageNames", reflect.TypeOf((*MockValidValuesFetcher)(nil).GetImageNames), cloud) -} - // GetNetworkNames mocks base method func (m *MockValidValuesFetcher) GetNetworkNames(cloud string) ([]string, error) { m.ctrl.T.Helper() diff --git a/pkg/types/openstack/validation/platform.go b/pkg/types/openstack/validation/platform.go index a8d3a89c122..121797893b8 100644 --- a/pkg/types/openstack/validation/platform.go +++ b/pkg/types/openstack/validation/platform.go @@ -23,12 +23,6 @@ func ValidatePlatform(p *openstack.Platform, fldPath *field.Path, fetcher ValidV } else if !isValidValue(p.Region, validRegions) { allErrs = append(allErrs, field.NotSupported(fldPath.Child("region"), p.Region, validRegions)) } - validImages, err := fetcher.GetImageNames(p.Cloud) - if err != nil { - allErrs = append(allErrs, field.InternalError(fldPath.Child("baseImage"), errors.New("could not retrieve valid images"))) - } else if !isValidValue(p.BaseImage, validImages) { - allErrs = append(allErrs, field.NotSupported(fldPath.Child("baseImage"), p.BaseImage, validImages)) - } validNetworks, err := fetcher.GetNetworkNames(p.Cloud) if err != nil { allErrs = append(allErrs, field.InternalError(fldPath.Child("externalNetwork"), errors.New("could not retrieve valid networks"))) diff --git a/pkg/types/openstack/validation/platform_test.go b/pkg/types/openstack/validation/platform_test.go index b79a4092d71..2f1c616f816 100644 --- a/pkg/types/openstack/validation/platform_test.go +++ b/pkg/types/openstack/validation/platform_test.go @@ -15,7 +15,6 @@ import ( func validPlatform() *openstack.Platform { return &openstack.Platform{ Region: "test-region", - BaseImage: "test-image", Cloud: "test-cloud", ExternalNetwork: "test-network", FlavorName: "test-flavor", @@ -28,7 +27,6 @@ func TestValidatePlatform(t *testing.T) { platform *openstack.Platform noClouds bool noRegions bool - noImages bool noNetworks bool noFlavors bool noNetExts bool @@ -48,15 +46,6 @@ func TestValidatePlatform(t *testing.T) { }(), valid: false, }, - { - name: "invalid base image", - platform: func() *openstack.Platform { - p := validPlatform() - p.BaseImage = "bad-image" - return p - }(), - valid: false, - }, { name: "missing cloud", platform: func() *openstack.Platform { @@ -96,12 +85,6 @@ func TestValidatePlatform(t *testing.T) { noRegions: true, valid: false, }, - { - name: "images fetch failure", - platform: validPlatform(), - noImages: true, - valid: false, - }, { name: "networks fetch failure", platform: validPlatform(), @@ -143,15 +126,6 @@ func TestValidatePlatform(t *testing.T) { Return([]string{"test-region"}, nil). MaxTimes(1) } - if tc.noImages { - fetcher.EXPECT().GetImageNames(tc.platform.Cloud). - Return(nil, errors.New("no images")). - MaxTimes(1) - } else { - fetcher.EXPECT().GetImageNames(tc.platform.Cloud). - Return([]string{"test-image"}, nil). - MaxTimes(1) - } if tc.noNetworks { fetcher.EXPECT().GetNetworkNames(tc.platform.Cloud). Return(nil, errors.New("no networks")). diff --git a/pkg/types/openstack/validation/realvalidvaluesfetcher.go b/pkg/types/openstack/validation/realvalidvaluesfetcher.go index f835ca1457d..57bc833cd34 100644 --- a/pkg/types/openstack/validation/realvalidvaluesfetcher.go +++ b/pkg/types/openstack/validation/realvalidvaluesfetcher.go @@ -4,7 +4,6 @@ import ( "github.com/gophercloud/gophercloud/openstack/common/extensions" "github.com/gophercloud/gophercloud/openstack/compute/v2/flavors" "github.com/gophercloud/gophercloud/openstack/identity/v3/regions" - "github.com/gophercloud/gophercloud/openstack/imageservice/v2/images" netext "github.com/gophercloud/gophercloud/openstack/networking/v2/extensions" "github.com/gophercloud/gophercloud/openstack/networking/v2/networks" "github.com/gophercloud/utils/openstack/clientconfig" @@ -62,36 +61,6 @@ func (f realValidValuesFetcher) GetRegionNames(cloud string) ([]string, error) { return regionNames, nil } -// GetImageNames gets the valid image names. -func (f realValidValuesFetcher) GetImageNames(cloud string) ([]string, error) { - opts := &clientconfig.ClientOpts{ - Cloud: cloud, - } - - conn, err := clientconfig.NewServiceClient("image", opts) - if err != nil { - return nil, err - } - - listOpts := images.ListOpts{} - allPages, err := images.List(conn, listOpts).AllPages() - if err != nil { - return nil, err - } - - allImages, err := images.ExtractImages(allPages) - if err != nil { - return nil, err - } - - imageNames := make([]string, len(allImages)) - for x, image := range allImages { - imageNames[x] = image.Name - } - - return imageNames, nil -} - // GetNetworkNames gets the valid network names. func (f realValidValuesFetcher) GetNetworkNames(cloud string) ([]string, error) { opts := &clientconfig.ClientOpts{ diff --git a/pkg/types/openstack/validation/validvaluesfetcher.go b/pkg/types/openstack/validation/validvaluesfetcher.go index 6b1e1e0880a..c06515a5e72 100644 --- a/pkg/types/openstack/validation/validvaluesfetcher.go +++ b/pkg/types/openstack/validation/validvaluesfetcher.go @@ -8,8 +8,6 @@ type ValidValuesFetcher interface { GetCloudNames() ([]string, error) // GetRegionNames gets the valid region names. GetRegionNames(cloud string) ([]string, error) - // GetImageNames gets the valid image names. - GetImageNames(cloud string) ([]string, error) // GetNetworkNames gets the valid network names. GetNetworkNames(cloud string) ([]string, error) // GetFlavorNames gets the valid flavor names. diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index a216e408da2..0a4e9f836e7 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -254,7 +254,6 @@ func TestValidateInstallConfig(t *testing.T) { c.Platform = types.Platform{ OpenStack: &openstack.Platform{ Region: "test-region", - BaseImage: "test-image", Cloud: "test-cloud", ExternalNetwork: "test-network", FlavorName: "test-flavor", @@ -283,7 +282,6 @@ func TestValidateInstallConfig(t *testing.T) { fetcher := mock.NewMockValidValuesFetcher(mockCtrl) fetcher.EXPECT().GetCloudNames().Return([]string{"test-cloud"}, nil).AnyTimes() fetcher.EXPECT().GetRegionNames(gomock.Any()).Return([]string{"test-region"}, nil).AnyTimes() - fetcher.EXPECT().GetImageNames(gomock.Any()).Return([]string{"test-image"}, nil).AnyTimes() fetcher.EXPECT().GetNetworkNames(gomock.Any()).Return([]string{"test-network"}, nil).AnyTimes() fetcher.EXPECT().GetFlavorNames(gomock.Any()).Return([]string{"test-flavor"}, nil).AnyTimes() fetcher.EXPECT().GetNetworkExtensionsAliases(gomock.Any()).Return([]string{"trunk"}, nil).AnyTimes() diff --git a/pkg/types/validation/machinepools_test.go b/pkg/types/validation/machinepools_test.go index 966ab643e4c..3f0554de3e4 100644 --- a/pkg/types/validation/machinepools_test.go +++ b/pkg/types/validation/machinepools_test.go @@ -81,19 +81,6 @@ func TestValidateMachinePool(t *testing.T) { platform: "libvirt", valid: true, }, - { - name: "invalid libvirt", - pool: &types.MachinePool{ - Name: "master", - Platform: types.MachinePoolPlatform{ - Libvirt: &libvirt.MachinePool{ - Image: "bad-image", - }, - }, - }, - platform: "libvirt", - valid: false, - }, { name: "valid openstack", pool: &types.MachinePool{ diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/doc.go b/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/doc.go deleted file mode 100644 index 14da9ac90da..00000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/doc.go +++ /dev/null @@ -1,60 +0,0 @@ -/* -Package images enables management and retrieval of images from the OpenStack -Image Service. - -Example to List Images - - images.ListOpts{ - Owner: "a7509e1ae65945fda83f3e52c6296017", - } - - allPages, err := images.List(imagesClient, listOpts).AllPages() - if err != nil { - panic(err) - } - - allImages, err := images.ExtractImages(allPages) - if err != nil { - panic(err) - } - - for _, image := range allImages { - fmt.Printf("%+v\n", image) - } - -Example to Create an Image - - createOpts := images.CreateOpts{ - Name: "image_name", - Visibility: images.ImageVisibilityPrivate, - } - - image, err := images.Create(imageClient, createOpts) - if err != nil { - panic(err) - } - -Example to Update an Image - - imageID := "1bea47ed-f6a9-463b-b423-14b9cca9ad27" - - updateOpts := images.UpdateOpts{ - images.ReplaceImageName{ - NewName: "new_name", - }, - } - - image, err := images.Update(imageClient, imageID, updateOpts).Extract() - if err != nil { - panic(err) - } - -Example to Delete an Image - - imageID := "1bea47ed-f6a9-463b-b423-14b9cca9ad27" - err := images.Delete(imageClient, imageID).ExtractErr() - if err != nil { - panic(err) - } -*/ -package images diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/requests.go b/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/requests.go deleted file mode 100644 index 16290d395a1..00000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/requests.go +++ /dev/null @@ -1,352 +0,0 @@ -package images - -import ( - "fmt" - "net/url" - "time" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/pagination" -) - -// ListOptsBuilder allows extensions to add additional parameters to the -// List request. -type ListOptsBuilder interface { - ToImageListQuery() (string, error) -} - -// ListOpts allows the filtering and sorting of paginated collections through -// the API. Filtering is achieved by passing in struct field values that map to -// the server attributes you want to see returned. Marker and Limit are used -// for pagination. -// -// http://developer.openstack.org/api-ref-image-v2.html -type ListOpts struct { - // ID is the ID of the image. - // Multiple IDs can be specified by constructing a string - // such as "in:uuid1,uuid2,uuid3". - ID string `q:"id"` - - // Integer value for the limit of values to return. - Limit int `q:"limit"` - - // UUID of the server at which you want to set a marker. - Marker string `q:"marker"` - - // Name filters on the name of the image. - // Multiple names can be specified by constructing a string - // such as "in:name1,name2,name3". - Name string `q:"name"` - - // Visibility filters on the visibility of the image. - Visibility ImageVisibility `q:"visibility"` - - // MemberStatus filters on the member status of the image. - MemberStatus ImageMemberStatus `q:"member_status"` - - // Owner filters on the project ID of the image. - Owner string `q:"owner"` - - // Status filters on the status of the image. - // Multiple statuses can be specified by constructing a string - // such as "in:saving,queued". - Status ImageStatus `q:"status"` - - // SizeMin filters on the size_min image property. - SizeMin int64 `q:"size_min"` - - // SizeMax filters on the size_max image property. - SizeMax int64 `q:"size_max"` - - // Sort sorts the results using the new style of sorting. See the OpenStack - // Image API reference for the exact syntax. - // - // Sort cannot be used with the classic sort options (sort_key and sort_dir). - Sort string `q:"sort"` - - // SortKey will sort the results based on a specified image property. - SortKey string `q:"sort_key"` - - // SortDir will sort the list results either ascending or decending. - SortDir string `q:"sort_dir"` - - // Tags filters on specific image tags. - Tags []string `q:"tag"` - - // CreatedAtQuery filters images based on their creation date. - CreatedAtQuery *ImageDateQuery - - // UpdatedAtQuery filters images based on their updated date. - UpdatedAtQuery *ImageDateQuery - - // ContainerFormat filters images based on the container_format. - // Multiple container formats can be specified by constructing a - // string such as "in:bare,ami". - ContainerFormat string `q:"container_format"` - - // DiskFormat filters images based on the disk_format. - // Multiple disk formats can be specified by constructing a string - // such as "in:qcow2,iso". - DiskFormat string `q:"disk_format"` -} - -// ToImageListQuery formats a ListOpts into a query string. -func (opts ListOpts) ToImageListQuery() (string, error) { - q, err := gophercloud.BuildQueryString(opts) - params := q.Query() - - if opts.CreatedAtQuery != nil { - createdAt := opts.CreatedAtQuery.Date.Format(time.RFC3339) - if v := opts.CreatedAtQuery.Filter; v != "" { - createdAt = fmt.Sprintf("%s:%s", v, createdAt) - } - - params.Add("created_at", createdAt) - } - - if opts.UpdatedAtQuery != nil { - updatedAt := opts.UpdatedAtQuery.Date.Format(time.RFC3339) - if v := opts.UpdatedAtQuery.Filter; v != "" { - updatedAt = fmt.Sprintf("%s:%s", v, updatedAt) - } - - params.Add("updated_at", updatedAt) - } - - q = &url.URL{RawQuery: params.Encode()} - - return q.String(), err -} - -// List implements image list request. -func List(c *gophercloud.ServiceClient, opts ListOptsBuilder) pagination.Pager { - url := listURL(c) - if opts != nil { - query, err := opts.ToImageListQuery() - if err != nil { - return pagination.Pager{Err: err} - } - url += query - } - return pagination.NewPager(c, url, func(r pagination.PageResult) pagination.Page { - imagePage := ImagePage{ - serviceURL: c.ServiceURL(), - LinkedPageBase: pagination.LinkedPageBase{PageResult: r}, - } - - return imagePage - }) -} - -// CreateOptsBuilder allows extensions to add parameters to the Create request. -type CreateOptsBuilder interface { - // Returns value that can be passed to json.Marshal - ToImageCreateMap() (map[string]interface{}, error) -} - -// CreateOpts represents options used to create an image. -type CreateOpts struct { - // Name is the name of the new image. - Name string `json:"name" required:"true"` - - // Id is the the image ID. - ID string `json:"id,omitempty"` - - // Visibility defines who can see/use the image. - Visibility *ImageVisibility `json:"visibility,omitempty"` - - // Tags is a set of image tags. - Tags []string `json:"tags,omitempty"` - - // ContainerFormat is the format of the - // container. Valid values are ami, ari, aki, bare, and ovf. - ContainerFormat string `json:"container_format,omitempty"` - - // DiskFormat is the format of the disk. If set, - // valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, - // and iso. - DiskFormat string `json:"disk_format,omitempty"` - - // MinDisk is the amount of disk space in - // GB that is required to boot the image. - MinDisk int `json:"min_disk,omitempty"` - - // MinRAM is the amount of RAM in MB that - // is required to boot the image. - MinRAM int `json:"min_ram,omitempty"` - - // protected is whether the image is not deletable. - Protected *bool `json:"protected,omitempty"` - - // properties is a set of properties, if any, that - // are associated with the image. - Properties map[string]string `json:"-"` -} - -// ToImageCreateMap assembles a request body based on the contents of -// a CreateOpts. -func (opts CreateOpts) ToImageCreateMap() (map[string]interface{}, error) { - b, err := gophercloud.BuildRequestBody(opts, "") - if err != nil { - return nil, err - } - - if opts.Properties != nil { - for k, v := range opts.Properties { - b[k] = v - } - } - return b, nil -} - -// Create implements create image request. -func Create(client *gophercloud.ServiceClient, opts CreateOptsBuilder) (r CreateResult) { - b, err := opts.ToImageCreateMap() - if err != nil { - r.Err = err - return r - } - _, r.Err = client.Post(createURL(client), b, &r.Body, &gophercloud.RequestOpts{OkCodes: []int{201}}) - return -} - -// Delete implements image delete request. -func Delete(client *gophercloud.ServiceClient, id string) (r DeleteResult) { - _, r.Err = client.Delete(deleteURL(client, id), nil) - return -} - -// Get implements image get request. -func Get(client *gophercloud.ServiceClient, id string) (r GetResult) { - _, r.Err = client.Get(getURL(client, id), &r.Body, nil) - return -} - -// Update implements image updated request. -func Update(client *gophercloud.ServiceClient, id string, opts UpdateOptsBuilder) (r UpdateResult) { - b, err := opts.ToImageUpdateMap() - if err != nil { - r.Err = err - return r - } - _, r.Err = client.Patch(updateURL(client, id), b, &r.Body, &gophercloud.RequestOpts{ - OkCodes: []int{200}, - MoreHeaders: map[string]string{"Content-Type": "application/openstack-images-v2.1-json-patch"}, - }) - return -} - -// UpdateOptsBuilder allows extensions to add additional parameters to the -// Update request. -type UpdateOptsBuilder interface { - // returns value implementing json.Marshaler which when marshaled matches - // the patch schema: - // http://specs.openstack.org/openstack/glance-specs/specs/api/v2/http-patch-image-api-v2.html - ToImageUpdateMap() ([]interface{}, error) -} - -// UpdateOpts implements UpdateOpts -type UpdateOpts []Patch - -// ToImageUpdateMap assembles a request body based on the contents of -// UpdateOpts. -func (opts UpdateOpts) ToImageUpdateMap() ([]interface{}, error) { - m := make([]interface{}, len(opts)) - for i, patch := range opts { - patchJSON := patch.ToImagePatchMap() - m[i] = patchJSON - } - return m, nil -} - -// Patch represents a single update to an existing image. Multiple updates -// to an image can be submitted at the same time. -type Patch interface { - ToImagePatchMap() map[string]interface{} -} - -// UpdateVisibility represents an updated visibility property request. -type UpdateVisibility struct { - Visibility ImageVisibility -} - -// ToImagePatchMap assembles a request body based on UpdateVisibility. -func (r UpdateVisibility) ToImagePatchMap() map[string]interface{} { - return map[string]interface{}{ - "op": "replace", - "path": "/visibility", - "value": r.Visibility, - } -} - -// ReplaceImageName represents an updated image_name property request. -type ReplaceImageName struct { - NewName string -} - -// ToImagePatchMap assembles a request body based on ReplaceImageName. -func (r ReplaceImageName) ToImagePatchMap() map[string]interface{} { - return map[string]interface{}{ - "op": "replace", - "path": "/name", - "value": r.NewName, - } -} - -// ReplaceImageChecksum represents an updated checksum property request. -type ReplaceImageChecksum struct { - Checksum string -} - -// ReplaceImageChecksum assembles a request body based on ReplaceImageChecksum. -func (r ReplaceImageChecksum) ToImagePatchMap() map[string]interface{} { - return map[string]interface{}{ - "op": "replace", - "path": "/checksum", - "value": r.Checksum, - } -} - -// ReplaceImageTags represents an updated tags property request. -type ReplaceImageTags struct { - NewTags []string -} - -// ToImagePatchMap assembles a request body based on ReplaceImageTags. -func (r ReplaceImageTags) ToImagePatchMap() map[string]interface{} { - return map[string]interface{}{ - "op": "replace", - "path": "/tags", - "value": r.NewTags, - } -} - -// UpdateOp represents a valid update operation. -type UpdateOp string - -const ( - AddOp UpdateOp = "add" - ReplaceOp UpdateOp = "replace" - RemoveOp UpdateOp = "remove" -) - -// UpdateImageProperty represents an update property request. -type UpdateImageProperty struct { - Op UpdateOp - Name string - Value string -} - -// ToImagePatchMap assembles a request body based on UpdateImageProperty. -func (r UpdateImageProperty) ToImagePatchMap() map[string]interface{} { - updateMap := map[string]interface{}{ - "op": r.Op, - "path": fmt.Sprintf("/%s", r.Name), - } - - if r.Value != "" { - updateMap["value"] = r.Value - } - - return updateMap -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/results.go b/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/results.go deleted file mode 100644 index 676181e1f4e..00000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/results.go +++ /dev/null @@ -1,202 +0,0 @@ -package images - -import ( - "encoding/json" - "fmt" - "reflect" - "time" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/internal" - "github.com/gophercloud/gophercloud/pagination" -) - -// Image represents an image found in the OpenStack Image service. -type Image struct { - // ID is the image UUID. - ID string `json:"id"` - - // Name is the human-readable display name for the image. - Name string `json:"name"` - - // Status is the image status. It can be "queued" or "active" - // See imageservice/v2/images/type.go - Status ImageStatus `json:"status"` - - // Tags is a list of image tags. Tags are arbitrarily defined strings - // attached to an image. - Tags []string `json:"tags"` - - // ContainerFormat is the format of the container. - // Valid values are ami, ari, aki, bare, and ovf. - ContainerFormat string `json:"container_format"` - - // DiskFormat is the format of the disk. - // If set, valid values are ami, ari, aki, vhd, vmdk, raw, qcow2, vdi, - // and iso. - DiskFormat string `json:"disk_format"` - - // MinDiskGigabytes is the amount of disk space in GB that is required to - // boot the image. - MinDiskGigabytes int `json:"min_disk"` - - // MinRAMMegabytes [optional] is the amount of RAM in MB that is required to - // boot the image. - MinRAMMegabytes int `json:"min_ram"` - - // Owner is the tenant ID the image belongs to. - Owner string `json:"owner"` - - // Protected is whether the image is deletable or not. - Protected bool `json:"protected"` - - // Visibility defines who can see/use the image. - Visibility ImageVisibility `json:"visibility"` - - // Checksum is the checksum of the data that's associated with the image. - Checksum string `json:"checksum"` - - // SizeBytes is the size of the data that's associated with the image. - SizeBytes int64 `json:"-"` - - // Metadata is a set of metadata associated with the image. - // Image metadata allow for meaningfully define the image properties - // and tags. - // See http://docs.openstack.org/developer/glance/metadefs-concepts.html. - Metadata map[string]string `json:"metadata"` - - // Properties is a set of key-value pairs, if any, that are associated with - // the image. - Properties map[string]interface{} - - // CreatedAt is the date when the image has been created. - CreatedAt time.Time `json:"created_at"` - - // UpdatedAt is the date when the last change has been made to the image or - // it's properties. - UpdatedAt time.Time `json:"updated_at"` - - // File is the trailing path after the glance endpoint that represent the - // location of the image or the path to retrieve it. - File string `json:"file"` - - // Schema is the path to the JSON-schema that represent the image or image - // entity. - Schema string `json:"schema"` - - // VirtualSize is the virtual size of the image - VirtualSize int64 `json:"virtual_size"` -} - -func (r *Image) UnmarshalJSON(b []byte) error { - type tmp Image - var s struct { - tmp - SizeBytes interface{} `json:"size"` - } - err := json.Unmarshal(b, &s) - if err != nil { - return err - } - *r = Image(s.tmp) - - switch t := s.SizeBytes.(type) { - case nil: - r.SizeBytes = 0 - case float32: - r.SizeBytes = int64(t) - case float64: - r.SizeBytes = int64(t) - default: - return fmt.Errorf("Unknown type for SizeBytes: %v (value: %v)", reflect.TypeOf(t), t) - } - - // Bundle all other fields into Properties - var result interface{} - err = json.Unmarshal(b, &result) - if err != nil { - return err - } - if resultMap, ok := result.(map[string]interface{}); ok { - delete(resultMap, "self") - delete(resultMap, "size") - r.Properties = internal.RemainingKeys(Image{}, resultMap) - } - - return err -} - -type commonResult struct { - gophercloud.Result -} - -// Extract interprets any commonResult as an Image. -func (r commonResult) Extract() (*Image, error) { - var s *Image - err := r.ExtractInto(&s) - return s, err -} - -// CreateResult represents the result of a Create operation. Call its Extract -// method to interpret it as an Image. -type CreateResult struct { - commonResult -} - -// UpdateResult represents the result of an Update operation. Call its Extract -// method to interpret it as an Image. -type UpdateResult struct { - commonResult -} - -// GetResult represents the result of a Get operation. Call its Extract -// method to interpret it as an Image. -type GetResult struct { - commonResult -} - -// DeleteResult represents the result of a Delete operation. Call its -// ExtractErr method to interpret it as an Image. -type DeleteResult struct { - gophercloud.ErrResult -} - -// ImagePage represents the results of a List request. -type ImagePage struct { - serviceURL string - pagination.LinkedPageBase -} - -// IsEmpty returns true if an ImagePage contains no Images results. -func (r ImagePage) IsEmpty() (bool, error) { - images, err := ExtractImages(r) - return len(images) == 0, err -} - -// NextPageURL uses the response's embedded link reference to navigate to -// the next page of results. -func (r ImagePage) NextPageURL() (string, error) { - var s struct { - Next string `json:"next"` - } - err := r.ExtractInto(&s) - if err != nil { - return "", err - } - - if s.Next == "" { - return "", nil - } - - return nextPageURL(r.serviceURL, s.Next) -} - -// ExtractImages interprets the results of a single page from a List() call, -// producing a slice of Image entities. -func ExtractImages(r pagination.Page) ([]Image, error) { - var s struct { - Images []Image `json:"images"` - } - err := (r.(ImagePage)).ExtractInto(&s) - return s.Images, err -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/types.go b/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/types.go deleted file mode 100644 index d2f9cbd3bfb..00000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/types.go +++ /dev/null @@ -1,104 +0,0 @@ -package images - -import ( - "time" -) - -// ImageStatus image statuses -// http://docs.openstack.org/developer/glance/statuses.html -type ImageStatus string - -const ( - // ImageStatusQueued is a status for an image which identifier has - // been reserved for an image in the image registry. - ImageStatusQueued ImageStatus = "queued" - - // ImageStatusSaving denotes that an image’s raw data is currently being - // uploaded to Glance - ImageStatusSaving ImageStatus = "saving" - - // ImageStatusActive denotes an image that is fully available in Glance. - ImageStatusActive ImageStatus = "active" - - // ImageStatusKilled denotes that an error occurred during the uploading - // of an image’s data, and that the image is not readable. - ImageStatusKilled ImageStatus = "killed" - - // ImageStatusDeleted is used for an image that is no longer available to use. - // The image information is retained in the image registry. - ImageStatusDeleted ImageStatus = "deleted" - - // ImageStatusPendingDelete is similar to Delete, but the image is not yet - // deleted. - ImageStatusPendingDelete ImageStatus = "pending_delete" - - // ImageStatusDeactivated denotes that access to image data is not allowed to - // any non-admin user. - ImageStatusDeactivated ImageStatus = "deactivated" -) - -// ImageVisibility denotes an image that is fully available in Glance. -// This occurs when the image data is uploaded, or the image size is explicitly -// set to zero on creation. -// According to design -// https://wiki.openstack.org/wiki/Glance-v2-community-image-visibility-design -type ImageVisibility string - -const ( - // ImageVisibilityPublic all users - ImageVisibilityPublic ImageVisibility = "public" - - // ImageVisibilityPrivate users with tenantId == tenantId(owner) - ImageVisibilityPrivate ImageVisibility = "private" - - // ImageVisibilityShared images are visible to: - // - users with tenantId == tenantId(owner) - // - users with tenantId in the member-list of the image - // - users with tenantId in the member-list with member_status == 'accepted' - ImageVisibilityShared ImageVisibility = "shared" - - // ImageVisibilityCommunity images: - // - all users can see and boot it - // - users with tenantId in the member-list of the image with - // member_status == 'accepted' have this image in their default image-list. - ImageVisibilityCommunity ImageVisibility = "community" -) - -// MemberStatus is a status for adding a new member (tenant) to an image -// member list. -type ImageMemberStatus string - -const ( - // ImageMemberStatusAccepted is the status for an accepted image member. - ImageMemberStatusAccepted ImageMemberStatus = "accepted" - - // ImageMemberStatusPending shows that the member addition is pending - ImageMemberStatusPending ImageMemberStatus = "pending" - - // ImageMemberStatusAccepted is the status for a rejected image member - ImageMemberStatusRejected ImageMemberStatus = "rejected" - - // ImageMemberStatusAll - ImageMemberStatusAll ImageMemberStatus = "all" -) - -// ImageDateFilter represents a valid filter to use for filtering -// images by their date during a List. -type ImageDateFilter string - -const ( - FilterGT ImageDateFilter = "gt" - FilterGTE ImageDateFilter = "gte" - FilterLT ImageDateFilter = "lt" - FilterLTE ImageDateFilter = "lte" - FilterNEQ ImageDateFilter = "neq" - FilterEQ ImageDateFilter = "eq" -) - -// ImageDateQuery represents a date field to be used for listing images. -// If no filter is specified, the query will act as though FilterEQ was -// set. -type ImageDateQuery struct { - Date time.Time - Filter ImageDateFilter -} diff --git a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/urls.go b/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/urls.go deleted file mode 100644 index 1780c3c6ca7..00000000000 --- a/vendor/github.com/gophercloud/gophercloud/openstack/imageservice/v2/images/urls.go +++ /dev/null @@ -1,65 +0,0 @@ -package images - -import ( - "net/url" - "strings" - - "github.com/gophercloud/gophercloud" - "github.com/gophercloud/gophercloud/openstack/utils" -) - -// `listURL` is a pure function. `listURL(c)` is a URL for which a GET -// request will respond with a list of images in the service `c`. -func listURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("images") -} - -func createURL(c *gophercloud.ServiceClient) string { - return c.ServiceURL("images") -} - -// `imageURL(c,i)` is the URL for the image identified by ID `i` in -// the service `c`. -func imageURL(c *gophercloud.ServiceClient, imageID string) string { - return c.ServiceURL("images", imageID) -} - -// `getURL(c,i)` is a URL for which a GET request will respond with -// information about the image identified by ID `i` in the service -// `c`. -func getURL(c *gophercloud.ServiceClient, imageID string) string { - return imageURL(c, imageID) -} - -func updateURL(c *gophercloud.ServiceClient, imageID string) string { - return imageURL(c, imageID) -} - -func deleteURL(c *gophercloud.ServiceClient, imageID string) string { - return imageURL(c, imageID) -} - -// builds next page full url based on current url -func nextPageURL(serviceURL, requestedNext string) (string, error) { - base, err := utils.BaseEndpoint(serviceURL) - if err != nil { - return "", err - } - - requestedNextURL, err := url.Parse(requestedNext) - if err != nil { - return "", err - } - - base = gophercloud.NormalizeURL(base) - nextPath := base + strings.TrimPrefix(requestedNextURL.Path, "/") - - nextURL, err := url.Parse(nextPath) - if err != nil { - return "", err - } - - nextURL.RawQuery = requestedNextURL.RawQuery - - return nextURL.String(), nil -}