def __init__(self, *args): super().__init__(*args) self._framework_wrapper = FrameworkWrapper(self.framework, self._state) self._resources = { 'mongodb-image': OCIImageResource('mongodb-image') } self._mongo_builder = MongoBuilder( self._framework_wrapper.app_name, self._framework_wrapper.config, self._resources, self._framework_wrapper.goal_state_units ) if self._framework_wrapper.config['enable-sidecar']: self._resources['mongodb-sidecar-image'] = OCIImageResource( 'mongodb-sidecar-image') self._pod = K8sPod(self._framework_wrapper.app_name) self._pvc = K8sPvc(self._framework_wrapper.app_name) self._mongodb = MongoDbServer(self, "mongo") self._k8s_builder = K8sBuilder(self._pvc) delegators = [ (self.on.start, self.on_config_changed_delegator), (self.on.upgrade_charm, self.on_config_changed_delegator), (self.on.config_changed, self.on_config_changed_delegator), (self.on.update_status, self.on_update_status_delegator), (self._mongodb.on.new_client, self.on_new_client_delegator), (self.on.remove_pvc_action, self.on_remove_pvc_action_delegator), ] for delegator in delegators: self.framework.observe(delegator[0], delegator[1])
def test_fetch_image_info_succesfully(self): # Setup mock_resource_name = f"{uuid4()}" mock_image_path = f"{uuid4()}/{uuid4()}" mock_image_username = f"{uuid4()}" mock_image_password = f"{uuid4()}" mock_path_obj = MagicMock(Path) mock_path_obj.exists.return_value = True mock_path_obj.read_text.return_value = f""" registrypath: {mock_image_path} username: {mock_image_username} password: {mock_image_password} """ mock_resources_adapter = MagicMock(Resources) mock_resources_adapter.fetch.return_value = mock_path_obj # Exercise image_resource = OCIImageResource(resource_name=mock_resource_name) result = image_resource.fetch(mock_resources_adapter) # Assert assert mock_resources_adapter.fetch.call_count == 1 assert mock_resources_adapter.fetch.call_args == \ call(mock_resource_name) assert result assert image_resource.image_path == mock_image_path assert image_resource.username == mock_image_username assert image_resource.password == mock_image_password
def __init__(self, framework, key): super().__init__(framework, key) for event in (self.on.start, self.on.upgrade_charm, self.on.config_changed, self.on.mysql_relation_changed): self.framework.observe(event, self.on_start) self.framework.observe(self.on.website_relation_joined, self) self.website = HTTPInterfaceProvides(self, 'website') self.mysql = MySQLInterfaceRequires(self, 'mysql') self.gitlab_image = OCIImageResource(self, 'gitlab_image')
def test_fetch_image_info_failed(self): # Setup mock_resource_name = f"{uuid4()}" mock_path_obj = MagicMock(Path) mock_path_obj.exists.return_value = False mock_resources_adapter = MagicMock(Resources) mock_resources_adapter.fetch.return_value = mock_path_obj # Exercise image_resource = OCIImageResource(resource_name=mock_resource_name) # Assertions with pytest.raises(MissingResourceError): assert image_resource.fetch(mock_resources_adapter) assert mock_resources_adapter.fetch.call_count == 1 assert mock_resources_adapter.fetch.call_args == \ call(mock_resource_name)
def test_resource_yaml_error(self): # Setup mock_resource_name = f"{uuid4()}" mock_path_obj = MagicMock(Path) mock_path_obj.exists.return_value = True mock_path_obj.read_text.return_value = f""" \0GIBRISH """ mock_resources_adapter = MagicMock(Resources) mock_resources_adapter.fetch.return_value = mock_path_obj # Exercise image_resource = OCIImageResource(resource_name=mock_resource_name) # Assertions with pytest.raises(InvalidResourceError): assert image_resource.fetch(mock_resources_adapter) assert mock_resources_adapter.fetch.call_count == 1 assert mock_resources_adapter.fetch.call_args == \ call(mock_resource_name)
class GitLabK8sCharm(CharmBase): state = StoredState() def __init__(self, framework, key): super().__init__(framework, key) for event in (self.on.start, self.on.upgrade_charm, self.on.config_changed, self.on.mysql_relation_changed): self.framework.observe(event, self.on_start) self.framework.observe(self.on.website_relation_joined, self) self.website = HTTPInterfaceProvides(self, 'website') self.mysql = MySQLInterfaceRequires(self, 'mysql') self.gitlab_image = OCIImageResource(self, 'gitlab_image') def on_install(self, event): self.state.is_started = False def on_start(self, event): unit = self.framework.model.unit if not self.gitlab_image.fetch(): unit.status = BlockedStatus('Missing or invalid image resource') return if not self.mysql.is_joined: unit.status = BlockedStatus('Missing database') if not self.mysql.is_single: unit.status = BlockedStatus('Too many databases') if not self.mysql.is_ready: unit.status = WaitingStatus('Waiting for database') return if not self.framework.model.unit.is_leader(): unit.status = WaitingStatus('Not leader') return unit.status = MaintenanceStatus('Configuring container') self.framework.model.pod.set_spec({ 'containers': [{ 'name': self.framework.model.app.name, 'imageDetails': { 'imagePath': self.gitlab_image.registry_path, 'username': self.gitlab_image.username, 'password': self.gitlab_image.password, }, 'ports': [{ 'containerPort': int(self.framework.model.config['http_port']), 'protocol': 'TCP', }], 'config': { 'GITLAB_OMNIBUS_CONFIG': '; '.join([ f"postgresql['enable'] = false", # disable DB included in image f"gitlab_rails['db_adapter'] = 'mysql2'", f"gitlab_rails['db_encoding'] = 'utf8'", f"gitlab_rails['db_database'] = '{self.mysql.database}'", f"gitlab_rails['db_host'] = '{self.mysql.host}'", f"gitlab_rails['db_port'] = {self.mysql.port}", f"gitlab_rails['db_username'] = '******'", f"gitlab_rails['db_password'] = '******'", ]), } }], }) self.state.is_started = True unit.status = ActiveStatus() def on_website_relation_joined(self, event): if not self.state.is_started: event.defer() return self.config = self.framework.model.config for client in self.website.clients: client.serve(hosts=[client.ingress_address], port=self.config['http_port'])