Example #1
0
        /// <summary>
        /// Creates a new <see cref="V1Service"/> for the specified <see cref="Resources.Channel"/>
        /// </summary>
        /// <param name="channel">The <see cref="Resources.Channel"/> to deploy</param>
        /// <returns>A new awaitable <see cref="Task"/></returns>
        protected virtual async Task CreateChannelServiceAsync(Resources.Channel channel)
        {
            V1Service service;

            try
            {
                this.Logger.LogInformation("Creating a new service for the channel with name '{resourceName}'...", channel.Name());
                V1ObjectMeta serviceMetadata = new V1ObjectMeta();
                serviceMetadata.Name = channel.Name();
                serviceMetadata.NamespaceProperty = channel.Namespace();
                serviceMetadata.Labels            = new Dictionary <string, string>()
                {
                    { "app", channel.Name() },
                    { "type", "channel" }
                };
                V1ServiceSpec serviceSpec = new V1ServiceSpec();
                serviceSpec.Ports = new List <V1ServicePort>()
                {
                    new V1ServicePort(80, name: "http")
                };
                serviceSpec.Selector = new Dictionary <string, string>()
                {
                    { "app", channel.Name() }
                };
                service = new V1Service(KubernetesDefaults.ApiVersions.V1, KubernetesDefaults.Kinds.Service, serviceMetadata, serviceSpec);
                await this.KubernetesClient.CreateNamespacedServiceAsync(service, channel.Namespace());

                this.Logger.LogInformation("A new service for the channel with name '{resourceName}' has been successfully created.", channel.Name());
            }
            catch (HttpOperationException ex)
            {
                this.Logger.LogError($"An error occured while creating the service for the channel with name '{{resourceName}}': the server responded with a non-success status code '{{statusCode}}'.{Environment.NewLine}Details: {{responseContent}}", channel.Name(), ex.Response.StatusCode, ex.Response.Content);
                throw;
            }
        }
Example #2
0
        /// <summary>
        /// Handles a <see cref="Resources.Channel"/> event
        /// </summary>
        /// <param name="e">The type of event to handle</param>
        /// <param name="channel">The <see cref="Resources.Channel"/> the event to handle applies to</param>
        protected virtual async void OnChannelEvent(WatchEventType e, Resources.Channel channel)
        {
            this.Logger.LogInformation("A new event of type '{watchEventType}' concerning the CRD of kind '{crdKind}' with name '{crdName}' has been received.", e, channel.Kind, channel.Name());
            switch (e)
            {
            case WatchEventType.Added:
                await this.DeployChannelAsync(channel);

                break;

            case WatchEventType.Modified:

                break;

            case WatchEventType.Deleted:
                await this.DeleteChannelAsync(channel);

                break;

            case WatchEventType.Bookmark:

                break;

            case WatchEventType.Error:

                break;

            default:
                throw new NotSupportedException($"The specified watch event type '{e}' is not supported");
            }
        }
Example #3
0
        /// <summary>
        /// Deletes an existing <see cref="Resources.Channel"/>
        /// </summary>
        /// <param name="channel">The <see cref="Resources.Channel"/> to delete</param>
        /// <returns>A new awaitable <see cref="Task"/></returns>
        protected virtual async Task DeleteChannelAsync(Resources.Channel channel)
        {
            try
            {
                this.UnregisterChannel(channel);
                await this.DeleteChannelServiceAsync(channel);

                await this.DeleteChannelDeploymentAsync(channel);
            }
            catch
            {
            }
        }
Example #4
0
        /// <summary>
        /// Creates a new <see cref="V1Deployment"/> for the specified <see cref="Resources.Channel"/>
        /// </summary>
        /// <param name="channel">The <see cref="Resources.Channel"/> to deploy</param>
        /// <returns>A new awaitable <see cref="Task"/></returns>
        protected virtual async Task CreateChannelDeploymentAsync(Resources.Channel channel)
        {
            V1Deployment deployment;

            try
            {
                this.Logger.LogInformation("Creating a new deployment for the channel with name '{resourceName}'...", channel.Name());
                V1PodSpec   podSpec   = new V1PodSpec();
                V1Container container = channel.Spec.Container;
                container.Env.Add(new V1EnvVar("SINK", $"http://gateway.{channel.Namespace()}.svc.cluster.local/events/"));
                podSpec.Containers = new List <V1Container>()
                {
                    container
                };
                V1ObjectMeta podMetadata = new V1ObjectMeta();
                podMetadata.Annotations = new Dictionary <string, string>()
                {
                    { "sidecar.istio.io/inject", "true" }
                };
                V1PodTemplateSpec podTemplateSpec = new V1PodTemplateSpec(podMetadata, podSpec);
                podTemplateSpec.Metadata.Labels = new Dictionary <string, string>()
                {
                    { "app", channel.Name() },
                    { "version", "1.0" }
                };
                V1DeploymentSpec deploymentSpec = new V1DeploymentSpec(new V1LabelSelector(), podTemplateSpec);
                deploymentSpec.Selector.MatchLabels = new Dictionary <string, string>()
                {
                    { "app", channel.Name() },
                    { "version", "1.0" }
                };
                V1ObjectMeta deploymentMetadata = new V1ObjectMeta(namespaceProperty: channel.Namespace(), name: channel.Name());
                deploymentMetadata.Labels = new Dictionary <string, string>()
                {
                    { "type", EventingDefaults.Labels.Channel }
                };
                deploymentMetadata.Name = channel.Name();
                deploymentMetadata.NamespaceProperty = channel.Namespace();
                deployment = new V1Deployment(KubernetesDefaults.ApiVersions.AppsV1, KubernetesDefaults.Kinds.Deployment, deploymentMetadata, deploymentSpec);
                await this.KubernetesClient.CreateNamespacedDeploymentAsync(deployment, channel.Namespace());

                this.Logger.LogInformation("A new deployment for the channel with name '{resourceName}' has been successfully created.", channel.Name());
            }
            catch (HttpOperationException ex)
            {
                this.Logger.LogError($"An error occured while creating the deployment for the channel with name '{{resourceName}}': the server responded with a non-success status code '{{statusCode}}'.{Environment.NewLine}Details: {{responseContent}}", channel.Name(), ex.Response.StatusCode, ex.Response.Content);
                throw;
            }
        }
Example #5
0
        /// <summary>
        /// Deletes the <see cref="V1Deployment"/> for the specified <see cref="Resources.Channel"/>
        /// </summary>
        /// <param name="channel">The <see cref="Resources.Channel"/> to delete</param>
        /// <returns>A new awaitable <see cref="Task"/></returns>
        protected virtual async Task DeleteChannelDeploymentAsync(Resources.Channel channel)
        {
            try
            {
                this.Logger.LogInformation("Deleting the deployment for the channel with name '{resourceName}'...", channel.Name());
                await this.KubernetesClient.DeleteNamespacedDeploymentAsync(channel.Name(), channel.Namespace());

                this.Logger.LogInformation("The deployment for the channel with name '{resourceName}' has been successfully deleted.", channel.Name());
            }
            catch (HttpOperationException ex)
            {
                this.Logger.LogError($"An error occured while deleting the deployment for the channel with name '{{resourceName}}': the server responded with a non-success status code '{{statusCode}}'.{Environment.NewLine}Details: {{responseContent}}", channel.Name(), ex.Response.StatusCode, ex.Response.Content);
                throw;
            }
        }
Example #6
0
 /// <summary>
 /// Unregisters the specified <see cref="Resources.Channel"/>
 /// </summary>
 /// <param name="channel">The <see cref="Resources.Channel"/> to unregister</param>
 protected virtual void UnregisterChannel(Resources.Channel channel)
 {
     this.ChannelManager.UnregisterChannel(channel.Name());
 }
Example #7
0
 /// <summary>
 /// Registers the specified <see cref="Resources.Channel"/>
 /// </summary>
 /// <param name="channel">The <see cref="Resources.Channel"/> to register</param>
 protected virtual void RegisterChannel(Resources.Channel channel)
 {
     this.ChannelManager.RegisterChannel(channel.Name(), new Uri($"http://{channel.Name()}/events/"));
 }