CreateServiceAsync(Kubernetes k8sClient, V1Service yamlModel, MTAServiceModel serviceModel)
        {
            try
            {
                var namespaceParams = PrepareNamespaceParams(_groupName);
                var serviceParams   = PrepareServiceParams(_serviceName);

                yamlModel.Metadata.Name = serviceParams;
                yamlModel.Spec.Selector = serviceModel.Selectors;

                var v1ServicePorts = new List <V1ServicePort>();
                foreach (var port in serviceModel.Ports)
                {
                    var v1ServicePort = new V1ServicePort(port);
                    v1ServicePorts.Add(v1ServicePort);
                }
                yamlModel.Spec.Ports = v1ServicePorts;

                var v1Service = await k8sClient.CreateNamespacedServiceAsync
                                    (yamlModel, namespaceParams);

                serviceModel = new MTAServiceModel(v1Service);
                return(new Tuple <MTAServiceModel, MTAErrorModel>(serviceModel, null));
            }
            catch (HttpOperationException ex)
            {
                var errorModel = new MTAErrorModel(ex);
                return(new Tuple <MTAServiceModel, MTAErrorModel>(null, errorModel));
            }
            catch (Exception)
            {
                throw;
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Creates an external name <see cref="V1Service"/> for the specified <see cref="Broker"/>
        /// </summary>
        /// <param name="broker">The <see cref="Broker"/> to deploy</param>
        /// <returns>A new awaitable <see cref="Task"/></returns>
        protected virtual async Task CreateBrokerExternalNameServiceAsync(Broker broker)
        {
            V1Service service;

            try
            {
                this.Logger.LogInformation("Creating a new external name service for the broker with name '{resourceName}'...", broker.Name());
                V1ObjectMeta  metadata = new V1ObjectMeta(name: broker.Name());
                V1ServiceSpec spec     = new V1ServiceSpec()
                {
                    Type         = KubernetesDefaults.ServiceTypes.ExternalName,
                    ExternalName = $"gateway.{this.Options.Pod.Namespace}.svc.cluster.local",
                    Ports        = new List <V1ServicePort>()
                    {
                        new V1ServicePort(80, name: "http")
                    }
                };
                service = new V1Service(KubernetesDefaults.ApiVersions.V1, KubernetesDefaults.Kinds.Service, metadata, spec);
                await this.KubernetesClient.CreateNamespacedServiceAsync(service, broker.Namespace());

                this.Logger.LogInformation("A new external name service for the broker with name '{resourceName}' has been successfully created.", broker.Name());
            }
            catch (HttpOperationException ex)
            {
                this.Logger.LogError($"An error occured while creating the external name service for the broker with name '{{resourceName}}': the server responded with a non-success status code '{{statusCode}}'.{Environment.NewLine}Details: {{responseContent}}", broker.Name(), ex.Response.StatusCode, ex.Response.Content);
                return;
            }
        }
Esempio n. 3
0
        public void BuildServiceOperator_ConfiguresService_Test(int sessionPort)
        {
            var builder = FakeOperators.BuildServiceOperator(this.host.Services);

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

            var service = new V1Service();

            builder.ChildFactory(session, service);

            Assert.Collection(
                service.Spec.Selector,
                l =>
            {
                Assert.Equal(Annotations.SessionName, l.Key);
                Assert.Equal("my-session", l.Value);
            });

            var port = Assert.Single(service.Spec.Ports);

            Assert.Equal(sessionPort, port.TargetPort);
            Assert.Equal(sessionPort, port.Port);
        }
Esempio n. 4
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;
            }
        }
        public void Attach(V1Service service)
        {
            ThreadHelper.ThrowIfNotOnUIThread();

            var outWindow = _package.GetService <SVsOutputWindow, IVsOutputWindow>();

            if (_output.TryGetValue(service.Description.Name, out var connector))
            {
                // Ensure logging poller is running
                connector.Start();

                var existingPaneId = connector.PaneId;
                outWindow.GetPane(ref existingPaneId, out var existingPane);
                existingPane.Activate();
                return;
            }

            var paneId = Guid.NewGuid();

            outWindow.CreatePane(ref paneId, $"Tye Explorer - {service.Description.Name}", 1, 0);

            outWindow.GetPane(ref paneId, out var customPane);

            connector = new TyeServiceOutputAdapter(customPane, service, paneId, _package.DisposalToken);
            connector.Start();
            customPane.Activate();

            _output[service.Description.Name] = connector;
        }
Esempio n. 6
0
        private IDictionary <string, string> GetServiceMetadata(V1Service service)
        {
            var serviceMetadata = new Dictionary <string, string>();
            var metadataProps   = _discoveryOptions.Metadata;

            if (metadataProps.AddLabels)
            {
                var labelMetadata = GetDictionaryWithPrefixedKeys(
                    service.Metadata.Labels, metadataProps.LabelsPrefix);
                foreach (var label in labelMetadata)
                {
                    serviceMetadata.Add(label.Key, label.Value);
                }
            }

            if (metadataProps.AddAnnotations)
            {
                var annotationMetadata = GetDictionaryWithPrefixedKeys(
                    service.Metadata.Annotations,
                    metadataProps.AnnotationsPrefix);
                foreach (var annotation in annotationMetadata)
                {
                    serviceMetadata.Add(annotation.Key, annotation.Value);
                }
            }

            return(serviceMetadata);
        }
Esempio n. 7
0
        private async Task AddService(DeployArg arg)
        {
            var body = new V1Service
            {
                Metadata = new V1ObjectMeta
                {
                    Name   = GlobalSetting.RedisServiceName,
                    Labels = new Dictionary <string, string>
                    {
                        { "name", GlobalSetting.RedisServiceName }
                    }
                },
                Spec = new V1ServiceSpec
                {
                    Ports = new List <V1ServicePort>
                    {
                        new V1ServicePort(arg.DBArg.Port)
                    },
                    Selector = new Dictionary <string, string>
                    {
                        { "name", GlobalSetting.RedisName }
                    },
                    ClusterIP = "None"
                }
            };

            await K8SRequestHelper.GetClient().CreateNamespacedServiceAsync(body, arg.SideChainId);
        }
        private V1Service ServiceBody(string name)
        {
            V1Service service = new V1Service();

            service.ApiVersion = "v1";
            service.Kind       = "Service";
            service.Metadata   = new V1ObjectMeta()
            {
                Name = name
            };


            var serviceSpec = new V1ServiceSpec()
            {
                Type = "LoadBalancer", Ports = new List <V1ServicePort>(), Selector = new Dictionary <string, string>()
            };

            serviceSpec.Ports.Add(new V1ServicePort()
            {
                Name = "main", Port = 25565
            });
            serviceSpec.Ports.Add(new V1ServicePort()
            {
                Name = "openhackcheck", Port = 25575
            });
            serviceSpec.Selector.Add("run", name);

            service.Spec = serviceSpec;
            return(service);
        }
Esempio n. 9
0
        public static string CreateAddress(V1Service service, HealthCheckResource resource)
        {
            var defaultPort = int.Parse(resource.Spec.PortNumber ?? Constants.DefaultPort);
            var port        = GetServicePort(service)?.Port ?? defaultPort;
            var address     = service.Spec.ClusterIP;

            string healthScheme = resource.Spec.HealthChecksScheme;

            if (service.Metadata.Annotations?.ContainsKey(Constants.HealthCheckSchemeAnnotation) ?? false)
            {
                healthScheme = service.Metadata.Annotations[Constants.HealthCheckSchemeAnnotation];
            }

            if (string.IsNullOrEmpty(healthScheme))
            {
                healthScheme = Constants.DefaultScheme;
            }

            if (address.Contains(":"))
            {
                return($"{healthScheme}://[{address}]:{port}");
            }
            else
            {
                return($"{healthScheme}://{address}:{port}");
            }
        }
        public static string CreateAddress(V1Service service, HealthCheckResource resource)
        {
            var defaultPort = int.Parse(resource.Spec.PortNumber ?? Constants.DEFAULT_PORT);
            var port        = GetServicePort(service)?.Port ?? defaultPort;
            var address     = service.Spec.ClusterIP;

            string healthScheme = resource.Spec.HealthChecksScheme;

            if (service.Metadata.Annotations?.ContainsKey(Constants.HEALTH_CHECK_SCHEME_ANNOTATION) ?? false)
            {
                healthScheme = service.Metadata.Annotations[Constants.HEALTH_CHECK_SCHEME_ANNOTATION];
            }

            if (healthScheme.IsEmpty())
            {
                healthScheme = Constants.DEFAULT_SCHEME;
            }

            if (address.Contains(":"))
            {
                return($"{healthScheme}://[{address}]:{port}");
            }
            else
            {
                return($"{healthScheme}://{address}:{port}");
            }
        }
Esempio n. 11
0
        private void OnAddUserServiceCommand(UIElement element)
        {
            var addUserServiceControl = new AddUserServiceControl();
            var flyout = new Flyout();

            flyout.Content         = addUserServiceControl;
            flyout.Placement       = PlacementMode.Top;
            flyout.PlacementTarget = element;
            flyout.IsOpen          = true;
            flyout.Background      = addUserServiceControl.Background;

            addUserServiceControl.AddClicked += async(sender, e) =>
            {
                flyout.IsOpen = false;

                var service = new V1Service(
                    addUserServiceControl.SelectedName,
                    addUserServiceControl.SelectedProtocol.Convert(),
                    UInt16.Parse(addUserServiceControl.SelectedPort),
                    true);
                AddUserServiceSelection(service);

                var userServices = new V1UserServices();
                userServices.Services.AddRange(m_userNetworkServices.Select(x => x.Service));
                await NetworkServiceConfigurator.WriteUserServicesAsync(userServices);
            };
        }
        public async Task <IActionResult> GetServiceLog(string serviceName, string namespaceName)
        {
            V1Service     services          = kubeClient.ReadNamespacedService(serviceName, namespaceName);
            var           serviceLabels     = services.Metadata.Labels;
            StringBuilder labelQueryBuilder = new StringBuilder();

            foreach (KeyValuePair <string, string> dictEntry in serviceLabels)
            {
                if (labelQueryBuilder.Length > 0)
                {
                    labelQueryBuilder.Append(",");
                }
                labelQueryBuilder.Append(dictEntry.Key);
                labelQueryBuilder.Append("=");
                labelQueryBuilder.Append(dictEntry.Value);
            }
            var           pods         = kubeClient.ListNamespacedPod(namespaceName, labelSelector: labelQueryBuilder.ToString());
            List <string> logAppendage = new List <string>();

            foreach (var pod in pods.Items)
            {
                using (var stream = await kubeClient.ReadNamespacedPodLogAsync(pod.Metadata.Name, namespaceName))
                {
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        logAppendage.Add(await reader.ReadToEndAsync());
                    }
                    stream.Flush();
                }
            }
            return(Json(logAppendage));
        }
Esempio n. 13
0
 public bool IsAttachable(V1Service service)
 {
     return(service != null &&
            (service.ServiceType == ServiceType.Project ||
             service.ServiceType == ServiceType.Function ||
             service.ServiceType == ServiceType.Executable));
 }
Esempio n. 14
0
        public string CreateAddress(V1Service service)
        {
            string address = string.Empty;

            var port = GetServicePortValue(service);

            switch (service.Spec.Type)
            {
            case ServiceType.LOAD_BALANCER:
            case ServiceType.NODE_PORT:
                address = GetLoadBalancerAddress(service);
                break;

            case ServiceType.CLUSTER_IP:
                address = service.Spec.ClusterIP;
                break;

            case ServiceType.EXTERNAL_NAME:
                address = service.Spec.ExternalName;
                break;
            }

            string healthPath = _settings.HealthPath;

            if (!string.IsNullOrEmpty(_settings.ServicesPathAnnotation) && (service.Metadata.Annotations?.ContainsKey(_settings.ServicesPathAnnotation) ?? false))
            {
                healthPath = service.Metadata.Annotations ![_settings.ServicesPathAnnotation] !;
Esempio n. 15
0
        private void AddService(DeployArg arg)
        {
            var body = new V1Service
            {
                Metadata = new V1ObjectMeta
                {
                    Name   = GlobalSetting.LighthouseServiceName,
                    Labels = new Dictionary <string, string>
                    {
                        { "name", GlobalSetting.LighthouseServiceName }
                    }
                },
                Spec = new V1ServiceSpec
                {
                    Ports = new List <V1ServicePort>
                    {
                        new V1ServicePort(Port)
                    },
                    Selector = new Dictionary <string, string>
                    {
                        { "name", GlobalSetting.LighthouseName }
                    },
                    ClusterIP = "None"
                }
            };

            K8SRequestHelper.GetClient().CreateNamespacedService(body, arg.SideChainId);
        }
Esempio n. 16
0
    public ImmutableList <string> Update(WatchEventType eventType, V1Service service)
    {
        if (service is null)
        {
            throw new ArgumentNullException(nameof(service));
        }

        var serviceName = service.Name();

        lock (_sync)
        {
            if (eventType == WatchEventType.Added || eventType == WatchEventType.Modified)
            {
                _serviceData[serviceName] = new ServiceData(service);
            }
            else if (eventType == WatchEventType.Deleted)
            {
                _serviceData.Remove(serviceName);
            }

            if (_serviceToIngressNames.TryGetValue(serviceName, out var ingressNames))
            {
                return(ingressNames);
            }
            else
            {
                return(ImmutableList <string> .Empty);
            }
        }
    }
Esempio n. 17
0
        private async Task AddService(DeployArg arg)
        {
            var body = new V1Service
            {
                Metadata = new V1ObjectMeta
                {
                    Name   = GlobalSetting.MonitorServiceName,
                    Labels = new Dictionary <string, string>
                    {
                        { "name", GlobalSetting.MonitorServiceName }
                    }
                },
                Spec = new V1ServiceSpec
                {
                    Type  = "LoadBalancer",
                    Ports = new List <V1ServicePort>
                    {
                        new V1ServicePort(GlobalSetting.MonitorPort, "monitor-port", null, "TCP", GlobalSetting.MonitorPort)
                    },
                    Selector = new Dictionary <string, string>
                    {
                        { "name", GlobalSetting.MonitorName }
                    }
                }
            };

            await K8SRequestHelper.GetClient().CreateNamespacedServiceAsync(body, arg.SideChainId);
        }
Esempio n. 18
0
 public void KillWebConsole(string id)
 {
     _logger.LogInformation($"Kill Runspace: {id}");
     try {
         RemoveSrsIngressWebConsolePath(id);
         _client.DeleteNamespacedDeployment(id, _namespace);
         _client.DeleteNamespacedService(id, _namespace);
         // Wait pod to be deleted
         int          maxRetry   = 20;
         int          retryCount = 1;
         V1Deployment deployment = null;
         V1Service    service    = null;
         do
         {
             deployment = null;
             service    = null;
             try {
                 deployment = _client.ReadNamespacedDeployment(id, _namespace);
                 service    = _client.ReadNamespacedService(id, _namespace);
                 Thread.Sleep(100);
             } catch (Exception) { }
             retryCount++;
         } while (deployment != null && service != null && retryCount < maxRetry);
     } catch (Exception exc) {
         _logger.LogError(exc.ToString());
         throw new RunspaceProviderException(
                   Resources.K8sRunspaceProvider_Create_K8sRunspaceCreateFail,
                   exc);
     }
 }
Esempio n. 19
0
        public void SerializeIntOrString()
        {
            var content = @"apiVersion: v1
kind: Service
metadata:
  labels:
    app: test
  name: test-svc
spec:
  ports:
  - port: 3000
    targetPort: 3000";

            var labels = new Dictionary <string, string> {
                { "app", "test" }
            };
            var obj = new V1Service
            {
                Kind       = "Service",
                Metadata   = new V1ObjectMeta(labels: labels, name: "test-svc"),
                ApiVersion = "v1",
                Spec       = new V1ServiceSpec
                {
                    Ports = new List <V1ServicePort> {
                        new V1ServicePort {
                            Port = 3000, TargetPort = 3000
                        }
                    },
                },
            };

            var output = Yaml.SaveToString(obj);

            Assert.Equal(ToLines(output), ToLines(content));
        }
Esempio n. 20
0
        private Dictionary <string, string> GetCurrentServiceConfig(V1ServiceList currentServices)
        {
            return(currentServices.Items.ToDictionary(
                       service =>
            {
                if (service?.Metadata?.Name != null)
                {
                    return service.Metadata.Name;
                }

                Events.InvalidCreationString("service", "null service");
                throw new NullReferenceException("null service in list");
            },
                       service =>
            {
                if (service == null)
                {
                    Events.InvalidCreationString("service", "null service");
                    throw new NullReferenceException("null service in list");
                }

                if (service.Metadata?.Annotations != null &&
                    service.Metadata.Annotations.TryGetValue(Constants.CreationString, out string creationString))
                {
                    return creationString;
                }

                Events.InvalidCreationString(service.Kind, service.Metadata?.Name);

                var serviceWithoutStatus = new V1Service(service.ApiVersion, service.Kind, service.Metadata, service.Spec);
                return JsonConvert.SerializeObject(serviceWithoutStatus);
            }));
        }
Esempio n. 21
0
        public static void Initialize(
            IBDatabaseServiceInterface _DatabaseService,
            IBFileServiceInterface _FileService,
            string _DeploymentBranchName,
            string _DeploymentBuildNumber,
            string _CadProcessServiceName,
            Dictionary <string, string> _FileWorkerEnvironmentVariables,
            System.Action _InitFailedAction,
            Action <string> _ErrorMessageAction = null)
        {
            FileWorkerEnvironmentVariables = _FileWorkerEnvironmentVariables;
            DeploymentBranchName           = _DeploymentBranchName;
            DeploymentBuildNumber          = _DeploymentBuildNumber;


            FileService     = _FileService;
            DatabaseService = _DatabaseService;
            Instance        = new BatchProcessingCreationService();

            string CadProcessServiceName = _CadProcessServiceName;

            BTaskWrapper.Run(() =>
            {
                while (true)
                {
                    try
                    {
                        V1Service CadProcessService = Instance.K8sManager.GetServiceByNameAndNamespace(CadProcessServiceName, SERVICE_NAMESPACE);

                        if (CadProcessService != null &&
                            CadProcessService.Status != null &&
                            CadProcessService.Status.LoadBalancer != null &&
                            CadProcessService.Status.LoadBalancer.Ingress != null &&
                            CadProcessService.Status.LoadBalancer.Ingress.Any()

                            && CadProcessService.Spec != null &&
                            CadProcessService.Spec.Ports != null &&
                            CadProcessService.Spec.Ports.Any() &&
                            !string.IsNullOrWhiteSpace(CadProcessService.Status.LoadBalancer.Ingress.First().Ip))
                        {
                            CadProcessUrl = $"http://{CadProcessService.Status.LoadBalancer.Ingress.First().Ip}:{CadProcessService.Spec.Ports.First().Port}/";
                            WaitInit.Set();
                            break;
                        }
                        else
                        {
                            Thread.Sleep(1000);
                        }
                    }
                    catch (Exception ex)
                    {
                        _ErrorMessageAction?.Invoke($"Failed to initialize Batch process environment: {ex.Message}\n{ex.StackTrace}");
                        //If we fail at this point then it means the cluster master endpoint is unavailable or there is no ingress which means batch process can't system can't initialize.
                        //This can happen instantly or 5 minutes after the program started depending on if an ingress is still being created and how long it takes so decide what to do in provided action
                        _InitFailedAction.Invoke();
                    }
                }
            });
        }
Esempio n. 22
0
        public void Update(WatchEventType eventType, V1Service service)
        {
            if (service is null)
            {
                throw new ArgumentNullException(nameof(service));
            }

            Namespace(service.Namespace()).Update(eventType, service);
        }
Esempio n. 23
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, V1Service resource)
    {
        var ingressNames = _cache.Update(eventType, resource);

        if (ingressNames.Count > 0)
        {
            NotificationIngressChanged();
        }
    }
Esempio n. 24
0
    public ImmutableList <string> Update(WatchEventType eventType, V1Service service)
    {
        if (service is null)
        {
            throw new ArgumentNullException(nameof(service));
        }

        return(Namespace(service.Namespace()).Update(eventType, service));
    }
Esempio n. 25
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, V1Service resource)
    {
        var ingressNames = _cache.Update(eventType, resource);

        if (ingressNames.Count > 0)
        {
            _queue.Add(_ingressChangeQueueItem);
        }
    }
Esempio n. 26
0
        public async Task InstallService(V1Service service, string nameSpace = "default")
        {
            var runningService = await GetService("rabbitmq-service", nameSpace);

            if (runningService == null)
            {
                await _client.CreateNamespacedServiceWithHttpMessagesAsync(service, nameSpace);
            }
        }
Esempio n. 27
0
        public ServiceData(V1Service service)
        {
            if (service is null)
            {
                throw new ArgumentNullException(nameof(service));
            }

            Spec     = service.Spec;
            Metadata = service.Metadata;
        }
Esempio n. 28
0
        public UserNetworkService(V1Service service, bool isEnabled)
        {
            if (service == null)
            {
                throw new ArgumentNullException("service");
            }

            m_service   = service;
            m_isEnabled = isEnabled;
        }
        private async Task <bool> AddService(DeployArg arg)
        {
            var body = new V1Service
            {
                Metadata = new V1ObjectMeta
                {
                    Name   = GlobalSetting.LauncherServiceName,
                    Labels = new Dictionary <string, string>
                    {
                        { "name", GlobalSetting.LauncherServiceName }
                    }
                },
                Spec = new V1ServiceSpec
                {
                    Type  = "LoadBalancer",
                    Ports = new List <V1ServicePort>
                    {
                        new V1ServicePort(GlobalSetting.NodePort, "node-port", null, "TCP", GlobalSetting.NodePort),
                        new V1ServicePort(GlobalSetting.RpcPort, "rpc-port", null, "TCP", GlobalSetting.RpcPort),
                        new V1ServicePort(GlobalSetting.GrpcPort, "grpc-port", null, "TCP", GlobalSetting.GrpcPort)
                    },
                    Selector = new Dictionary <string, string>
                    {
                        { "name", GlobalSetting.LauncherName }
                    }
                }
            };

            var result = await K8SRequestHelper.GetClient().CreateNamespacedServiceAsync(body, arg.SideChainId);

            var service = await K8SRequestHelper.GetClient().ReadNamespacedServiceAsync(result.Metadata.Name, arg.SideChainId);

            var retryGetCount = 0;

            while (true)
            {
                arg.LauncherArg.ClusterIp = service.Spec.ClusterIP;
                if (!string.IsNullOrWhiteSpace(arg.LauncherArg.ClusterIp))
                {
                    break;
                }

                if (retryGetCount > GlobalSetting.DeployRetryTime)
                {
                    return(false);
                }

                retryGetCount++;
                Thread.Sleep(3000);
                service = await K8SRequestHelper.GetClient().ReadNamespacedServiceAsync(result.Metadata.Name, arg.SideChainId);
            }

            return(true);
        }
        private static string GetLoadBalancerAddress(V1Service service)
        {
            var ingress = service.Status.LoadBalancer?.Ingress?.FirstOrDefault();

            if (ingress != null)
            {
                return(ingress.Hostname ?? ingress.Ip);
            }

            return(service.Spec.ClusterIP);
        }