def create(self, *args, **kwargs): # noqa """ Create a application with an initial config, release, domain and k8s resource if needed """ try: cfg = self.config_set.latest() except Config.DoesNotExist: cfg = Config.objects.create(owner=self.owner, app=self) # Only create if no release can be found try: rel = self.release_set.latest() except Release.DoesNotExist: rel = Release.objects.create(version=1, owner=self.owner, app=self, config=cfg, build=None) # create required minimum resources in k8s for the application namespace = self.id service = self.id try: self.log('creating Namespace {} and services'.format(namespace), level=logging.DEBUG) # Create essential resources try: self._scheduler.get_namespace(namespace) except KubeException: self._scheduler.create_namespace(namespace) try: self._scheduler.get_service(namespace, service) except KubeException: self._scheduler.create_service(namespace, service) except KubeException as e: # Blow it all away only if something horrible happens try: self._scheduler.delete_namespace(namespace) except KubeException as e: # Just feed into the item below raise ServiceUnavailable( 'Could not delete the Namespace in Kubernetes') from e raise ServiceUnavailable( 'Kubernetes resources could not be created') from e # Attach the platform specific application sub domain to the k8s service # Only attach it on first release in case a customer has remove the app domain if rel.version == 1 and not Domain.objects.filter( domain=self.id).exists(): Domain(owner=self.owner, app=self, domain=self.id).save()
def create(self, *args, **kwargs): # noqa """ Create a application with an initial config, settings, release, domain and k8s resource if needed """ try: cfg = self.config_set.latest() except Config.DoesNotExist: cfg = Config.objects.create(owner=self.owner, app=self) # Only create if no release can be found try: rel = self.release_set.latest() except Release.DoesNotExist: rel = Release.objects.create( version=1, owner=self.owner, app=self, config=cfg, build=None ) # create required minimum resources in k8s for the application namespace = self.id ingress = self.id service = self.id quota_name = '{}-quota'.format(self.id) try: self.log('creating Namespace {} and services'.format(namespace), level=logging.DEBUG) # Create essential resources try: self._scheduler.ns.get(namespace) except KubeException: try: self._scheduler.ns.create(namespace, settings.ENABLE_ISTIO_INJECTION) except KubeException as e: raise ServiceUnavailable('Could not create the Namespace in Kubernetes') from e if settings.KUBERNETES_NAMESPACE_DEFAULT_QUOTA_SPEC != '': quota_spec = json.loads(settings.KUBERNETES_NAMESPACE_DEFAULT_QUOTA_SPEC) self.log('creating Quota {} for namespace {}'.format(quota_name, namespace), level=logging.DEBUG) try: self._scheduler.quota.get(namespace, quota_name) except KubeException: self._scheduler.quota.create(namespace, quota_name, data=quota_spec) try: self._scheduler.svc.get(namespace, service) except KubeException: self._scheduler.svc.create(namespace, service) except KubeException as e: # Blow it all away only if something horrible happens try: self._scheduler.ns.delete(namespace) except KubeException as e: # Just feed into the item below raise ServiceUnavailable('Could not delete the Namespace in Kubernetes') from e raise ServiceUnavailable('Kubernetes resources could not be created') from e try: # In order to create an ingress, we must first have a namespace. if settings.EXPERIMENTAL_NATIVE_INGRESS: if ingress == "": raise ServiceUnavailable('Empty hostname') try: self._scheduler.ingress.get(ingress) except KubeException: self.log("creating Ingress {}".format(namespace), level=logging.INFO) self._scheduler.ingress.create(ingress, namespace, settings.EXPERIMENTAL_NATIVE_INGRESS_HOSTNAME, settings.EXPERIMENTAL_NATIVE_INGRESS_CLASS) except KubeException as e: raise ServiceUnavailable('Could not create Ingress in Kubernetes') from e try: self.appsettings_set.latest() except AppSettings.DoesNotExist: AppSettings.objects.create(owner=self.owner, app=self) try: self.tls_set.latest() except TLS.DoesNotExist: TLS.objects.create(owner=self.owner, app=self) # Attach the platform specific application sub domain to the k8s service # Only attach it on first release in case a customer has remove the app domain if rel.version == 1 and not Domain.objects.filter(domain=self.id).exists(): Domain(owner=self.owner, app=self, domain=self.id).save()