Skip to content

Commit

Permalink
CI/CD workflows
Browse files Browse the repository at this point in the history
  • Loading branch information
juditnovak committed Mar 21, 2024
1 parent 4c0d730 commit eb2c72e
Show file tree
Hide file tree
Showing 4 changed files with 247 additions and 0 deletions.
71 changes: 71 additions & 0 deletions .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
# Copyright 2022 Canonical Ltd.
# See LICENSE file for licensing details.
name: Tests

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: true

on:
pull_request:
schedule:
- cron: '53 0 * * *' # Daily at 00:53 UTC
# Triggered on push to branch "main" by .github/workflows/release.yaml
workflow_call:

jobs:
lint:
name: Lint
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install tox & poetry
run: |
pipx install tox
pipx install poetry
- name: Run linters
run: tox run -e lint

unit-test:
name: Unit test charm
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install tox & poetry
run: |
pipx install tox
pipx install poetry
- name: Run tests
run: tox run -e unit

build:
strategy:
matrix:
path:
- .
# - tests/integration/app-charm
name: Build charm
uses: canonical/data-platform-workflows/.github/workflows/[email protected]
with:
path-to-charm-directory: ${{ matrix.path }}
cache: true

integration-test:
name: Integration test charm
needs:
- lint
- unit-test
- build
uses: canonical/data-platform-workflows/.github/workflows/[email protected]
with:
# artifact-prefix: packed-charm-cache-true
artifact-prefix: ${{ needs.build.outputs.artifact-prefix }}
cloud: lxd
juju-agent-version: 3.1.6
_beta_allure_report: false
permissions:
contents: write # Needed for Allure Report beta
33 changes: 33 additions & 0 deletions .github/workflows/sync_docs.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: Sync docs from Discourse

on:
workflow_dispatch:
schedule:
- cron: '53 0 * * *' # Daily at 00:53 UTC
push:
branches:
- main

jobs:
sync-docs:
name: Open PR with docs changes
runs-on: ubuntu-latest
permissions:
contents: write # Needed to login to Discourse
pull-requests: write # Need to create PR
steps:
- uses: actions/checkout@v3
- name: Open PR with docs changes
uses: deusebio/discourse-gatekeeper@c8adb89ea1cbceca54d78da798658373615487ac
id: docs-pr
with:
discourse_host: discourse.charmhub.io
discourse_api_username: ${{ secrets.DISCOURSE_API_USERNAME }}
discourse_api_key: ${{ secrets.DISCOURSE_API_KEY }}
github_token: ${{ secrets.GITHUB_TOKEN }}
dry_run: "true"

- name: Show migrate output
run: echo '${{ steps.docs-pr.outputs.migrate }}'
- name: Show reconcile output
run: echo '${{ steps.docs-pr.outputs.reconcile }}'
21 changes: 21 additions & 0 deletions .github/workflows/sync_issue_to_jira.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2023 Canonical Ltd.
# See LICENSE file for licensing details.
name: Sync issue to Jira

on:
issues:
types: [opened, reopened, closed]

jobs:
sync:
name: Sync GitHub issue to Jira
uses: canonical/data-platform-workflows/.github/workflows/[email protected]
with:
jira-base-url: https://warthogs.atlassian.net
jira-project-key: DPE
jira-component-names: mysql-router-vm
secrets:
jira-api-token: ${{ secrets.JIRA_API_TOKEN }}
jira-user-email: ${{ secrets.JIRA_USER_EMAIL }}
permissions:
issues: write # Needed to create GitHub issue comment
122 changes: 122 additions & 0 deletions tests/integration/test_password_rotation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
#!/usr/bin/env python3
# Copyright 2022 Canonical Ltd.
# See LICENSE file for licensing details.

import asyncio
import logging
from pathlib import Path

import pytest
import yaml
from pytest_operator.plugin import OpsTest

from .helpers import (
access_dashboard,
check_key,
get_address,
get_user_password,
ping_servers,
set_password,
)

logger = logging.getLogger(__name__)

METADATA = yaml.safe_load(Path("./metadata.yaml").read_text())
APP_NAME = METADATA["name"]


@pytest.mark.group(1)
@pytest.mark.abort_on_fail
@pytest.mark.password_rotation
async def test_deploy_active(ops_test: OpsTest):
charm = await ops_test.build_charm(".")
await ops_test.model.deploy(charm, application_name=APP_NAME, num_units=1)

async with ops_test.fast_forward():
await ops_test.model.block_until(
lambda: len(ops_test.model.applications[APP_NAME].units) == 1
)
await ops_test.model.wait_for_idle(
apps=[APP_NAME], status="active", timeout=1000, idle_period=30
)

assert ops_test.model.applications[APP_NAME].status == "active"


# @pytest.mark.abort_on_fail
# @pytest.mark.log_level_change
# async def test_log_level_change(ops_test: OpsTest):
#
# for unit in ops_test.model.applications[APP_NAME].units:
# assert (
# count_lines_with(
# ops_test.model_full_name,
# unit.name,
# "/var/snap/opensearch-dashboards/common/var/log/opensearch-dashboards/opensearch_dashboards.log",
# "DEBUG",
# )
# == 0
# )
#
# await ops_test.model.applications[APP_NAME].set_config({"log-level": "DEBUG"})
#
# await ops_test.model.wait_for_idle(
# apps=[APP_NAME], status="active", timeout=1000, idle_period=30
# )
#
# for unit in ops_test.model.applications[APP_NAME].units:
# assert (
# count_lines_with(
# ops_test.model_full_name,
# unit.name,
# "/var/snap/opensearch-dashboards/common/var/log/opensearch-dashboards/opensearch_dashboards.log",
# "DEBUG",
# )
# == 0
# )
#
# await ops_test.model.applications[APP_NAME].set_config({"log-level": "INFO"})
#
# await ops_test.model.wait_for_idle(
# apps=[APP_NAME], status="active", timeout=1000, idle_period=30
# )


@pytest.mark.group(1)
@pytest.mark.abort_on_fail
@pytest.mark.password_rotation
async def test_password_rotation(ops_test: OpsTest):
"""Test password rotation action."""
user = "kibanaserver"
password = await get_user_password(ops_test, user)

leader = None
for unit in ops_test.model.applications[APP_NAME].units:
if await unit.is_leader_from_status():
leader = unit.name
break
leader_num = leader.split("/")[-1]

# Change both passwords
result = await set_password(ops_test, username=user, num_unit=leader_num)
assert f"{user}-password" in result.keys()

await ops_test.model.wait_for_idle(
apps=[APP_NAME], status="active", timeout=1000, idle_period=30
)
assert ops_test.model.applications[APP_NAME].status == "active"
assert ping_servers(ops_test)

new_password = await get_user_password(ops_test, user)

assert password != new_password

await asyncio.sleep(30)

host = await get_address(ops_test, APP_NAME, leader_num)
access_dashboard(host=host, username=user, password=new_password)

# Check key in all units
for unit in ops_test.model.applications[APP_NAME].units:
host = await get_address(ops_test, APP_NAME, unit.name.split("/")[-1])
check_key(host=host, password=new_password)

0 comments on commit eb2c72e

Please sign in to comment.