コード例 #1
0
 /// <summary>
 /// Called by the informer with real-time resource updates.
 /// </summary>
 /// <param name="eventType">Indicates if the resource new, updated, or deleted.</param>
 /// <param name="resource">The information as provided by the Kubernetes API server.</param>
 private void Notification(WatchEventType eventType, V1Ingress resource)
 {
     if (_cache.Update(eventType, resource))
     {
         NotificationIngressChanged();
     }
 }
コード例 #2
0
    public bool Update(WatchEventType eventType, V1Ingress ingress)
    {
        if (ingress is null)
        {
            throw new ArgumentNullException(nameof(ingress));
        }

        if (IsYarpIngress(ingress.Spec))
        {
            Namespace(ingress.Namespace()).Update(eventType, ingress);
            return(true);
        }

#pragma warning disable CA1303 // Do not pass literals as localized parameters
        if (eventType == WatchEventType.Modified && Namespace(ingress.Namespace()).IngressExists(ingress))
        {
            // Special handling for an ingress that has the ingressClassName removed
            _logger.LogInformation("Removing ingress {IngressNamespace}/{IngressName} because of unknown ingress class", ingress.Metadata.NamespaceProperty, ingress.Metadata.Name);
            Namespace(ingress.Namespace()).Update(WatchEventType.Deleted, ingress);
            return(true);
        }

        _logger.LogInformation("Ignoring ingress {IngressNamespace}/{IngressName} because of ingress class", ingress.Metadata.NamespaceProperty, ingress.Metadata.Name);
#pragma warning restore CA1303 // Do not pass literals as localized parameters

        return(false);
    }
コード例 #3
0
        private async Task AddIngress(V1Ingress ingress, CancellationToken cancellation)
        {
            var legacyIngressClass = ingress.LegacyIngressClass();

            if (!IngressMatch(ingress, legacyIngressClass))
            {
                _logger.LogInformation($"Ignoring ingress ingress={ingress.Metadata.NamespaceProperty}/{ingress.Metadata.Name} kubernetes.io/ingress.class={legacyIngressClass} ingressClassName={ingress.Spec.IngressClassName}");
                return;
            }

            var model  = ingress.ToModel();
            var objRef = new V1ObjectReference
            {
                Kind              = V1Ingress.KubeKind,
                ApiVersion        = V1Ingress.KubeGroup + "/" + V1Ingress.KubeApiVersion,
                Name              = model.Name,
                NamespaceProperty = model.Namespace,
                Uid             = ingress.Metadata.Uid,
                ResourceVersion = ingress.Metadata.ResourceVersion,
            };

            await _eventRecorder.CreateEvent(objRef, KubeEvent.EventType.Normal, "Sync", "Scheduled for sync", cancellation);

            var key = ingress.Metadata.Uid;

            _ingresses.AddOrUpdate(key, a => model, (s, u) => model);

            RaiseChanged();
        }
コード例 #4
0
ファイル: IngressCache.cs プロジェクト: endless001/Sail
 public void Update(WatchEventType eventType, V1Ingress ingress)
 {
     if (ingress is null)
     {
         throw new ArgumentNullException(nameof(ingress));
     }
 }
コード例 #5
0
        public static string LegacyIngressClass(this V1Ingress ingress)
        {
            if (ingress != null && ingress.Metadata.Annotations.TryGetValue("kubernetes.io/ingress.class", out var legacyIngressClass))
            {
                return(legacyIngressClass);
            }

            return(null);
        }
コード例 #6
0
 public static IngressModel ToModel(this V1Ingress ingress)
 {
     return(new IngressModel
     {
         Name = ingress.Metadata.Name,
         Namespace = ingress.Metadata.NamespaceProperty,
         Rules = ingress.Spec.Rules.Select(r => r.ToModel()),
         Original = ingress,
     });
 }
コード例 #7
0
        public IngressData(V1Ingress ingress)
        {
            if (ingress is null)
            {
                throw new ArgumentNullException(nameof(ingress));
            }

            Spec     = ingress.Spec;
            Metadata = ingress.Metadata;
        }
コード例 #8
0
        private void DeleteIngress(V1Ingress ingress)
        {
            var legacyIngressClass = ingress.LegacyIngressClass();

            if (!IngressMatch(ingress, legacyIngressClass))
            {
                return;
            }

            var key = ingress.Metadata.Uid;

            _ingresses.TryRemove(key, out var dummy);

            RaiseChanged();
        }
コード例 #9
0
        private void UpdateIngress(V1Ingress ingress)
        {
            var legacyIngressClass = ingress.LegacyIngressClass();

            if (!IngressMatch(ingress, legacyIngressClass))
            {
                return;
            }

            var model = ingress.ToModel();
            var key   = ingress.Metadata.Uid;

            _ingresses.AddOrUpdate(key, a => model, (s, u) => model);

            RaiseChanged();
        }
コード例 #10
0
    public static V1Ingress CreateIngress(string name, string namespaceName, string ingressClassName)
    {
        var ingress = new V1Ingress
        {
            Spec     = new V1IngressSpec(),
            Metadata = new V1ObjectMeta
            {
                Name = name,
                NamespaceProperty = namespaceName,
            }
        };

        if (!string.IsNullOrEmpty(ingressClassName))
        {
            ingress.Spec.IngressClassName = ingressClassName;
        }

        return(ingress);
    }
コード例 #11
0
        public void BuildIngressOperator_ConfiguresIngress_Test(int sessionPort)
        {
            var builder = FakeOperators.BuildIngressOperator(this.host.Services);

            var session = new WebDriverSession()
            {
                Metadata = new V1ObjectMeta()
                {
                    Name = "my-session",
                },
                Status = new WebDriverSessionStatus()
                {
                    SessionId   = "1234",
                    SessionPort = sessionPort,
                },
            };

            var ingress = new V1Ingress();

            builder.ChildFactory(session, ingress);

            var rule = Assert.Single(ingress.Spec.Rules);
            var path = Assert.Single(rule.Http.Paths);

            Assert.Equal("/wd/hub/session/my-session/", path.Path);
            Assert.Equal("Prefix", path.PathType);
            Assert.Equal("my-session", path.Backend.Service.Name);
            Assert.Equal(sessionPort, path.Backend.Service.Port.Number);

            Assert.NotNull(ingress.Metadata?.Annotations);
            Assert.Collection(
                ingress.Metadata.Annotations,
                a =>
            {
                Assert.Equal(Annotations.RequestModifier, a.Key);
                Assert.Equal("ReplacePathRegex: /wd/hub/session/my-session/(.*) /wd/hub/session/1234/$1", a.Value);
            },
                a =>
            {
                Assert.Equal(Annotations.IngressClass, a.Key);
                Assert.Equal("traefik", a.Value);
            });
        }
コード例 #12
0
 /// <summary>
 /// Called by the informer with real-time resource updates.
 /// </summary>
 /// <param name="eventType">Indicates if the resource new, updated, or deleted.</param>
 /// <param name="resource">The information as provided by the Kubernets API server.</param>
 private void Notification(WatchEventType eventType, V1Ingress resource)
 {
     _cache.Update(eventType, resource);
     _queue.Add(new QueueItem(NamespacedName.From(resource), null));
 }
コード例 #13
0
    public void Update(WatchEventType eventType, V1Ingress ingress)
    {
        if (ingress is null)
        {
            throw new ArgumentNullException(nameof(ingress));
        }

        var serviceNames = ImmutableList <string> .Empty;

        if (eventType == WatchEventType.Added || eventType == WatchEventType.Modified)
        {
            // If the ingress exists, list out the related services
            var spec           = ingress.Spec;
            var defaultBackend = spec?.DefaultBackend;
            var defaultService = defaultBackend?.Service;
            if (!string.IsNullOrEmpty(defaultService?.Name))
            {
                serviceNames = serviceNames.Add(defaultService.Name);
            }

            foreach (var rule in spec.Rules ?? Enumerable.Empty <V1IngressRule>())
            {
                var http = rule.Http;
                foreach (var path in http.Paths ?? Enumerable.Empty <V1HTTPIngressPath>())
                {
                    var backend = path.Backend;
                    var service = backend.Service;

                    if (!serviceNames.Contains(service.Name))
                    {
                        serviceNames = serviceNames.Add(service.Name);
                    }
                }
            }
        }

        var ingressName = ingress.Name();

        lock (_sync)
        {
            var serviceNamesPrevious = ImmutableList <string> .Empty;
            if (eventType == WatchEventType.Added || eventType == WatchEventType.Modified)
            {
                // If the ingress exists then remember details

                _ingressData[ingressName] = new IngressData(ingress);

                if (_ingressToServiceNames.TryGetValue(ingressName, out serviceNamesPrevious))
                {
                    _ingressToServiceNames[ingressName] = serviceNames;
                }
                else
                {
                    serviceNamesPrevious = ImmutableList <string> .Empty;
                    _ingressToServiceNames.Add(ingressName, serviceNames);
                }
            }
            else if (eventType == WatchEventType.Deleted)
            {
                // otherwise clear out details

                _ingressData.Remove(ingressName);

                if (_ingressToServiceNames.TryGetValue(ingressName, out serviceNamesPrevious))
                {
                    _ingressToServiceNames.Remove(ingressName);
                }
            }

            // update cross-reference for new ingress-to-services linkage not previously known
            foreach (var serviceName in serviceNames)
            {
                if (!serviceNamesPrevious.Contains(serviceName))
                {
                    if (_serviceToIngressNames.TryGetValue(serviceName, out var ingressNamesPrevious))
                    {
                        _serviceToIngressNames[serviceName] = _serviceToIngressNames[serviceName].Add(ingressName);
                    }
                    else
                    {
                        _serviceToIngressNames.Add(serviceName, ImmutableList <string> .Empty.Add(ingressName));
                    }
                }
            }

            // remove cross-reference for previous ingress-to-services linkage no longer present
            foreach (var serviceName in serviceNamesPrevious)
            {
                if (!serviceNames.Contains(serviceName))
                {
                    _serviceToIngressNames[serviceName] = _serviceToIngressNames[serviceName].Remove(ingressName);
                }
            }
        }
    }
コード例 #14
0
 public bool IngressExists(V1Ingress ingress)
 {
     return(_ingressData.ContainsKey(ingress.Name()));
 }
コード例 #15
0
 private bool IngressMatch(V1Ingress ingress, string legacyIngressClass)
 {
     return(string.Equals(ingress.Spec.IngressClassName, MatchingIngressClass, StringComparison.OrdinalIgnoreCase) ||
            string.Equals(legacyIngressClass, MatchingIngressClass, StringComparison.OrdinalIgnoreCase));
 }
コード例 #16
0
 /// <summary>
 /// Called by the informer with real-time resource updates.
 /// </summary>
 /// <param name="eventType">Indicates if the resource new, updated, or deleted.</param>
 /// <param name="resource">The information as provided by the Kubernets API server.</param>
 private void Notification(WatchEventType eventType, V1Ingress resource)
 {
     _cache.Update(eventType, resource);
     _queue.Add(_ingressChangeQueueItem);
 }