def setUpClass(cls):
super().setUpClass()
cls._ceph_cmd(['mgr', 'module', 'enable', 'feedback'], wait=3)
+ # Point the feedback module at an unreachable host so the test
+ # does not depend on tracker.ceph.com being available. Any
+ # create_issue call will fail fast with a ConnectionError
+ # (a RequestException subclass) which the dashboard controller
+ # is expected to surface as HTTP 400.
+ cls._ceph_cmd(['config', 'set', 'mgr',
+ 'mgr/feedback/tracker_url',
+ 'invalid.example.invalid'])
cls._get(
'/api/mgr/module',
retries=5,
from .cli import FeedbackCLICommand
-from mgr_module import HandleCommandResult, MgrModule
+from mgr_module import HandleCommandResult, MgrModule, Option
import errno
from .service import CephTrackerClient
class FeedbackModule(MgrModule):
CLICommand = FeedbackCLICommand
+ MODULE_OPTIONS = [
+ Option(
+ name='tracker_url',
+ type='str',
+ default='tracker.ceph.com',
+ desc='Hostname of the Ceph issue tracker (Redmine) instance',
+ runtime=True),
+ ]
+
# there are CLI commands we implement
@FeedbackCLICommand.Read('feedback set api-key')
def _cmd_feedback_set_api_key(self, key: str) -> HandleCommandResult:
"""
Fetch issue list
"""
- tracker_client = CephTrackerClient()
+ tracker_client = CephTrackerClient(self.get_module_option('tracker_url'))
try:
response = tracker_client.list_issues()
except Exception:
return HandleCommandResult(stderr='Issue tracker key is not set. Set key with `ceph set issue_key <your_key>`')
except Exception as error:
return HandleCommandResult(stderr=f'Error in retreiving issue tracker API key: {error}')
- tracker_client = CephTrackerClient()
+ tracker_client = CephTrackerClient(self.get_module_option('tracker_url'))
try:
response = tracker_client.create_issue(feedback, current_api_key)
except RequestException as error:
return 'Successfully deleted API key'
def get_issues(self):
- tracker_client = CephTrackerClient()
+ tracker_client = CephTrackerClient(self.get_module_option('tracker_url'))
return tracker_client.list_issues()
def validate_and_create_issue(self, project: str, tracker: str, subject: str, description: str, api_key=None):
feedback = Feedback(Feedback.Project[project].value,
Feedback.TrackerType[tracker].value, subject, description)
- tracker_client = CephTrackerClient()
+ tracker_client = CephTrackerClient(self.get_module_option('tracker_url'))
stored_api_key = self.get_store('api_key')
try:
if api_key:
from .model import Feedback
-class config:
- url = 'tracker.ceph.com'
- port = 443
+DEFAULT_TRACKER_URL = 'tracker.ceph.com'
+
class CephTrackerClient():
+ def __init__(self, tracker_url: str = DEFAULT_TRACKER_URL):
+ self.tracker_url = tracker_url
+
def list_issues(self):
'''
Fetch an issue from the Ceph Issue tracker
'Content-Type': 'application/json',
}
response = requests.get(
- f'https://{config.url}/issues.json', headers=headers)
+ f'https://{self.tracker_url}/issues.json', headers=headers)
if not response.ok:
if response.status_code == 404:
raise FileNotFoundError
raise Exception("Ceph Tracker API Key not set")
data = json.dumps(feedback.as_dict())
response = requests.post(
- f'https://{config.url}/projects/{feedback.project_id}/issues.json',
+ f'https://{self.tracker_url}/projects/{feedback.project_id}/issues.json',
headers=headers, data=data)
if not response.ok:
if response.status_code == 401: