Add SAML support to ceph-dashboard
This patchset adds support to setup authentication via the SAML protocol for the ceph-dashboard. Change-Id: I96c0d856d173a76739a6d2a9d4ad4811d3d196c3 func-test-pr: https://github.com/openstack-charmers/zaza-openstack-tests/pull/741
This commit is contained in:
parent
16653c75e1
commit
af80051429
20
config.yaml
20
config.yaml
@ -83,6 +83,26 @@ options:
|
||||
default: ""
|
||||
description: |
|
||||
Message of the day settings. Should be in the format "severity|expires|message". Set to "" to disable.
|
||||
saml-base-url:
|
||||
type: string
|
||||
default: ""
|
||||
description: |
|
||||
The base URL from where the Ceph dashboard is accessed. Must support the SAML protocol.
|
||||
saml-idp-metadata:
|
||||
type: string
|
||||
default: ""
|
||||
description: |
|
||||
URL that points to the IdP metadata XML. Can be remote or local.
|
||||
saml-username-attribute:
|
||||
type: string
|
||||
default: ""
|
||||
description: |
|
||||
The attribute that is used to get the username from the authentication response.
|
||||
saml-idp-entity-id:
|
||||
type: string
|
||||
default: "uid"
|
||||
description: |
|
||||
Unique ID to disambiguate when more than one entity id exists on the IdP metadata.
|
||||
ssl_cert:
|
||||
type: string
|
||||
default:
|
||||
|
@ -18,6 +18,7 @@ series:
|
||||
- focal
|
||||
- groovy
|
||||
- hirsute
|
||||
- jammy
|
||||
requires:
|
||||
dashboard:
|
||||
interface: ceph-dashboard
|
||||
|
39
src/charm.py
39
src/charm.py
@ -14,6 +14,7 @@ from ops.framework import StoredState
|
||||
from ops.main import main
|
||||
from ops.model import ActiveStatus, BlockedStatus, StatusBase
|
||||
from ops.charm import ActionEvent
|
||||
from ops_openstack.core import charm_class, get_charm_class_for_release
|
||||
from typing import List, Union, Tuple
|
||||
|
||||
import base64
|
||||
@ -425,6 +426,7 @@ class CephDashboardCharm(ops_openstack.core.OSBaseCharm):
|
||||
ceph_utils.mgr_enable_dashboard()
|
||||
self._apply_ceph_config_from_charm_config()
|
||||
self._configure_tls()
|
||||
self._configure_saml()
|
||||
ceph_utils.mgr_config_set(
|
||||
'mgr/dashboard/{hostname}/server_addr'.format(
|
||||
hostname=socket.gethostname()),
|
||||
@ -568,6 +570,26 @@ class CephDashboardCharm(ops_openstack.core.OSBaseCharm):
|
||||
self.TLS_KEY_PATH)
|
||||
self.kick_dashboard()
|
||||
|
||||
def _configure_saml(self) -> None:
|
||||
if 'python3-onelogin-saml2' not in self.PACKAGES:
|
||||
return
|
||||
|
||||
base_url = self.config.get('saml-base-url')
|
||||
idp_metadata = self.config.get('saml-idp-metadata')
|
||||
if not base_url or not idp_metadata:
|
||||
return
|
||||
|
||||
cmd = ['ceph', 'dashboard', 'sso', 'setup', 'saml2',
|
||||
base_url, idp_metadata]
|
||||
username_attr = self.config.get('saml-username-attribute')
|
||||
if username_attr:
|
||||
cmd.append(username_attr)
|
||||
idp_entity_id = self.config.get('saml-idp-entity-id')
|
||||
if idp_entity_id:
|
||||
cmd.append(idp_entity_id)
|
||||
|
||||
self._run_cmd(cmd)
|
||||
|
||||
def _gen_user_password(self, length: int = 12) -> str:
|
||||
"""Generate a password"""
|
||||
alphabet = (
|
||||
@ -604,5 +626,20 @@ class CephDashboardCharm(ops_openstack.core.OSBaseCharm):
|
||||
event.fail(exc.output)
|
||||
|
||||
|
||||
@charm_class
|
||||
class CephDashboardCharmOctopus(CephDashboardCharm):
|
||||
|
||||
_stored = StoredState()
|
||||
release = 'octopus'
|
||||
|
||||
|
||||
@charm_class
|
||||
class CephDashboardCharmQuincy(CephDashboardCharm):
|
||||
|
||||
_stored = StoredState()
|
||||
PACKAGES = ['ceph-mgr-dashboard', 'python3-onelogin-saml2']
|
||||
release = 'quincy'
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main(CephDashboardCharm)
|
||||
main(get_charm_class_for_release())
|
||||
|
122
tests/bundles/focal-yoga.yaml
Normal file
122
tests/bundles/focal-yoga.yaml
Normal file
@ -0,0 +1,122 @@
|
||||
local_overlay_enabled: False
|
||||
series: focal
|
||||
variables:
|
||||
openstack-origin: &openstack-origin cloud:focal-yoga
|
||||
applications:
|
||||
ceph-osd:
|
||||
charm: ch:ceph-osd
|
||||
num_units: 6
|
||||
storage:
|
||||
osd-devices: 'cinder,10G'
|
||||
options:
|
||||
osd-devices: '/dev/test-non-existent'
|
||||
source: *openstack-origin
|
||||
channel: quincy/edge
|
||||
ceph-mon:
|
||||
charm: ch:ceph-mon
|
||||
num_units: 3
|
||||
options:
|
||||
monitor-count: '3'
|
||||
source: *openstack-origin
|
||||
channel: quincy/edge
|
||||
vault:
|
||||
num_units: 1
|
||||
charm: ch:vault
|
||||
channel: latest/edge
|
||||
mysql-innodb-cluster:
|
||||
charm: ch:mysql-innodb-cluster
|
||||
constraints: mem=3072M
|
||||
num_units: 3
|
||||
options:
|
||||
source: *openstack-origin
|
||||
channel: latest/edge
|
||||
vault-mysql-router:
|
||||
charm: ch:mysql-router
|
||||
channel: latest/edge
|
||||
ceph-dashboard:
|
||||
charm: ../../ceph-dashboard.charm
|
||||
options:
|
||||
public-hostname: 'ceph-dashboard.zaza.local'
|
||||
source: *openstack-origin
|
||||
prometheus:
|
||||
charm: cs:prometheus2
|
||||
num_units: 1
|
||||
grafana:
|
||||
# SSL and allow_embedding are not released into cs:grafana yet, due
|
||||
# October 2021
|
||||
charm: ch:grafana
|
||||
num_units: 1
|
||||
options:
|
||||
anonymous: True
|
||||
install_plugins: https://storage.googleapis.com/plugins-community/vonage-status-panel/release/1.0.11/vonage-status-panel-1.0.11.zip,https://storage.googleapis.com/plugins-community/grafana-piechart-panel/release/1.6.2/grafana-piechart-panel-1.6.2.zip
|
||||
install_method: snap
|
||||
allow_embedding: True
|
||||
telegraf:
|
||||
charm: telegraf
|
||||
channel: stable
|
||||
options:
|
||||
hostname: "{host}"
|
||||
prometheus-alertmanager:
|
||||
charm: cs:prometheus-alertmanager
|
||||
num_units: 1
|
||||
ceph-radosgw:
|
||||
charm: ch:ceph-radosgw
|
||||
num_units: 3
|
||||
channel: latest/edge
|
||||
ceph-fs:
|
||||
charm: ch:ceph-fs
|
||||
num_units: 1
|
||||
channel: latest/edge
|
||||
ceph-iscsi:
|
||||
charm: ch:ceph-iscsi
|
||||
num_units: 2
|
||||
options:
|
||||
gateway-metadata-pool: iscsi-foo-metadata
|
||||
channel: latest/edge
|
||||
relations:
|
||||
- - 'ceph-osd:mon'
|
||||
- 'ceph-mon:osd'
|
||||
- - 'vault:shared-db'
|
||||
- 'vault-mysql-router:shared-db'
|
||||
- - 'vault-mysql-router:db-router'
|
||||
- 'mysql-innodb-cluster:db-router'
|
||||
- - 'ceph-dashboard:dashboard'
|
||||
- 'ceph-mon:dashboard'
|
||||
- - 'ceph-dashboard:certificates'
|
||||
- 'vault:certificates'
|
||||
- - 'ceph-mon:prometheus'
|
||||
- 'prometheus:target'
|
||||
- - 'grafana:grafana-source'
|
||||
- 'prometheus:grafana-source'
|
||||
- - 'grafana:certificates'
|
||||
- 'vault:certificates'
|
||||
- - 'ceph-osd:juju-info'
|
||||
- 'telegraf:juju-info'
|
||||
- - 'ceph-mon:juju-info'
|
||||
- 'telegraf:juju-info'
|
||||
- - 'telegraf:prometheus-client'
|
||||
- 'prometheus:target'
|
||||
- - 'telegraf:dashboards'
|
||||
- 'grafana:dashboards'
|
||||
- - 'ceph-dashboard:grafana-dashboard'
|
||||
- 'grafana:dashboards'
|
||||
- - 'ceph-dashboard:alertmanager-service'
|
||||
- 'prometheus-alertmanager:alertmanager-service'
|
||||
- - 'ceph-dashboard:prometheus'
|
||||
- 'prometheus:website'
|
||||
- - 'prometheus:alertmanager-service'
|
||||
- 'prometheus-alertmanager:alertmanager-service'
|
||||
- - 'ceph-radosgw:mon'
|
||||
- 'ceph-mon:radosgw'
|
||||
- - 'ceph-radosgw:certificates'
|
||||
- 'vault:certificates'
|
||||
- - 'ceph-dashboard:radosgw-dashboard'
|
||||
- 'ceph-radosgw:radosgw-user'
|
||||
- - 'ceph-mon:mds'
|
||||
- 'ceph-fs:ceph-mds'
|
||||
- - 'ceph-mon:client'
|
||||
- 'ceph-iscsi:ceph-client'
|
||||
- - 'vault:certificates'
|
||||
- 'ceph-iscsi:certificates'
|
||||
- - 'ceph-dashboard:iscsi-dashboard'
|
||||
- 'ceph-iscsi:admin-access'
|
@ -679,3 +679,31 @@ class TestCephDashboardCharmBase(CharmTestCase):
|
||||
self.subprocess.check_output.assert_called_once_with(
|
||||
['ceph', 'dashboard', 'ac-user-delete', 'auser'],
|
||||
stderr=self.subprocess.STDOUT)
|
||||
|
||||
def test_saml(self):
|
||||
self.subprocess.check_output.return_value = b''
|
||||
self.harness.begin()
|
||||
self.harness.charm.PACKAGES.append('python3-onelogin-saml2')
|
||||
self.harness.charm._configure_saml()
|
||||
self.subprocess.check_output.assert_not_called()
|
||||
|
||||
base_url = 'https://saml-base'
|
||||
idp_meta = 'file://idp.xml'
|
||||
username_attr = 'uid'
|
||||
entity_id = 'some_id'
|
||||
|
||||
self.harness.update_config(
|
||||
key_values={
|
||||
'saml-base-url': base_url,
|
||||
'saml-idp-metadata': idp_meta,
|
||||
'saml-username-attribute': username_attr,
|
||||
'saml-idp-entity-id': entity_id,
|
||||
}
|
||||
)
|
||||
|
||||
self.harness.charm._configure_saml()
|
||||
self.subprocess.check_output.assert_called_with(
|
||||
['ceph', 'dashboard', 'sso', 'setup', 'saml2',
|
||||
base_url, idp_meta, username_attr, entity_id],
|
||||
stderr=ANY
|
||||
)
|
||||
|
Loading…
Reference in New Issue
Block a user