Skip to content
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
Empty file.
113 changes: 113 additions & 0 deletions sunbeam-python/sunbeam/storage/backends/dellunity/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
# SPDX-FileCopyrightText: 2025 - Canonical Ltd
# SPDX-License-Identifier: Apache-2.0

"""Dell Unity backend implementation using base step classes."""

import logging
from enum import StrEnum
from typing import Annotated

from pydantic import Field
from rich.console import Console

from sunbeam.core.manifest import StorageBackendConfig
from sunbeam.storage.base import StorageBackendBase
from sunbeam.storage.models import SecretDictField

LOG = logging.getLogger(__name__)
console = Console()


class Protocol(StrEnum):
"""Enumeration of valid protocol types."""

ISCSI = "iscsi"
FC = "fc"


class DellunityConfig(StorageBackendConfig):
"""Configuration model for Dell Unity backend.

This model includes ALL configuration options for the backend.
Additional configuration can be managed dynamically through the charm.
"""

# Mandatory connection parameters
san_ip: Annotated[str, Field(description="IP address of SAN controller")]
san_login: Annotated[
str,
Field(description="Username for SAN controller"),
SecretDictField(field="san-login"),
]
san_password: Annotated[
str,
Field(description="Password for SAN controller"),
SecretDictField(field="san-password"),
]

# Optional backend configuration
protocol: Annotated[
Protocol | None,
Field(description="Protocol selector: iscsi, fc."),
] = None
Comment thread
ahmad-can marked this conversation as resolved.
unity_storage_pool_names: Annotated[
str | None,
Field(description="A comma-separated list of storage pool names to be used."),
] = None
unity_io_ports: Annotated[
str | None,
Field(description="A comma-separated list of iSCSI or FC ports to be used."),
] = None
remove_empty_host: Annotated[
bool | None,
Field(
description=(
"To remove the host from Unity when the last LUN is detached from it."
)
),
] = None
san_thin_provision: Annotated[
bool | None,
Field(description="Use thin provisioning for SAN volumes?"),
] = None
use_multipath_for_image_xfer: Annotated[
bool | None,
Field(description="Enable multipathing for image transfer operations."),
] = None


class DellunityBackend(StorageBackendBase):
"""Dell Unity backend implementation."""

backend_type = "dellunity"
display_name = "Dell Unity"
generally_available = False

@property
def charm_name(self) -> str:
"""Return the charm name for Dell Unity."""
return "cinder-volume-dellunity"

@property
def charm_channel(self) -> str:
"""Return the default charm channel."""
return "latest/edge"

@property
def charm_revision(self) -> str | None:
"""Return the pinned charm revision, if any."""
return None

@property
def charm_base(self) -> str:
"""Return the charm base OS."""
return "ubuntu@24.04"

@property
def supports_ha(self) -> bool:
"""Return whether this backend supports high availability."""
return False

def config_type(self) -> type[StorageBackendConfig]:
"""Return the configuration model class for Dell Unity."""
return DellunityConfig
Empty file.
135 changes: 135 additions & 0 deletions sunbeam-python/sunbeam/storage/backends/huawei/backend.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,135 @@
# SPDX-FileCopyrightText: 2025 - Canonical Ltd
# SPDX-License-Identifier: Apache-2.0

"""Huawei OceanStor Dorado backend implementation using base step classes."""

import logging
from enum import StrEnum
from typing import Annotated

from pydantic import Field
from rich.console import Console

from sunbeam.core.manifest import StorageBackendConfig
from sunbeam.storage.base import StorageBackendBase
from sunbeam.storage.models import SecretDictField

LOG = logging.getLogger(__name__)
console = Console()


class Protocol(StrEnum):
"""Enumeration of valid protocol types."""

ISCSI = "iscsi"
FC = "fc"


class HuaweiConfig(StorageBackendConfig):
"""Configuration model for Huawei OceanStor Dorado backend.

This model includes ALL configuration options for the backend.
Additional configuration can be managed dynamically through the charm.
"""

# Mandatory connection parameters
san_ip: Annotated[
str,
Field(
description="IP address or hostname of the Huawei OceanStor storage array"
),
]
san_login: Annotated[
str,
Field(description="Username for Huawei storage array REST API"),
SecretDictField(field="san-login"),
]
san_password: Annotated[
str,
Field(description="Password for Huawei storage array REST API"),
SecretDictField(field="san-password"),
]

# Optional backend configuration
protocol: Annotated[
Protocol | None,
Field(description="Protocol selector: iscsi, fc."),
] = None
Comment thread
ahmad-can marked this conversation as resolved.

cinder_huawei_conf_file: Annotated[
str | None,
Field(description="The configuration file for the Cinder Huawei driver."),
] = None

hypermetro_devices: Annotated[
str | None,
Field(description="The remote device hypermetro will use."),
] = None

metro_san_user: Annotated[
str | None,
Field(description="The remote metro device san user."),
] = None

metro_san_password: Annotated[
str | None,
Field(
description=(
"The remote metro device san password"
" (only needed for HyperMetro replication)."
)
),
SecretDictField(field="metro-san-password"),
] = None

metro_domain_name: Annotated[
str | None,
Field(description="The remote metro device domain name."),
] = None

metro_san_address: Annotated[
str | None,
Field(description="The remote metro device request url."),
] = None

metro_storage_pools: Annotated[
str | None,
Field(description="The remote metro device pool names."),
] = None


class HuaweiBackend(StorageBackendBase):
"""Huawei OceanStor Dorado backend implementation."""

backend_type = "huawei"
display_name = "Huawei OceanStor Dorado"
generally_available = False

@property
def charm_name(self) -> str:
"""Return the charm name for Huawei OceanStor Dorado."""
return "cinder-volume-huawei"

@property
def charm_channel(self) -> str:
"""Return the default charm channel."""
return "latest/edge"

@property
def charm_revision(self) -> str | None:
"""Return the pinned charm revision, if any."""
return None

@property
def charm_base(self) -> str:
"""Return the charm base OS."""
return "ubuntu@24.04"

@property
def supports_ha(self) -> bool:
"""Return whether this backend supports high availability."""
return False

def config_type(self) -> type[StorageBackendConfig]:
"""Return the configuration model class for Huawei OceanStor Dorado."""
return HuaweiConfig
16 changes: 16 additions & 0 deletions sunbeam-python/tests/unit/sunbeam/storage/backends/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,12 @@
from sunbeam.storage.backends.dellpowerstore.backend import DellPowerstoreBackend
from sunbeam.storage.backends.dellpowervault.backend import DellPowerVaultBackend
from sunbeam.storage.backends.dellsc.backend import DellSCBackend
from sunbeam.storage.backends.dellunity.backend import DellunityBackend
from sunbeam.storage.backends.fujitsueternusdx.backend import FujitsueternusdxBackend
from sunbeam.storage.backends.hitachi.backend import HitachiBackend
from sunbeam.storage.backends.hpe3par.backend import HPEthreeparBackend
from sunbeam.storage.backends.hpexp.backend import HpexpBackend
from sunbeam.storage.backends.huawei.backend import HuaweiBackend
from sunbeam.storage.backends.ibmflashsystemcommon.backend import (
IbmflashsystemcommonBackend,
)
Expand Down Expand Up @@ -66,6 +68,18 @@ def dellsc_backend():
return DellSCBackend()


@pytest.fixture
def dellunity_backend():
"""Provide a Dell Unity backend instance."""
return DellunityBackend()


@pytest.fixture
def huawei_backend():
"""Provide a Huawei OceanStor Dorado backend instance."""
return HuaweiBackend()


@pytest.fixture
def datacore_backend():
"""Provide a DataCore backend instance."""
Expand Down Expand Up @@ -309,6 +323,8 @@ def hpe3par_backend():
"solidfire": SolidFireBackend,
"hpe3par": HPEthreeparBackend,
"infinidat": InfinidatBackend,
"dellunity": DellunityBackend,
"huawei": HuaweiBackend,
}


Expand Down
Loading
Loading