Skip to content

Commit 054322e

Browse files
committed
Refactor IngressNodeFirewall deployment to use Operator base class
Eliminates code duplication by replacing IngressNodeFirewallInstaller class with IngressNodeFirewallOperator that extends the Operator base class. This aligns the implementation with other operators (NMStateOperator, LocalStorageOperator, etc.) and automatically handles unreleased operator catalogs. Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com> Signed-off-by: Daniel Horak <dahorak@redhat.com>
1 parent 4194687 commit 054322e

File tree

2 files changed

+92
-143
lines changed

2 files changed

+92
-143
lines changed
Lines changed: 29 additions & 143 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,10 @@
11
import logging
22

3-
from ocs_ci.deployment.qe_app_registry import QeAppRegistry
43
from ocs_ci.framework import config
5-
from ocs_ci.ocs import constants, exceptions
6-
from ocs_ci.ocs.resources.csv import CSV, get_csvs_start_with_prefix
7-
from ocs_ci.ocs.resources.ocs import OCS
8-
from ocs_ci.ocs.resources.packagemanifest import PackageManifest
4+
from ocs_ci.ocs import constants
95
from ocs_ci.utility import templating
10-
from ocs_ci.utility.utils import TimeoutSampler
6+
from ocs_ci.utility.operators import IngressNodeFirewallOperator
7+
from ocs_ci.ocs.resources.ocs import OCS
118

129

1310
logger = logging.getLogger(__name__)
@@ -80,149 +77,38 @@ def deploy_ingress_node_firewall(rules):
8077
rules (dict): dictionary of IngressNodeFirewall Rules (content of `spec.ingress`)
8178
8279
"""
83-
inf = IngressNodeFirewallInstaller()
84-
85-
# check if Ingress Node Firewall Operator is available
86-
if not inf.check_existing_packagemanifests():
87-
# Ingress Node Firewall Operator is not available, we have to create QE App Registry Catalog Source
88-
# and related Image content source policy
89-
qe_app_registry = QeAppRegistry()
90-
qe_app_registry.icsp()
91-
qe_app_registry.catalog_source()
92-
inf.source = constants.QE_APP_REGISTRY_CATALOG_SOURCE_NAME
93-
# create openshift-ingress-node-firewall namespace
94-
inf.create_namespace()
80+
# Create and deploy the Ingress Node Firewall Operator
81+
inf_operator = IngressNodeFirewallOperator(create_catalog=True)
82+
inf_operator.deploy()
9583

96-
# create operator group
97-
inf.create_operatorgroup()
84+
# Create firewall configuration and rules
85+
create_config()
86+
create_rules(rules=rules)
9887

99-
# subscribe to the Ingress Node Firewall Operator
100-
inf.create_subscription()
10188

102-
# verify installation
103-
inf.verify_csv_status()
104-
105-
# create config
106-
inf.create_config()
89+
def create_config(self):
90+
"""
91+
Creates configuration for IngressNodeFirewall
10792
108-
# add firewall rules
109-
inf.create_rules(rules=rules)
93+
"""
94+
logger.info("Creating IngressNodeFirewallConfig")
95+
config_yaml_file = templating.load_yaml(constants.INF_CONFIG_YAML)
96+
config_yaml = OCS(**config_yaml_file)
97+
config_yaml.create()
98+
logger.info("IngressNodeFirewallConfig created successfully")
11099

111100

112-
class IngressNodeFirewallInstaller(object):
101+
def create_rules(self, rules):
113102
"""
114-
IngressNodeFirewall Installer class for Ingress Node Firewall deployment
103+
Create IngressNodeFirewall Rules
115104
116-
"""
105+
Args:
106+
rules (dict): dictionary of IngressNodeFirewall Rules (content of `spec.ingress`)
117107
118-
def __init__(self):
119-
self.namespace = constants.INGRESS_NODE_FIREWALL_NAMESPACE
120-
self.source = constants.OPERATOR_CATALOG_SOURCE_NAME
121-
122-
def check_existing_packagemanifests(self):
123-
"""
124-
Check if Ingress Node Firewall Operator is available or not.
125-
126-
Returns:
127-
bool: True if Ingress Node Operator is available, False otherwise
128-
"""
129-
try:
130-
pm = PackageManifest(constants.INGRESS_NODE_FIREWALL_OPERATOR_NAME)
131-
pm.get(silent=True)
132-
return True
133-
except (exceptions.CommandFailed, exceptions.ResourceNotFoundError):
134-
return False
135-
136-
def create_namespace(self):
137-
"""
138-
Creates the namespace for IngressNodeFirewall resources
139-
140-
Raises:
141-
CommandFailed: If the 'oc create' command fails.
142-
143-
"""
144-
try:
145-
logger.info(
146-
f"Creating namespace {self.namespace} for IngressNodeFirewall resources"
147-
)
148-
namespace_yaml_file = templating.load_yaml(constants.INF_NAMESPACE_YAML)
149-
namespace_yaml = OCS(**namespace_yaml_file)
150-
namespace_yaml.create()
151-
logger.info(
152-
f"IngressNodeFirewall namespace {self.namespace} was created successfully"
153-
)
154-
except exceptions.CommandFailed as err:
155-
if (
156-
f'project.project.openshift.io "{self.namespace}" already exists'
157-
in str(err)
158-
):
159-
logger.info(f"Namespace {self.namespace} already exists")
160-
else:
161-
raise err
162-
163-
def create_operatorgroup(self):
164-
"""
165-
Creates an OperatorGroup for IngressNodeFirewall
166-
167-
"""
168-
logger.info("Creating OperatorGroup for IngressNodeFirewall")
169-
operatorgroup_yaml_file = templating.load_yaml(constants.INF_OPERATORGROUP_YAML)
170-
operatorgroup_yaml = OCS(**operatorgroup_yaml_file)
171-
operatorgroup_yaml.create()
172-
logger.info("IngressNodeFirewall OperatorGroup created successfully")
173-
174-
def create_subscription(self):
175-
"""
176-
Creates subscription for IngressNodeFirewall operator
177-
178-
"""
179-
logger.info("Creating Subscription for IngressNodeFirewall")
180-
subscription_yaml_file = templating.load_yaml(constants.INF_SUBSCRIPTION_YAML)
181-
subscription_yaml_file["spec"]["source"] = self.source
182-
subscription_yaml = OCS(**subscription_yaml_file)
183-
subscription_yaml.create()
184-
logger.info("IngressNodeFirewall Subscription created successfully")
185-
186-
def verify_csv_status(self):
187-
"""
188-
Verify the CSV status for the IngressNodeFirewall Operator deployment equals Succeeded
189-
190-
"""
191-
for csv in TimeoutSampler(
192-
timeout=900,
193-
sleep=15,
194-
func=get_csvs_start_with_prefix,
195-
csv_prefix=constants.INGRESS_NODE_FIREWALL_CSV_NAME,
196-
namespace=self.namespace,
197-
):
198-
if csv:
199-
break
200-
csv_name = csv[0]["metadata"]["name"]
201-
csv_obj = CSV(resource_name=csv_name, namespace=self.namespace)
202-
csv_obj.wait_for_phase(phase="Succeeded", timeout=720)
203-
204-
def create_config(self):
205-
"""
206-
Creates configuration for IngressNodeFirewall
207-
208-
"""
209-
logger.info("Creating IngressNodeFirewallConfig")
210-
config_yaml_file = templating.load_yaml(constants.INF_CONFIG_YAML)
211-
config_yaml = OCS(**config_yaml_file)
212-
config_yaml.create()
213-
logger.info("IngressNodeFirewallConfig created successfully")
214-
215-
def create_rules(self, rules):
216-
"""
217-
Create IngressNodeFirewall Rules
218-
219-
Args:
220-
rules (dict): dictionary of IngressNodeFirewall Rules (content of `spec.ingress`)
221-
222-
"""
223-
logger.info("Creating IngressNodeFirewall Rules")
224-
rules_yaml_file = templating.load_yaml(constants.INF_RULES_YAML)
225-
rules_yaml_file["spec"]["ingress"] = rules
226-
rules_yaml = OCS(**rules_yaml_file)
227-
rules_yaml.create()
228-
logger.info("IngressNodeFirewall Rules created successfully")
108+
"""
109+
logger.info("Creating IngressNodeFirewall Rules")
110+
rules_yaml_file = templating.load_yaml(constants.INF_RULES_YAML)
111+
rules_yaml_file["spec"]["ingress"] = rules
112+
rules_yaml = OCS(**rules_yaml_file)
113+
rules_yaml.create()
114+
logger.info("IngressNodeFirewall Rules created successfully")

ocs_ci/utility/operators.py

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -648,3 +648,66 @@ def _deployment_verification(self):
648648
selector=constants.MANAGED_CONTROLLER_LABEL,
649649
timeout=600,
650650
), "OADP operator did not reach running phase"
651+
652+
653+
class IngressNodeFirewallOperator(Operator):
654+
def __init__(self, create_catalog: bool = False):
655+
self.name = constants.INGRESS_NODE_FIREWALL_OPERATOR_NAME
656+
ocp_version = get_semantic_ocp_version_from_config()
657+
self.unreleased_catalog_image_tag: str = (
658+
f"ocp__{ocp_version}__ingress-node-firewall-rhel9-operator"
659+
)
660+
self.unreleased_images = [
661+
"registry.redhat.io/openshift4/ingress-node-firewall-operator-bundle",
662+
"registry.redhat.io/openshift4/ingress-node-firewall-rhel9-operator",
663+
"registry.redhat.io/openshift4/ingress-node-firewall-rhel9",
664+
"registry.redhat.io/openshift4/ose-kube-rbac-proxy-rhel9",
665+
]
666+
self.disconnected_required_packages = [
667+
"ingress-node-firewall",
668+
]
669+
self.namespace = constants.INGRESS_NODE_FIREWALL_NAMESPACE
670+
super().__init__(create_catalog)
671+
672+
def _customize_operatorgroup(self, operatorgroup_data: dict):
673+
"""
674+
Hook for Ingress Node Firewall to customize OperatorGroup YAML
675+
676+
Args:
677+
operatorgroup_data (dict): the OperatorGroup YAML data
678+
"""
679+
operatorgroup_data["spec"]["targetNamespaces"] = []
680+
681+
def verify_csv_status(self):
682+
"""
683+
Verify the CSV status for the IngressNodeFirewall Operator deployment equals Succeeded
684+
"""
685+
for csv in TimeoutSampler(
686+
timeout=900,
687+
sleep=15,
688+
func=get_csvs_start_with_prefix,
689+
csv_prefix=constants.INGRESS_NODE_FIREWALL_CSV_NAME,
690+
namespace=self.namespace,
691+
):
692+
if csv:
693+
break
694+
csv_name = csv[0]["metadata"]["name"]
695+
csv_obj = CSV(resource_name=csv_name, namespace=self.namespace)
696+
csv_obj.wait_for_phase(phase="Succeeded", timeout=720)
697+
698+
def _customize_post_deployment_steps(self):
699+
"""
700+
Customize post deployment steps for IngressNodeFirewallOperator
701+
"""
702+
self.verify_csv_status()
703+
704+
def _deployment_verification(self):
705+
"""
706+
Verify the deployment of the Ingress Node Firewall operator
707+
"""
708+
inf_operator = OCP(kind=constants.POD, namespace=self.namespace)
709+
assert inf_operator.wait_for_resource(
710+
condition=constants.STATUS_RUNNING,
711+
selector=constants.MANAGED_CONTROLLER_LABEL,
712+
timeout=600,
713+
), "Ingress Node Operator operator did not reach running phase"

0 commit comments

Comments
 (0)