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

feat: update support bundle to adapt change for mqttbroker #256

Merged
merged 14 commits into from
Jul 3, 2024
6 changes: 3 additions & 3 deletions azext_edge/edge/_help.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
COMPAT_CLUSTER_CONFIG_APIS,
COMPAT_DATA_PROCESSOR_APIS,
COMPAT_DEVICEREGISTRY_APIS,
COMPAT_MQ_APIS,
COMPAT_MQTT_BROKER_APIS,
COMPAT_OPCUA_APIS,
COMPAT_ORC_APIS,
)
Expand Down Expand Up @@ -51,7 +51,7 @@ def load_iotops_help():
short-summary: Creates a standard support bundle zip archive for use in troubleshooting and diagnostics.
long-summary: |
{{Supported service APIs}}
- {COMPAT_MQ_APIS.as_str()}
- {COMPAT_MQTT_BROKER_APIS.as_str()}
- {COMPAT_OPCUA_APIS.as_str()}
- {COMPAT_DATA_PROCESSOR_APIS.as_str()}
- {COMPAT_ORC_APIS.as_str()}
Expand Down Expand Up @@ -91,7 +91,7 @@ def load_iotops_help():
- {COMPAT_AKRI_APIS.as_str()}
- {COMPAT_DATA_PROCESSOR_APIS.as_str()}
- {COMPAT_DEVICEREGISTRY_APIS.as_str()}
- {COMPAT_MQ_APIS.as_str()}
- {COMPAT_MQTT_BROKER_APIS.as_str()}
- {COMPAT_OPCUA_APIS.as_str()}

examples:
Expand Down
2 changes: 1 addition & 1 deletion azext_edge/edge/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ class OpsServiceType(ListableEnum):
"""

auto = "auto"
mq = "mq"
mq = "broker"
opcua = "opcua"
dataprocessor = "dataprocessor"
orc = "orc"
Expand Down
2 changes: 1 addition & 1 deletion azext_edge/edge/params.py
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ def load_iotops_arguments(self, _):
context.argument(
"ops_service",
options_list=["--ops-service", "--svc"],
choices=CaseInsensitiveList(["akri", "dataprocessor", "deviceregistry", "mq", "opcua"]),
choices=CaseInsensitiveList(["akri", "dataprocessor", "deviceregistry", "broker", "opcua"]),
help="The IoT Operations service deployment that will be evaluated.",
)
context.argument(
Expand Down
4 changes: 2 additions & 2 deletions azext_edge/edge/providers/edge_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

from .base import EdgeResourceApi, EdgeApiManager
from .clusterconfig import CLUSTER_CONFIG_API_V1
from .mq import MQ_ACTIVE_API, MQ_API_V1B1, MqResourceKinds
from .mq import MQ_ACTIVE_API, MQTT_BROKER_API_V1B1, MqResourceKinds
from .dataprocessor import DATA_PROCESSOR_API_V1, DataProcessorResourceKinds
from .opcua import OPCUA_API_V1, OpcuaResourceKinds
from .orc import ORC_API_V1, OrcResourceKinds
Expand All @@ -22,7 +22,7 @@
"EdgeApiManager",
"MqResourceKinds",
"MQ_ACTIVE_API",
"MQ_API_V1B1",
"MQTT_BROKER_API_V1B1",
"OpcuaResourceKinds",
"OPCUA_API_V1",
"OrcResourceKinds",
Expand Down
11 changes: 6 additions & 5 deletions azext_edge/edge/providers/edge_api/mq.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,12 +21,13 @@ class MqResourceKinds(ListableEnum):
DATALAKE_CONNECTOR_TOPIC_MAP = "datalakeconnectortopicmap"
KAFKA_CONNECTOR = "kafkaconnector"
KAFKA_CONNECTOR_TOPIC_MAP = "kafkaconnectortopicmap"
IOT_HUB_CONNECTOR = "iothubconnector"
IOT_HUB_CONNECTOR_ROUTE_MAP = "iothubconnectorroutesmap"


MQ_API_V1B1 = EdgeResourceApi(
group="mq.iotoperations.azure.com", version="v1beta1", moniker="mq", label="microsoft-iotoperations-mq"
MQTT_BROKER_API_V1B1 = EdgeResourceApi(
group="mqttbroker.iotoperations.azure.com",
version="v1beta1",
moniker="broker",
label="microsoft-iotoperations-mq",
)

MQ_ACTIVE_API = MQ_API_V1B1
MQ_ACTIVE_API = MQTT_BROKER_API_V1B1
15 changes: 14 additions & 1 deletion azext_edge/edge/providers/support/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -174,6 +174,7 @@ def process_deployments(

def process_statefulset(
directory_path: str,
return_namespaces: bool = False,
field_selector: Optional[str] = None,
label_selector: Optional[str] = None,
) -> List[dict]:
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can fix the type here.

Expand All @@ -183,13 +184,25 @@ def process_statefulset(
statefulsets: V1StatefulSetList = v1_apps.list_stateful_set_for_all_namespaces(
label_selector=label_selector, field_selector=field_selector
)
namespace_pods_work = {}

return _process_kubernetes_resources(
processed = _process_kubernetes_resources(
directory_path=directory_path,
resources=statefulsets,
kind=BundleResourceKind.statefulset.value,
)

for statefulset in statefulsets.items:
statefulset_namespace: str = statefulset.metadata.namespace

if statefulset_namespace not in namespace_pods_work:
namespace_pods_work[statefulset_namespace] = True

if return_namespaces:
return processed, namespace_pods_work

return processed


def process_services(
directory_path: str,
Expand Down
65 changes: 14 additions & 51 deletions azext_edge/edge/providers/support/mq.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

from knack.log import get_logger

from azext_edge.edge.common import AIO_MQ_OPERATOR, AIO_MQ_RESOURCE_PREFIX
from azext_edge.edge.common import AIO_MQ_RESOURCE_PREFIX
from azext_edge.edge.providers.edge_api.mq import MqResourceKinds

from ..edge_api import MQ_ACTIVE_API, EdgeResourceApi
Expand All @@ -19,7 +19,6 @@
DAY_IN_SECONDS,
assemble_crd_work,
get_mq_namespaces,
process_deployments,
process_replicasets,
process_services,
process_statefulset,
Expand All @@ -31,14 +30,9 @@

# TODO: @jiacju - will remove old labels once new labels are stabled
MQ_APP_LABELS = [
"broker", # aio-mq-dmqtt-frontend, aio-mq-dmqtt-backend, aio-mq-dmqtt-authentication
"diagnostics", # aio-mq-diagnostics-service
"health-manager", # aio-mq-dmqtt-health-manager
"aio-mq-operator",
"aio-mq-mqttbridge",
"aio-mq-datalake",
"aio-mq-kafka-connector",
"aio-mq-iothub-connector",
]

MQ_LABEL = f"app in ({','.join(MQ_APP_LABELS)})"
Expand Down Expand Up @@ -87,51 +81,14 @@ def fetch_diagnostic_traces():
return result


def fetch_deployments():
processed, namespaces = process_deployments(
directory_path=MQ_DIRECTORY_PATH, label_selector=MQ_LABEL, return_namespaces=True
)
# aio-mq-operator deployment has no app label
operators, operator_namespaces = process_deployments(
directory_path=MQ_DIRECTORY_PATH, field_selector=f"metadata.name={AIO_MQ_OPERATOR}", return_namespaces=True
)
processed.extend(operators)

operators_v2, operator_namespaces_v2 = process_deployments(
directory_path=MQ_DIRECTORY_PATH, label_selector=MQ_NAME_LABEL, return_namespaces=True
)
processed.extend(operators_v2)

for namespace in {**namespaces, **operator_namespaces, **operator_namespaces_v2}:
metrics: dict = fetch_diagnostic_metrics(namespace)
if metrics:
processed.append(metrics)

# TODO: @digimaun - enable after support for disabling check polling UX.
# try:
# checks = run_checks(namespace=namespace)
# checks_data = {
# "data": checks,
# "zinfo": f"{MQ_ACTIVE_API.moniker}/{namespace}/checks.yaml",
# }
# processed.append(checks_data)
# except Exception:
# logger.debug(f"Unable to run checks against namespace {namespace}.")

return processed


def fetch_statefulsets():
processed = process_statefulset(
metrics_namespaces = []
processed, namespaces = process_statefulset(
directory_path=MQ_DIRECTORY_PATH,
label_selector=MQ_LABEL,
)
processed.extend(
process_statefulset(
directory_path=MQ_DIRECTORY_PATH,
label_selector=MQ_NAME_LABEL,
)
label_selector=MQ_NAME_LABEL,
return_namespaces=True,
)
metrics_namespaces.extend(namespaces)

# bridge connector stateful sets have no labels
connectors = []
Expand All @@ -144,11 +101,18 @@ def fetch_statefulsets():

for connector in connectors:
connector_name = connector.get("metadata", {}).get("name")
stateful_set = process_statefulset(
stateful_set, connector_namespaces = process_statefulset(
directory_path=MQ_DIRECTORY_PATH,
field_selector=f"metadata.name={AIO_MQ_RESOURCE_PREFIX}{connector_name}",
return_namespaces=True,
)
processed.extend(stateful_set)
metrics_namespaces.extend(connector_namespaces)

for namespace in metrics_namespaces:
metrics = fetch_diagnostic_metrics(namespace)
if metrics:
processed.append(metrics)

return processed

Expand Down Expand Up @@ -204,7 +168,6 @@ def fetch_pods(since_seconds: int = DAY_IN_SECONDS):
"statefulsets": fetch_statefulsets,
"replicasets": fetch_replicasets,
"services": fetch_services,
"deployments": fetch_deployments,
}


Expand Down
2 changes: 1 addition & 1 deletion azext_edge/edge/providers/support/orc.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@


ORC_APP_LABEL = "app in (aio-orc-api, cert-manager, cainjector, webhook)"
ORC_CONTROLLER_LABEL = "control-plane in (aio-orc-controller-manager)"
ORC_CONTROLLER_LABEL = "control-plane in (aio-plat-controller-manager)"
ORC_DIRECTORY_PATH = ORC_API_V1.moniker

# TODO: @jiacju - this label will be used near future for consistency
Expand Down
6 changes: 3 additions & 3 deletions azext_edge/edge/providers/support_bundle.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
from ..providers.edge_api import (
CLUSTER_CONFIG_API_V1,
DATA_PROCESSOR_API_V1,
MQ_API_V1B1,
MQTT_BROKER_API_V1B1,
OPCUA_API_V1,
ORC_API_V1,
AKRI_API_V0,
Expand All @@ -28,7 +28,7 @@
console = Console()

COMPAT_CLUSTER_CONFIG_APIS = EdgeApiManager(resource_apis=[CLUSTER_CONFIG_API_V1])
COMPAT_MQ_APIS = EdgeApiManager(resource_apis=[MQ_API_V1B1])
COMPAT_MQTT_BROKER_APIS = EdgeApiManager(resource_apis=[MQTT_BROKER_API_V1B1])
COMPAT_OPCUA_APIS = EdgeApiManager(resource_apis=[OPCUA_API_V1])
COMPAT_DATA_PROCESSOR_APIS = EdgeApiManager(resource_apis=[DATA_PROCESSOR_API_V1])
COMPAT_ORC_APIS = EdgeApiManager(resource_apis=[ORC_API_V1])
Expand Down Expand Up @@ -61,7 +61,7 @@ def build_bundle(
api_map = {
# TODO: re-enable billing once service is available post 0.6.0 release
# OpsServiceType.billing.value: {"apis": COMPAT_CLUSTER_CONFIG_APIS, "prepare_bundle": prepare_billing_bundle},
OpsServiceType.mq.value: {"apis": COMPAT_MQ_APIS, "prepare_bundle": prepare_mq_bundle},
OpsServiceType.mq.value: {"apis": COMPAT_MQTT_BROKER_APIS, "prepare_bundle": prepare_mq_bundle},
OpsServiceType.opcua.value: {
"apis": COMPAT_OPCUA_APIS,
"prepare_bundle": prepare_opcua_bundle,
Expand Down
2 changes: 1 addition & 1 deletion azext_edge/tests/edge/checks/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def mock_get_cluster_custom_api(mocker):
def mock_resource_types(mocker, ops_service):
patched = mocker.patch("azext_edge.edge.providers.check.base.deployment.enumerate_ops_service_resources")

if ops_service == "mq":
if ops_service == "broker":
patched.return_value = (
{},
{
Expand Down
2 changes: 1 addition & 1 deletion azext_edge/tests/edge/checks/test_mq_checks_unit.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@
],
],
)
@pytest.mark.parametrize("ops_service", ["mq"])
@pytest.mark.parametrize("ops_service", ["broker"])
def test_check_mq_by_resource_types(ops_service, mocker, mock_resource_types, resource_kinds):
eval_lookup = {
MqResourceKinds.BROKER.value: "azext_edge.edge.providers.check.mq.evaluate_brokers",
Expand Down
4 changes: 2 additions & 2 deletions azext_edge/tests/edge/support/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,8 +84,8 @@ def mocked_cluster_resources(request, mocker):

from azext_edge.edge.providers.edge_api import (
EdgeResourceApi,
MQ_API_V1B1,
MQ_ACTIVE_API,
MQTT_BROKER_API_V1B1,
OPCUA_API_V1,
DATA_PROCESSOR_API_V1,
ORC_API_V1,
Expand All @@ -105,7 +105,7 @@ def _get_api_resource(kind: str):
r_key = r.as_str()
v1_resources: List[V1APIResource] = []

if r == MQ_API_V1B1:
if r == MQTT_BROKER_API_V1B1:
v1_resources.append(_get_api_resource("Broker"))
v1_resources.append(_get_api_resource("BrokerListener"))
v1_resources.append(_get_api_resource("BrokerDiagnostic"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,13 +64,13 @@ def test_create_bundle(init_setup, bundle_dir, mq_traces, ops_service, tracked_f

# Check and take out mq traces:
if mq_traces and ops_service in [OpsServiceType.auto.value, OpsServiceType.mq.value]:
mq_level = walk_result.pop(path.join(BASE_ZIP_PATH, namespace, "mq", "traces"), {})
mq_level = walk_result.pop(path.join(BASE_ZIP_PATH, namespace, OpsServiceType.mq.value, "traces"), {})
if mq_level:
assert not mq_level["folders"]
assert_file_names(mq_level["files"])
# make sure level 2 doesnt get messed up
assert walk_result[path.join(BASE_ZIP_PATH, namespace, "mq")]["folders"] == ["traces"]
walk_result[path.join(BASE_ZIP_PATH, namespace, "mq")]["folders"] = []
assert walk_result[path.join(BASE_ZIP_PATH, namespace, OpsServiceType.mq.value)]["folders"] == ["traces"]
walk_result[path.join(BASE_ZIP_PATH, namespace, OpsServiceType.mq.value)]["folders"] = []

# Level 2 and 3 - bottom
actual_walk_result = (len(expected_services) + int("clusterconfig" in expected_services))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ def test_create_bundle_mq(init_setup, tracked_files, mq_traces):
resource_api=MQ_ACTIVE_API
)

expected_workload_types = ["deployment", "pod", "replicaset", "service", "statefulset"]
expected_workload_types = ["pod", "replicaset", "service", "statefulset"]
expected_types = set(expected_workload_types).union(MQ_ACTIVE_API.kinds)
assert set(file_map.keys()).issubset(expected_types)

Expand Down
Loading