Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Azure STS deployment support #10869

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
26 changes: 26 additions & 0 deletions conf/deployment/azure/ipi_3az_rhcos_sts_3m_3w.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
DEPLOYMENT:
openshift_install_timeout: 4800
allow_lower_instance_requirements: false
sts_enabled: true
subscription_plan_approval: "Manual"
ENV_DATA:
platform: 'azure'
deployment_type: 'ipi'
region: 'eastus'
azure_base_domain_resource_group_name: 'odfqe'
worker_availability_zones:
- '1'
- '2'
- '3'
master_availability_zones:
- '1'
- '2'
- '3'
worker_replicas: 3
master_replicas: 3
master_instance_type: 'Standard_D8s_v3'
worker_instance_type: 'Standard_D16s_v3'
REPORTING:
polarion:
deployment_id: 'OCS-2461'
2 changes: 1 addition & 1 deletion ocs_ci/deployment/aws.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ def sts_setup(self):
release_image = get_ocp_release_image_from_installer()
cco_image = cco.get_cco_container_image(release_image, pull_secret_path)
cco.extract_ccoctl_binary(cco_image, pull_secret_path)
cco.extract_credentials_requests_aws(
cco.extract_credentials_requests(
release_image,
install_config,
pull_secret_path,
Expand Down
60 changes: 55 additions & 5 deletions ocs_ci/deployment/azure.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,19 @@
This module contains platform specific methods and classes for deployment
on Azure platform.
"""

import logging
import json
import logging
import os
import shutil

from ocs_ci.framework import config
from ocs_ci.deployment.cloud import CloudDeploymentBase
from ocs_ci.deployment.cloud import IPIOCPDeployment
from ocs_ci.deployment.ocp import OCPDeployment as BaseOCPDeployment
from ocs_ci.utility import version
from ocs_ci.ocs import constants
from ocs_ci.utility import cco, version
from ocs_ci.utility.azure_utils import AZURE as AzureUtil, AzureAroUtil
from ocs_ci.utility.deployment import get_ocp_release_image_from_installer
from ocs_ci.utility.utils import exec_cmd

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -78,12 +81,59 @@ class AZUREIPI(AZUREBase):
A class to handle Azure IPI specific deployment.
"""

OCPDeployment = IPIOCPDeployment

def __init__(self):
self.name = self.__class__.__name__
super(AZUREIPI, self).__init__()

class OCPDeployment(IPIOCPDeployment):
def deploy_prereq(self):
super().deploy_prereq()
if config.DEPLOYMENT.get("sts_enabled"):
self.sts_setup()

def sts_setup(self):
"""
Perform setup procedure for STS Mode deployments.
"""
cluster_path = config.ENV_DATA["cluster_path"]
output_dir = os.path.join(cluster_path, "output-dir")
pull_secret_path = os.path.join(constants.DATA_DIR, "pull-secret")
credentials_requests_dir = os.path.join(cluster_path, "creds_reqs")
install_config = os.path.join(cluster_path, "install-config.yaml")

release_image = get_ocp_release_image_from_installer()
cco_image = cco.get_cco_container_image(release_image, pull_secret_path)
cco.extract_ccoctl_binary(cco_image, pull_secret_path)
cco.extract_credentials_requests(
release_image,
install_config,
pull_secret_path,
credentials_requests_dir,
)
cco.set_credentials_mode_manual(install_config)
cco.set_resource_group_name(install_config, self.cluster_name)
cco.create_manifests(self.installer, cluster_path)
cco.process_credentials_requests_azure(
self.cluster_name,
config.ENV_DATA["region"],
credentials_requests_dir,
output_dir,
config.AUTH["azure_auth"]["subscription_id"],
config.ENV_DATA["azure_base_domain_resource_group_name"],
config.AUTH["azure_auth"]["tenant_id"],
)
manifests_source_dir = os.path.join(output_dir, "manifests")
manifests_target_dir = os.path.join(cluster_path, "manifests")
file_names = os.listdir(manifests_source_dir)
for file_name in file_names:
shutil.move(
os.path.join(manifests_source_dir, file_name), manifests_target_dir
)

tls_source_dir = os.path.join(output_dir, "tls")
tls_target_dir = os.path.join(cluster_path, "tls")
shutil.move(tls_source_dir, tls_target_dir)

# For Azure IPI there is no need to implement custom:
# - deploy_ocp() method (as long as we don't tweak host network)

Expand Down
32 changes: 29 additions & 3 deletions ocs_ci/deployment/deployment.py
Original file line number Diff line number Diff line change
Expand Up @@ -901,8 +901,16 @@ def subscribe_ocs(self):

"""
live_deployment = config.DEPLOYMENT.get("live_deployment")
platform = config.ENV_DATA["platform"]
aws_sts_deployment = (
config.DEPLOYMENT.get("sts_enabled") and platform == constants.AWS_PLATFORM
)
azure_sts_deployment = (
config.DEPLOYMENT.get("sts_enabled")
and platform == constants.AZURE_PLATFORM
)
managed_ibmcloud = (
config.ENV_DATA["platform"] == constants.IBMCLOUD_PLATFORM
platform == constants.IBMCLOUD_PLATFORM
and config.ENV_DATA["deployment_type"] == "managed"
)
if managed_ibmcloud and not live_deployment:
Expand Down Expand Up @@ -944,14 +952,28 @@ def subscribe_ocs(self):
subscription_yaml_data["spec"]["source"] = config.DEPLOYMENT.get(
"live_content_source", defaults.LIVE_CONTENT_SOURCE
)
if config.DEPLOYMENT.get("sts_enabled"):
if aws_sts_deployment:
if "config" not in subscription_yaml_data["spec"]:
subscription_yaml_data["spec"]["config"] = {}
role_arn_data = {"name": "ROLEARN", "value": self.sts_role_arn}
if "env" not in subscription_yaml_data["spec"]["config"]:
subscription_yaml_data["spec"]["config"]["env"] = [role_arn_data]
else:
subscription_yaml_data["spec"]["config"]["env"].append([role_arn_data])
elif azure_sts_deployment:
if "config" not in subscription_yaml_data["spec"]:
subscription_yaml_data["spec"]["config"] = {}
azure_auth_data = config.AUTH["azure_auth"]
azure_sub_data = [
{"name": "CLIENTID", "value": azure_auth_data["client_id"]},
{"name": "TENANTID", "value": azure_auth_data["tenant_id"]},
{"name": "SUBSCRIPTIONID", "value": azure_auth_data["subscription_id"]},
]
if "env" not in subscription_yaml_data["spec"]["config"]:
subscription_yaml_data["spec"]["config"]["env"] = azure_sub_data
else:
subscription_yaml_data["spec"]["config"]["env"] = azure_sub_data

subscription_yaml_data["metadata"]["namespace"] = self.namespace
subscription_manifest = tempfile.NamedTemporaryFile(
mode="w+", prefix="subscription_manifest", delete=False
Expand Down Expand Up @@ -1062,6 +1084,10 @@ def deploy_ocs_via_operator(self, image=None):
live_deployment = config.DEPLOYMENT.get("live_deployment")
arbiter_deployment = config.DEPLOYMENT.get("arbiter_deployment")
local_storage = config.DEPLOYMENT.get("local_storage")
platform = config.ENV_DATA.get("platform").lower()
aws_sts_deployment = (
config.DEPLOYMENT.get("sts_enabled") and platform == constants.AWS_PLATFORM
)

if ui_deployment and ui_deployment_conditions():
log_step("Start ODF deployment with UI")
Expand All @@ -1072,7 +1098,7 @@ def deploy_ocs_via_operator(self, image=None):
log_step("Deployment of OCS via OCS operator")
self.label_and_taint_nodes()

if config.DEPLOYMENT.get("sts_enabled"):
if aws_sts_deployment:
log_step("Create STS role and attach AmazonS3FullAccess Policy")
role_data = create_and_attach_sts_role()
self.sts_role_arn = role_data["Role"]["Arn"]
Expand Down
2 changes: 1 addition & 1 deletion ocs_ci/utility/azure_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ def resource_client(self):
"""
if not self._resource_client:
self._resource_client = ResourceManagementClient(
credentials=self.credentials, subscription_id=self._subscription_id
credential=self.credentials, subscription_id=self._subscription_id
)
return self._resource_client

Expand Down
54 changes: 52 additions & 2 deletions ocs_ci/utility/cco.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"""
Cloud Credential Operator utility functions
"""

import logging
import os
import shutil
Expand Down Expand Up @@ -69,11 +70,11 @@ def extract_credentials_requests_ibmcloud(
exec_cmd(cmd)


def extract_credentials_requests_aws(
def extract_credentials_requests(
release_image, install_config, pull_secret, credentials_requests_dir
):
"""
Extract the CredentialsRequests (AWS STS variant).
Extract the CredentialsRequests (AWS and Azure STS variant).

Args:
release_image (str): Release image from the openshift installer
Expand Down Expand Up @@ -203,6 +204,38 @@ def process_credentials_requests_aws(
exec_cmd(cmd)


def process_credentials_requests_azure(
name,
azure_region,
credentials_requests_dir,
output_dir,
subscription_id,
dns_zone_group_name,
tenant_id,
):
"""
Process all CredentialsRequest objects.

Args:
name (str): Name used to tag any created cloud resources
azure_region (str): Region to create cloud resources
credentials_requests_dir (str): Path to the CredentialsRequest directory
output_dir (str): Path to the output directory
subscription_id (str): Service Principal Subscription ID
dns_zone_group_name (str): Name of the DNS Zone
tenant_id (str): Service Principal Tenant ID

"""
logger.info("Processing all CredentialsRequest objects")
cmd = (
f"ccoctl azure create-all --name={name} --output-dir={output_dir} "
f"--region={azure_region} --subscription-id={subscription_id} "
f"--credentials-requests-dir={credentials_requests_dir} "
f"--dnszone-resource-group-name={dns_zone_group_name} --tenant-id={tenant_id}"
)
exec_cmd(cmd)


def set_credentials_mode_manual(install_config):
"""
Set credentialsMode to Manual in the install-config.yaml
Expand All @@ -213,3 +246,20 @@ def set_credentials_mode_manual(install_config):
install_config_data["credentialsMode"] = "Manual"
with open(install_config, "w") as f:
yaml.dump(install_config_data, f)


def set_resource_group_name(install_config, name):
"""
Set resourceGroupName to Manual in the install-config.yaml for Azure deployments.

Args:
install_config (str): Path to the install-config.yaml
name (str): Name of the Resource Group

"""
logger.info("Set resourceGroupName")
with open(install_config, "r") as f:
install_config_data = yaml.safe_load(f)
install_config_data["platform"]["azure"]["resourceGroupName"] = name
with open(install_config, "w") as f:
yaml.dump(install_config_data, f)
10 changes: 5 additions & 5 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,11 @@
"python-ipmi==0.4.2",
"scipy==1.12.0",
"PrettyTable==0.7.2",
"azure-common==1.1.25",
"azure-mgmt-compute==12.0.0",
"azure-mgmt-network==10.2.0",
"azure-mgmt-resource==10.0.0",
"azure-storage-blob==12.19.0",
"azure-common==1.1.28",
"azure-mgmt-compute==33.0.0",
"azure-mgmt-network==28.0.0",
"azure-mgmt-resource==23.2.0",
"azure-storage-blob==12.23.1",
"msrestazure==0.6.3",
"python-novaclient==17.1.0",
"python-cinderclient==7.1.0",
Expand Down
Loading