Skip to content

Commit

Permalink
Refactor to remove wp eval code (#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
javierdelapuente authored May 10, 2024
1 parent 83b3df5 commit 4d56849
Show file tree
Hide file tree
Showing 7 changed files with 210 additions and 76 deletions.
5 changes: 1 addition & 4 deletions src-docs/charm.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,14 @@ Charm for WordPress on kubernetes.
**Global Variables**
---------------
- **APACHE_LOG_PATHS**
- **WORDPRESS_SCRAPE_JOBS**


---

## <kbd>class</kbd> `WordpressCharm`
Charm for WordPress on kubernetes.

Attrs: state: Persistent charm state used to store metadata after various events.

<a href="../src/charm.py#L137"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>
<a href="../src/charm.py#L132"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `__init__`

Expand Down
52 changes: 51 additions & 1 deletion src-docs/cos.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,58 @@ COS integration for WordPress charm.
**Global Variables**
---------------
- **APACHE_PROMETHEUS_SCRAPE_PORT**
- **WORDPRESS_SCRAPE_JOBS**
- **APACHE_LOG_PATHS**
- **REQUEST_DURATION_MICROSECONDS_BUCKETS**


---

## <kbd>class</kbd> `ApacheLogProxyConsumer`
Extends LogProxyConsumer to add a metrics pipeline to promtail.


---

#### <kbd>property</kbd> loki_endpoints

Fetch Loki Push API endpoints sent from LokiPushApiProvider through relation data.



**Returns:**
A list of dictionaries with Loki Push API endpoints, for instance: [
- <b>`{"url"`</b>: "http://loki1:3100/loki/api/v1/push"},
- <b>`{"url"`</b>: "http://loki2:3100/loki/api/v1/push"}, ]

---

#### <kbd>property</kbd> model

Shortcut for more simple access the model.

---

#### <kbd>property</kbd> rsyslog_config

Generates a config line for use with rsyslog.



**Returns:**
The rsyslog config line as a string

---

#### <kbd>property</kbd> syslog_port

Gets the port on which promtail is listening for syslog.



**Returns:**
A str representing the port




---
Expand Down
112 changes: 112 additions & 0 deletions src-docs/state.py.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
<!-- markdownlint-disable -->

<a href="../src/state.py#L0"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

# <kbd>module</kbd> `state.py`
Wordpress charm state.



---

## <kbd>class</kbd> `CharmConfigInvalidError`
Exception raised when a charm configuration is found to be invalid.



**Attributes:**

- <b>`msg`</b>: Explanation of the error.

<a href="../src/state.py#L25"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>function</kbd> `__init__`

```python
__init__(msg: str)
```

Initialize a new instance of the CharmConfigInvalidError exception.



**Args:**

- <b>`msg`</b>: Explanation of the error.





---

## <kbd>class</kbd> `ProxyConfig`
Configuration for external access through proxy.



**Attributes:**

- <b>`http_proxy`</b>: The http proxy URL.
- <b>`https_proxy`</b>: The https proxy URL.
- <b>`no_proxy`</b>: Comma separated list of hostnames to bypass proxy.




---

<a href="../src/state.py#L47"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `from_env`

```python
from_env() → Optional[ForwardRef('ProxyConfig')]
```

Instantiate ProxyConfig from juju charm environment.



**Returns:**
ProxyConfig if proxy configuration is provided, None otherwise.


---

## <kbd>class</kbd> `State`
The Wordpress k8s operator charm state.



**Attributes:**

- <b>`proxy_config`</b>: Proxy configuration to access Jenkins upstream through.




---

<a href="../src/state.py#L78"><img align="right" style="float:right;" src="https://img.shields.io/badge/-source-cccccc?style=flat-square"></a>

### <kbd>classmethod</kbd> `from_charm`

```python
from_charm(_: CharmBase) → State
```

Initialize the state from charm.



**Returns:**
Current state of the charm.



**Raises:**

- <b>`CharmConfigInvalidError`</b>: if invalid state values were encountered.


2 changes: 1 addition & 1 deletion src-docs/types_.py.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ Attrs: return_code: exit code from executed command. stdout: standard output f
## <kbd>class</kbd> `DatabaseConfig`
Configuration values required to connect to database.

Attrs: hostname: The hostname under which the database is being served. database: The name of the database to connect to. username: The username to use to authenticate to the database. password: The password to use to authenticat to the database.
Attrs: hostname: The hostname under which the database is being served. port: The port which the database is listening on. database: The name of the database to connect to. username: The username to use to authenticate to the database. password: The password to use to authenticat to the database.



Expand Down
40 changes: 14 additions & 26 deletions src/charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -1178,19 +1178,8 @@ def _plugin_akismet_reconciliation(self) -> None:
f"Unable to config akismet plugin, {result.message}"
)

def _wp_eval(self, php_code: str):
"""Execute arbitrary PHP code.
Args:
php_code: PHP code to be executed.
Returns:
An instance of :attr:`types_.ExecResult`.
"""
return self._wrapped_run_wp_cli(["wp", "eval", php_code])

@staticmethod
def _encode_openid_team_map(team_map: str) -> str:
def _encode_openid_team_map(team_map: str) -> dict:
"""Convert wp_plugin_openid_team_map setting to openid_teams_trust_list WordPress option.
example input: site-sysadmins=administrator,site-editors=editor,site-executives=editor
Expand All @@ -1199,21 +1188,20 @@ def _encode_openid_team_map(team_map: str) -> str:
team_map (str): team definition.
Returns:
A PHP array, as a Python string.
A Python structure that will be converted to json
"""
array_items = []
teams_parsed: dict = {}
for idx, mapping in enumerate(team_map.split(","), start=1):
launchpad_role, wordpress_role = mapping.split("=")
launchpad_role = launchpad_role.strip()
wordpress_role = wordpress_role.strip()
array_items.append(
f"{idx} => (object) array ("
f"'id'=>{idx},"
f"'team'=>'{launchpad_role}',"
f"'role'=>'{wordpress_role}',"
f"'server' => '0',),"
)
return f"array({''.join(array_items)})"
teams_parsed[str(idx)] = {
"id": idx,
"team": launchpad_role,
"role": wordpress_role,
"server": "0",
}
return teams_parsed

def _plugin_openid_reconciliation(self) -> None:
"""Reconciliation process for the openid plugin."""
Expand Down Expand Up @@ -1254,10 +1242,10 @@ def check_result():
check_result()
result = self._activate_plugin("wordpress-teams-integration", {})
check_result()
result = self._wp_eval(
"update_option("
f"'openid_teams_trust_list', {self._encode_openid_team_map(openid_team_map)}"
");"
result = self._wp_option_update(
"openid_teams_trust_list",
value=json.dumps(self._encode_openid_team_map(openid_team_map)),
format_="json",
)
check_result()
result = self._wp_option_update("users_can_register", "1")
Expand Down
67 changes: 31 additions & 36 deletions tests/unit/test_charm.py
Original file line number Diff line number Diff line change
Expand Up @@ -560,40 +560,15 @@ def test_team_map():
"""
arrange: no arrange.
act: convert the team_map config using _encode_openid_team_map method.
assert: the converted result should be a valid PHP array with the meaning matching the config.
assert: the converted result should be a valid dict with the meaning matching the config.
"""
team_map = "site-sysadmins=administrator,site-editors=editor,site-executives=editor"
option = WordpressCharm._encode_openid_team_map(team_map)
assert (
option.replace(" ", "").replace("\n", "")
== """array (
1 =>
(object) array(
'id' => 1,
'team' => 'site-sysadmins',
'role' => 'administrator',
'server' => '0',
),
2 =>
(object) array(
'id' => 2,
'team' => 'site-editors',
'role' => 'editor',
'server' => '0',
),
3 =>
(object) array(
'id' => 3,
'team' => 'site-executives',
'role' => 'editor',
'server' => '0',
),
)""".replace(
" ", ""
).replace(
"\n", ""
)
)
assert option == {
"1": {"id": 1, "team": "site-sysadmins", "role": "administrator", "server": "0"},
"2": {"id": 2, "team": "site-editors", "role": "editor", "server": "0"},
"3": {"id": 3, "team": "site-executives", "role": "editor", "server": "0"},
}


def test_swift_config(
Expand Down Expand Up @@ -657,7 +632,7 @@ def test_akismet_plugin(run_standard_plugin_test: typing.Callable):


@pytest.mark.usefixtures("attach_storage")
def test_openid_plugin(patch: WordpressPatch, run_standard_plugin_test: typing.Callable):
def test_openid_plugin(run_standard_plugin_test: typing.Callable):
"""
arrange: after peer relation established and database ready.
act: update openid plugin configuration.
Expand All @@ -669,12 +644,32 @@ def test_openid_plugin(patch: WordpressPatch, run_standard_plugin_test: typing.C
plugin_config={
"wp_plugin_openid_team_map": "site-sysadmins=administrator,site-editors=editor,site-executives=editor"
},
excepted_options={"openid_required_for_registration": "1", "users_can_register": "1"},
excepted_options={
"openid_required_for_registration": "1",
"users_can_register": "1",
"openid_teams_trust_list": {
"1": {
"id": 1,
"role": "administrator",
"server": "0",
"team": "site-sysadmins",
},
"2": {
"id": 2,
"role": "editor",
"server": "0",
"team": "site-editors",
},
"3": {
"id": 3,
"role": "editor",
"server": "0",
"team": "site-executives",
},
},
},
excepted_options_after_removed={"users_can_register": "0"},
)
assert patch.container.wp_eval_history[-1].startswith(
"update_option('openid_teams_trust_list',"
), "PHP function update_option should be invoked after openid plugin enabled"


@pytest.mark.usefixtures("attach_storage")
Expand Down
8 changes: 0 additions & 8 deletions tests/unit/wordpress_mock.py
Original file line number Diff line number Diff line change
Expand Up @@ -359,7 +359,6 @@ def __init__(
self._wordpress_database_mock = wordpress_database_mock
self.installed_plugins = set(WordpressCharm._WORDPRESS_DEFAULT_PLUGINS)
self.installed_themes = set(WordpressCharm._WORDPRESS_DEFAULT_THEMES)
self.wp_eval_history: typing.List[str] = []

def exec(
self, cmd, user=None, group=None, working_dir=None, combine_stderr=None, timeout=None
Expand Down Expand Up @@ -602,13 +601,6 @@ def _mock_wp_option_delete(self, cmd):
db.delete_option(option)
return ExecProcessMock(return_code=0, stdout="", stderr="")

@_exec_handler.register(lambda cmd: cmd[:2] == ["wp", "eval"])
def _mock_wp_eval(self, cmd):
"""Simulate ``wp eval <php_code>`` command execution in the container."""
php_code = cmd[2]
self.wp_eval_history.append(php_code)
return ExecProcessMock(return_code=0, stdout="", stderr="")

@_exec_handler.register(lambda cmd: cmd[0] == "a2enconf")
def _mock_a2enconf(self, cmd):
"""Simulate ``a2enconf <conf>`` command execution in the container.
Expand Down

0 comments on commit 4d56849

Please sign in to comment.