diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000000..b36c4960344 --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,32 @@ +name: Power VS Verify + +on: + pull_request: + branches: [ add-ipi ] + +jobs: + build: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + - uses: actions/setup-go@v2 + with: + go-version: '1.16.6' + + - name: Install dependencies + run: | + go version + go install golang.org/x/lint/golint + + - name: Run go fmt & lint + run: | + go fmt -mod=readonly ./... + git diff HEAD + if [ `git diff HEAD --name-only | wc -l` -gt 0 ]; then exit 1; fi + golint -set_exit_status=1 `go list -mod=readonly ./... | grep -v /vendor/` + + - name: Build + run: | + go mod vendor + ./hack/build.sh diff --git a/OWNERS_ALIASES b/OWNERS_ALIASES index f1da1e8b3eb..06b549ab0f3 100644 --- a/OWNERS_ALIASES +++ b/OWNERS_ALIASES @@ -35,7 +35,16 @@ aliases: - mandre - mdbooth - pierreprinetti - - stephenfin + powervs-approvers: + - Prashanth684 + - clnperez + - mkumatag + powervs-reviewers: + - 23TNC + - clnperez + - mjturek + - mkumatag + - Prashanth684 vsphere-approvers: - dav1x - jcpowermac diff --git a/data/data/install.openshift.io_installconfigs.yaml b/data/data/install.openshift.io_installconfigs.yaml index ec229f4c2db..e543b93ae3f 100644 --- a/data/data/install.openshift.io_installconfigs.yaml +++ b/data/data/install.openshift.io_installconfigs.yaml @@ -450,6 +450,30 @@ spec: - high_performance type: string type: object + powervs: + description: PowerVS is the configuration used when installing + on IBM Power VS. + properties: + memory: + description: Memory defines the memory in GB for the instance. + type: integer + procType: + description: ProcType defines the processor sharing model + for the instance. + type: string + processors: + description: Processors defines the processing units for + the instance. + sysType: + description: SysType defines the system type for instance. + type: string + volumeIDs: + description: VolumeIDs is the list of volumes attached to + the instance. + items: + type: string + type: array + type: object vsphere: description: VSphere is the configuration used when installing on vSphere. @@ -891,6 +915,30 @@ spec: - high_performance type: string type: object + powervs: + description: PowerVS is the configuration used when installing + on IBM Power VS. + properties: + memory: + description: Memory defines the memory in GB for the instance. + type: integer + procType: + description: ProcType defines the processor sharing model + for the instance. + type: string + processors: + description: Processors defines the processing units for the + instance. + sysType: + description: SysType defines the system type for instance. + type: string + volumeIDs: + description: VolumeIDs is the list of volumes attached to + the instance. + items: + type: string + type: array + type: object vsphere: description: VSphere is the configuration used when installing on vSphere. @@ -2089,6 +2137,87 @@ spec: - ovirt_cluster_id - ovirt_storage_domain_id type: object + powervs: + description: PowerVS is the configuration used when installing on + Power VS. + properties: + APIKey: + description: APIKey is the API key for the user's IBM Cloud account. + type: string + clusterOSImage: + description: ClusterOSImage is a pre-created Power VS boot image + that overrides the default image for cluster nodes. + type: string + defaultMachinePlatform: + description: DefaultMachinePlatform is the default configuration + used when installing on Power VS for machine pools which do + not define their own platform configuration. + properties: + memory: + description: Memory defines the memory in GB for the instance. + type: integer + procType: + description: ProcType defines the processor sharing model + for the instance. + type: string + processors: + description: Processors defines the processing units for the + instance. + sysType: + description: SysType defines the system type for instance. + type: string + volumeIDs: + description: VolumeIDs is the list of volumes attached to + the instance. + items: + type: string + type: array + type: object + powervsResourceGroup: + description: PowerVSResourceGroup is the resource group for creating + Power VS resources. + type: string + pvsNetworkName: + description: PVSNetworkName specifies an existing network within + the Power VS Service Instance. + type: string + region: + description: Region specifies the IBM Cloud region where the cluster + will be created. + type: string + serviceInstance: + description: ServiceInstanceID is the ID of the Power IAAS instance + created from the IBM Cloud Catalog + type: string + subnets: + description: Subnets specifies existing subnets (by ID) where + cluster resources will be created. Leave unset to have the + installer create subnets in a new VPC on your behalf. + items: + type: string + type: array + userID: + description: UserID is the login for the user's IBM Cloud account. + type: string + vpc: + description: VPC is a VPC inside IBM Cloud. Needed in order to + create VPC Load Balancers. + type: string + vpcRegion: + description: Zone in the region used to create VPC resources. + Leave unset to allow installer to randomly select a zone. + type: string + zone: + description: Zone specifies the IBM Cloud colo region where the + cluster will be created. Required for multi-zone regions. + type: string + required: + - powervsResourceGroup + - region + - serviceInstance + - userID + - zone + type: object vsphere: description: VSphere is the configuration used when installing on vSphere. diff --git a/data/data/powervs/bootstrap/main.tf b/data/data/powervs/bootstrap/main.tf new file mode 100644 index 00000000000..bb38c885c5a --- /dev/null +++ b/data/data/powervs/bootstrap/main.tf @@ -0,0 +1,83 @@ +# TODO(mjturek): network and image data blocks can be in main module +# as master and bootstrap will be using the same +# network and image. Once we add in master module, make +# the move. +data "ibm_pi_network" "network" { + pi_network_name = var.network_name + pi_cloud_instance_id = var.cloud_instance_id +} + +data "ignition_config" "bootstrap" { + merge { + source = ibms3presign.bootstrap_ignition.presigned_url + } +} + +data "ibm_resource_group" "cos_group" { + name = var.resource_group +} + +resource "ibm_resource_instance" "cos_instance" { + name = "${var.cluster_id}-cos" + resource_group_id = data.ibm_resource_group.cos_group.id + service = "cloud-object-storage" + plan = "standard" + location = var.cos_instance_location + tags = [var.cluster_id] +} + +# Create an IBM COS Bucket to store ignition +resource "ibm_cos_bucket" "ignition" { + bucket_name = "${var.cluster_id}-bootstrap-ign" + resource_instance_id = ibm_resource_instance.cos_instance.id + region_location = var.cos_bucket_location + storage_class = var.cos_storage_class +} + +resource "ibm_resource_key" "cos_service_cred" { + name = "${var.cluster_id}-cred" + role = "Reader" + resource_instance_id = ibm_resource_instance.cos_instance.id + parameters = { HMAC = true } +} + +resource "ibms3presign" "bootstrap_ignition" { + access_key_id = ibm_resource_key.cos_service_cred.credentials["cos_hmac_keys.access_key_id"] + secret_access_key = ibm_resource_key.cos_service_cred.credentials["cos_hmac_keys.secret_access_key"] + bucket_name = "${var.cluster_id}-bootstrap-ign" + key = "bootstrap.ign" + region_location = ibm_cos_bucket.ignition.region_location + storage_class = ibm_cos_bucket.ignition.storage_class +} + +# Place the bootstrap ignition file in the ignition COS bucket +resource "ibm_cos_bucket_object" "ignition" { + bucket_crn = ibm_cos_bucket.ignition.crn + bucket_location = ibm_cos_bucket.ignition.region_location + content = var.ignition + key = "bootstrap.ign" +} + +# Create the bootstrap instance +resource "ibm_pi_instance" "bootstrap" { + pi_memory = var.memory + pi_processors = var.processors + pi_instance_name = "${var.cluster_id}-bootstrap" + pi_proc_type = var.proc_type + pi_image_id = var.image_id + pi_sys_type = var.sys_type + pi_cloud_instance_id = var.cloud_instance_id + pi_network_ids = [data.ibm_pi_network.network.id] + + pi_user_data = base64encode(data.ignition_config.bootstrap.rendered) + pi_key_pair_name = var.key_id + pi_health_status = "WARNING" +} + +data "ibm_pi_instance_ip" "bootstrap_ip" { + depends_on = [ibm_pi_instance.bootstrap] + + pi_instance_name = ibm_pi_instance.bootstrap.pi_instance_name + pi_network_name = data.ibm_pi_network.network.pi_network_name + pi_cloud_instance_id = var.cloud_instance_id +} diff --git a/data/data/powervs/bootstrap/outputs.tf b/data/data/powervs/bootstrap/outputs.tf new file mode 100644 index 00000000000..72b65f4787c --- /dev/null +++ b/data/data/powervs/bootstrap/outputs.tf @@ -0,0 +1,3 @@ +output "bootstrap_ip" { + value = data.ibm_pi_instance_ip.bootstrap_ip.ip +} diff --git a/data/data/powervs/bootstrap/variables.tf b/data/data/powervs/bootstrap/variables.tf new file mode 100644 index 00000000000..b5dc4531368 --- /dev/null +++ b/data/data/powervs/bootstrap/variables.tf @@ -0,0 +1,16 @@ +variable "memory" {} +variable "processors" {} +variable "ignition" {} + +variable "cloud_instance_id" {} +variable "resource_group" {} +variable "image_id" {} +variable "network_name" {} +variable "proc_type" {} +variable "sys_type" {} +variable "cluster_id" {} +variable "key_id" {} + +variable "cos_instance_location" {} +variable "cos_bucket_location" {} +variable "cos_storage_class" {} diff --git a/data/data/powervs/dns/dns.tf b/data/data/powervs/dns/dns.tf new file mode 100644 index 00000000000..276515abcfa --- /dev/null +++ b/data/data/powervs/dns/dns.tf @@ -0,0 +1,31 @@ +data "ibm_cis_domain" "base_domain" { + cis_id = var.cis_id + domain = var.base_domain +} + +resource "ibm_cis_dns_record" "kubernetes_api" { + cis_id = var.cis_id + domain_id = data.ibm_cis_domain.base_domain.id + type = "CNAME" + name = "api.${var.cluster_domain}" + content = var.load_balancer_hostname + ttl = 60 +} + +resource "ibm_cis_dns_record" "kubernetes_api_internal" { + cis_id = var.cis_id + domain_id = data.ibm_cis_domain.base_domain.id + type = "CNAME" + name = "api-int.${var.cluster_domain}" + content = var.load_balancer_int_hostname + ttl = 60 +} + +resource "ibm_cis_dns_record" "apps" { + cis_id = var.cis_id + domain_id = data.ibm_cis_domain.base_domain.id + type = "CNAME" + name = "*.apps.${var.cluster_domain}" + content = var.load_balancer_hostname + ttl = 60 +} diff --git a/data/data/powervs/dns/variables.tf b/data/data/powervs/dns/variables.tf new file mode 100644 index 00000000000..c7631cae426 --- /dev/null +++ b/data/data/powervs/dns/variables.tf @@ -0,0 +1,13 @@ +variable "cis_id" {} + +variable "base_domain" {} + +variable "cluster_domain" {} + +variable "load_balancer_hostname" {} + +variable "load_balancer_int_hostname" {} + + + + diff --git a/data/data/powervs/iaas/power-iaas.tf b/data/data/powervs/iaas/power-iaas.tf new file mode 100644 index 00000000000..071535e415b --- /dev/null +++ b/data/data/powervs/iaas/power-iaas.tf @@ -0,0 +1,22 @@ +provider "ibm" { + ibmcloud_api_key = var.powervs_api_key +} + +data "ibm_resource_group" "group" { + name = var.powervs_resource_group +} + +resource "ibm_resource_instance" "resource_instance" { + name = "${var.cluster_id}-power-iaas" + service = "power-iaas" + plan = "power-virtual-server-group" + location = var.powervs_region + tags = concat(var.service_tags, ["${var.cluster_id}-power-iaas", "${var.cluster_id}"]) + resource_group_id = data.ibm_resource_group.group.id + + timeouts { + create = "10m" + update = "10m" + delete = "10m" + } +} diff --git a/data/data/powervs/iaas/variables.tf b/data/data/powervs/iaas/variables.tf new file mode 100644 index 00000000000..c9569ff8808 --- /dev/null +++ b/data/data/powervs/iaas/variables.tf @@ -0,0 +1,28 @@ +variable "powervs_api_key" { + type = string + description = "IBM Cloud API key associated with user's identity" + default = "" +} + +variable "powervs_resource_group" { + type = string + description = "The cloud instance resource group" + default = "" +} + +variable "powervs_region" { + type = string + description = "The IBM Cloud region where you want to create the resources" + default = "" +} + +variable "cluster_id" { + type = string + default = "" +} + +variable "service_tags" { + type = list(string) + description = "A list of tags for our resource instance." + default = [] +} diff --git a/data/data/powervs/loadbalancer/alb.tf b/data/data/powervs/loadbalancer/alb.tf new file mode 100644 index 00000000000..4b3f126cda0 --- /dev/null +++ b/data/data/powervs/loadbalancer/alb.tf @@ -0,0 +1,148 @@ +locals { + api_servers = concat([var.bootstrap_ip], var.master_ips) + api_servers_count = length(var.master_ips) + 1 # bootstrap + master + app_servers = var.master_ips + app_servers_count = length(var.master_ips) +} + +data "ibm_resource_group" "resource_group" { + name = var.resource_group +} + +resource "ibm_is_lb" "load_balancer" { + name = "${var.cluster_id}-loadbalancer" + resource_group = data.ibm_resource_group.resource_group.id + subnets = [var.vpc_subnet_id] + security_groups = [ibm_is_security_group.ocp_security_group.id] + tags = [var.cluster_id, "${var.cluster_id}-loadbalancer"] + type = "public" +} + +resource "ibm_is_lb" "load_balancer_int" { + name = "${var.cluster_id}-loadbalancer-int" + resource_group = data.ibm_resource_group.resource_group.id + subnets = [var.vpc_subnet_id] + security_groups = [ibm_is_security_group.ocp_security_group.id] + tags = [var.cluster_id, "${var.cluster_id}-loadbalancer-int"] + type = "private" +} + +# Using explicit depends_on as otherwise there are issues with updating and adding of pool members +# Ref: https://registry.terraform.io/providers/IBM-Cloud/ibm/latest/docs/resources/is_lb_listener + +## TODO move this to internal/private LB +# machine config listener and backend pool +resource "ibm_is_lb_listener" "machine_config_listener" { + lb = ibm_is_lb.load_balancer_int.id + port = 22623 + protocol = "tcp" + default_pool = ibm_is_lb_pool.machine_config_pool.id +} +resource "ibm_is_lb_pool" "machine_config_pool" { + depends_on = [ibm_is_lb.load_balancer_int] + + name = "machine-config-server" + lb = ibm_is_lb.load_balancer_int.id + algorithm = "round_robin" + protocol = "tcp" + health_delay = 60 + health_retries = 5 + health_timeout = 30 + health_type = "tcp" +} +resource "ibm_is_lb_pool_member" "machine_config_member" { + depends_on = [ibm_is_lb_listener.machine_config_listener] + count = local.api_servers_count + + lb = ibm_is_lb.load_balancer_int.id + pool = ibm_is_lb_pool.machine_config_pool.id + port = 22623 + target_address = local.api_servers[count.index] +} + +# api listener and backend pool (internal) +resource "ibm_is_lb_listener" "api_listener_int" { + lb = ibm_is_lb.load_balancer_int.id + port = 6443 + protocol = "tcp" + default_pool = ibm_is_lb_pool.api_pool_int.id +} +resource "ibm_is_lb_pool" "api_pool_int" { + depends_on = [ibm_is_lb.load_balancer_int] + + name = "openshift-api-server" + lb = ibm_is_lb.load_balancer_int.id + algorithm = "round_robin" + protocol = "tcp" + health_delay = 60 + health_retries = 5 + health_timeout = 30 + health_type = "tcp" +} +resource "ibm_is_lb_pool_member" "api_member_int" { + depends_on = [ibm_is_lb_listener.api_listener_int, ibm_is_lb_pool_member.machine_config_member] + count = local.api_servers_count + + lb = ibm_is_lb.load_balancer_int.id + pool = ibm_is_lb_pool.api_pool_int.id + port = 6443 + target_address = local.api_servers[count.index] +} + +# api listener and backend pool (external) +resource "ibm_is_lb_listener" "api_listener" { + lb = ibm_is_lb.load_balancer.id + port = 6443 + protocol = "tcp" + default_pool = ibm_is_lb_pool.api_pool.id +} +resource "ibm_is_lb_pool" "api_pool" { + depends_on = [ibm_is_lb.load_balancer] + + name = "openshift-api-server" + lb = ibm_is_lb.load_balancer.id + algorithm = "round_robin" + protocol = "tcp" + health_delay = 60 + health_retries = 5 + health_timeout = 30 + health_type = "tcp" +} +resource "ibm_is_lb_pool_member" "api_member" { + depends_on = [ibm_is_lb_listener.api_listener, ibm_is_lb_pool_member.machine_config_member] + count = local.api_servers_count + + lb = ibm_is_lb.load_balancer.id + pool = ibm_is_lb_pool.api_pool.id + port = 6443 + target_address = local.api_servers[count.index] +} + +# bootstrap listener and backend pool +resource "ibm_is_lb_listener" "bootstrap_listener" { + lb = ibm_is_lb.load_balancer.id + port = 22 + protocol = "tcp" + default_pool = ibm_is_lb_pool.bootstrap_pool.id +} +resource "ibm_is_lb_pool" "bootstrap_pool" { + depends_on = [ibm_is_lb.load_balancer] + + name = "bootstrap-node" + lb = ibm_is_lb.load_balancer.id + algorithm = "round_robin" + protocol = "tcp" + health_delay = 5 + health_retries = 2 + health_timeout = 2 + health_type = "tcp" +} +resource "ibm_is_lb_pool_member" "bootstrap" { + depends_on = [ibm_is_lb_listener.bootstrap_listener] + + lb = ibm_is_lb.load_balancer.id + pool = ibm_is_lb_pool.bootstrap_pool.id + port = 22 + target_address = var.bootstrap_ip +} + diff --git a/data/data/powervs/loadbalancer/outputs.tf b/data/data/powervs/loadbalancer/outputs.tf new file mode 100644 index 00000000000..b4c6c184fb8 --- /dev/null +++ b/data/data/powervs/loadbalancer/outputs.tf @@ -0,0 +1,7 @@ +output "powervs_lb_hostname" { + value = ibm_is_lb.load_balancer.hostname +} + +output "powervs_lb_int_hostname" { + value = ibm_is_lb.load_balancer_int.hostname +} diff --git a/data/data/powervs/loadbalancer/sg.tf b/data/data/powervs/loadbalancer/sg.tf new file mode 100644 index 00000000000..64cde9cf93f --- /dev/null +++ b/data/data/powervs/loadbalancer/sg.tf @@ -0,0 +1,28 @@ +locals { + tcp_ports = [22623, 6443, 22] +} +data "ibm_is_vpc" "vpc" { + name = var.vpc_name +} + +resource "ibm_is_security_group" "ocp_security_group" { + name = "${var.cluster_id}-ocp-sec-group" + resource_group = data.ibm_resource_group.resource_group.id + vpc = data.ibm_is_vpc.vpc.id + tags = [var.cluster_id] +} + +resource "ibm_is_security_group_rule" "inbound_ports" { + count = length(local.tcp_ports) + group = ibm_is_security_group.ocp_security_group.id + direction = "inbound" + tcp { + port_min = local.tcp_ports[count.index] + port_max = local.tcp_ports[count.index] + } +} + +resource "ibm_is_security_group_rule" "outbound_any" { + group = ibm_is_security_group.ocp_security_group.id + direction = "outbound" +} diff --git a/data/data/powervs/loadbalancer/variables.tf b/data/data/powervs/loadbalancer/variables.tf new file mode 100644 index 00000000000..c64b3344fa4 --- /dev/null +++ b/data/data/powervs/loadbalancer/variables.tf @@ -0,0 +1,9 @@ +variable "cluster_id" {} + +variable "vpc_name" {} +variable "vpc_subnet_id" {} + +variable "bootstrap_ip" {} +variable "master_ips" {} + +variable "resource_group" {} diff --git a/data/data/powervs/main.tf b/data/data/powervs/main.tf new file mode 100644 index 00000000000..db626671ef1 --- /dev/null +++ b/data/data/powervs/main.tf @@ -0,0 +1,112 @@ +provider "ibm" { + alias = "vpc" + ibmcloud_api_key = var.powervs_api_key + region = var.powervs_vpc_region + zone = var.powervs_vpc_zone +} + +provider "ibm" { + alias = "powervs" + ibmcloud_api_key = var.powervs_api_key + region = var.powervs_region +} + +resource "ibm_pi_key" "cluster_key" { + provider = ibm.powervs + pi_key_name = "${var.cluster_id}-key" + pi_ssh_key = var.powervs_ssh_key + pi_cloud_instance_id = var.powervs_cloud_instance_id +} + +module "bootstrap" { + providers = { + ibm = ibm.powervs + } + source = "./bootstrap" + cloud_instance_id = var.powervs_cloud_instance_id + cluster_id = var.cluster_id + resource_group = var.powervs_resource_group + + cos_instance_location = var.powervs_cos_instance_location + cos_bucket_location = var.powervs_cos_bucket_location + cos_storage_class = var.powervs_cos_storage_class + + memory = var.powervs_bootstrap_memory + processors = var.powervs_bootstrap_processors + ignition = var.ignition_bootstrap + sys_type = var.powervs_sys_type + proc_type = var.powervs_proc_type + key_id = ibm_pi_key.cluster_key.key_id + image_id = ibm_pi_image.boot_image.image_id + network_name = var.powervs_network_name +} + +module "master" { + providers = { + ibm = ibm.powervs + } + source = "./master" + cloud_instance_id = var.powervs_cloud_instance_id + cluster_id = var.cluster_id + resource_group = var.powervs_resource_group + instance_count = var.master_count + + memory = var.powervs_master_memory + processors = var.powervs_master_processors + ignition = var.ignition_master + sys_type = var.powervs_sys_type + proc_type = var.powervs_proc_type + key_id = ibm_pi_key.cluster_key.key_id + image_id = ibm_pi_image.boot_image.image_id + network_name = var.powervs_network_name +} + +data "ibm_is_subnet" "vpc_subnet" { + provider = ibm.vpc + name = var.powervs_vpc_subnet_name +} + +resource "ibm_pi_image" "boot_image" { + provider = ibm.powervs + pi_image_name = "${var.cluster_id}-boot-image" + pi_cloud_instance_id = var.powervs_cloud_instance_id + pi_image_bucket_name = "rhcos-powervs-images-${var.powervs_vpc_region}" + pi_image_bucket_access = "public" + pi_image_bucket_region = var.powervs_vpc_region + pi_image_bucket_file_name = var.powervs_image_bucket_file_name + pi_image_storage_type = var.powervs_image_storage_type +} + +data "ibm_pi_network" "pvs_net" { + provider = ibm.powervs + pi_network_name = var.powervs_network_name + pi_cloud_instance_id = var.powervs_cloud_instance_id +} + +module "loadbalancer" { + providers = { + ibm = ibm.vpc + } + source = "./loadbalancer" + + cluster_id = var.cluster_id + vpc_name = var.powervs_vpc_name + vpc_subnet_id = data.ibm_is_subnet.vpc_subnet.id + bootstrap_ip = module.bootstrap.bootstrap_ip + master_ips = module.master.master_ips + resource_group = var.powervs_resource_group +} + + +module "dns" { + providers = { + ibm = ibm.vpc + } + source = "./dns" + + cis_id = var.powervs_cis_crn + base_domain = var.base_domain + cluster_domain = var.cluster_domain + load_balancer_hostname = module.loadbalancer.powervs_lb_hostname + load_balancer_int_hostname = module.loadbalancer.powervs_lb_int_hostname +} diff --git a/data/data/powervs/master/main.tf b/data/data/powervs/master/main.tf new file mode 100644 index 00000000000..3f885da5665 --- /dev/null +++ b/data/data/powervs/master/main.tf @@ -0,0 +1,34 @@ +# TODO(mjturek): network and image data blocks can be in main module +# as master and bootstrap will be using the same +# network and image. Once we add in master module, make +# the move. +data "ibm_pi_network" "network" { + pi_network_name = var.network_name + pi_cloud_instance_id = var.cloud_instance_id +} + +# Create the master instances +resource "ibm_pi_instance" "master" { + count = var.instance_count + pi_memory = var.memory + pi_processors = var.processors + pi_instance_name = "${var.cluster_id}-master-${count.index}" + pi_proc_type = var.proc_type + pi_image_id = var.image_id + pi_sys_type = var.sys_type + pi_cloud_instance_id = var.cloud_instance_id + pi_network_ids = [data.ibm_pi_network.network.id] + + pi_user_data = base64encode(var.ignition) + pi_key_pair_name = var.key_id + pi_health_status = "WARNING" +} + +data "ibm_pi_instance_ip" "master_ip" { + count = var.instance_count + depends_on = [ibm_pi_instance.master] + + pi_instance_name = ibm_pi_instance.master[count.index].pi_instance_name + pi_network_name = data.ibm_pi_network.network.pi_network_name + pi_cloud_instance_id = var.cloud_instance_id +} diff --git a/data/data/powervs/master/outputs.tf b/data/data/powervs/master/outputs.tf new file mode 100644 index 00000000000..910e18ebb0b --- /dev/null +++ b/data/data/powervs/master/outputs.tf @@ -0,0 +1,3 @@ +output "master_ips" { + value = data.ibm_pi_instance_ip.master_ip.*.ip +} diff --git a/data/data/powervs/master/variables.tf b/data/data/powervs/master/variables.tf new file mode 100644 index 00000000000..c977befe336 --- /dev/null +++ b/data/data/powervs/master/variables.tf @@ -0,0 +1,14 @@ +variable "instance_count" {} + +variable "memory" {} +variable "processors" {} +variable "ignition" {} +variable "key_id" {} + +variable "cloud_instance_id" {} +variable "resource_group" {} +variable "image_id" {} +variable "network_name" {} +variable "proc_type" {} +variable "sys_type" {} +variable "cluster_id" {} diff --git a/data/data/powervs/topology/pi_network.tf b/data/data/powervs/topology/pi_network.tf new file mode 100644 index 00000000000..5f5e3a5f7c9 --- /dev/null +++ b/data/data/powervs/topology/pi_network.tf @@ -0,0 +1,40 @@ +## Network +## These are be optional arguments in the install-config (e.g. Platform) +## so that users may specify them. Have them be "hidden" in that the survey doesn't ask for them +## unless the OCP leads disagree. +## And since they're optional, use the count = construct to conditionally create them if the tf +## vars are unset. + +## Note, the following are incomplete placeholders to be tested and reviewed later when the TF +## support for these has been added to the ibmcloud terraform provider (which is now forked into +## https://github.com/openshift/terraform-provider-ibm) + +#resource "ibm_direct_link" "ocp_direct_link" { +# TODO +#} + +#resource "ibm_pi_network" "ocp_network" { +# provider = ibm.powervs +# count = var.powervs_network_name == "" ? 1 : 0 +# pi_network_name = "pvs-net-${var.cluster_id}" +# pi_cloud_instance_id = "powervs_cloud_instance_id" +# pi_network_type = "dhcp" +# pi_cidr = "192.168.0.0/24" +# pi_dns = [<"DNS Servers">] +#} + +#resource "ibm_is_vpc" "ocp_vpc" { +# provider = ibm.vpc +# count = var.powervs_vpc == "" ? 1 : 0 +# name = "vpc_${var.cluster_id}" +# classic_access = false +# resource_group = var.powervs_resource_group +#} + +#resource "ibm_is_subnet" "ocp_vpc_subnet" { +# provider = ibm.vpc +# count = var.powervs_vpc_subnet == "" ? 1 : 0 +# name = "vpc_subnet_${var.cluster_id}" +# vpc = ibm_is_vpc..id +# ipv4_cidr_block = "192.168.0.0/1" +#} diff --git a/data/data/powervs/variables-powervs.tf b/data/data/powervs/variables-powervs.tf new file mode 100644 index 00000000000..d44e53a2e8c --- /dev/null +++ b/data/data/powervs/variables-powervs.tf @@ -0,0 +1,152 @@ +################################################################ +# Configure the IBM Cloud provider +################################################################ +variable "powervs_api_key" { + type = string + description = "IBM Cloud API key associated with user's identity" + default = "" +} + +variable "powervs_vpc_region" { + type = string + description = "The IBM Cloud region where you want to create the resources" + default = "eu-gb" +} + +variable "powervs_vpc_zone" { + type = string + description = "The IBM Cloud zone associated with the VPC region you're using" +} + +variable "powervs_region" { + type = string + description = "The IBM Cloud region where you want to create the resources" + default = "lon" +} + +variable "powervs_zone" { + type = string + description = "The IBM Cloud zone associated with the region you're using" +} + +variable "powervs_resource_group" { + type = string + description = "The cloud instance resource group" +} + +variable "powervs_cloud_instance_id" { + type = string + description = "The cloud instance ID of your account" +} + +################################################################ +# Configure storage +################################################################ +variable "powervs_cos_instance_location" { + type = string + description = "The location of your COS instance" + default = "global" +} + +variable "powervs_cos_bucket_location" { + type = string + description = "The location to create your COS bucket" + default = "us-east" +} + +variable "powervs_cos_storage_class" { + type = string + description = "The plan used for your COS instance" + default = "smart" +} + +################################################################ +# Configure instances +################################################################ +variable "powervs_bootstrap_memory" { + type = string + description = "Amount of memory, in GiB, used by the bootstrap node." + default = "32" +} + +variable "powervs_bootstrap_processors" { + type = string + description = "Number of processors used by the bootstrap node." + default = "0.5" +} + +variable "powervs_master_memory" { + type = string + description = "Amount of memory, in GiB, used by each master node." + default = "32" +} + +variable "powervs_master_processors" { + type = string + description = "Number of processors used by each master node." + default = "0.5" +} + +variable "powervs_proc_type" { + type = string + description = "The type of processor mode for all nodes (shared/dedicated)" + default = "shared" +} + +variable "powervs_sys_type" { + type = string + description = "The type of system (s922/e980)" + default = "s922" +} + +variable "powervs_key_name" { + type = string + description = "The name for the SSH key created in the Service Instance" + default = "" +} + +variable "powervs_ssh_key" { + type = string + description = "Public key for keypair used to access cluster. Required when creating 'ibm_pi_instance' resources." + default = "" +} + +variable "powervs_image_bucket_file_name" { + type = string + description = "File name of the image in the COS bucket." + default = "rhcos-410-84-202111101637-0-ppc64le-powervs.ova.gz" +} + +variable "powervs_image_storage_type" { + type = string + description = "Storage type used when storing image in Power VS." + default = "tier3" +} + +################################################################ +# Configure Network Topology +################################################################ +variable "powervs_network_name" { + type = string + description = "Name of the network within the Power VS instance." +} + +variable "powervs_vpc_name" { + type = string + description = "Name of the IBM Cloud Virtual Private Cloud (VPC) to setup the load balancer." +} + +variable "powervs_vpc_subnet_name" { + type = string + description = "Name of the VPC subnet connected via DirectLink to the Power VS private network." +} + +################################################################ +# Configure DNS +################################################################ +## TODO: Pass the CIS CRN from the installer program, refer the IBM Cloud code to see the implementation. +variable "powervs_cis_crn" { + type = string + description = "The CRN of CIS instance to use." +} + diff --git a/data/data/rhcos-ppc64le.json b/data/data/rhcos-ppc64le.json new file mode 100644 index 00000000000..6415680b83c --- /dev/null +++ b/data/data/rhcos-ppc64le.json @@ -0,0 +1,66 @@ +{ + "baseURI": "https://rhcos-redirector.apps.art.xq1c.p1.openshiftapps.com/art/storage/releases/rhcos-4.9-ppc64le/49.84.202107010047-0/ppc64le/", + "buildid": "49.84.202107010047-0", + "images": { + "live-initramfs": { + "path": "rhcos-49.84.202107010047-0-live-initramfs.ppc64le.img", + "sha256": "79e42469694b273fce31a54e6790e4c594619577693e1b34621f1675a33538e8" + }, + "live-iso": { + "path": "rhcos-49.84.202107010047-0-live.ppc64le.iso", + "sha256": "0f6418dc5eb43b0f12da60cf583ce19cbbf85f421c0d35b0be85c33161ab8e87" + }, + "live-kernel": { + "path": "rhcos-49.84.202107010047-0-live-kernel-ppc64le", + "sha256": "ae1165bb13992f9b6543e2c8baa0f1f10460d84db740d1876c8f4f9226cb9a6d" + }, + "live-rootfs": { + "path": "rhcos-49.84.202107010047-0-live-rootfs.ppc64le.img", + "sha256": "6c3a9728fd82b09d11778370b68ae0875502a84d3ccbea5a0e1a9c69d855c08b" + }, + "metal": { + "path": "rhcos-49.84.202107010047-0-metal.ppc64le.raw.gz", + "sha256": "f08f36d75aa726dbb6dd1cd5f1c0ef561174c7f5324f3fba2cd8ff52187bc242", + "size": 988450954, + "uncompressed-sha256": "3d268c733b48b884f4215bb1f4e53883dd460b2a3eedd0e02e5b4e5800dafcc6", + "uncompressed-size": 4126146560 + }, + "metal4k": { + "path": "rhcos-49.84.202107010047-0-metal4k.ppc64le.raw.gz", + "sha256": "fc64722125fa0db0eb534db6af8a9ebcfff3c1bd6bf34482041ab09191e83f5d", + "size": 988748793, + "uncompressed-sha256": "662cf671d988c6b7feb48413384630596ebc0b33bfbbbfae8bef5d03ad494d4e", + "uncompressed-size": 4126146560 + }, + "openstack": { + "path": "rhcos-49.84.202107010047-0-openstack.ppc64le.qcow2.gz", + "sha256": "e30fc32cdf50ff02a72feb71cd3f4e9c92f1b038aef506d6e8396dbbf841d085", + "size": 986664044, + "uncompressed-sha256": "9d1dc160337cda643805c96109f086015f111d46e7982b9f21cf49276cab3fb5", + "uncompressed-size": 2665480192 + }, + "ostree": { + "path": "rhcos-49.84.202107010047-0-ostree.ppc64le.tar", + "sha256": "2387066fe638c276c2ec89e2a4ab66a526bb70cc039fecadd4d9ed563df7e8cf", + "size": 909711360 + }, + "powervs": { + "path": "rhcos-48.84.202105182221-0-powervs-ppc64le.ova", + "sha256": "02addcf3150a34ea76c8e5b86db3a78fd8925ce2ff7dd4507d8895d5dd139030", + "size": 2463334400 + }, + "qemu": { + "path": "rhcos-49.84.202107010047-0-qemu.ppc64le.qcow2.gz", + "sha256": "9145e08f39baf2df968ea6803303ccb1fc2941f8eae60d41ba91c9016e13ba33", + "size": 987690835, + "uncompressed-sha256": "b3822dd7eddcf2faf4028c6a6cfa7fcfaf56153d2da6bd47c462705f90887871", + "uncompressed-size": 2702639104 + } + }, + "oscontainer": { + "digest": "sha256:cbb5ff0ef87cf99ec4873720bc350e09c699e5a533a8bef95a7805042da5254e", + "image": "quay.io/openshift-release-dev/ocp-v4.0-art-dev" + }, + "ostree-commit": "63a0c41848555ff81ef062bfbfbd8c467979c2a3c4889bdf2b61eb83069efb90", + "ostree-version": "49.84.202107010047-0" +} diff --git a/go.mod b/go.mod index f3aa527f60a..3bb6e51e465 100644 --- a/go.mod +++ b/go.mod @@ -13,10 +13,11 @@ require ( github.com/Azure/go-autorest/autorest/to v0.4.0 github.com/Azure/go-ntlmssp v0.0.0-20191115210519-2b2be6cc8ed4 // indirect github.com/ChrisTrenkamp/goxpath v0.0.0-20190607011252-c5096ec8773d // indirect - github.com/IBM-Cloud/bluemix-go v0.0.0-20210611051827-cdc80c935c05 + github.com/IBM-Cloud/bluemix-go v0.0.0-20210706092416-dc4055f8e0ea + github.com/IBM-Cloud/power-go-client v1.0.72 github.com/IBM-Cloud/terraform-provider-ibm v1.26.2 - github.com/IBM/go-sdk-core/v5 v5.4.3 - github.com/IBM/networking-go-sdk v0.14.0 + github.com/IBM/go-sdk-core/v5 v5.5.1 + github.com/IBM/networking-go-sdk v0.19.0 github.com/IBM/platform-services-go-sdk v0.18.16 github.com/IBM/vpc-go-sdk v1.0.1 github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667 // indirect @@ -70,6 +71,7 @@ require ( github.com/openshift/cluster-api-provider-ibmcloud v0.0.0-20210702173623-676faba9895d github.com/openshift/cluster-api-provider-libvirt v0.2.1-0.20191219173431-2336783d4603 github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210817084941-2262c7c6cece + github.com/openshift/cluster-api-provider-powervs v0.0.2-0.20210928133618-8eb5ebcb07a1 github.com/openshift/library-go v0.0.0-20210408164723-7a65fdb398e2 github.com/openshift/machine-api-operator v0.2.1-0.20210505133115-b7ef098180db github.com/openshift/machine-config-operator v0.0.0 @@ -100,7 +102,7 @@ require ( github.com/vmware/govmomi v0.24.0 github.com/wxnacy/wgo v1.0.4 github.com/zclconf/go-cty v1.6.1 - golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 + golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 golang.org/x/lint v0.0.0-20200302205851-738671d3881b golang.org/x/oauth2 v0.0.0-20200902213428-5d25da1a8d43 golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c @@ -124,7 +126,7 @@ require ( replace ( cloud.google.com/go => cloud.google.com/go v0.57.0 - github.com/IBM-Cloud/terraform-provider-ibm => github.com/openshift/terraform-provider-ibm v1.26.2-openshift-2 + github.com/IBM-Cloud/terraform-provider-ibm => github.com/yussufsh/terraform-provider-ibm v1.89.0 github.com/go-log/log => github.com/go-log/log v0.1.1-0.20181211034820-a514cf01a3eb // Pinned by MCO github.com/hashicorp/terraform => github.com/openshift/terraform v0.12.20-openshift-4 // Pin to fork with deduplicated rpc types v0.12.20-openshift-4 github.com/hashicorp/terraform-plugin-sdk => github.com/openshift/hashicorp-terraform-plugin-sdk v1.14.0-openshift // Pin to fork with public rpc types @@ -150,7 +152,7 @@ replace ( // Prevent the following modules from upgrading version as result of terraform-provider-kubernetes module // The following modules need to be locked to compile correctly with terraform-provider-azure, terraform-provider-google, and terraform-provider-ibm replace ( - github.com/IBM/vpc-go-sdk => github.com/IBM/vpc-go-sdk v0.7.0 + github.com/IBM/vpc-go-sdk => github.com/IBM/vpc-go-sdk v0.8.0 github.com/apparentlymart/go-cidr => github.com/apparentlymart/go-cidr v1.0.1 github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v1.32.3 github.com/go-openapi/errors => github.com/go-openapi/errors v0.19.2 @@ -162,3 +164,9 @@ replace ( google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 google.golang.org/grpc => google.golang.org/grpc v1.29.1 ) + +replace github.com/openshift/machine-api-operator => github.com/openshift-powervs/machine-api-operator v0.2.1-0.20210809115935-a9fd8f5d2767 + +replace github.com/IBM-Cloud/power-go-client => github.com/yussufsh/power-go-client v1.99.4 + +replace github.com/softlayer/softlayer-go => github.com/IBM-Cloud/softlayer-go v1.0.3-tf diff --git a/go.sum b/go.sum index c215a162e1b..1ec1f6be220 100644 --- a/go.sum +++ b/go.sum @@ -117,11 +117,14 @@ github.com/DataDog/datadog-go v3.2.0+incompatible/go.mod h1:LButxg5PwREeZtORoXG3 github.com/Djarvur/go-err113 v0.0.0-20200410182137-af658d038157/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Djarvur/go-err113 v0.0.0-20200511133814-5174e21577d5/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= github.com/Djarvur/go-err113 v0.1.0/go.mod h1:4UJr5HIiMZrwgkSPdsjy2uOQExX/WEILpIrO9UPGuXs= -github.com/IBM-Cloud/bluemix-go v0.0.0-20210611051827-cdc80c935c05 h1:b/epmuvf99xhUlf81l0r/ciONJSjoUs78t+BC7lCcvI= -github.com/IBM-Cloud/bluemix-go v0.0.0-20210611051827-cdc80c935c05/go.mod h1:kqTYO0mts71aa8PVwviaKlCKYud/NbEkFIqU8aHH3/g= +github.com/IBM-Cloud/bluemix-go v0.0.0-20200921095234-26d1d0148c62/go.mod h1:gPJbH1etcDj7qS/hBRiLuYW9CY0bRcostSKusa51xR0= +github.com/IBM-Cloud/bluemix-go v0.0.0-20210706092416-dc4055f8e0ea h1:3B8Hd2WknLK8mA8UonA2MxgkMS9ZdLK0PjUwgc+czTU= +github.com/IBM-Cloud/bluemix-go v0.0.0-20210706092416-dc4055f8e0ea/go.mod h1:AEc+cXhUc63zc7PB1YjvZFoRtfCJcI12w5TrLudEgXg= +github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20210705152127-41ca00fc9a62 h1:MOkcr6qQGk4tY542ZJ1DggVh2WUP72EEyLB79llFVH8= +github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20210705152127-41ca00fc9a62/go.mod h1:xUQL9SGAjoZFd4GNjrjjtEpjpkgU7RFXRyHesbKTjiY= github.com/IBM-Cloud/ibm-cloud-cli-sdk v0.5.3/go.mod h1:RiUvKuHKTBmBApDMUQzBL14pQUGKcx/IioKQPIcRQjs= -github.com/IBM-Cloud/power-go-client v1.0.55 h1:XoRU8FWYY8NUKau1nkErkf2FHAUbFEbbXtbLTvaGp9c= -github.com/IBM-Cloud/power-go-client v1.0.55/go.mod h1:I4r5tCrA8mV5GFqGAJG4/Tn+/JpR+XLnDCLLNVKJxuI= +github.com/IBM-Cloud/softlayer-go v1.0.3-tf h1:FZF0D11BcYvDCZtWC0ZNEC6PKivuahW/nW9naK7H2PU= +github.com/IBM-Cloud/softlayer-go v1.0.3-tf/go.mod h1:6HepcfAXROz0Rf63krk5hPZyHT6qyx2MNvYyHof7ik4= github.com/IBM/apigateway-go-sdk v0.0.0-20210714141226-a5d5d49caaca h1:crniVcf+YcmgF03NmmfonXwSQ73oJF+IohFYBwknMxs= github.com/IBM/apigateway-go-sdk v0.0.0-20210714141226-a5d5d49caaca/go.mod h1:IjXrnOcTe92Q4pEBHmui3H/GM1hw5Pd0zXA5cw5/iZU= github.com/IBM/appconfiguration-go-admin-sdk v0.1.0 h1:9rdOk32VQFnMqsBB7cTpkZbD7/b0EnwrU3VNN8vuUYc= @@ -131,9 +134,8 @@ github.com/IBM/container-registry-go-sdk v0.0.13/go.mod h1:GYi1VN59VaJWWq2xP06o9 github.com/IBM/go-sdk-core v1.1.0 h1:pV73lZqr9r1xKb3h08c1uNG3AphwoV5KzUzhS+pfEqY= github.com/IBM/go-sdk-core v1.1.0/go.mod h1:2pcx9YWsIsZ3I7kH+1amiAkXvLTZtAq9kbxsfXilSoY= github.com/IBM/go-sdk-core/v3 v3.0.0/go.mod h1:JI5NS2+iCoY/D8Oq3JNEZNA7qO42agu6fnaUmDsRcJA= +github.com/IBM/go-sdk-core/v3 v3.2.4 h1:WKYJYYKlZnw1y/gM+Qbf5EQVAL9xaoD54+ooJZz/iBQ= github.com/IBM/go-sdk-core/v3 v3.2.4/go.mod h1:lk9eOzNbNltPf3CBpcg1Ewkhw4qC3u2QCCKDRsUA2M0= -github.com/IBM/go-sdk-core/v3 v3.3.1 h1:DoXjP1+Wm8Yd4XJsvBMRcYLvQwSLFnzKlMjSrg3Rzpw= -github.com/IBM/go-sdk-core/v3 v3.3.1/go.mod h1:lk9eOzNbNltPf3CBpcg1Ewkhw4qC3u2QCCKDRsUA2M0= github.com/IBM/go-sdk-core/v4 v4.5.1/go.mod h1:lTUXbqIX6/aAbSCkP6q59+dyFsTwZAc0ewRS2vJWVbg= github.com/IBM/go-sdk-core/v4 v4.8.1/go.mod h1:GECJ/p0r9Hs0XcOnCiGjZrt6M/rQc+gW8YkCsGJ+j5U= github.com/IBM/go-sdk-core/v4 v4.9.0/go.mod h1:DbQ+3pFoIjxGGTEiA9zQ2V0cemMNmFMkLBBnR729HKg= @@ -142,20 +144,21 @@ github.com/IBM/go-sdk-core/v4 v4.10.0/go.mod h1:0uz2ca0MZ2DwsBRGl9Jp3EaCTqxmKZTd github.com/IBM/go-sdk-core/v5 v5.0.0/go.mod h1:vyNdbFujJtdTj9HbihtvKwwS3k/GKSKpOx9ZIQ6MWDY= github.com/IBM/go-sdk-core/v5 v5.0.3/go.mod h1:vyNdbFujJtdTj9HbihtvKwwS3k/GKSKpOx9ZIQ6MWDY= github.com/IBM/go-sdk-core/v5 v5.1.0/go.mod h1:vyNdbFujJtdTj9HbihtvKwwS3k/GKSKpOx9ZIQ6MWDY= -github.com/IBM/go-sdk-core/v5 v5.4.0/go.mod h1:+MNa5Jbqb9FO7KEevo982Pb/YXr4adkyEffJlPs2TGc= github.com/IBM/go-sdk-core/v5 v5.4.2/go.mod h1:Sn+z+qTDREQvCr+UFa22TqqfXNxx3o723y8GsfLV8e0= -github.com/IBM/go-sdk-core/v5 v5.4.3 h1:g3HUKD2wyptGTAGOjS4IkYWmLFgGsioFCnBUXz5NB4g= -github.com/IBM/go-sdk-core/v5 v5.4.3/go.mod h1:Sn+z+qTDREQvCr+UFa22TqqfXNxx3o723y8GsfLV8e0= +github.com/IBM/go-sdk-core/v5 v5.4.5/go.mod h1:Sn+z+qTDREQvCr+UFa22TqqfXNxx3o723y8GsfLV8e0= +github.com/IBM/go-sdk-core/v5 v5.5.1 h1:Hb4xB1BL8L6uCnskIqSCxF9wLfOmj4+sVzM5vFtuhs4= +github.com/IBM/go-sdk-core/v5 v5.5.1/go.mod h1:Sn+z+qTDREQvCr+UFa22TqqfXNxx3o723y8GsfLV8e0= github.com/IBM/ibm-cos-sdk-go v1.3.1/go.mod h1:YLBAYobEA8bD27P7xpMwSQeNQu6W3DNBtBComXrRzRY= github.com/IBM/ibm-cos-sdk-go v1.7.0 h1:3DZULY/D5WzjlIm+Iaj6h0surEjQs65EZk1YAe8+rj0= github.com/IBM/ibm-cos-sdk-go v1.7.0/go.mod h1:Oi8AC5WNDhmUJgbo1GL2FtBdo0nRgbzE/1HmCL1SERU= github.com/IBM/ibm-cos-sdk-go-config v1.2.0 h1:1E93234yZgVS0ntm7eUwVb3h0AAayPGcxEhhizEN1LE= github.com/IBM/ibm-cos-sdk-go-config v1.2.0/go.mod h1:Wetfgv6m1xyuzpZLQTTLIBsWstxjYa15h+Utj7x53Dk= +github.com/IBM/ibm-hpcs-tke-sdk v0.0.0-20210723145459-a232c3f3ac91 h1:8ICDvg7YM+PmfF+LQ42D4w/p4QEpiknbycAgGdbk0dw= +github.com/IBM/ibm-hpcs-tke-sdk v0.0.0-20210723145459-a232c3f3ac91/go.mod h1:M2JyuyeWHPtgGNeezr6YqVRuaav2MpY8Ha4QrEYvMoI= github.com/IBM/keyprotect-go-client v0.7.0 h1:JstSHD14Lp6ihwQseyPuGcs1AjOBjAmcisP0dTBA6A0= github.com/IBM/keyprotect-go-client v0.7.0/go.mod h1:SVr2ylV/fhSQPDiUjWirN9fsyWFCNNbt8GIT8hPJVjE= -github.com/IBM/networking-go-sdk v0.14.0 h1:CWQufnSxynqxYORGbkSqePPSZ33fUijiwmcuZsMRv/Q= -github.com/IBM/networking-go-sdk v0.14.0/go.mod h1:8f3hEoWVUSYKbaIj7WZhdeJaseYGDSY85Iz+PqxLEbQ= -github.com/IBM/platform-services-go-sdk v0.18.12/go.mod h1:awc7TZUeGMlToSeMSaWEz34Knf0lQnuGWumcI4pcuoM= +github.com/IBM/networking-go-sdk v0.19.0 h1:oXmRZPLnL28OE7bVRJLvKB6vGYjCG58pLWAeTjVBajs= +github.com/IBM/networking-go-sdk v0.19.0/go.mod h1:nViqUm1Bv+ke8dyOhjQ6e+2U1XeqZX2y4bQbR8Od3Hc= github.com/IBM/platform-services-go-sdk v0.18.16 h1:blYycstPoNtPKtu1uZe240WvzcJENy/Lzx+HMUA8bOo= github.com/IBM/platform-services-go-sdk v0.18.16/go.mod h1:awc7TZUeGMlToSeMSaWEz34Knf0lQnuGWumcI4pcuoM= github.com/IBM/push-notifications-go-sdk v0.0.0-20210310100607-5790b96c47f5 h1:NPUhkoOCRuv3OFWt19PmwjXGGTKlvmbuPg9fUrBUNe4= @@ -164,11 +167,13 @@ github.com/IBM/schematics-go-sdk v0.0.2 h1:IFdM73VL3xwf/KaTh1IY99hkiTfFRYg5F1JNj github.com/IBM/schematics-go-sdk v0.0.2/go.mod h1:ymN1+3uEaWNT0RthwHzExxMiN0AnTh6W3piSY8canjs= github.com/IBM/secrets-manager-go-sdk v0.1.19 h1:0GPs5EoTaWNsjo4QPj64GNxlWfN8VHJy4RDFLqddSe8= github.com/IBM/secrets-manager-go-sdk v0.1.19/go.mod h1:eO3dBhzPrHkkt+yPex/jB2xD6qHZxBko+Aw+0tfqHeA= -github.com/IBM/vpc-go-sdk v0.7.0 h1:LNAnzcDLD2Bf2UbiYfFFsWGlHQf2N/Qc6S5iM7qln1o= -github.com/IBM/vpc-go-sdk v0.7.0/go.mod h1:wxicPDnSTPXt1eNxSO/9KNGqOW9RMgxPoSh4gd8KJY4= +github.com/IBM/vpc-go-sdk v0.8.0 h1:CPuLXuKa0fbhAR+veaynW8AtGqkO846XYBdfTQGrq4s= +github.com/IBM/vpc-go-sdk v0.8.0/go.mod h1:rnMs3IWLSr0n0MvqX3pg96u0mkHVBk4oBsHQYYv5CXw= github.com/InVisionApp/go-health v2.1.0+incompatible/go.mod h1:/+Gv1o8JUsrjC6pi6MN6/CgKJo4OqZ6x77XAnImrzhg= github.com/Jeffail/gabs v1.1.1/go.mod h1:6xMvQMK4k33lb7GUUpaAPh6nKMmemQeg5d4gn7/bOXc= github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0= +github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56 h1:vuquMR410psHNax14XKNWa0Ae/kYgWJcXi0IFuX60N0= +github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56/go.mod h1:Zb3OT4l0mf7P/GOs2w2Ilj5sdm5Whoq3pa24dAEBHFc= github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E= github.com/MakeNowJust/heredoc v1.0.0 h1:cXCdzVdstXyiTqTvfqk9SDHpKNjxuom+DOlyEeQ4pzQ= github.com/MakeNowJust/heredoc v1.0.0/go.mod h1:mG5amYoWBHf8vpLOuehzbGGw0EHxpZZ6lCpQ4fNJ8LE= @@ -194,6 +199,8 @@ github.com/PaesslerAG/gval v1.0.0/go.mod h1:y/nm5yEyTeX6av0OfKJNp9rBNj2XrGhAf5+v github.com/PaesslerAG/jsonpath v0.1.0/go.mod h1:4BzmtoM/PI8fPO4aQGIusjGxGir2BzcV0grWtFzq1Y8= github.com/PaesslerAG/jsonpath v0.1.1 h1:c1/AToHQMVsduPAa4Vh6xp2U0evy4t8SWp8imEsylIk= github.com/PaesslerAG/jsonpath v0.1.1/go.mod h1:lVboNxFGal/VwW6d9JzIy56bUsYAP6tH/x80vjnCseY= +github.com/PromonLogicalis/asn1 v0.0.0-20190312173541-d60463189a56 h1:zL3Ph7RCZadAPb7QV0gMIDmjuZHFawNhoPZ5erh6TRw= +github.com/PromonLogicalis/asn1 v0.0.0-20190312173541-d60463189a56/go.mod h1:nE9BGpMlMfM9Z3U+P+mWtcHNDwHcGctalMx1VTkODAY= github.com/PuerkitoBio/goquery v1.5.0/go.mod h1:qD2PgZ9lccMbQlc7eEOjaeRlFQON7xY8kdmcsrnKqMg= github.com/PuerkitoBio/purell v1.0.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/purell v1.1.0/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= @@ -433,12 +440,10 @@ github.com/containers/libtrust v0.0.0-20190913040956-14b96171aa3b/go.mod h1:9rfv github.com/containers/ocicrypt v1.0.2/go.mod h1:nsOhbP19flrX6rE7ieGFvBlr7modwmNjsqWarIUce4M= github.com/containers/storage v1.20.2/go.mod h1:oOB9Ie8OVPojvoaKWEGSEtHbXUAs+tSyr7RO7ZGteMc= github.com/coreos/bbolt v1.3.0/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= -github.com/coreos/bbolt v1.3.1-coreos.6/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= github.com/coreos/container-linux-config-transpiler v0.9.0/go.mod h1:SlcxXZQ2c42knj8pezMiQsM1f+ADxFMjGetuMKR/YSQ= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= -github.com/coreos/etcd v3.3.15+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/fcct v0.5.0/go.mod h1:cbE+j77YSQwFB2fozWVB3qsI2Pi3YiVEbDz/b6Yywdo= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-json v0.0.0-20170920214419-6a2fe990e083/go.mod h1:FmxyHfvrCFfCsXRylD4QQRlQmvzl+DG6iTHyEEykPfU= @@ -788,6 +793,8 @@ github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXP github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/goji/httpauth v0.0.0-20160601135302-2da839ab0f4d/go.mod h1:nnjvkQ9ptGaCkuDUx6wNykzzlUixGxvkme+H/lnzb+A= +github.com/golang-jwt/jwt v3.2.1+incompatible h1:73Z+4BJcrTC+KczS6WvTPvRGOp1WmfEP4Q1lOd9Z/+c= +github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20180513044358-24b0969c4cb7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -1194,7 +1201,6 @@ github.com/json-iterator/go v1.1.5/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCV github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.7/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.8/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= -github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= github.com/json-iterator/go v1.1.11 h1:uVUAXhF2To8cbw/3xN3pxj6kk7TYKs98NIrTqPlMWAQ= github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -1462,6 +1468,7 @@ github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9k github.com/onsi/ginkgo v1.14.1/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.14.2/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISqnKUg= +github.com/onsi/ginkgo v1.16.2/go.mod h1:CObGmKUOKaSC0RjmoAK7tKyn4Azo5P2IWuoMnvwxz1E= github.com/onsi/ginkgo v1.16.4 h1:29JGrr5oVBm5ulCWet69zQkzWipVXIol6ygQUe/EzNc= github.com/onsi/ginkgo v1.16.4/go.mod h1:dX+/inL/fNMqNlz0e9LfyB9TswhZpCVdJM/Z6Vvnwo0= github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA= @@ -1478,6 +1485,7 @@ github.com/onsi/gomega v1.10.2/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.10.3/go.mod h1:V9xEwhxec5O8UDM77eCW8vLymOMltsqPVYWrpDsH8xc= github.com/onsi/gomega v1.10.4/go.mod h1:g/HbgYopi++010VEqkFgJHKC09uJiW9UkXvMUuKHUCQ= github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48= +github.com/onsi/gomega v1.13.0/go.mod h1:lRk9szgn8TxENtWd0Tp4c3wjlRfMTMH27I+3Je41yGY= github.com/onsi/gomega v1.14.0 h1:ep6kpPVwmr/nTbklSx2nrLNSIO62DoYAhnPNIMhK8gI= github.com/onsi/gomega v1.14.0/go.mod h1:cIuvLEne0aoVhAgh/O6ac0Op8WWw9H6eYCriF+tEHG0= github.com/op/go-logging v0.0.0-20160315200505-970db520ece7/go.mod h1:HzydrMdWErDVzsI23lYNej1Htcns9BCg93Dk0bBINWk= @@ -1496,14 +1504,14 @@ github.com/opencontainers/runtime-spec v0.1.2-0.20190507144316-5b71a03e2700/go.m github.com/opencontainers/selinux v1.5.2/go.mod h1:yTcKuYAh6R95iDpefGLQaPaRwJFwyzAJufJyiTt7s0g= github.com/openshift-metal3/terraform-provider-ironic v0.2.6 h1:R48DOxq2z6NpFkRs/OHzbkWA8aLZMIXljMK2aq1VvbM= github.com/openshift-metal3/terraform-provider-ironic v0.2.6/go.mod h1:ux2W6gsCIYsY/fX5N0V0ZgwFEBNN7P8g6RlH6ACi97k= +github.com/openshift-powervs/machine-api-operator v0.2.1-0.20210809115935-a9fd8f5d2767 h1:HjHocKp0/sxuNiNHbTkGzbp30YEsTovjEu7x5YFK1lk= +github.com/openshift-powervs/machine-api-operator v0.2.1-0.20210809115935-a9fd8f5d2767/go.mod h1:+b/AyRJ/X/1Hceap+ybH/L/wq558FCYm3JPEbh5xALs= github.com/openshift/api v0.0.0-20200326160804-ecb9283fe820/go.mod h1:RKMJ5CBnljLfnej+BJ/xnOWc3kZDvJUaIAEq2oKSPtE= -github.com/openshift/api v0.0.0-20200424083944-0422dc17083e/go.mod h1:VnbEzX8SAaRj7Yfl836NykdQIlbEjfL6/CD+AaJQg5Q= github.com/openshift/api v0.0.0-20200827090112-c05698d102cf/go.mod h1:M3xexPhgM8DISzzRpuFUy+jfPjQPIcs9yqEYj17mXV8= github.com/openshift/api v0.0.0-20200829102639-8a3a835f1acf/go.mod h1:M3xexPhgM8DISzzRpuFUy+jfPjQPIcs9yqEYj17mXV8= github.com/openshift/api v0.0.0-20200901182017-7ac89ba6b971/go.mod h1:M3xexPhgM8DISzzRpuFUy+jfPjQPIcs9yqEYj17mXV8= github.com/openshift/api v0.0.0-20200929171550-c99a4deebbe5/go.mod h1:Si/I9UGeRR3qzg01YWPmtlr0GeGk2fnuggXJRmjAZ6U= github.com/openshift/api v0.0.0-20201019163320-c6a5ec25f267/go.mod h1:RDvBcRQMGLa3aNuDuejVBbTEQj/2i14NXdpOLqbNBvM= -github.com/openshift/api v0.0.0-20201214114959-164a2fb63b5f/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg= github.com/openshift/api v0.0.0-20201216151826-78a19e96f9eb/go.mod h1:aqU5Cq+kqKKPbDMqxo9FojgDeSpNJI7iuskjXjtojDg= github.com/openshift/api v0.0.0-20210331193751-3acddb19d360/go.mod h1:dZ4kytOo3svxJHNYd0J55hwe/6IQG5gAUHUE0F3Jkio= github.com/openshift/api v0.0.0-20210412212256-79bd8cfbbd59/go.mod h1:dZ4kytOo3svxJHNYd0J55hwe/6IQG5gAUHUE0F3Jkio= @@ -1516,7 +1524,6 @@ github.com/openshift/baremetal-operator v0.0.0-20210706141527-5240e42f012a/go.mo github.com/openshift/baremetal-operator/apis v0.0.0-20210706141527-5240e42f012a h1:oXPw/sck0Lr0yAarZZCOCFE/3+9+UziPIIhREzhE2SU= github.com/openshift/baremetal-operator/apis v0.0.0-20210706141527-5240e42f012a/go.mod h1:b2uTLrpVxUWaXRhQeaONl8jOjPxSjtdmjCNKlgsoGI0= github.com/openshift/build-machinery-go v0.0.0-20200211121458-5e3d6e570160/go.mod h1:1CkcsT3aVebzRBzVTSbiKSkJMsC/CASqxesfqEMfJEc= -github.com/openshift/build-machinery-go v0.0.0-20200424080330-082bf86082cc/go.mod h1:1CkcsT3aVebzRBzVTSbiKSkJMsC/CASqxesfqEMfJEc= github.com/openshift/build-machinery-go v0.0.0-20200819073603-48aa266c95f7/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/build-machinery-go v0.0.0-20200917070002-f171684f77ab/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= github.com/openshift/build-machinery-go v0.0.0-20210209125900-0da259a2c359/go.mod h1:b1BuldmJlbA/xYtdZvKi+7j5YGB44qJUJDZ9zwiNCfE= @@ -1534,10 +1541,6 @@ github.com/openshift/cluster-api-provider-azure v0.1.0-alpha.3.0.20210626224711- github.com/openshift/cluster-api-provider-azure v0.1.0-alpha.3.0.20210626224711-5d94c794092f/go.mod h1:GR+ocB8I+Z7JTSBdO+DMu/diBfH66lRlRpnc1KWysUM= github.com/openshift/cluster-api-provider-baremetal v0.0.0-20190821174549-a2a477909c1d h1:6+XwaVvSMPHm3nFdZW3g+iXiOHpf0Y2ajY5/Zr66Dt0= github.com/openshift/cluster-api-provider-baremetal v0.0.0-20190821174549-a2a477909c1d/go.mod h1:S+wtA0Rm2FZ5ccC9zNQXUWUDesR6Jsdn5eb6HjAR+Gs= -github.com/openshift/cluster-api-provider-gcp v0.0.1-0.20200701112720-3a7d727c9a10/go.mod h1:wgkZrOlcIMWTzo8khB4Js2PoDJDlIUUdzCBm7BuDdqw= -github.com/openshift/cluster-api-provider-gcp v0.0.1-0.20200713133651-5c8a640669ac/go.mod h1:XVYX9JE339nKbDDa/W481XD+1GTeqeaBm8bDPr7WE7I= -github.com/openshift/cluster-api-provider-gcp v0.0.1-0.20200901173901-9056dbc8c9b9/go.mod h1:rcwAydGZX+z4l91wtOdbq+fqDwuo6iu0YuFik3UUc+8= -github.com/openshift/cluster-api-provider-gcp v0.0.1-0.20201002065957-9854f7420570/go.mod h1:7NRECVE26rvP1/fs1CbhfY5gsgnnFQNhb9txTFzWmUw= github.com/openshift/cluster-api-provider-gcp v0.0.1-0.20201201000827-1117a4fc438c/go.mod h1:21N0wWjiTQypZ7WosEYhcGJHr9JoDR1RBFztE0NvdYM= github.com/openshift/cluster-api-provider-gcp v0.0.1-0.20201203141909-4dc702fd57a5 h1:75U75i/GfStAartlsP/F9v3Gv3MwzuLwqdLTjP1vPeE= github.com/openshift/cluster-api-provider-gcp v0.0.1-0.20201203141909-4dc702fd57a5/go.mod h1:/XjFaKnqBc8K/jcRXHO7tau39CmzNinqmpxYaQGRvnE= @@ -1549,28 +1552,15 @@ github.com/openshift/cluster-api-provider-openstack v0.0.0-20210302164104-849824 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.20210817084941-2262c7c6cece h1:w32C7hy52lkIpDvJqz/tRyYCIZmhE/8bSIVt+L0c9Mg= github.com/openshift/cluster-api-provider-ovirt v0.1.1-0.20210817084941-2262c7c6cece/go.mod h1:lrKTKMpd3OERMlQgVJi6VKcE57EvtUORGSFIoE7BEAs= +github.com/openshift/cluster-api-provider-powervs v0.0.2-0.20210928133618-8eb5ebcb07a1 h1:fFRg32p+RR2Li1ynhl74RtSvEFstYEQ+QQufdE6plx8= +github.com/openshift/cluster-api-provider-powervs v0.0.2-0.20210928133618-8eb5ebcb07a1/go.mod h1:J5ynCgpZbdXNBPF9ukQXWeEt5ruMn8BEPSq/h55NfLo= github.com/openshift/cluster-autoscaler-operator v0.0.0-20190521201101-62768a6ba480/go.mod h1:/XmV44Fh28Vo3Ye93qFrxAbcFJ/Uy+7LPD+jGjmfJYc= github.com/openshift/hashicorp-terraform-plugin-sdk v1.14.0-openshift h1:CuH9qNELLH3y0QoSaLchdG+7We75AO4kNBy6P3+oLug= github.com/openshift/hashicorp-terraform-plugin-sdk v1.14.0-openshift/go.mod h1:t62Xy+m7Zjq5tA2vrs8Wuo/TQ0sc9Mx9MjXL3+7MHBQ= github.com/openshift/library-go v0.0.0-20191003152030-97c62d8a2901/go.mod h1:NBttNjZpWwup/nthuLbPAPSYC8Qyo+BBK5bCtFoyYjo= -github.com/openshift/library-go v0.0.0-20200512120242-21a1ff978534/go.mod h1:2kWwXTkpoQJUN3jZ3QW88EIY1hdRMqxgRs2hheEW/pg= github.com/openshift/library-go v0.0.0-20200831114015-2ab0c61c15de/go.mod h1:6vwp+YhYOIlj8MpkQKkebTTSn2TuYyvgiAFQ206jIEQ= -github.com/openshift/library-go v0.0.0-20200909173121-1d055d971916/go.mod h1:6vwp+YhYOIlj8MpkQKkebTTSn2TuYyvgiAFQ206jIEQ= -github.com/openshift/library-go v0.0.0-20201109112824-093ad3cf6600/go.mod h1:1xYaYQcQsn+AyCRsvOU+Qn5z6GGiCmcblXkT/RZLVfo= -github.com/openshift/library-go v0.0.0-20201215165635-4ee79b1caed5/go.mod h1:udseDnqxn5ON8i+NBjDp00fBTK0JRu1/6Y6tf6EivDE= github.com/openshift/library-go v0.0.0-20210408164723-7a65fdb398e2 h1:eYdrmOSwRqHhfuPK8bhCSkBRUmCNYkgkOLgnImnz3Rs= github.com/openshift/library-go v0.0.0-20210408164723-7a65fdb398e2/go.mod h1:pnz961veImKsbn7pQcuFbcVpCQosYiC1fUOjzEDeOLU= -github.com/openshift/machine-api-operator v0.0.0-20190312153711-9650e16c9880/go.mod h1:7HeAh0v04zQn1L+4ItUjvpBQYsm2Nf81WaZLiXTcnkc= -github.com/openshift/machine-api-operator v0.2.1-0.20200611014855-9a69f85c32dd/go.mod h1:6vMi+R3xqznBdq5rgeal9N3ak3sOpy50t0fdRCcQXjE= -github.com/openshift/machine-api-operator v0.2.1-0.20200701225707-950912b03628/go.mod h1:cxjy/RUzv5C2T5FNl1KKXUgtakWsezWQ642B/CD9VQA= -github.com/openshift/machine-api-operator v0.2.1-0.20200722104429-f4f9b84df9b7/go.mod h1:XDsNRAVEJtkI00e51SAZ/PnqNJl1zv0rHXSdl9L1oOY= -github.com/openshift/machine-api-operator v0.2.1-0.20200926044412-b7d860f8074c/go.mod h1:cp/wPVzxHZeLUjOLkNPNqrk4wyyW6HuHd3Kz9+hl5xw= -github.com/openshift/machine-api-operator v0.2.1-0.20201002104344-6abfb5440597/go.mod h1:+oAfoCl+TUd2TM79/6NdqLpFUHIJpmqkKdmiHe2O7mw= -github.com/openshift/machine-api-operator v0.2.1-0.20201203125141-79567cb3368e/go.mod h1:Vxdx8K+8sbdcGozW86hSvcVl5JgJOqNFYhLRRhEM9HY= -github.com/openshift/machine-api-operator v0.2.1-0.20210104142355-8e6ae0acdfcf/go.mod h1:U5eAHChde1XvtQy3s1Zcr7ll4X7heb0SzYpaiAwxmQc= -github.com/openshift/machine-api-operator v0.2.1-0.20210504014029-a132ec00f7dd/go.mod h1:DFZBMPtC2TYZH5NE9+2JQIpbZAnruqc9F26QmbOm9pw= -github.com/openshift/machine-api-operator v0.2.1-0.20210505133115-b7ef098180db h1:uxSkm3BCC6jkrygfCxjm0iEJqJvNL8zDTXWQv2gmyZI= -github.com/openshift/machine-api-operator v0.2.1-0.20210505133115-b7ef098180db/go.mod h1:DFZBMPtC2TYZH5NE9+2JQIpbZAnruqc9F26QmbOm9pw= github.com/openshift/machine-config-operator v0.0.1-0.20201009041932-4fe8559913b8 h1:C4gCipkWTDp0B9jb0wZdLgB+HWC7EzVVwQOeNaKnTRA= github.com/openshift/machine-config-operator v0.0.1-0.20201009041932-4fe8559913b8/go.mod h1:fjKreLaKEeUKsyIkT4wlzIQwUVJ2ZKDUh3CI73ckYIY= github.com/openshift/runtime-utils v0.0.0-20200415173359-c45d4ff3f912/go.mod h1:0OXNy7VoqFexkxKqyQbHJLPwn1MFp1/CxRJAgKHM+/o= @@ -1582,8 +1572,6 @@ github.com/openshift/terraform-provider-azurerm v1.44.1-0.20210224232508-7509319 github.com/openshift/terraform-provider-azurerm v1.44.1-0.20210224232508-7509319df0f4/go.mod h1:MohWawSEwkGnsTTEW/U/sPVxsgQVHBNg2LsqQPbMa/U= github.com/openshift/terraform-provider-azurestack v0.10.0-openshift h1:OB8vX01eavwH+6pdJjAh5nE2HYfnotzHpXtNbugTOQo= github.com/openshift/terraform-provider-azurestack v0.10.0-openshift/go.mod h1:wUvqPoPkdMZxYSgdyePsJm8mYbjAeIwR5hEyY9/UFI4= -github.com/openshift/terraform-provider-ibm v1.26.2-openshift-2 h1:HxvKVrzgLpfuzxU3KfYeruRuop1pG34rh2yXTKn42+I= -github.com/openshift/terraform-provider-ibm v1.26.2-openshift-2/go.mod h1:LnGKkV2HJUeJrIMMPK+/Ka6F+5JIy45mbEj9VpoHHqc= github.com/openshift/terraform-provider-vsphere v1.24.3-openshift h1:tG83XgfFwH4OLONUeEsxh8JPG9QRrqKLoPzkPmLye/Y= github.com/openshift/terraform-provider-vsphere v1.24.3-openshift/go.mod h1:FgcsrcPpnjLUO4XWpudYiBho9ETIXYRxVXWV7R3Iz6k= github.com/opentracing-contrib/go-observer v0.0.0-20170622124052-a52f23424492/go.mod h1:Ngi6UdF0k5OKD5t5wlmGhe/EDKPoUM3BXZSSfIuJbis= @@ -1653,6 +1641,7 @@ github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXq github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s= github.com/posener/complete/v2 v2.0.1-alpha.12/go.mod h1://JlL91cS2JV7rOl6LVHrRqBXoBUecJu3ILQPgbJiMQ= github.com/posener/script v1.0.4/go.mod h1:Rg3ijooqulo05aGLyGsHoLmIOUzHUVK19WVgrYBPU/E= +github.com/ppc64le-cloud/powervs-utils v0.0.0-20210415051532-4cdd6a79c8fa/go.mod h1:KImYgHmvBVtAczNhyDBDSN54PGIdz0+QiPVQMmObEQY= github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/pquerna/cachecontrol v0.0.0-20180517163645-1555304b9b35/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/pquerna/ffjson v0.0.0-20181028064349-e517b90714f7/go.mod h1:YARuvh7BUWHNhzDq2OM5tzR2RiCcN2D7sapiKyCel/M= @@ -1785,8 +1774,6 @@ github.com/smartystreets/goconvey v0.0.0-20190222223459-a17d461953aa/go.mod h1:2 github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v1.6.4 h1:fv0U8FUIMPNf1L9lnHLvLhgicrIVChEkdzIKYqbNC9s= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= -github.com/softlayer/softlayer-go v1.0.3 h1:9FONm5xzQ9belQtbdryR6gBg4EF6hX6lrjNKi0IvZkU= -github.com/softlayer/softlayer-go v1.0.3/go.mod h1:6HepcfAXROz0Rf63krk5hPZyHT6qyx2MNvYyHof7ik4= github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e h1:3OgWYFw7jxCZPcvAg+4R8A50GZ+CCkARF10lxu2qDsQ= github.com/softlayer/xmlrpc v0.0.0-20200409220501-5f089df7cb7e/go.mod h1:fKZCUVdirrxrBpwd9wb+lSoVixvpwAu8eHzbQB2tums= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= @@ -1970,6 +1957,10 @@ github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9de github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yujunz/go-getter v1.4.1-lite/go.mod h1:sbmqxXjyLunH1PkF3n7zSlnVeMvmYUuIl9ZVs/7NyCc= +github.com/yussufsh/power-go-client v1.99.4 h1:+7Zz60BOBZCOlTkbU8LeNiwh2wRfZ+anNwcTG+X30eg= +github.com/yussufsh/power-go-client v1.99.4/go.mod h1:I4r5tCrA8mV5GFqGAJG4/Tn+/JpR+XLnDCLLNVKJxuI= +github.com/yussufsh/terraform-provider-ibm v1.89.0 h1:gjdIIr5DFPQg2ncFVQcM7sgouBCC4ZEtrTqmnezpVoU= +github.com/yussufsh/terraform-provider-ibm v1.89.0/go.mod h1:iPP4zVJhZ0YsaPNVaWNTZHYmWLXFAoou4uE+kRkYF+M= github.com/zclconf/go-cty v1.0.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.1.0/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= github.com/zclconf/go-cty v1.1.1/go.mod h1:xnAOWiHeOqg2nWS62VtQ7pbOu17FtxJNW8RLEih+O3s= @@ -2067,8 +2058,8 @@ golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20201016220609-9e8e0b390897/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201221181555-eec23a3978ad/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 h1:It14KIkyBFYkHkwZ7k45minvA9aorojkyjGk9KJ5B/w= -golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 h1:/UOmuWzQfxxo9UtlXMwuQU8CMgg1eZXqTRwkSQJWKOI= +golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190312203227-4b39c73a6495/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -2140,7 +2131,6 @@ golang.org/x/net v0.0.0-20200222125558-5a598a2470a0/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200301022130-244492dfa37a/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= -golang.org/x/net v0.0.0-20200421231249-e086a090c8fd/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200501053045-e0ff5e5a1de5/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200513185701-a91f0712d120/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= @@ -2155,14 +2145,14 @@ golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210224082022-3d97a244fca7/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226101413-39120d07d75e/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= golang.org/x/net v0.0.0-20210428140749-89ef3d95e781/go.mod h1:OJAsFXCWl8Ukc7SiCT/9KSuxbyM7479/AVlXFRxuMCk= -golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 h1:ADo5wSpq2gqaCGQWzk7S5vd//0iyyLeAratkEoG5dLE= golang.org/x/net v0.0.0-20210520170846-37e1c6afe023/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e h1:XpT3nA5TvE525Ne3hInMh6+GETgn27Zfm9dxsThnX2Q= +golang.org/x/net v0.0.0-20210614182718-04defd469f4e/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20190130055435-99b60b757ec1/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= @@ -2274,6 +2264,7 @@ golang.org/x/sys v0.0.0-20210330210617-4fbd30eecc44/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603125802-9665404d3644/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c h1:F1jZWGFhYfh0Ci55sIpILtKKK8p3i2/krTr0H1rg74I= golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -2552,8 +2543,6 @@ k8s.io/api v0.22.2/go.mod h1:y3ydYpLJAaDI+BbSe2xmGcqxiWHmWjkEeIbiwHvnPR8= k8s.io/apiextensions-apiserver v0.18.0-beta.2/go.mod h1:Hnrg5jx8/PbxRbUoqDGxtQkULjwx8FDW4WYJaKNK+fk= k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY= k8s.io/apiextensions-apiserver v0.19.0/go.mod h1:znfQxNpjqz/ZehvbfMg5N6fvBJW5Lqu5HVLTJQdP4Fs= -k8s.io/apiextensions-apiserver v0.19.2/go.mod h1:EYNjpqIAvNZe+svXVx9j4uBaVhTB4C94HkY3w058qcg= -k8s.io/apiextensions-apiserver v0.20.0/go.mod h1:ZH+C33L2Bh1LY1+HphoRmN1IQVLTShVcTojivK3N9xg= k8s.io/apiextensions-apiserver v0.21.0-beta.1/go.mod h1:vluMqsJ5+hPgM9UtBhkFSGrfD86KUac9yeKVqpGBZz0= k8s.io/apiextensions-apiserver v0.21.0-rc.0 h1:gxeak4PvTBhuiZagZRFv9WyNnAdG39/VCmI9XTwVCRk= k8s.io/apiextensions-apiserver v0.21.0-rc.0/go.mod h1:ItIoMBJU1gy93Qwr/B2699r4b0VmZqAOU+15BvozxMY= @@ -2581,8 +2570,6 @@ k8s.io/apiserver v0.18.0-beta.2/go.mod h1:bnblMkMoCFnIfVnVftd0SXJPzyvrk3RtaqSbbl k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw= k8s.io/apiserver v0.19.0/go.mod h1:XvzqavYj73931x7FLtyagh8WibHpePJ1QwWrSJs2CLk= k8s.io/apiserver v0.19.1/go.mod h1:iRxYIjA0X2XEyoW8KslN4gDhasfH4bWcjj6ckVeZX28= -k8s.io/apiserver v0.19.2/go.mod h1:FreAq0bJ2vtZFj9Ago/X0oNGC51GfubKK/ViOKfVAOA= -k8s.io/apiserver v0.20.0/go.mod h1:6gRIWiOkvGvQt12WTYmsiYoUyYW0FXSiMdNl4m+sxY8= k8s.io/apiserver v0.21.0-beta.1/go.mod h1:nl/H4DPS1abtRhCj8bhosbyU9XOgnMt0QFK3fAFEhSE= k8s.io/apiserver v0.21.0-rc.0/go.mod h1:QlW7+1CZTZtAcKvJ34/n4DIb8sC93FeQpkd1KSU+Sok= k8s.io/apiserver v0.21.0/go.mod h1:w2YSn4/WIwYuxG5zJmcqtRdtqgW/J2JRgFAqps3bBpg= @@ -2607,8 +2594,6 @@ k8s.io/component-base v0.18.0-beta.2/go.mod h1:HVk5FpRnyzQ/MjBr9//e/yEBjTVa2qjGX k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM= k8s.io/component-base v0.19.0/go.mod h1:dKsY8BxkA+9dZIAh2aWJLL/UdASFDNtGYTCItL4LM7Y= k8s.io/component-base v0.19.1/go.mod h1:b0vDKYa8EdJJ8dHUA6fGPj4z8taqGks5mfZvp3p/jVo= -k8s.io/component-base v0.19.2/go.mod h1:g5LrsiTiabMLZ40AR6Hl45f088DevyGY+cCE2agEIVo= -k8s.io/component-base v0.20.0/go.mod h1:wKPj+RHnAr8LW2EIBIK7AxOHPde4gme2lzXwVSoRXeA= k8s.io/component-base v0.21.0-beta.1/go.mod h1:WPMZyV0sNk3ruzA8cWt1EO2KWAnLDK2docEC14JWbTM= k8s.io/component-base v0.21.0-rc.0/go.mod h1:XlP0bM7QJFWRGZYPc5NmphkvsYQ+o7804HWH3GTGjDY= k8s.io/component-base v0.21.0 h1:tLLGp4BBjQaCpS/KiuWh7m2xqvAdsxLm4ATxHSe5Zpg= @@ -2636,11 +2621,8 @@ k8s.io/klog/v2 v2.8.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/klog/v2 v2.9.0 h1:D7HV+n1V57XeZ0m6tdRkfknthUaM06VFbWldOFh8kzM= k8s.io/klog/v2 v2.9.0/go.mod h1:hy9LJ/NvuK+iVyP4Ehqva4HxZG/oXyIS3n3Jmire4Ec= k8s.io/kube-aggregator v0.18.0-beta.2/go.mod h1:O3Td9mheraINbLHH4pzoFP2gRzG0Wk1COqzdSL4rBPk= -k8s.io/kube-aggregator v0.18.2/go.mod h1:ijq6FnNUoKinA6kKbkN6svdTacSoQVNtKqmQ1+XJEYQ= k8s.io/kube-aggregator v0.19.0/go.mod h1:1Ln45PQggFAG8xOqWPIYMxUq8WNtpPnYsbUJ39DpF/A= k8s.io/kube-aggregator v0.19.1/go.mod h1:oAj1kWeSDCh7sdzUOs6XXPn/jbzJY+yGGxDd0QyLJC8= -k8s.io/kube-aggregator v0.19.2/go.mod h1:wVsjy6OTeUrWkgG9WVsGftnjpm8JIY0vJV7LH2j4nhM= -k8s.io/kube-aggregator v0.20.0/go.mod h1:3Is/gzzWmhhG/rA3CpA1+eVye87lreBQDFGcAGT7gzo= k8s.io/kube-aggregator v0.21.0-rc.0 h1:PxnBqTgEQHCOhWl3J6EX2OKbfx0epwgKF4phlhgNyFA= k8s.io/kube-aggregator v0.21.0-rc.0/go.mod h1:M+whOmsAeQf8ObJ0/eO9Af1Dz2UQEB9OW9BWmt9b2sU= k8s.io/kube-openapi v0.0.0-20190228160746-b3a7cee44a30/go.mod h1:BXM9ceUBTj2QnfH2MK1odQs778ajze1RxcmP6S8RVVc= @@ -2660,7 +2642,6 @@ k8s.io/metrics v0.21.0-rc.0/go.mod h1:iCF67TNbrhChr/eb99uHt0H1hE7Rd1EC2Ic/yknzIE k8s.io/utils v0.0.0-20190529001817-6999998975a7/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200229041039-0a110f9eb7ab/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= -k8s.io/utils v0.0.0-20200327001022-6496210b90e8/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew= k8s.io/utils v0.0.0-20200729134348-d5654de09c73/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20200821003339-5e75c0163111/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= k8s.io/utils v0.0.0-20201110183641-67b214c5f920/go.mod h1:jPW/WVKK9YHAvNhRxK0md/EJ228hCsBRufyofKtW8HA= @@ -2686,7 +2667,6 @@ rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.9/go.mod h1:dzAXnQbTRyDlZPJX2SUPEqvnB+j7AJjtlox7PEwigU0= -sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.14/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.15/go.mod h1:LEScyzhFmoF5pso/YSeBstl57mOzx9xlU9n85RGrDQg= sigs.k8s.io/controller-runtime v0.9.0-alpha.1 h1:yIYTxDHQfcrYWO1hjZvHhjkGY1fYFo1k07FzlTono4E= sigs.k8s.io/controller-runtime v0.9.0-alpha.1/go.mod h1:BARxVvgj+8Ihw9modUvYh7/OJmjxuBtLK8P36jdf7rY= diff --git a/pkg/asset/cluster/metadata.go b/pkg/asset/cluster/metadata.go index fadc5b71057..8a0540d4406 100644 --- a/pkg/asset/cluster/metadata.go +++ b/pkg/asset/cluster/metadata.go @@ -17,6 +17,7 @@ import ( "github.com/openshift/installer/pkg/asset/cluster/libvirt" "github.com/openshift/installer/pkg/asset/cluster/openstack" "github.com/openshift/installer/pkg/asset/cluster/ovirt" + "github.com/openshift/installer/pkg/asset/cluster/powervs" "github.com/openshift/installer/pkg/asset/cluster/vsphere" "github.com/openshift/installer/pkg/asset/ignition/bootstrap" "github.com/openshift/installer/pkg/asset/installconfig" @@ -31,6 +32,7 @@ import ( nonetypes "github.com/openshift/installer/pkg/types/none" openstacktypes "github.com/openshift/installer/pkg/types/openstack" ovirttypes "github.com/openshift/installer/pkg/types/ovirt" + powervstypes "github.com/openshift/installer/pkg/types/powervs" vspheretypes "github.com/openshift/installer/pkg/types/vsphere" ) @@ -93,6 +95,8 @@ func (m *Metadata) Generate(parents asset.Parents) (err error) { metadata.ClusterPlatformMetadata.VSphere = vsphere.Metadata(installConfig.Config) case alibabacloudtypes.Name: metadata.ClusterPlatformMetadata.AlibabaCloud = alibabacloud.Metadata(installConfig.Config) + case powervstypes.Name: + metadata.ClusterPlatformMetadata.PowerVS = powervs.Metadata(installConfig.Config, installConfig.PowerVS) case nonetypes.Name: default: return errors.Errorf("no known platform") diff --git a/pkg/asset/cluster/powervs/powervs.go b/pkg/asset/cluster/powervs/powervs.go new file mode 100644 index 00000000000..9fadf5b601f --- /dev/null +++ b/pkg/asset/cluster/powervs/powervs.go @@ -0,0 +1,21 @@ +// Package powervs extracts Power VS metadata from install configurations. +package powervs + +import ( + "context" + + icpowervs "github.com/openshift/installer/pkg/asset/installconfig/powervs" + "github.com/openshift/installer/pkg/types" + "github.com/openshift/installer/pkg/types/powervs" +) + +// Metadata converts an install configuration to PowerVS metadata. +func Metadata(config *types.InstallConfig, meta *icpowervs.Metadata) *powervs.Metadata { + cisCRN, _ := meta.CISInstanceCRN(context.TODO()) + + return &powervs.Metadata{ + CISInstanceCRN: cisCRN, + Region: config.Platform.PowerVS.Region, + Zone: config.Platform.PowerVS.Zone, + } +} diff --git a/pkg/asset/cluster/tfvars.go b/pkg/asset/cluster/tfvars.go index 4159323a6a0..75c131e80e3 100644 --- a/pkg/asset/cluster/tfvars.go +++ b/pkg/asset/cluster/tfvars.go @@ -15,6 +15,7 @@ import ( ibmcloudprovider "github.com/openshift/cluster-api-provider-ibmcloud/pkg/apis/ibmcloudprovider/v1beta1" libvirtprovider "github.com/openshift/cluster-api-provider-libvirt/pkg/apis/libvirtproviderconfig/v1beta1" ovirtprovider "github.com/openshift/cluster-api-provider-ovirt/pkg/apis/ovirtprovider/v1beta1" + powervsprovider "github.com/openshift/cluster-api-provider-powervs/pkg/apis/powervsprovider/v1alpha1" vsphereprovider "github.com/openshift/machine-api-operator/pkg/apis/vsphereprovider/v1beta1" "github.com/pkg/errors" "github.com/sirupsen/logrus" @@ -31,6 +32,7 @@ import ( awsconfig "github.com/openshift/installer/pkg/asset/installconfig/aws" gcpconfig "github.com/openshift/installer/pkg/asset/installconfig/gcp" ovirtconfig "github.com/openshift/installer/pkg/asset/installconfig/ovirt" + powervsconfig "github.com/openshift/installer/pkg/asset/installconfig/powervs" "github.com/openshift/installer/pkg/asset/machines" "github.com/openshift/installer/pkg/asset/manifests" "github.com/openshift/installer/pkg/asset/openshiftinstall" @@ -46,6 +48,7 @@ import ( libvirttfvars "github.com/openshift/installer/pkg/tfvars/libvirt" openstacktfvars "github.com/openshift/installer/pkg/tfvars/openstack" ovirttfvars "github.com/openshift/installer/pkg/tfvars/ovirt" + powervstfvars "github.com/openshift/installer/pkg/tfvars/powervs" vspheretfvars "github.com/openshift/installer/pkg/tfvars/vsphere" "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/alibabacloud" @@ -58,6 +61,7 @@ import ( "github.com/openshift/installer/pkg/types/none" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -607,6 +611,52 @@ func (t *TerraformVariables) Generate(parents asset.Parents) error { Filename: fmt.Sprintf(TfPlatformVarsFileName, platform), Data: data, }) + case powervs.Name: + // @TODO: Can we just use the install config for all these values? + session, err := powervsconfig.GetSession() + if err != nil { + return err + } + + masters, err := mastersAsset.Machines() + if err != nil { + return err + } + + // Get CISInstanceCRN from InstallConfig metadata + crn, err := installConfig.PowerVS.CISInstanceCRN(ctx) + if err != nil { + return err + } + + masterConfigs := make([]*powervsprovider.PowerVSMachineProviderConfig, len(masters)) + for i, m := range masters { + masterConfigs[i] = m.Spec.ProviderSpec.Value.Object.(*powervsprovider.PowerVSMachineProviderConfig) + } + + data, err = powervstfvars.TFVars( + powervstfvars.TFVarsSources{ + MasterConfigs: masterConfigs, + Region: installConfig.Config.Platform.PowerVS.Region, + Zone: installConfig.Config.Platform.PowerVS.Zone, + VPCZone: installConfig.Config.Platform.PowerVS.VPCZone, + APIKey: session.Session.IAMToken, + SSHKey: installConfig.Config.SSHKey, + PowerVSResourceGroup: installConfig.Config.PowerVS.PowerVSResourceGroup, + NetworkName: installConfig.Config.PowerVS.PVSNetworkName, + CISInstanceCRN: crn, + VPCSubnetName: installConfig.Config.PowerVS.Subnets[0], + VPCName: installConfig.Config.PowerVS.VPC, + }, + ) + if err != nil { + return errors.Wrapf(err, "failed to get %s Terraform variables", platform) + } + t.FileList = append(t.FileList, &asset.File{ + Filename: fmt.Sprintf(TfPlatformVarsFileName, platform), + Data: data, + }) + case vsphere.Name: controlPlanes, err := mastersAsset.Machines() if err != nil { diff --git a/pkg/asset/installconfig/basedomain.go b/pkg/asset/installconfig/basedomain.go index 88a379a2b1f..00caa9e1b23 100644 --- a/pkg/asset/installconfig/basedomain.go +++ b/pkg/asset/installconfig/basedomain.go @@ -14,6 +14,7 @@ import ( "github.com/openshift/installer/pkg/types/azure" "github.com/openshift/installer/pkg/types/gcp" "github.com/openshift/installer/pkg/types/ibmcloud" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/validate" ) @@ -70,6 +71,13 @@ func (a *baseDomain) Generate(parents asset.Parents) error { } a.BaseDomain = zone.Name return nil + case powervs.Name: + zone, err := ibmcloudconfig.GetDNSZone() + if err != nil { + return err + } + a.BaseDomain = zone.Name + return nil default: //Do nothing } diff --git a/pkg/asset/installconfig/installconfig.go b/pkg/asset/installconfig/installconfig.go index b4fd37535a5..aa98ce95506 100644 --- a/pkg/asset/installconfig/installconfig.go +++ b/pkg/asset/installconfig/installconfig.go @@ -18,6 +18,7 @@ import ( icibmcloud "github.com/openshift/installer/pkg/asset/installconfig/ibmcloud" icopenstack "github.com/openshift/installer/pkg/asset/installconfig/openstack" icovirt "github.com/openshift/installer/pkg/asset/installconfig/ovirt" + icpowervs "github.com/openshift/installer/pkg/asset/installconfig/powervs" icvsphere "github.com/openshift/installer/pkg/asset/installconfig/vsphere" "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/conversion" @@ -37,6 +38,7 @@ type InstallConfig struct { Azure *icazure.Metadata `json:"azure,omitempty"` IBMCloud *icibmcloud.Metadata `json:"ibmcloud,omitempty"` AlibabaCloud *alibabacloud.Metadata `json:"alibabacloud,omitempty"` + PowerVS *icpowervs.Metadata `json:"powervs,omitempty"` } var _ asset.WritableAsset = (*InstallConfig)(nil) @@ -97,6 +99,7 @@ func (a *InstallConfig) Generate(parents asset.Parents) error { a.Config.IBMCloud = platform.IBMCloud a.Config.BareMetal = platform.BareMetal a.Config.Ovirt = platform.Ovirt + a.Config.PowerVS = platform.PowerVS return a.finish("") } @@ -161,6 +164,10 @@ func (a *InstallConfig) finish(filename string) error { if a.Config.IBMCloud != nil { a.IBMCloud = icibmcloud.NewMetadata(a.Config.BaseDomain) } + if a.Config.PowerVS != nil { + a.PowerVS = icpowervs.NewMetadata(a.Config.BaseDomain) + } + if err := validation.ValidateInstallConfig(a.Config).ToAggregate(); err != nil { if filename == "" { return errors.Wrap(err, "invalid install config") diff --git a/pkg/asset/installconfig/platform.go b/pkg/asset/installconfig/platform.go index 84faf7e7ab2..fd2f625046e 100644 --- a/pkg/asset/installconfig/platform.go +++ b/pkg/asset/installconfig/platform.go @@ -18,6 +18,7 @@ import ( libvirtconfig "github.com/openshift/installer/pkg/asset/installconfig/libvirt" openstackconfig "github.com/openshift/installer/pkg/asset/installconfig/openstack" ovirtconfig "github.com/openshift/installer/pkg/asset/installconfig/ovirt" + powervsconfig "github.com/openshift/installer/pkg/asset/installconfig/powervs" vsphereconfig "github.com/openshift/installer/pkg/asset/installconfig/vsphere" "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/alibabacloud" @@ -30,6 +31,7 @@ import ( "github.com/openshift/installer/pkg/types/none" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -106,6 +108,11 @@ func (a *platform) Generate(asset.Parents) error { if err != nil { return err } + case powervs.Name: + a.PowerVS, err = powervsconfig.Platform() + if err != nil { + return err + } default: return fmt.Errorf("unknown platform type %q", platform) } diff --git a/pkg/asset/installconfig/platformcredscheck.go b/pkg/asset/installconfig/platformcredscheck.go index a77cf68478a..7a3375aec7c 100644 --- a/pkg/asset/installconfig/platformcredscheck.go +++ b/pkg/asset/installconfig/platformcredscheck.go @@ -11,6 +11,7 @@ import ( ibmcloudconfig "github.com/openshift/installer/pkg/asset/installconfig/ibmcloud" openstackconfig "github.com/openshift/installer/pkg/asset/installconfig/openstack" ovirtconfig "github.com/openshift/installer/pkg/asset/installconfig/ovirt" + powervsconfig "github.com/openshift/installer/pkg/asset/installconfig/powervs" "github.com/openshift/installer/pkg/types/alibabacloud" "github.com/openshift/installer/pkg/types/aws" "github.com/openshift/installer/pkg/types/azure" @@ -21,6 +22,7 @@ import ( "github.com/openshift/installer/pkg/types/none" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -52,6 +54,7 @@ func (a *PlatformCredsCheck) Generate(dependencies asset.Parents) error { if err != nil { return errors.Wrap(err, "creating AlibabaCloud Cloud session") } + case aws.Name: _, err := ic.AWS.Session(ctx) if err != nil { @@ -64,6 +67,8 @@ func (a *PlatformCredsCheck) Generate(dependencies asset.Parents) error { } case ibmcloud.Name: _, err = ibmcloudconfig.NewClient() + case powervs.Name: + _, err = powervsconfig.GetSession() if err != nil { return errors.Wrap(err, "creating IBM Cloud session") } diff --git a/pkg/asset/installconfig/platformpermscheck.go b/pkg/asset/installconfig/platformpermscheck.go index e514c465f73..896489ad807 100644 --- a/pkg/asset/installconfig/platformpermscheck.go +++ b/pkg/asset/installconfig/platformpermscheck.go @@ -9,6 +9,8 @@ import ( "github.com/openshift/installer/pkg/asset" awsconfig "github.com/openshift/installer/pkg/asset/installconfig/aws" gcpconfig "github.com/openshift/installer/pkg/asset/installconfig/gcp" + + //powervsconfig "github.com/openshift/installer/pkg/asset/installconfig/powervs" "github.com/openshift/installer/pkg/types/alibabacloud" "github.com/openshift/installer/pkg/types/aws" "github.com/openshift/installer/pkg/types/azure" @@ -19,6 +21,7 @@ import ( "github.com/openshift/installer/pkg/types/none" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -87,6 +90,8 @@ func (a *PlatformPermsCheck) Generate(dependencies asset.Parents) error { } case ibmcloud.Name: // TODO: IBM[#90]: platformpermscheck + case powervs.Name: + //@TODO add check that the account plan is anything but "lite" case azure.Name, baremetal.Name, libvirt.Name, none.Name, openstack.Name, ovirt.Name, vsphere.Name, alibabacloud.Name: // no permissions to check default: diff --git a/pkg/asset/installconfig/platformprovisioncheck.go b/pkg/asset/installconfig/platformprovisioncheck.go index 5a50458a64a..802f52ec488 100644 --- a/pkg/asset/installconfig/platformprovisioncheck.go +++ b/pkg/asset/installconfig/platformprovisioncheck.go @@ -13,6 +13,7 @@ import ( ibmcloudconfig "github.com/openshift/installer/pkg/asset/installconfig/ibmcloud" osconfig "github.com/openshift/installer/pkg/asset/installconfig/openstack" ovirtconfig "github.com/openshift/installer/pkg/asset/installconfig/ovirt" + powervsconfig "github.com/openshift/installer/pkg/asset/installconfig/powervs" vsconfig "github.com/openshift/installer/pkg/asset/installconfig/vsphere" "github.com/openshift/installer/pkg/types/alibabacloud" "github.com/openshift/installer/pkg/types/aws" @@ -24,6 +25,7 @@ import ( "github.com/openshift/installer/pkg/types/none" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -112,6 +114,8 @@ func (a *PlatformProvisionCheck) Generate(dependencies asset.Parents) error { return err } err = alibabacloudconfig.ValidateForProvisioning(client, ic.Config, ic.AlibabaCloud) + case powervs.Name: + err = powervsconfig.ValidateForProvisioning() if err != nil { return err } diff --git a/pkg/asset/installconfig/powervs/metadata.go b/pkg/asset/installconfig/powervs/metadata.go new file mode 100644 index 00000000000..2321095bd23 --- /dev/null +++ b/pkg/asset/installconfig/powervs/metadata.go @@ -0,0 +1,71 @@ +package powervs + +import ( + "context" + "fmt" + "sync" + + "github.com/openshift/installer/pkg/asset/installconfig/ibmcloud" +) + +// Metadata holds additional metadata for InstallConfig resources that +// do not need to be user-supplied (e.g. because it can be retrieved +// from external APIs). +type Metadata struct { + BaseDomain string + + cisInstanceCRN string + client *ibmcloud.Client + + mutex sync.Mutex +} + +// NewMetadata initializes a new Metadata object. +func NewMetadata(baseDomain string) *Metadata { + return &Metadata{BaseDomain: baseDomain} +} + +// CISInstanceCRN returns the Cloud Internet Services instance CRN that is +// managing the DNS zone for the base domain. +func (m *Metadata) CISInstanceCRN(ctx context.Context) (string, error) { + m.mutex.Lock() + defer m.mutex.Unlock() + + if m.cisInstanceCRN == "" { + client, err := m.Client() + if err != nil { + return "", err + } + + zones, err := client.GetDNSZones(ctx) + if err != nil { + return "", err + } + + for _, z := range zones { + if z.Name == m.BaseDomain { + m.SetCISInstanceCRN(z.CISInstanceCRN) + return m.cisInstanceCRN, nil + } + } + return "", fmt.Errorf("cisInstanceCRN unknown due to DNS zone %q not found", m.BaseDomain) + } + return m.cisInstanceCRN, nil +} + +// SetCISInstanceCRN sets Cloud Internet Services instance CRN to a string value. +func (m *Metadata) SetCISInstanceCRN(crn string) { + m.cisInstanceCRN = crn +} + +// Client returns a client used for making API calls to IBM Cloud services. +func (m *Metadata) Client() (*ibmcloud.Client, error) { + if m.client == nil { + client, err := ibmcloud.NewClient() + if err != nil { + return nil, err + } + m.client = client + } + return m.client, nil +} diff --git a/pkg/asset/installconfig/powervs/platform.go b/pkg/asset/installconfig/powervs/platform.go new file mode 100644 index 00000000000..a05c15c2fb4 --- /dev/null +++ b/pkg/asset/installconfig/powervs/platform.go @@ -0,0 +1,28 @@ +package powervs + +import ( + "os" + + "github.com/openshift/installer/pkg/types/powervs" +) + +// Platform collects powervs-specific configuration. +func Platform() (*powervs.Platform, error) { + + ssn, err := GetSession() + if err != nil { + return nil, err + } + + var p powervs.Platform + if osOverride := os.Getenv("OPENSHIFT_INSTALL_OS_IMAGE_OVERRIDE"); len(osOverride) != 0 { + p.ClusterOSImage = osOverride + } + + p.Region = ssn.Session.Region + p.Zone = ssn.Session.Zone + p.APIKey = ssn.Session.IAMToken + p.UserID = ssn.Session.UserAccount + + return &p, nil +} diff --git a/pkg/asset/installconfig/powervs/regions.go b/pkg/asset/installconfig/powervs/regions.go new file mode 100644 index 00000000000..af96a02139e --- /dev/null +++ b/pkg/asset/installconfig/powervs/regions.go @@ -0,0 +1,141 @@ +package powervs + +import ( + "fmt" + "sort" + "strings" + + survey "github.com/AlecAivazis/survey/v2" + "github.com/AlecAivazis/survey/v2/core" + "github.com/openshift/installer/pkg/rhcos" + "github.com/pkg/errors" +) + +func knownRegions() map[string]string { + + regions := make(map[string]string) + + for _, region := range rhcos.PowerVSRegions { + regions[region.Name] = region.Description + } + return regions +} + +// IsKnownRegion return true is a specified region is Known to the installer. +// A known region is subset of AWS regions and the regions where RHEL CoreOS images are published. +func IsKnownRegion(region string) bool { + if _, ok := knownRegions()[region]; ok { + return true + } + return false +} + +// Todo(cklokman): Need some form of error handing in this function... +func knownZones(region string) []string { + return rhcos.PowerVSRegions[region].Zones +} + +// IsKnownZone return true is a specified zone is Known to the installer. +func IsKnownZone(region string, zone string) bool { + if _, ok := knownRegions()[region]; ok { + zones := knownZones(region) + for _, z := range zones { + if z == zone { + return true + } + } + return false + } + return false +} + +// GetRegion prompts the user to select a region and returns that region +func GetRegion() (string, error) { + regions := knownRegions() + + longRegions := make([]string, 0, len(regions)) + shortRegions := make([]string, 0, len(regions)) + for id, location := range regions { + longRegions = append(longRegions, fmt.Sprintf("%s (%s)", id, location)) + shortRegions = append(shortRegions, id) + } + sort.Strings(longRegions) + sort.Strings(shortRegions) + + var regionTransform survey.Transformer = func(ans interface{}) interface{} { + switch v := ans.(type) { + case core.OptionAnswer: + return core.OptionAnswer{Value: strings.SplitN(v.Value, " ", 2)[0], Index: v.Index} + case string: + return strings.SplitN(v, " ", 2)[0] + } + return "" + } + + var region string + + err := survey.Ask([]*survey.Question{ + { + Prompt: &survey.Select{ + Message: "Region", + Help: "The Power VS region to be used for installation.", + Options: longRegions, + }, + Validate: survey.ComposeValidators(survey.Required, func(ans interface{}) error { + choice := regionTransform(ans).(core.OptionAnswer).Value + i := sort.SearchStrings(shortRegions, choice) + if i == len(shortRegions) || shortRegions[i] != choice { + return errors.Errorf("Invalid region %q", choice) + } + return nil + }), + Transform: regionTransform, + }, + }, ®ion) + if err != nil { + return "", err + } + + return region, nil +} + +// GetZone prompts the user for a zone given a zone +func GetZone(region string) (string, error) { + zones := knownZones(region) + defaultZone := zones[0] + + var zoneTransform survey.Transformer = func(ans interface{}) interface{} { + switch v := ans.(type) { + case core.OptionAnswer: + return core.OptionAnswer{Value: strings.SplitN(v.Value, " ", 2)[0], Index: v.Index} + case string: + return strings.SplitN(v, " ", 2)[0] + } + return "" + } + + var zone string + err := survey.Ask([]*survey.Question{ + { + Prompt: &survey.Select{ + Message: "Zone", + Help: "The Power VS zone within the region to be used for installation.", + Default: fmt.Sprintf("%s", defaultZone), + Options: zones, + }, + Validate: survey.ComposeValidators(survey.Required, func(ans interface{}) error { + choice := zoneTransform(ans).(core.OptionAnswer).Value + i := sort.SearchStrings(zones, choice) + if i == len(zones) || zones[i] != choice { + return errors.Errorf("Invalid zone %q", choice) + } + return nil + }), + Transform: zoneTransform, + }, + }, &zone) + if err != nil { + return "", err + } + return zone, err +} diff --git a/pkg/asset/installconfig/powervs/session.go b/pkg/asset/installconfig/powervs/session.go new file mode 100644 index 00000000000..dfe449db33f --- /dev/null +++ b/pkg/asset/installconfig/powervs/session.go @@ -0,0 +1,238 @@ +package powervs + +import ( + "encoding/json" + "io/ioutil" + "os" + "path/filepath" + "time" + + "github.com/pkg/errors" + + survey "github.com/AlecAivazis/survey/v2" + "github.com/IBM-Cloud/power-go-client/ibmpisession" + + "github.com/sirupsen/logrus" +) + +var ( + //reqAuthEnvs = []string{"IBMID", "IBMID_PASSWORD"} + //optAuthEnvs = []string{"IBMCLOUD_REGION", "IBMCLOUD_ZONE"} + //debug = false + defSessionTimeout time.Duration = 9000000000000000000.0 + defRegion = "us_south" +) + +// Session is an object representing a session for the IBM Power VS API. +// A bluemix session object may be a better fit here +type Session struct { + Session *ibmpisession.IBMPISession +} + +// PISessionVars is an object that holds the variables required to create an ibmpisession object +type PISessionVars struct { + ID string `json:"id,omitempty"` + APIKey string `json:"apikey,omitempty"` + Region string `json:"region,omitempty"` + Zone string `json:"zone,omitempty"` +} + +// GetSession returns an ibmpisession object +func GetSession() (*Session, error) { + s, err := getPISession() + if err != nil { + return nil, errors.Wrap(err, "failed to load credentials") + } + return &Session{Session: s}, nil +} + +var ( + defaultAuthFilePath = filepath.Join(os.Getenv("HOME"), ".powervs", "config.json") +) + +func getPISession() (*ibmpisession.IBMPISession, error) { + + var err error + var pisv PISessionVars + + // Grab variables from the installer written authFilePath + logrus.Debug("Gathering variables from AuthFile") + err = getPISessionVarsFromAuthFile(&pisv) + if err != nil { + return nil, err + } + + // Frab variables from the users environment + logrus.Debug("Gathering variables from user environment") + err = getPISessionVarsFromEnv(&pisv) + if err != nil { + return nil, err + } + + // Prompt the user for the remaining variables + logrus.Debug("Gathering variables from user") + err = getPISessionVarsFromUser(&pisv) + if err != nil { + return nil, err + } + + // Save variables to disk + err = savePISessionVars(&pisv) + if err != nil { + return nil, err + } + + // This is needed by ibmcloud code to gather dns information later + os.Setenv("IC_API_KEY", pisv.APIKey) + + // We are using the iamtoken field to hold the api key + s, err := ibmpisession.New(pisv.APIKey, pisv.Region, false, defSessionTimeout, pisv.ID, pisv.Zone) + if err != nil { + return nil, err + } + + return s, err + +} + +func getPISessionVarsFromAuthFile(pisv *PISessionVars) error { + + if pisv == nil { + return errors.New("PISession Variable Object pointer cannot be nil") + } + + authFilePath := defaultAuthFilePath + if f := os.Getenv("POWERVS_AUTH_FILEPATH"); len(f) > 0 { + authFilePath = f + } + + // Check if AuthFile exists, return if it does not + if _, err := os.Stat(authFilePath); os.IsNotExist(err) { + return nil + } + + content, err := ioutil.ReadFile(authFilePath) + if err != nil { + return err + } + + err = json.Unmarshal(content, pisv) + if err != nil { + return err + } + + return nil +} + +func getPISessionVarsFromEnv(pisv *PISessionVars) error { + + if pisv == nil { + return errors.New("PISession Variable Object pointer cannot be nil") + } + + if len(pisv.ID) == 0 { + pisv.ID = os.Getenv("IBMID") + } + + if len(pisv.APIKey) == 0 { + // APIKeyEnvVars is a list of environment variable names containing an IBM Cloud API key + var APIKeyEnvVars = []string{"IC_API_KEY", "IBMCLOUD_API_KEY", "BM_API_KEY", "BLUEMIX_API_KEY"} + pisv.APIKey = getEnv(APIKeyEnvVars) + } + + if len(pisv.Region) == 0 { + var regionEnvVars = []string{"IBMCLOUD_REGION", "IC_REGION"} + pisv.Region = getEnv(regionEnvVars) + } + + if len(pisv.Zone) == 0 { + var zoneEnvVars = []string{"IBMCLOUD_ZONE"} + pisv.Zone = getEnv(zoneEnvVars) + } + + return nil +} + +func getPISessionVarsFromUser(pisv *PISessionVars) error { + var err error + + if pisv == nil { + return errors.New("PISession Variable Object pointer cannot be nil") + } + + if len(pisv.ID) == 0 { + err = survey.Ask([]*survey.Question{ + { + Prompt: &survey.Input{ + Message: "IBM Cloud User ID", + Help: "The login for \nhttps://cloud.ibm.com/", + }, + }, + }, &pisv.ID) + if err != nil { + return errors.New("Error saving the IBM Cloud User ID") + } + + } + + if len(pisv.APIKey) == 0 { + err = survey.Ask([]*survey.Question{ + { + Prompt: &survey.Password{ + Message: "IBM Cloud API Key", + Help: "The API key installation.\nhttps://cloud.ibm.com/iam/apikeys", + }, + }, + }, &pisv.APIKey) + if err != nil { + return errors.New("Error saving the API Key") + } + + } + + if len(pisv.Region) == 0 { + pisv.Region, err = GetRegion() + if err != nil { + return err + } + + } + + if len(pisv.Zone) == 0 { + pisv.Zone, err = GetZone(pisv.Region) + if err != nil { + return err + } + } + + return nil +} + +func savePISessionVars(pisv *PISessionVars) error { + + authFilePath := defaultAuthFilePath + if f := os.Getenv("POWERVS_AUTH_FILEPATH"); len(f) > 0 { + authFilePath = f + } + + jsonVars, err := json.Marshal(*pisv) + if err != nil { + return err + } + + err = os.MkdirAll(filepath.Dir(authFilePath), 0700) + if err != nil { + return err + } + logrus.Debug("Saving variables to ", authFilePath) + return ioutil.WriteFile(authFilePath, jsonVars, 0600) +} + +func getEnv(envs []string) string { + for _, k := range envs { + if v := os.Getenv(k); v != "" { + return v + } + } + return "" +} diff --git a/pkg/asset/installconfig/powervs/validation.go b/pkg/asset/installconfig/powervs/validation.go new file mode 100644 index 00000000000..954b2e3b2e5 --- /dev/null +++ b/pkg/asset/installconfig/powervs/validation.go @@ -0,0 +1,8 @@ +package powervs + +// ValidateForProvisioning only validates credentials +// @TODO: Expand this to use the install config creds +func ValidateForProvisioning() error { + _, err := GetSession() + return err +} diff --git a/pkg/asset/machines/master.go b/pkg/asset/machines/master.go index 60211338c1d..f9221c0ed9a 100644 --- a/pkg/asset/machines/master.go +++ b/pkg/asset/machines/master.go @@ -21,6 +21,8 @@ import ( libvirtprovider "github.com/openshift/cluster-api-provider-libvirt/pkg/apis/libvirtproviderconfig/v1beta1" ovirtproviderapi "github.com/openshift/cluster-api-provider-ovirt/pkg/apis" ovirtprovider "github.com/openshift/cluster-api-provider-ovirt/pkg/apis/ovirtprovider/v1beta1" + powervsapi "github.com/openshift/cluster-api-provider-powervs/pkg/apis" + powervsprovider "github.com/openshift/cluster-api-provider-powervs/pkg/apis/powervsprovider/v1alpha1" vsphereapi "github.com/openshift/machine-api-operator/pkg/apis/vsphereprovider" vsphereprovider "github.com/openshift/machine-api-operator/pkg/apis/vsphereprovider/v1beta1" mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" @@ -48,6 +50,7 @@ import ( "github.com/openshift/installer/pkg/asset/machines/machineconfig" "github.com/openshift/installer/pkg/asset/machines/openstack" "github.com/openshift/installer/pkg/asset/machines/ovirt" + "github.com/openshift/installer/pkg/asset/machines/powervs" "github.com/openshift/installer/pkg/asset/machines/vsphere" "github.com/openshift/installer/pkg/asset/rhcos" rhcosutils "github.com/openshift/installer/pkg/rhcos" @@ -64,6 +67,7 @@ import ( nonetypes "github.com/openshift/installer/pkg/types/none" openstacktypes "github.com/openshift/installer/pkg/types/openstack" ovirttypes "github.com/openshift/installer/pkg/types/ovirt" + powervstypes "github.com/openshift/installer/pkg/types/powervs" vspheretypes "github.com/openshift/installer/pkg/types/vsphere" ) @@ -415,6 +419,19 @@ func (m *Master) Generate(dependencies asset.Parents) error { return errors.Wrap(err, "failed to create master machine objects") } vsphere.ConfigMasters(machines, clusterID.InfraID) + case powervstypes.Name: + mpool := defaultPowerVSMachinePoolPlatform() + mpool.Set(ic.Platform.PowerVS.DefaultMachinePlatform) + mpool.Set(pool.Platform.PowerVS) + // Only the service instance is guaranteed to exist and be passed via the install config + // The other two, we should standardize a name including the cluster id. At this point, all + // we have are names. + pool.Platform.PowerVS = &mpool + machines, err = powervs.Machines(clusterID.InfraID, ic, &pool, "master", "master-user-data") + if err != nil { + return errors.Wrap(err, "failed to create master machine objects") + } + powervs.ConfigMasters(machines, clusterID.InfraID) case nonetypes.Name: default: return fmt.Errorf("invalid Platform") @@ -545,6 +562,7 @@ func (m *Master) Machines() ([]machineapi.Machine, error) { openstackapi.AddToScheme(scheme) ovirtproviderapi.AddToScheme(scheme) vsphereapi.AddToScheme(scheme) + powervsapi.AddToScheme(scheme) decoder := serializer.NewCodecFactory(scheme).UniversalDecoder( alibabacloudprovider.SchemeGroupVersion, awsprovider.SchemeGroupVersion, @@ -556,6 +574,7 @@ func (m *Master) Machines() ([]machineapi.Machine, error) { openstackprovider.SchemeGroupVersion, vsphereprovider.SchemeGroupVersion, ovirtprovider.SchemeGroupVersion, + powervsprovider.GroupVersion, ) machines := []machineapi.Machine{} diff --git a/pkg/asset/machines/master_test.go b/pkg/asset/machines/master_test.go index ae1c5754cef..d09d8eac996 100644 --- a/pkg/asset/machines/master_test.go +++ b/pkg/asset/machines/master_test.go @@ -13,6 +13,7 @@ import ( "github.com/openshift/installer/pkg/asset/rhcos" "github.com/openshift/installer/pkg/types" awstypes "github.com/openshift/installer/pkg/types/aws" + powervstypes "github.com/openshift/installer/pkg/types/powervs" ) func TestMasterGenerateMachineConfigs(t *testing.T) { @@ -192,6 +193,57 @@ spec: } } +func TestPowerVSMaster(t *testing.T) { + t.Log("Testing powerVS platform master") + parents := asset.Parents{} + parents.Add( + &installconfig.ClusterID{ + UUID: "test-uuid", + InfraID: "test-infra-id", + }, + &installconfig.InstallConfig{ + Config: &types.InstallConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + SSHKey: "dummy ssh key", + BaseDomain: "test-domain", + Platform: types.Platform{ + PowerVS: &powervstypes.Platform{}, + }, + ControlPlane: &types.MachinePool{ + Hyperthreading: types.HyperthreadingEnabled, + Replicas: pointer.Int64Ptr(1), + Platform: types.MachinePoolPlatform{ + PowerVS: &powervstypes.MachinePool{ + ServiceInstance: "dummy-service-instance", + ImageID: "dummy-image-id", + NetworkIDs: []string{"dummy-network"}, + KeyPairName: "dummy-keypair", + }, + }, + }, + }, + }, + (*rhcos.Image)(pointer.StringPtr("test-image")), + &machine.Master{ + File: &asset.File{ + Filename: "master-ignition", + Data: []byte("test-ignition"), + }, + }, + ) + master := &Master{} + if err := master.Generate(parents); err != nil { + t.Fatalf("failed to generate master machines: %v", err) + } + + _, err := master.Machines() + if err != nil { + t.Fatalf("failed to get master machine set: %v", err) + } +} + func TestControlPlaneIsNotModified(t *testing.T) { parents := asset.Parents{} installConfig := installconfig.InstallConfig{ diff --git a/pkg/asset/machines/powervs/machines.go b/pkg/asset/machines/powervs/machines.go new file mode 100644 index 00000000000..e6c334bfdb8 --- /dev/null +++ b/pkg/asset/machines/powervs/machines.go @@ -0,0 +1,109 @@ +// Package powervs generates Machine objects for powerVS. +package powervs + +import ( + "fmt" + + corev1 "k8s.io/api/core/v1" + + machineapi "github.com/openshift/api/machine/v1beta1" + powervsprovider "github.com/openshift/cluster-api-provider-powervs/pkg/apis/powervsprovider/v1alpha1" + "github.com/openshift/installer/pkg/types" + "github.com/openshift/installer/pkg/types/powervs" + "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" +) + +// Machines returns a list of machines for a machinepool. +func Machines(clusterID string, config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]machineapi.Machine, error) { + if poolPlatform := pool.Platform.Name(); poolPlatform != powervs.Name { + return nil, fmt.Errorf("non-PowerVS machine-pool: %q", poolPlatform) + } + platform := config.Platform.PowerVS + mpool := pool.Platform.PowerVS + + var ( + image, network string + ) + + // Only the service instance is guaranteed to exist and be passed via the install config + // The other two, we should standardize a name including the cluster id. + + if platform.ClusterOSImage != "" { + image = platform.ClusterOSImage + } else { + image = fmt.Sprintf("rhcos-%s", clusterID) + } + if platform.PVSNetworkName != "" { + network = platform.PVSNetworkName + } else { + network = fmt.Sprintf("pvs-net-%s", clusterID) + } + + total := int64(1) + if pool.Replicas != nil { + total = *pool.Replicas + } + var machines []machineapi.Machine + for idx := int64(0); idx < total; idx++ { + provider, err := provider(clusterID, platform, mpool, userDataSecret, image, network) + if err != nil { + return nil, errors.Wrap(err, "failed to create provider") + } + machine := machineapi.Machine{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "machine.openshift.io/v1beta1", + Kind: "Machine", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "openshift-machine-api", + Name: fmt.Sprintf("%s-%s-%d", clusterID, pool.Name, idx), + Labels: map[string]string{ + "machine.openshift.io/cluster-api-cluster": clusterID, + "machine.openshift.io/cluster-api-machine-role": role, + "machine.openshift.io/cluster-api-machine-type": role, + }, + }, + Spec: machineapi.MachineSpec{ + ProviderSpec: machineapi.ProviderSpec{ + Value: &runtime.RawExtension{Object: provider}, + }, + }, + } + machines = append(machines, machine) + } + return machines, nil +} + +func provider(clusterID string, platform *powervs.Platform, mpool *powervs.MachinePool, userDataSecret string, image string, network string) (*powervsprovider.PowerVSMachineProviderConfig, error) { + + if clusterID == "" || platform == nil || mpool == nil || userDataSecret == "" || image == "" || network == "" { + return nil, fmt.Errorf("invalid value passed to provider") + } + + //Setting only the mandatory parameters + config := &powervsprovider.PowerVSMachineProviderConfig{ + TypeMeta: metav1.TypeMeta{ + Kind: "PowerVSMachineProviderConfig", + APIVersion: powervsprovider.GroupVersion.String(), + }, + ObjectMeta: metav1.ObjectMeta{}, + ServiceInstanceID: platform.ServiceInstanceID, + Image: powervsprovider.PowerVSResourceReference{Name: &image}, + UserDataSecret: &corev1.LocalObjectReference{Name: userDataSecret}, + CredentialsSecret: &corev1.LocalObjectReference{Name: "powervs-credentials"}, + SysType: mpool.SysType, + ProcType: mpool.ProcType, + Processors: fmt.Sprintf("%f", mpool.Processors), + Memory: fmt.Sprintf("%d", mpool.Memory), + Network: powervsprovider.PowerVSResourceReference{Name: &network}, + KeyPairName: fmt.Sprintf("%s-key", clusterID), + } + return config, nil +} + +// ConfigMasters sets the network and boot image IDs +func ConfigMasters(machines []machineapi.Machine, clusterID string) { + +} diff --git a/pkg/asset/machines/powervs/machinesets.go b/pkg/asset/machines/powervs/machinesets.go new file mode 100644 index 00000000000..832cd4f594e --- /dev/null +++ b/pkg/asset/machines/powervs/machinesets.go @@ -0,0 +1,95 @@ +// Package powervs generates Machine objects for IBM Power VS. +package powervs + +import ( + "fmt" + + "github.com/openshift/installer/pkg/types/powervs" + + machineapi "github.com/openshift/machine-api-operator/pkg/apis/machine/v1beta1" + "github.com/pkg/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + + "github.com/openshift/installer/pkg/types" +) + +// MachineSets returns a list of machinesets for a machinepool. +func MachineSets(clusterID string, config *types.InstallConfig, pool *types.MachinePool, role, userDataSecret string) ([]*machineapi.MachineSet, error) { + if configPlatform := config.Platform.Name(); configPlatform != powervs.Name { + return nil, fmt.Errorf("non-powerVS configuration: %q", configPlatform) + } + if poolPlatform := pool.Platform.Name(); poolPlatform != powervs.Name { + return nil, fmt.Errorf("non-powerVS machine-pool: %q", poolPlatform) + } + + var ( + image, network string + ) + + platform := config.Platform.PowerVS + mpool := pool.Platform.PowerVS + + if platform.ClusterOSImage != "" { + image = platform.ClusterOSImage + } else { + image = fmt.Sprintf("rhcos-%s", clusterID) + } + if platform.PVSNetworkName != "" { + network = platform.PVSNetworkName + } else { + network = fmt.Sprintf("pvs-net-%s", clusterID) + } + + total := int32(0) + if pool.Replicas != nil { + total = int32(*pool.Replicas) + } + var machinesets []*machineapi.MachineSet + provider, err := provider(clusterID, platform, mpool, userDataSecret, image, network) + if err != nil { + return nil, errors.Wrap(err, "failed to create provider") + } + + name := fmt.Sprintf("%s-%s", clusterID, pool.Name) + mset := &machineapi.MachineSet{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "machine.openshift.io/v1beta1", + Kind: "MachineSet", + }, + ObjectMeta: metav1.ObjectMeta{ + Namespace: "openshift-machine-api", + Name: name, + Labels: map[string]string{ + "machine.openshift.io/cluster-api-cluster": clusterID, + }, + }, + Spec: machineapi.MachineSetSpec{ + Replicas: &total, + Selector: metav1.LabelSelector{ + MatchLabels: map[string]string{ + "machine.openshift.io/cluster-api-machineset": name, + "machine.openshift.io/cluster-api-cluster": clusterID, + }, + }, + Template: machineapi.MachineTemplateSpec{ + ObjectMeta: machineapi.ObjectMeta{ + Labels: map[string]string{ + "machine.openshift.io/cluster-api-machineset": name, + "machine.openshift.io/cluster-api-cluster": clusterID, + "machine.openshift.io/cluster-api-machine-role": role, + "machine.openshift.io/cluster-api-machine-type": role, + }, + }, + Spec: machineapi.MachineSpec{ + ProviderSpec: machineapi.ProviderSpec{ + Value: &runtime.RawExtension{Object: provider}, + }, + }, + }, + }, + } + machinesets = append(machinesets, mset) + + return machinesets, nil +} diff --git a/pkg/asset/machines/worker.go b/pkg/asset/machines/worker.go index 01fc88f8794..182b8113818 100644 --- a/pkg/asset/machines/worker.go +++ b/pkg/asset/machines/worker.go @@ -21,6 +21,8 @@ import ( libvirtprovider "github.com/openshift/cluster-api-provider-libvirt/pkg/apis/libvirtproviderconfig/v1beta1" ovirtproviderapi "github.com/openshift/cluster-api-provider-ovirt/pkg/apis" ovirtprovider "github.com/openshift/cluster-api-provider-ovirt/pkg/apis/ovirtprovider/v1beta1" + powervsapi "github.com/openshift/cluster-api-provider-powervs/pkg/apis" + powervsprovider "github.com/openshift/cluster-api-provider-powervs/pkg/apis/powervsprovider/v1alpha1" vsphereproviderapi "github.com/openshift/machine-api-operator/pkg/apis/vsphereprovider" vsphereprovider "github.com/openshift/machine-api-operator/pkg/apis/vsphereprovider/v1beta1" mcfgv1 "github.com/openshift/machine-config-operator/pkg/apis/machineconfiguration.openshift.io/v1" @@ -48,6 +50,7 @@ import ( "github.com/openshift/installer/pkg/asset/machines/machineconfig" "github.com/openshift/installer/pkg/asset/machines/openstack" "github.com/openshift/installer/pkg/asset/machines/ovirt" + "github.com/openshift/installer/pkg/asset/machines/powervs" "github.com/openshift/installer/pkg/asset/machines/vsphere" "github.com/openshift/installer/pkg/asset/rhcos" rhcosutils "github.com/openshift/installer/pkg/rhcos" @@ -64,6 +67,7 @@ import ( nonetypes "github.com/openshift/installer/pkg/types/none" openstacktypes "github.com/openshift/installer/pkg/types/openstack" ovirttypes "github.com/openshift/installer/pkg/types/ovirt" + powervstypes "github.com/openshift/installer/pkg/types/powervs" vspheretypes "github.com/openshift/installer/pkg/types/vsphere" ) @@ -163,6 +167,15 @@ func defaultVSphereMachinePoolPlatform() vspheretypes.MachinePool { } } +func defaultPowerVSMachinePoolPlatform() powervstypes.MachinePool { + return powervstypes.MachinePool{ + Memory: 32, + Processors: 0.5, + ProcType: "shared", + SysType: "s922", + } +} + func awsDefaultWorkerMachineTypes(region string, arch types.Architecture) []string { classes := awsdefaults.InstanceClasses(region, arch) types := make([]string, len(classes)) @@ -462,6 +475,18 @@ func (w *Worker) Generate(dependencies asset.Parents) error { for _, set := range sets { machineSets = append(machineSets, set) } + case powervstypes.Name: + mpool := defaultPowerVSMachinePoolPlatform() + mpool.Set(ic.Platform.PowerVS.DefaultMachinePlatform) + mpool.Set(pool.Platform.PowerVS) + pool.Platform.PowerVS = &mpool + sets, err := powervs.MachineSets(clusterID.InfraID, ic, &pool, "worker", "worker-user-data") + if err != nil { + return errors.Wrap(err, "failed to create worker machine objects for powervs provider") + } + for _, set := range sets { + machineSets = append(machineSets, set) + } case nonetypes.Name: default: return fmt.Errorf("invalid Platform") @@ -548,6 +573,7 @@ func (w *Worker) MachineSets() ([]machineapi.MachineSet, error) { openstackapi.AddToScheme(scheme) ovirtproviderapi.AddToScheme(scheme) vsphereproviderapi.AddToScheme(scheme) + powervsapi.AddToScheme(scheme) decoder := serializer.NewCodecFactory(scheme).UniversalDecoder( alibabacloudprovider.SchemeGroupVersion, awsprovider.SchemeGroupVersion, @@ -559,6 +585,7 @@ func (w *Worker) MachineSets() ([]machineapi.MachineSet, error) { openstackprovider.SchemeGroupVersion, ovirtprovider.SchemeGroupVersion, vsphereprovider.SchemeGroupVersion, + powervsprovider.GroupVersion, ) machineSets := []machineapi.MachineSet{} diff --git a/pkg/asset/machines/worker_test.go b/pkg/asset/machines/worker_test.go index 07877089a49..ff96afda867 100644 --- a/pkg/asset/machines/worker_test.go +++ b/pkg/asset/machines/worker_test.go @@ -1,8 +1,11 @@ package machines import ( + powervstypes "github.com/openshift/installer/pkg/types/powervs" "testing" + powervstypes "github.com/openshift/installer/pkg/types/powervs" + "github.com/stretchr/testify/assert" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/pointer" @@ -249,3 +252,51 @@ func TestComputeIsNotModified(t *testing.T) { t.Fatalf("compute in the install config has been modified") } } + +func TestPowerVSWorker(t *testing.T) { + t.Log("Testing Power VS platform worker") + parents := asset.Parents{} + parents.Add( + &installconfig.ClusterID{ + UUID: "test-uuid", + InfraID: "test-infra-id", + }, + &installconfig.InstallConfig{ + Config: &types.InstallConfig{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-cluster", + }, + SSHKey: "dummy ssh key", + BaseDomain: "test-domain", + Platform: types.Platform{ + PowerVS: &powervstypes.Platform{}, + }, + Compute: []types.MachinePool{ + { + Hyperthreading: types.HyperthreadingEnabled, + Replicas: pointer.Int64Ptr(1), + Platform: types.MachinePoolPlatform{ + PowerVS: &powervstypes.MachinePool{ + ServiceInstance: "dummy-service-instance", + ImageName: "dummy-image-name", + NetworkIDs: []string{"dummy-network"}, + KeyPairName: "dummy-keypair", + }, + }, + }, + }, + }, + }, + (*rhcos.Image)(pointer.StringPtr("test-image")), + &machine.Worker{ + File: &asset.File{ + Filename: "master-ignition", + Data: []byte("test-ignition"), + }, + }, + ) + worker := &Worker{} + if err := worker.Generate(parents); err != nil { + t.Fatalf("failed to generate worker machines: %v", err) + } +} diff --git a/pkg/asset/manifests/cloudproviderconfig.go b/pkg/asset/manifests/cloudproviderconfig.go index b30f248f894..bf16fddf535 100644 --- a/pkg/asset/manifests/cloudproviderconfig.go +++ b/pkg/asset/manifests/cloudproviderconfig.go @@ -31,6 +31,7 @@ import ( nonetypes "github.com/openshift/installer/pkg/types/none" openstacktypes "github.com/openshift/installer/pkg/types/openstack" ovirttypes "github.com/openshift/installer/pkg/types/ovirt" + powervstypes "github.com/openshift/installer/pkg/types/powervs" vspheretypes "github.com/openshift/installer/pkg/types/vsphere" ) @@ -90,7 +91,7 @@ func (cpc *CloudProviderConfig) Generate(dependencies asset.Parents) error { } switch installConfig.Config.Platform.Name() { - case libvirttypes.Name, nonetypes.Name, baremetaltypes.Name, ovirttypes.Name: + case libvirttypes.Name, nonetypes.Name, baremetaltypes.Name, ovirttypes.Name, powervstypes.Name: return nil case awstypes.Name: // Store the additional trust bundle in the ca-bundle.pem key if the cluster is being installed on a C2S region. diff --git a/pkg/asset/manifests/dns.go b/pkg/asset/manifests/dns.go index 7f728491f9f..6bf2e6c60a3 100644 --- a/pkg/asset/manifests/dns.go +++ b/pkg/asset/manifests/dns.go @@ -28,6 +28,7 @@ import ( nonetypes "github.com/openshift/installer/pkg/types/none" openstacktypes "github.com/openshift/installer/pkg/types/openstack" ovirttypes "github.com/openshift/installer/pkg/types/ovirt" + powervstypes "github.com/openshift/installer/pkg/types/powervs" vspheretypes "github.com/openshift/installer/pkg/types/vsphere" ) @@ -158,7 +159,7 @@ func (d *DNS) Generate(dependencies asset.Parents) error { config.Spec.PrivateZone = &configv1.DNSZone{ ID: zoneID, } - case libvirttypes.Name, openstacktypes.Name, baremetaltypes.Name, nonetypes.Name, vspheretypes.Name, ovirttypes.Name: + case libvirttypes.Name, openstacktypes.Name, baremetaltypes.Name, nonetypes.Name, vspheretypes.Name, ovirttypes.Name, powervstypes.Name: default: return errors.New("invalid Platform") } diff --git a/pkg/asset/manifests/infrastructure.go b/pkg/asset/manifests/infrastructure.go index 835d472a8e5..5004b66147e 100644 --- a/pkg/asset/manifests/infrastructure.go +++ b/pkg/asset/manifests/infrastructure.go @@ -23,6 +23,7 @@ import ( "github.com/openshift/installer/pkg/types/none" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -211,6 +212,17 @@ func (i *Infrastructure) Generate(dependencies asset.Parents) error { APIServerInternalIP: installConfig.Config.Ovirt.APIVIP, IngressIP: installConfig.Config.Ovirt.IngressVIP, } + case powervs.Name: + config.Spec.PlatformSpec.Type = configv1.PowerVSPlatformType + cisInstanceCRN, err := installConfig.PowerVS.CISInstanceCRN(ctx) + if err != nil { + return err + } + config.Status.PlatformStatus.PowerVS = &configv1.PowerVSPlatformStatus{ + Region: installConfig.Config.Platform.PowerVS.Region, + Zone: installConfig.Config.Platform.PowerVS.Zone, + CISInstanceCRN: cisInstanceCRN + } default: config.Spec.PlatformSpec.Type = configv1.NonePlatformType } diff --git a/pkg/asset/quota/quota.go b/pkg/asset/quota/quota.go index 403386ff225..93d34464540 100644 --- a/pkg/asset/quota/quota.go +++ b/pkg/asset/quota/quota.go @@ -31,6 +31,7 @@ import ( "github.com/openshift/installer/pkg/types/none" typesopenstack "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -141,7 +142,7 @@ func (a *PlatformQuotaCheck) Generate(dependencies asset.Parents) error { return summarizeFailingReport(reports) } summarizeReport(reports) - case alibabacloud.Name, azure.Name, baremetal.Name, ibmcloud.Name, libvirt.Name, none.Name, ovirt.Name, vsphere.Name: + case alibabacloud.Name, azure.Name, baremetal.Name, ibmcloud.Name, libvirt.Name, none.Name, ovirt.Name, powervs.Name, vsphere.Name: // no special provisioning requirements to check default: err = fmt.Errorf("unknown platform type %q", platform) diff --git a/pkg/asset/rhcos/image.go b/pkg/asset/rhcos/image.go index aacfa683c14..96aa9843947 100644 --- a/pkg/asset/rhcos/image.go +++ b/pkg/asset/rhcos/image.go @@ -25,6 +25,7 @@ import ( "github.com/openshift/installer/pkg/types/none" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -164,6 +165,16 @@ func osImage(config *types.InstallConfig) (string, error) { return "", err } return osimage, nil + case powervs.Name: + // Check for image URL override + if config.Platform.PowerVS.ClusterOSImage != "" { + return config.Platform.PowerVS.ClusterOSImage, nil + } + + if a, ok := streamArch.Artifacts["powervs"]; ok { + return rhcos.FindArtifactURL(a) + } + return "", fmt.Errorf("%s: No Power VS build found", st.FormatPrefix(archName)) case none.Name: return "", nil default: diff --git a/pkg/rhcos/powervs_regions.go b/pkg/rhcos/powervs_regions.go new file mode 100644 index 00000000000..66678b1dff4 --- /dev/null +++ b/pkg/rhcos/powervs_regions.go @@ -0,0 +1,86 @@ +package rhcos + +// Since there is no API to query these, we have to hard-code them here. + +// PowerVSRegion describes resources associated with a region in Power VS. +// We're using a few items from the IBM Cloud VPC offering. The region names +// for VPC are different so another function of this is to correlate those. +type PowerVSRegion struct { + Name string + Description string + VPCRegion string + Zones []string +} + +// PowerVSRegions holds the regions for IBM Power VS, and descriptions used during the survey +var PowerVSRegions = map[string]PowerVSRegion{ + "dal": { + Name: "dal", + Description: "Dallas, USA", + VPCRegion: "us-south", + Zones: []string{"dal12"}, + }, + "eu-de": { + Name: "eu-de", + Description: "Frankfurt, Germany", + VPCRegion: "eu-de", + Zones: []string{ + "eu-de-1", + "eu-de-2", + }, + }, + "lon": { + Name: "lon", + Description: "London, UK.", + VPCRegion: "eu-gb", + Zones: []string{ + "lon04", + "lon06", + }, + }, + "osa": { + Name: "osa", + Description: "Osaka, Japan", + VPCRegion: "jp-osa", + Zones: []string{"osa21"}, + }, + "syd": { + Name: "syd", + Description: "Sydney, Australia", + VPCRegion: "au-syd", + Zones: []string{"syd04"}, + }, + "sao": { + Name: "sao", + Description: "São Paulo, Brazil", + VPCRegion: "br-sao", + Zones: []string{"sao01"}, + }, + "tor": { + Name: "tor", + Description: "Toronto, Canada", + VPCRegion: "ca-tor", + Zones: []string{"tor01"}, + }, + "tok": { + Name: "tok", + Description: "Tokyo, Japan", + VPCRegion: "jp-tok", + Zones: []string{"tok04"}, + }, + "us-east": { + Name: "us-east", + Description: "Washington DC, USA", + VPCRegion: "us-east", + Zones: []string{"us-east"}, + }, +} + +// PowerVSZones retrieves a slice of all zones in Power VS +func PowerVSZones() []string { + var zones []string + for _, r := range PowerVSRegions { + zones = append(zones, r.Zones...) + } + return zones +} diff --git a/pkg/terraform/exec/plugins/ibms3presign.go b/pkg/terraform/exec/plugins/ibms3presign.go new file mode 100644 index 00000000000..21a0f742caf --- /dev/null +++ b/pkg/terraform/exec/plugins/ibms3presign.go @@ -0,0 +1,15 @@ +package plugins + +import ( + "github.com/hashicorp/terraform-plugin-sdk/plugin" + "github.com/openshift/installer/pkg/terraform/exec/plugins/ibms3presign" +) + +func init() { + ibmS3PresignProvider := func() { + plugin.Serve(&plugin.ServeOpts{ + ProviderFunc: ibms3presign.Provider, + }) + } + KnownPlugins["terraform-provider-ibms3presign"] = ibmS3PresignProvider +} diff --git a/pkg/terraform/exec/plugins/ibms3presign/provider.go b/pkg/terraform/exec/plugins/ibms3presign/provider.go new file mode 100644 index 00000000000..35a8beef52a --- /dev/null +++ b/pkg/terraform/exec/plugins/ibms3presign/provider.go @@ -0,0 +1,15 @@ +package ibms3presign + +import ( + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" + "github.com/hashicorp/terraform-plugin-sdk/terraform" +) + +// Provider returns a terraform.ResourceProvider. +func Provider() terraform.ResourceProvider { + return &schema.Provider{ + ResourcesMap: map[string]*schema.Resource{ + "ibms3presign": resourcePresign(), + }, + } +} diff --git a/pkg/terraform/exec/plugins/ibms3presign/resource_presign.go b/pkg/terraform/exec/plugins/ibms3presign/resource_presign.go new file mode 100644 index 00000000000..f780866ce10 --- /dev/null +++ b/pkg/terraform/exec/plugins/ibms3presign/resource_presign.go @@ -0,0 +1,154 @@ +package ibms3presign + +import ( + "fmt" + "time" + + "github.com/aws/aws-sdk-go/aws" + "github.com/aws/aws-sdk-go/aws/credentials" + "github.com/aws/aws-sdk-go/aws/session" + "github.com/aws/aws-sdk-go/service/s3" + "github.com/hashicorp/terraform-plugin-sdk/helper/schema" +) + +var storageClasses = []string{ + "standard", "vault", "cold", "flex", "smart", +} + +var endpointTypes = []string{ + "public", "private", "direct", +} + +func resourcePresign() *schema.Resource { + return &schema.Resource{ + Create: resourceIBMCOSBucketObjectPresignCreate, + Read: resourceIBMCOSBucketObjectPresignCreate, + Delete: resourceIBMCOSBucketObjectPresignDelete, + Importer: &schema.ResourceImporter{ + State: schema.ImportStatePassthrough, + }, + Schema: map[string]*schema.Schema{ + "access_key_id": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Sensitive: true, + Description: "access_key_id", + }, + "secret_access_key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Sensitive: true, + Description: "secret_access_key", + }, + "bucket_name": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "COS Bucket name", + }, + "key": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "COS object key", + }, + "region_location": { + Type: schema.TypeString, + Required: true, + ForceNew: true, + Description: "Region Location info.", + }, + "storage_class": { + Type: schema.TypeString, + Required: true, + ValidateFunc: validateAllowedStringValue(storageClasses), + ForceNew: true, + Description: "Storage class info", + }, + "endpoint_type": { + Type: schema.TypeString, + Optional: true, + ForceNew: true, + ValidateFunc: validateAllowedStringValue(endpointTypes), + Description: "public, private or direct", + Default: "public", + }, + "presigned_url": { + Type: schema.TypeString, + Computed: true, + Optional: true, + Sensitive: true, + Description: "Presigned URL", + }, + "expire": { + Type: schema.TypeInt, + Optional: true, + ForceNew: true, + Description: "Set expire time for URL in minutes", + Default: 60, + }, + }, + } +} + +func validateAllowedStringValue(validValues []string) schema.SchemaValidateFunc { + return func(v interface{}, k string) (ws []string, errors []error) { + input := v.(string) + existed := false + for _, s := range validValues { + if s == input { + existed = true + break + } + } + if !existed { + errors = append(errors, fmt.Errorf( + "%q must contain a value from %#v, got %q", + k, validValues, input)) + } + return + + } +} + +// resourceIBMCOSBucketObjectPresignDelete is just a placeholder NOP function to satisfy the schema resource +func resourceIBMCOSBucketObjectPresignDelete(d *schema.ResourceData, m interface{}) error { + return nil +} + +func resourceIBMCOSBucketObjectPresignCreate(d *schema.ResourceData, m interface{}) error { + storageClass := d.Get("storage_class").(string) + bucketName := d.Get("bucket_name").(string) + object := d.Get("key").(string) + regionLocation := d.Get("region_location").(string) + endpointType := d.Get("endpoint_type").(string) + accessKey := d.Get("access_key_id").(string) + secretKey := d.Get("secret_access_key").(string) + expire := d.Get("expire").(int) + var svcEndpoint string + if endpointType != "public" { + regionLocation = fmt.Sprintf("%s.%s", endpointType, regionLocation) + } + svcEndpoint = fmt.Sprintf("https://s3.%s.cloud-object-storage.appdomain.cloud", regionLocation) + region := fmt.Sprintf("%s-%s", regionLocation, storageClass) + conf := aws.NewConfig(). + WithRegion(region). + WithEndpoint(svcEndpoint). + WithS3ForcePathStyle(true). + WithCredentials(credentials.NewStaticCredentials(accessKey, secretKey, "")) + sess := session.Must(session.NewSession()) // Creating a new session + client := s3.New(sess, conf) + req, _ := client.GetObjectRequest(&s3.GetObjectInput{ + Bucket: aws.String(bucketName), + Key: aws.String(object), + }) + presignedURL, err := req.Presign(time.Duration(expire) * time.Minute) + if err != nil { + return err + } + d.Set("presigned_url", presignedURL) + d.SetId(fmt.Sprintf("%s/%s", bucketName, object)) + return nil +} diff --git a/pkg/tfvars/powervs/powervs.go b/pkg/tfvars/powervs/powervs.go new file mode 100644 index 00000000000..66cdbe83db7 --- /dev/null +++ b/pkg/tfvars/powervs/powervs.go @@ -0,0 +1,92 @@ +// Package powervs contains Power Virtual Servers-specific Terraform-variable logic. +package powervs + +import ( + "encoding/json" + "fmt" + "math/rand" + "time" + + "github.com/openshift/cluster-api-provider-powervs/pkg/apis/powervsprovider/v1alpha1" + "github.com/openshift/installer/pkg/rhcos" +) + +type config struct { + ServiceInstanceID string `json:"powervs_cloud_instance_id"` + APIKey string `json:"powervs_api_key"` + SSHKey string `json:"powervs_ssh_key"` + PowerVSRegion string `json:"powervs_region"` + PowerVSZone string `json:"powervs_zone"` + VPCRegion string `json:"powervs_vpc_region"` + VPCZone string `json:"powervs_vpc_zone"` + PowerVSResourceGroup string `json:"powervs_resource_group"` + CISInstanceCRN string `json:"powervs_cis_crn"` + ImageName string `json:"powervs_image_name"` + ImageID string `json:"powervs_image_id"` + NetworkName string `json:"powervs_network_name"` + VPCName string `json:"powervs_vpc_name"` + VPCSubnetName string `json:"powervs_vpc_subnet_name"` + BootstrapMemory string `json:"powervs_bootstrap_memory"` + BootstrapProcessors string `json:"powervs_bootstrap_processors"` + MasterMemory string `json:"powervs_master_memory"` + MasterProcessors string `json:"powervs_master_processors"` + ProcType string `json:"powervs_proc_type"` + SysType string `json:"powervs_sys_type"` +} + +// TFVarsSources contains the parameters to be converted into Terraform variables +type TFVarsSources struct { + MasterConfigs []*v1alpha1.PowerVSMachineProviderConfig + APIKey string + SSHKey string + Region string + Zone string + NetworkName string + ImageName string + PowerVSResourceGroup string + VPCZone string + CISInstanceCRN string + VPCName string + VPCSubnetName string +} + +// TFVars generates Power VS-specific Terraform variables launching the cluster. +func TFVars(sources TFVarsSources) ([]byte, error) { + masterConfig := sources.MasterConfigs[0] + // TODO(mjturek): Allow user to specify vpcRegion in install config like we're doing for vpcZone + vpcRegion := rhcos.PowerVSRegions[sources.Region].VPCRegion + + vpcZone := sources.VPCZone + if vpcZone == "" { + // Randomly select a zone in the VPC region. + // @TODO: Align this with a region later. + rand.Seed(time.Now().UnixNano()) + // All supported Regions are MZRs and have Zones named "region-[1-3]" + vpcZone = fmt.Sprintf("%s-%d", vpcRegion, rand.Intn(3)) + } + + //@TODO: Add resource group to platform + cfg := &config{ + ServiceInstanceID: masterConfig.ServiceInstanceID, + APIKey: sources.APIKey, + SSHKey: sources.SSHKey, + PowerVSRegion: sources.Region, + PowerVSZone: sources.Zone, + VPCRegion: vpcRegion, + VPCZone: vpcZone, + PowerVSResourceGroup: sources.PowerVSResourceGroup, + CISInstanceCRN: sources.CISInstanceCRN, + ImageName: *masterConfig.Image.Name, + NetworkName: *masterConfig.Network.Name, + VPCName: sources.VPCName, + VPCSubnetName: sources.VPCSubnetName, + BootstrapMemory: masterConfig.Memory, + BootstrapProcessors: masterConfig.Processors, + MasterMemory: masterConfig.Memory, + MasterProcessors: masterConfig.Processors, + ProcType: masterConfig.ProcType, + SysType: masterConfig.SysType, + } + + return json.MarshalIndent(cfg, "", " ") +} diff --git a/pkg/types/clustermetadata.go b/pkg/types/clustermetadata.go index e0ab9fa696e..5c6dcc2d03f 100644 --- a/pkg/types/clustermetadata.go +++ b/pkg/types/clustermetadata.go @@ -10,6 +10,7 @@ import ( "github.com/openshift/installer/pkg/types/libvirt" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -36,6 +37,7 @@ type ClusterPlatformMetadata struct { IBMCloud *ibmcloud.Metadata `json:"ibmcloud,omitempty"` BareMetal *baremetal.Metadata `json:"baremetal,omitempty"` Ovirt *ovirt.Metadata `json:"ovirt,omitempty"` + PowerVS *powervs.Metadata `json:"powervs,omitempty"` VSphere *vsphere.Metadata `json:"vsphere,omitempty"` } @@ -73,6 +75,9 @@ func (cpm *ClusterPlatformMetadata) Platform() string { if cpm.Ovirt != nil { return ovirt.Name } + if cpm.PowerVS != nil { + return powervs.Name + } if cpm.VSphere != nil { return vsphere.Name } diff --git a/pkg/types/defaults/installconfig.go b/pkg/types/defaults/installconfig.go index ace0565aa01..720b82b98d2 100644 --- a/pkg/types/defaults/installconfig.go +++ b/pkg/types/defaults/installconfig.go @@ -14,6 +14,7 @@ import ( nonedefaults "github.com/openshift/installer/pkg/types/none/defaults" openstackdefaults "github.com/openshift/installer/pkg/types/openstack/defaults" ovirtdefaults "github.com/openshift/installer/pkg/types/ovirt/defaults" + powervsdefaults "github.com/openshift/installer/pkg/types/powervs/defaults" vspheredefaults "github.com/openshift/installer/pkg/types/vsphere/defaults" ) @@ -105,6 +106,8 @@ func SetInstallConfigDefaults(c *types.InstallConfig) { for i := range c.Compute { ovirtdefaults.SetComputeDefaults(c.Platform.Ovirt, &c.Compute[i]) } + case c.Platform.PowerVS != nil: + powervsdefaults.SetPlatformDefaults(c.Platform.PowerVS) case c.Platform.None != nil: nonedefaults.SetPlatformDefaults(c.Platform.None) } diff --git a/pkg/types/defaults/machinepools.go b/pkg/types/defaults/machinepools.go index 7896ae451d3..e23882265f1 100644 --- a/pkg/types/defaults/machinepools.go +++ b/pkg/types/defaults/machinepools.go @@ -3,6 +3,7 @@ package defaults import ( "github.com/openshift/installer/pkg/types" "github.com/openshift/installer/pkg/types/libvirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/version" ) @@ -11,6 +12,8 @@ func SetMachinePoolDefaults(p *types.MachinePool, platform string) { defaultReplicaCount := int64(3) if platform == libvirt.Name { defaultReplicaCount = 1 + } else if platform == powervs.Name { + p.Architecture = "ppc64le" } if p.Replicas == nil { p.Replicas = &defaultReplicaCount diff --git a/pkg/types/installconfig.go b/pkg/types/installconfig.go index fc1c65909c8..48a92f8808e 100644 --- a/pkg/types/installconfig.go +++ b/pkg/types/installconfig.go @@ -15,6 +15,7 @@ import ( "github.com/openshift/installer/pkg/types/none" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" ) @@ -38,6 +39,7 @@ var ( gcp.Name, openstack.Name, ovirt.Name, + powervs.Name, vsphere.Name, } // HiddenPlatformNames is a slice with all the @@ -47,6 +49,7 @@ var ( baremetal.Name, ibmcloud.Name, none.Name, + powervs.Name, } // OKD is a setting to enable community-only modifications @@ -205,6 +208,10 @@ type Platform struct { // +optional OpenStack *openstack.Platform `json:"openstack,omitempty"` + // PowerVS is the configuration used when installing on Power VS. + // +optional + PowerVS *powervs.Platform `json:"powervs,omitempty"` + // VSphere is the configuration used when installing on vSphere. // +optional VSphere *vsphere.Platform `json:"vsphere,omitempty"` @@ -243,6 +250,8 @@ func (p *Platform) Name() string { return vsphere.Name case p.Ovirt != nil: return ovirt.Name + case p.PowerVS != nil: + return powervs.Name default: return "" } diff --git a/pkg/types/machinepools.go b/pkg/types/machinepools.go index e37ee8eba4f..f3ea6602293 100644 --- a/pkg/types/machinepools.go +++ b/pkg/types/machinepools.go @@ -10,6 +10,7 @@ import ( "github.com/openshift/installer/pkg/types/libvirt" "github.com/openshift/installer/pkg/types/openstack" "github.com/openshift/installer/pkg/types/ovirt" + "github.com/openshift/installer/pkg/types/powervs" "github.com/openshift/installer/pkg/types/vsphere" ) @@ -100,6 +101,9 @@ type MachinePoolPlatform struct { // Ovirt is the configuration used when installing on oVirt. Ovirt *ovirt.MachinePool `json:"ovirt,omitempty"` + + // PowerVS is the configuration used when installing on IBM Power VS. + PowerVS *powervs.MachinePool `json:"powervs,omitempty"` } // Name returns a string representation of the platform (e.g. "aws" if @@ -129,6 +133,8 @@ func (p *MachinePoolPlatform) Name() string { return vsphere.Name case p.Ovirt != nil: return ovirt.Name + case p.PowerVS != nil: + return powervs.Name default: return "" } diff --git a/pkg/types/powervs/OWNERS b/pkg/types/powervs/OWNERS new file mode 100644 index 00000000000..0d9360c02b3 --- /dev/null +++ b/pkg/types/powervs/OWNERS @@ -0,0 +1,7 @@ +# See the OWNERS docs: https://git.k8s.io/community/contributors/guide/owners.md +# This file just uses aliases defined in OWNERS_ALIASES. + +approvers: + - multiarch-approvers +reviewers: + - multiarch-reviewers diff --git a/pkg/types/powervs/defaults/platform.go b/pkg/types/powervs/defaults/platform.go new file mode 100644 index 00000000000..f4efb5c615e --- /dev/null +++ b/pkg/types/powervs/defaults/platform.go @@ -0,0 +1,34 @@ +package defaults + +import ( + "github.com/openshift/installer/pkg/types/powervs" +) + +var ( + defaultMachineClass = map[string][]string{ + // Example region default machine class override: + // "ap-east-1": {"m5", "m4"}, + } +) + +// SetPlatformDefaults sets the defaults for the platform. +func SetPlatformDefaults(p *powervs.Platform) { +} + +// InstanceClass returns the instance "class" we should use for a given +// region. Default is m5 unless a region override is defined in defaultMachineClass. +func InstanceClass(region string) string { + if classes, ok := defaultMachineClass[region]; ok { + return classes[0] + } + return "m5" +} + +// InstanceClasses returns a list of instance "class", in decreasing priority order, which we should use for a given +// region. Default is m5 then m4 unless a region override is defined in defaultMachineClass. +func InstanceClasses(region string) []string { + if classes, ok := defaultMachineClass[region]; ok { + return classes + } + return []string{"m5", "m4"} +} diff --git a/pkg/types/powervs/doc.go b/pkg/types/powervs/doc.go new file mode 100644 index 00000000000..7f0864590c0 --- /dev/null +++ b/pkg/types/powervs/doc.go @@ -0,0 +1,6 @@ +// Package powervs contains Power VS-specific structures for installer +// configuration and management. +package powervs + +// Name is name for the Power VS platform. +const Name string = "powervs" diff --git a/pkg/types/powervs/machinepools.go b/pkg/types/powervs/machinepools.go new file mode 100644 index 00000000000..3854d573ce2 --- /dev/null +++ b/pkg/types/powervs/machinepools.go @@ -0,0 +1,70 @@ +package powervs + +// MachinePool stores the configuration for a machine pool installed on IBM Power VS. +type MachinePool struct { + // ServiceInstance is Service Instance to install into. + // + ServiceInstance string `json:"serviceinstance"` + + // Name is the name of the instance + // + Name string `json:"name"` + + // KeyPairName is the name of an SSH key pair stored in the Power VS + // Service Instance + KeyPairName string `json:"keypairname"` + + // VolumeIDs is the list of volumes attached to the instance. + // + VolumeIDs []string `json:"volumeIDs"` + + // Memory defines the memory in GB for the instance. + // + Memory int `json:"memory"` + + // Processors defines the processing units for the instance. + // @TODO: + Processors float32 `json:"processors"` + + // ProcType defines the processor sharing model for the instance. + // + // +optional + ProcType string `json:"procType"` + + // ImageID defines the ImageID for the instance. + // + // +optional (does this mean user-optional, or completely?) + ImageID string `json:"imageID"` + + // NetworkIDs defines the network IDs of the instance. + // + // +optional + NetworkIDs []string `json:"networkIDs"` + + // SysType defines the system type for instance. + // + // +optional + SysType string `json:sysType"` +} + +// Set stores values from required into a +func (a *MachinePool) Set(required *MachinePool) { + if required == nil || a == nil { + return + } + if required.ImageID != "" { + a.ImageID = required.ImageID + } + if required.ServiceInstance != "" { + a.ServiceInstance = required.ServiceInstance + } + if len(required.NetworkIDs) > 0 { + a.NetworkIDs = required.NetworkIDs + } + if required.ServiceInstance != "" { + a.ServiceInstance = required.ServiceInstance + } + if required.KeyPairName != "" { + a.KeyPairName = required.KeyPairName + } +} diff --git a/pkg/types/powervs/metadata.go b/pkg/types/powervs/metadata.go new file mode 100644 index 00000000000..ef67610ab97 --- /dev/null +++ b/pkg/types/powervs/metadata.go @@ -0,0 +1,8 @@ +package powervs + +// Metadata contains Power VS metadata (e.g. for uninstalling the cluster). +type Metadata struct { + CISInstanceCRN string `json:"cisInstanceCRN"` + Region string `json:"region"` + Zone string `json:"zone"` +} diff --git a/pkg/types/powervs/platform.go b/pkg/types/powervs/platform.go new file mode 100644 index 00000000000..163f78e7bf5 --- /dev/null +++ b/pkg/types/powervs/platform.go @@ -0,0 +1,89 @@ +package powervs + +// Platform stores all the global configuration that all machinesets +// use. +// Note: The subsequent mentions of future-TF support refer to work that is +// undergoing and should be available to test well in time for 4.10 feature- +// freeze. We do not plan to GA with these as required inputs. +type Platform struct { + + // ServiceInstanceID is the ID of the Power IAAS instance created from the IBM Cloud Catalog + ServiceInstanceID string `json:"serviceInstance"` + + // PowerVSResourceGroup is the resource group for creating Power VS resources. + PowerVSResourceGroup string `json:"powervsResourceGroup"` + + // Region specifies the IBM Cloud region where the cluster will be created. + Region string `json:"region"` + + // Zone specifies the IBM Cloud colo region where the cluster will be created. + // Required for multi-zone regions. + Zone string `json:"zone"` + + // Zone in the region used to create VPC resources. Leave unset + // to allow installer to randomly select a zone. + // + // +optional + VPCZone string `json:"vpcRegion,omitempty"` + + // UserID is the login for the user's IBM Cloud account. + UserID string `json:"userID"` + + // APIKey is the API key for the user's IBM Cloud account. + APIKey string `json:"APIKey,omitempty"` + + // SSHKeyName is the name of an SSH key stored in the Service Instance. + SSHKeyName string `json:"SSHKeyName,omitempty"` + + // VPC is a VPC inside IBM Cloud. Needed in order to create VPC Load Balancers. + // + // +optional + VPC string `json:"vpc,omitempty"` + + // Subnets specifies existing subnets (by ID) where cluster + // resources will be created. Leave unset to have the installer + // create subnets in a new VPC on your behalf. + // + // @TODO: make this +optional when we have TF support + Subnets []string `json:"subnets,omitempty"` + + // PVSNetworkName specifies an existing network within the Power VS Service Instance. + // @TODO: make this +optional when we have TF support + PVSNetworkName string `json:pvsNetworkName,omitempty"` + + // PVSNetworkID is the associated ID for the PVSNetworkName. This is currently required + // For the machine config. + // @TODO: Remove when machine config resolves the ID from name. + // Leave unset to have the installer create the network. + // + // @TODO: make this +optional when we have TF support + PVSNetworkID string `json:"pvsNetworkID,omitempty"` + + // UserTags additional keys and values that the installer will add + // as tags to all resources that it creates. Resources created by the + // cluster itself may not include these tags. + // +optional + UserTags map[string]string `json:"userTags,omitempty"` + + // ImageName is equivalent to BootStrap/ClusterOSImage. + // Until the machine provider config in cluster-api-provider-powervs + // takes an ID instead of a name, we're using this for TF Creation, + // and the other two for machine-config. + // + // @TODO: Remove when provider resolves ID from name + // @TODO: make this +optional when we have TF support + ImageName string `json:"imageName,omitempty"` + + // ClusterOSImage is a URL to override the default OS image + // for the bootstrap node. The URL must contain a sha256 hash of the image + // e.g https://mirror.example.com/images/image.ova.gz?sha256=a07bd... + // + // +optional + ClusterOSImage string `json:"clusterOSImage,omitempty"` + + // DefaultMachinePlatform is the default configuration used when + // installing on Power VS for machine pools which do not define their own + // platform configuration. + // +optional + DefaultMachinePlatform *MachinePool `json:"defaultMachinePlatform,omitempty"` +} diff --git a/pkg/types/powervs/validation/machinepool.go b/pkg/types/powervs/validation/machinepool.go new file mode 100644 index 00000000000..b214e4a0bae --- /dev/null +++ b/pkg/types/powervs/validation/machinepool.go @@ -0,0 +1,27 @@ +package validation + +import ( + "k8s.io/apimachinery/pkg/util/validation/field" + + "github.com/openshift/installer/pkg/types/powervs" +) + +// ValidateMachinePool checks that the specified machine pool is valid. +func ValidateMachinePool(p *powervs.MachinePool, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + /* + for i, zone := range p.Zones { + if !strings.HasPrefix(zone, platform.Region) { + allErrs = append(allErrs, field.Invalid(fldPath.Child("zones").Index(i), zone, fmt.Sprintf("Zone not in configured region (%s)", platform.Region))) + } + } + + if p.OSDisk.DiskType != "" { + diskTypes := sets.NewString("pd-standard", "pd-ssd") + if !diskTypes.Has(p.OSDisk.DiskType) { + allErrs = append(allErrs, field.NotSupported(fldPath.Child("diskType"), p.OSDisk.DiskType, diskTypes.List())) + } + }*/ + + return allErrs +} diff --git a/pkg/types/powervs/validation/platform.go b/pkg/types/powervs/validation/platform.go new file mode 100644 index 00000000000..ec3855f144c --- /dev/null +++ b/pkg/types/powervs/validation/platform.go @@ -0,0 +1,23 @@ +package validation + +import ( + "k8s.io/apimachinery/pkg/util/validation/field" + + "github.com/openshift/installer/pkg/types/powervs" +) + +// ValidatePlatform checks that the specified platform is valid. +func ValidatePlatform(p *powervs.Platform, fldPath *field.Path) field.ErrorList { + allErrs := field.ErrorList{} + + if p.Region == "" { + allErrs = append(allErrs, field.Required(fldPath.Child("region"), "region must be specified")) + } + + /*if p.DefaultMachinePlatform != nil { + allErrs = append(allErrs, ValidateMachinePool(p, p.DefaultMachinePlatform, fldPath.Child("defaultMachinePlatform"))...) + }*/ + return allErrs +} + +//var schemeRE = regexp.MustCompile("^([^:]+)://") diff --git a/pkg/types/powervs/validation/platform_test.go b/pkg/types/powervs/validation/platform_test.go new file mode 100644 index 00000000000..187111ad81e --- /dev/null +++ b/pkg/types/powervs/validation/platform_test.go @@ -0,0 +1,176 @@ +package validation + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "k8s.io/apimachinery/pkg/util/validation/field" + + "github.com/openshift/installer/pkg/types/powervs" +) + +func TestValidatePlatform(t *testing.T) { + cases := []struct { + name string + platform *aws.Platform + expected string + }{ + { + name: "minimal", + platform: &aws.Platform{ + Region: "us-east-1", + }, + }, + { + name: "invalid region", + platform: &aws.Platform{ + Region: "", + }, + expected: `^test-path\.region: Required value: region must be specified$`, + }, + { + name: "hosted zone with subnets", + platform: &aws.Platform{ + Region: "us-east-1", + Subnets: []string{"test-subnet"}, + HostedZone: "test-hosted-zone", + }, + }, + { + name: "hosted zone without subnets", + platform: &aws.Platform{ + Region: "us-east-1", + HostedZone: "test-hosted-zone", + }, + expected: `^test-path\.hostedZone: Invalid value: "test-hosted-zone": may not use an existing hosted zone when not using existing subnets$`, + }, + { + name: "invalid url for service endpoint", + platform: &aws.Platform{ + Region: "us-east-1", + ServiceEndpoints: []aws.ServiceEndpoint{{ + Name: "ec2", + URL: "/path/some", + }}, + }, + expected: `^test-path\.serviceEndpoints\[0\]\.url: Invalid value: "(.*)": host cannot be empty, empty host provided$`, + }, + { + name: "invalid url for service endpoint", + platform: &aws.Platform{ + Region: "us-east-1", + ServiceEndpoints: []aws.ServiceEndpoint{{ + Name: "ec2", + URL: "https://test-ec2.random.local/path/some", + }}, + }, + expected: `^test-path\.serviceEndpoints\[0\]\.url: Invalid value: "(.*)": no path or request parameters must be provided, "/path/some" was provided$`, + }, + { + name: "invalid url for service endpoint", + platform: &aws.Platform{ + Region: "us-east-1", + ServiceEndpoints: []aws.ServiceEndpoint{{ + Name: "ec2", + URL: "https://test-ec2.random.local?foo=some", + }}, + }, + expected: `^test-path\.serviceEndpoints\[0\]\.url: Invalid value: "(.*)": no path or request parameters must be provided, "/\?foo=some" was provided$`, + }, + { + name: "valid url for service endpoint", + platform: &aws.Platform{ + Region: "us-east-1", + ServiceEndpoints: []aws.ServiceEndpoint{{ + Name: "ec2", + URL: "test-ec2.random.local", + }}, + }, + }, + { + name: "valid url for service endpoint", + platform: &aws.Platform{ + Region: "us-east-1", + ServiceEndpoints: []aws.ServiceEndpoint{{ + Name: "ec2", + URL: "https://test-ec2.random.local", + }}, + }, + }, + { + name: "duplicate service endpoints", + platform: &aws.Platform{ + Region: "us-east-1", + ServiceEndpoints: []aws.ServiceEndpoint{{ + Name: "ec2", + URL: "test-ec2.random.local", + }, { + Name: "s3", + URL: "test-ec2.random.local", + }, { + Name: "ec2", + URL: "test-ec2.random.local", + }}, + }, + expected: `^test-path\.serviceEndpoints\[2\]\.name: Invalid value: "ec2": duplicate service endpoint not allowed for ec2, service endpoint already defined at test-path\.serviceEndpoints\[0\]$`, + }, + { + name: "valid machine pool", + platform: &aws.Platform{ + Region: "us-east-1", + DefaultMachinePlatform: &aws.MachinePool{}, + }, + }, + { + name: "invalid machine pool", + platform: &aws.Platform{ + Region: "us-east-1", + DefaultMachinePlatform: &aws.MachinePool{ + EC2RootVolume: aws.EC2RootVolume{ + IOPS: -10, + }, + }, + }, + expected: `^test-path\.defaultMachinePlatform\.iops: Invalid value: -10: Storage IOPS must be positive$`, + }, + { + name: "invalid userTags, Name key", + platform: &aws.Platform{ + Region: "us-east-1", + UserTags: map[string]string{ + "Name": "test-cluster", + }, + }, + expected: `^\Qtest-path.userTags[Name]: Invalid value: "test-cluster": Name key is not allowed for user defined tags\E$`, + }, + { + name: "invalid userTags, key with kubernetes.io/cluster/", + platform: &aws.Platform{ + Region: "us-east-1", + UserTags: map[string]string{ + "kubernetes.io/cluster/test-cluster": "shared", + }, + }, + expected: `^\Qtest-path.userTags[kubernetes.io/cluster/test-cluster]: Invalid value: "shared": Keys with prefix 'kubernetes.io/cluster/' are not allowed for user defined tags\E$`, + }, + { + name: "valid userTags", + platform: &aws.Platform{ + Region: "us-east-1", + UserTags: map[string]string{ + "app": "production", + }, + }, + }, + } + for _, tc := range cases { + t.Run(tc.name, func(t *testing.T) { + err := ValidatePlatform(tc.platform, field.NewPath("test-path")).ToAggregate() + if tc.expected == "" { + assert.NoError(t, err) + } else { + assert.Regexp(t, tc.expected, err) + } + }) + } +} diff --git a/pkg/types/validation/installconfig.go b/pkg/types/validation/installconfig.go index 1e86f6bab05..36e78d279e2 100644 --- a/pkg/types/validation/installconfig.go +++ b/pkg/types/validation/installconfig.go @@ -39,6 +39,8 @@ import ( openstackvalidation "github.com/openshift/installer/pkg/types/openstack/validation" "github.com/openshift/installer/pkg/types/ovirt" ovirtvalidation "github.com/openshift/installer/pkg/types/ovirt/validation" + "github.com/openshift/installer/pkg/types/powervs" + powervsvalidation "github.com/openshift/installer/pkg/types/powervs/validation" "github.com/openshift/installer/pkg/types/vsphere" vspherevalidation "github.com/openshift/installer/pkg/types/vsphere/validation" "github.com/openshift/installer/pkg/validate" @@ -487,6 +489,9 @@ func validatePlatform(platform *types.Platform, fldPath *field.Path, network *ty return openstackvalidation.ValidatePlatform(platform.OpenStack, network, f, c) }) } + if platform.PowerVS != nil { + validate(powervs.Name, platform.PowerVS, func(f *field.Path) field.ErrorList { return powervsvalidation.ValidatePlatform(platform.PowerVS, f) }) + } if platform.VSphere != nil { validate(vsphere.Name, platform.VSphere, func(f *field.Path) field.ErrorList { return vspherevalidation.ValidatePlatform(platform.VSphere, f) }) } diff --git a/pkg/types/validation/installconfig_test.go b/pkg/types/validation/installconfig_test.go index cd1e10fc846..dd5e1e9f571 100644 --- a/pkg/types/validation/installconfig_test.go +++ b/pkg/types/validation/installconfig_test.go @@ -524,7 +524,7 @@ func TestValidateInstallConfig(t *testing.T) { c.Platform = types.Platform{} return c }(), - expectedError: `^platform: Invalid value: "": must specify one of the platforms \(alibabacloud, aws, azure, baremetal, gcp, ibmcloud, none, openstack, ovirt, vsphere\)$`, + expectedError: `^platform: Invalid value: "": must specify one of the platforms \(alibabacloud, aws, azure, baremetal, gcp, ibmcloud, none, openstack, ovirt, powervs, vsphere\)$`, }, { name: "multiple platforms", @@ -555,7 +555,7 @@ func TestValidateInstallConfig(t *testing.T) { } return c }(), - expectedError: `^platform: Invalid value: "libvirt": must specify one of the platforms \(alibabacloud, aws, azure, baremetal, gcp, ibmcloud, none, openstack, ovirt, vsphere\)$`, + expectedError: `^platform: Invalid value: "libvirt": must specify one of the platforms \(alibabacloud, aws, azure, baremetal, gcp, ibmcloud, none, openstack, ovirt, powervs, vsphere\)$`, }, { name: "invalid libvirt platform", @@ -567,7 +567,7 @@ func TestValidateInstallConfig(t *testing.T) { c.Platform.Libvirt.URI = "" return c }(), - expectedError: `^\[platform: Invalid value: "libvirt": must specify one of the platforms \(alibabacloud, aws, azure, baremetal, gcp, ibmcloud, none, openstack, ovirt, vsphere\), platform\.libvirt\.uri: Invalid value: "": invalid URI "" \(no scheme\)]$`, + expectedError: `^\[platform: Invalid value: "libvirt": must specify one of the platforms \(alibabacloud, aws, azure, baremetal, gcp, ibmcloud, none, openstack, ovirt, powervs, vsphere\), platform\.libvirt\.uri: Invalid value: "": invalid URI "" \(no scheme\)]$`, }, { name: "valid none platform", diff --git a/pkg/types/validation/machinepools.go b/pkg/types/validation/machinepools.go index f14f8078113..d7b0af2c271 100644 --- a/pkg/types/validation/machinepools.go +++ b/pkg/types/validation/machinepools.go @@ -22,6 +22,8 @@ import ( openstackvalidation "github.com/openshift/installer/pkg/types/openstack/validation" "github.com/openshift/installer/pkg/types/ovirt" ovirtvalidation "github.com/openshift/installer/pkg/types/ovirt/validation" + "github.com/openshift/installer/pkg/types/powervs" + powervsvalidation "github.com/openshift/installer/pkg/types/powervs/validation" "github.com/openshift/installer/pkg/types/vsphere" vspherevalidation "github.com/openshift/installer/pkg/types/vsphere/validation" ) @@ -117,6 +119,9 @@ func validateMachinePoolPlatform(platform *types.Platform, p *types.MachinePoolP if p.Ovirt != nil { validate(ovirt.Name, p.Ovirt, func(f *field.Path) field.ErrorList { return ovirtvalidation.ValidateMachinePool(p.Ovirt, f) }) } + if p.PowerVS != nil { + validate(powervs.Name, p.PowerVS, func(f *field.Path) field.ErrorList { return powervsvalidation.ValidateMachinePool(p.PowerVS, f) }) + } if p.OpenStack != nil { validate(openstack.Name, p.OpenStack, func(f *field.Path) field.ErrorList { return openstackvalidation.ValidateMachinePool(platform.OpenStack, p.OpenStack, pool.Name, f) diff --git a/vendor/modules.txt b/vendor/modules.txt index c3e192a1b67..c50386fdfcb 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -202,7 +202,7 @@ github.com/ChrisTrenkamp/goxpath/tree/xmltree/xmlbuilder github.com/ChrisTrenkamp/goxpath/tree/xmltree/xmlele github.com/ChrisTrenkamp/goxpath/tree/xmltree/xmlnode github.com/ChrisTrenkamp/goxpath/xconst -# github.com/IBM-Cloud/bluemix-go v0.0.0-20210611051827-cdc80c935c05 +# github.com/IBM-Cloud/bluemix-go v0.0.0-20210706092416-dc4055f8e0ea ## explicit github.com/IBM-Cloud/bluemix-go github.com/IBM-Cloud/bluemix-go/api/account/accountv1 @@ -240,8 +240,13 @@ github.com/IBM-Cloud/bluemix-go/rest github.com/IBM-Cloud/bluemix-go/session github.com/IBM-Cloud/bluemix-go/trace github.com/IBM-Cloud/bluemix-go/utils -# github.com/IBM-Cloud/power-go-client v1.0.55 +# github.com/IBM-Cloud/container-services-go-sdk v0.0.0-20210705152127-41ca00fc9a62 +github.com/IBM-Cloud/container-services-go-sdk/common +github.com/IBM-Cloud/container-services-go-sdk/kubernetesserviceapiv1 +# github.com/IBM-Cloud/power-go-client v1.0.72 => github.com/yussufsh/power-go-client v1.99.4 +## explicit github.com/IBM-Cloud/power-go-client/clients/instance +github.com/IBM-Cloud/power-go-client/errors github.com/IBM-Cloud/power-go-client/helpers github.com/IBM-Cloud/power-go-client/ibmpisession github.com/IBM-Cloud/power-go-client/power/client @@ -255,15 +260,20 @@ github.com/IBM-Cloud/power-go-client/power/client/p_cloud_cloud_connections github.com/IBM-Cloud/power-go-client/power/client/p_cloud_events github.com/IBM-Cloud/power-go-client/power/client/p_cloud_images github.com/IBM-Cloud/power-go-client/power/client/p_cloud_instances +github.com/IBM-Cloud/power-go-client/power/client/p_cloud_jobs github.com/IBM-Cloud/power-go-client/power/client/p_cloud_networks github.com/IBM-Cloud/power-go-client/power/client/p_cloud_p_vm_instances +github.com/IBM-Cloud/power-go-client/power/client/p_cloud_placement_groups github.com/IBM-Cloud/power-go-client/power/client/p_cloud_s_a_p +github.com/IBM-Cloud/power-go-client/power/client/p_cloud_service_d_h_c_p github.com/IBM-Cloud/power-go-client/power/client/p_cloud_snapshots github.com/IBM-Cloud/power-go-client/power/client/p_cloud_storage_capacity github.com/IBM-Cloud/power-go-client/power/client/p_cloud_system_pools github.com/IBM-Cloud/power-go-client/power/client/p_cloud_tasks github.com/IBM-Cloud/power-go-client/power/client/p_cloud_tenants github.com/IBM-Cloud/power-go-client/power/client/p_cloud_tenants_ssh_keys +github.com/IBM-Cloud/power-go-client/power/client/p_cloud_v_p_n_connections +github.com/IBM-Cloud/power-go-client/power/client/p_cloud_v_p_n_policies github.com/IBM-Cloud/power-go-client/power/client/p_cloud_volumes github.com/IBM-Cloud/power-go-client/power/client/service_bindings github.com/IBM-Cloud/power-go-client/power/client/service_instances @@ -271,7 +281,7 @@ github.com/IBM-Cloud/power-go-client/power/client/storage_types github.com/IBM-Cloud/power-go-client/power/client/swagger_spec github.com/IBM-Cloud/power-go-client/power/models github.com/IBM-Cloud/power-go-client/utils -# github.com/IBM-Cloud/terraform-provider-ibm v1.26.2 => github.com/openshift/terraform-provider-ibm v1.26.2-openshift-2 +# github.com/IBM-Cloud/terraform-provider-ibm v1.26.2 => github.com/yussufsh/terraform-provider-ibm v1.89.0 ## explicit github.com/IBM-Cloud/terraform-provider-ibm/ibm github.com/IBM-Cloud/terraform-provider-ibm/ibm/internal/hashcode @@ -286,13 +296,11 @@ github.com/IBM/appconfiguration-go-admin-sdk/common # github.com/IBM/container-registry-go-sdk v0.0.13 github.com/IBM/container-registry-go-sdk/common github.com/IBM/container-registry-go-sdk/containerregistryv1 -# github.com/IBM/go-sdk-core v1.1.0 -github.com/IBM/go-sdk-core/core -# github.com/IBM/go-sdk-core/v3 v3.3.1 +# github.com/IBM/go-sdk-core/v3 v3.2.4 github.com/IBM/go-sdk-core/v3/core # github.com/IBM/go-sdk-core/v4 v4.10.0 github.com/IBM/go-sdk-core/v4/core -# github.com/IBM/go-sdk-core/v5 v5.4.3 +# github.com/IBM/go-sdk-core/v5 v5.5.1 ## explicit github.com/IBM/go-sdk-core/v5/core # github.com/IBM/ibm-cos-sdk-go v1.7.0 @@ -338,10 +346,15 @@ github.com/IBM/ibm-cos-sdk-go/service/s3 # github.com/IBM/ibm-cos-sdk-go-config v1.2.0 github.com/IBM/ibm-cos-sdk-go-config/common github.com/IBM/ibm-cos-sdk-go-config/resourceconfigurationv1 +# github.com/IBM/ibm-hpcs-tke-sdk v0.0.0-20210723145459-a232c3f3ac91 +github.com/IBM/ibm-hpcs-tke-sdk/common +github.com/IBM/ibm-hpcs-tke-sdk/ep11cmds +github.com/IBM/ibm-hpcs-tke-sdk/rest +github.com/IBM/ibm-hpcs-tke-sdk/tkesdk # github.com/IBM/keyprotect-go-client v0.7.0 github.com/IBM/keyprotect-go-client github.com/IBM/keyprotect-go-client/iam -# github.com/IBM/networking-go-sdk v0.14.0 +# github.com/IBM/networking-go-sdk v0.19.0 ## explicit github.com/IBM/networking-go-sdk/cachingapiv1 github.com/IBM/networking-go-sdk/cisipapiv1 @@ -353,6 +366,7 @@ github.com/IBM/networking-go-sdk/dnsrecordbulkv1 github.com/IBM/networking-go-sdk/dnsrecordsv1 github.com/IBM/networking-go-sdk/dnssvcsv1 github.com/IBM/networking-go-sdk/edgefunctionsapiv1 +github.com/IBM/networking-go-sdk/filtersv1 github.com/IBM/networking-go-sdk/globalloadbalancermonitorv1 github.com/IBM/networking-go-sdk/globalloadbalancerpoolsv0 github.com/IBM/networking-go-sdk/globalloadbalancerv1 @@ -389,11 +403,12 @@ github.com/IBM/schematics-go-sdk/schematicsv1 # github.com/IBM/secrets-manager-go-sdk v0.1.19 github.com/IBM/secrets-manager-go-sdk/common github.com/IBM/secrets-manager-go-sdk/secretsmanagerv1 -# github.com/IBM/vpc-go-sdk v1.0.1 => github.com/IBM/vpc-go-sdk v0.7.0 +# github.com/IBM/vpc-go-sdk v1.0.1 => github.com/IBM/vpc-go-sdk v0.8.0 ## explicit github.com/IBM/vpc-go-sdk/common -github.com/IBM/vpc-go-sdk/vpcclassicv1 github.com/IBM/vpc-go-sdk/vpcv1 +# github.com/Logicalis/asn1 v0.0.0-20190312173541-d60463189a56 +github.com/Logicalis/asn1 # github.com/MakeNowJust/heredoc v1.0.0 github.com/MakeNowJust/heredoc # github.com/Netflix/go-expect v0.0.0-20190729225929-0e00d9168667 @@ -903,6 +918,8 @@ github.com/gogo/protobuf/gogoproto github.com/gogo/protobuf/proto github.com/gogo/protobuf/protoc-gen-gogo/descriptor github.com/gogo/protobuf/sortkeys +# github.com/golang-jwt/jwt v3.2.1+incompatible +github.com/golang-jwt/jwt # github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da github.com/golang/groupcache/lru # github.com/golang/mock v1.6.0 @@ -1552,11 +1569,15 @@ github.com/openshift/cluster-api-provider-libvirt/pkg/apis/libvirtproviderconfig ## explicit github.com/openshift/cluster-api-provider-ovirt/pkg/apis github.com/openshift/cluster-api-provider-ovirt/pkg/apis/ovirtprovider/v1beta1 +# github.com/openshift/cluster-api-provider-powervs v0.0.2-0.20210928133618-8eb5ebcb07a1 +## explicit +github.com/openshift/cluster-api-provider-powervs/pkg/apis +github.com/openshift/cluster-api-provider-powervs/pkg/apis/powervsprovider/v1alpha1 # github.com/openshift/library-go v0.0.0-20210408164723-7a65fdb398e2 ## explicit github.com/openshift/library-go/pkg/config/clusteroperator/v1helpers github.com/openshift/library-go/pkg/route/routeapihelpers -# github.com/openshift/machine-api-operator v0.2.1-0.20210505133115-b7ef098180db +# github.com/openshift/machine-api-operator v0.2.1-0.20210505133115-b7ef098180db => github.com/openshift-powervs/machine-api-operator v0.2.1-0.20210809115935-a9fd8f5d2767 ## explicit github.com/openshift/machine-api-operator/pkg/apis/machine github.com/openshift/machine-api-operator/pkg/apis/machine/v1beta1 @@ -1642,7 +1663,7 @@ github.com/shurcooL/vfsgen ## explicit github.com/sirupsen/logrus github.com/sirupsen/logrus/hooks/test -# github.com/softlayer/softlayer-go v1.0.3 +# github.com/softlayer/softlayer-go v1.0.3 => github.com/IBM-Cloud/softlayer-go v1.0.3-tf github.com/softlayer/softlayer-go/config github.com/softlayer/softlayer-go/datatypes github.com/softlayer/softlayer-go/filter @@ -2204,13 +2225,14 @@ go.starlark.net/resolve go.starlark.net/starlark go.starlark.net/starlarkstruct go.starlark.net/syntax -# golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2 +# golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97 ## explicit golang.org/x/crypto/bcrypt golang.org/x/crypto/blowfish golang.org/x/crypto/cast5 golang.org/x/crypto/chacha20 golang.org/x/crypto/curve25519 +golang.org/x/crypto/curve25519/internal/field golang.org/x/crypto/ed25519 golang.org/x/crypto/ed25519/internal/edwards25519 golang.org/x/crypto/internal/subtle @@ -2239,7 +2261,7 @@ golang.org/x/mod/internal/lazyregexp golang.org/x/mod/modfile golang.org/x/mod/module golang.org/x/mod/semver -# golang.org/x/net v0.0.0-20210520170846-37e1c6afe023 +# golang.org/x/net v0.0.0-20210614182718-04defd469f4e golang.org/x/net/context golang.org/x/net/context/ctxhttp golang.org/x/net/html @@ -3054,7 +3076,7 @@ sigs.k8s.io/structured-merge-diff/v4/value # sigs.k8s.io/yaml v1.2.0 sigs.k8s.io/yaml # cloud.google.com/go => cloud.google.com/go v0.57.0 -# github.com/IBM-Cloud/terraform-provider-ibm => github.com/openshift/terraform-provider-ibm v1.26.2-openshift-2 +# github.com/IBM-Cloud/terraform-provider-ibm => github.com/yussufsh/terraform-provider-ibm v1.89.0 # github.com/go-log/log => github.com/go-log/log v0.1.1-0.20181211034820-a514cf01a3eb # github.com/hashicorp/terraform => github.com/openshift/terraform v0.12.20-openshift-4 # github.com/hashicorp/terraform-plugin-sdk => github.com/openshift/hashicorp-terraform-plugin-sdk v1.14.0-openshift @@ -3075,7 +3097,7 @@ sigs.k8s.io/yaml # sigs.k8s.io/cluster-api-provider-openstack => github.com/openshift/cluster-api-provider-openstack v0.0.0-20210302164104-8498241fa4bd # sigs.k8s.io/controller-runtime => sigs.k8s.io/controller-runtime v0.9.0-alpha.1 # sigs.k8s.io/controller-tools => sigs.k8s.io/controller-tools v0.3.1-0.20200617211605-651903477185 -# github.com/IBM/vpc-go-sdk => github.com/IBM/vpc-go-sdk v0.7.0 +# github.com/IBM/vpc-go-sdk => github.com/IBM/vpc-go-sdk v0.8.0 # github.com/apparentlymart/go-cidr => github.com/apparentlymart/go-cidr v1.0.1 # github.com/aws/aws-sdk-go => github.com/aws/aws-sdk-go v1.32.3 # github.com/go-openapi/errors => github.com/go-openapi/errors v0.19.2 @@ -3086,3 +3108,6 @@ sigs.k8s.io/yaml # google.golang.org/api => google.golang.org/api v0.25.0 # google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 # google.golang.org/grpc => google.golang.org/grpc v1.29.1 +# github.com/openshift/machine-api-operator => github.com/openshift-powervs/machine-api-operator v0.2.1-0.20210809115935-a9fd8f5d2767 +# github.com/IBM-Cloud/power-go-client => github.com/yussufsh/power-go-client v1.99.4 +# github.com/softlayer/softlayer-go => github.com/IBM-Cloud/softlayer-go v1.0.3-tf