public async void ReadDeploymentConfigFromSecret()
        {
            ISerde <DeploymentConfigInfo> serde = this.GetSerde();

            var secretData = new Dictionary <string, byte[]>
            {
                ["backup.json"] = System.Text.Encoding.UTF8.GetBytes(serde.Serialize(ValidConfigInfo1))
            };
            var secret   = new V1Secret(data: secretData);
            var response = new HttpOperationResponse <V1Secret>()
            {
                Body     = secret,
                Response = new HttpResponseMessage(HttpStatusCode.OK)
            };

            var client = new Mock <IKubernetes>(MockBehavior.Strict);

            client.Setup(c => c.ReadNamespacedSecretWithHttpMessagesAsync(DefaultSecretName, DefaultNamespace, It.IsAny <bool?>(), It.IsAny <bool?>(), null, null, It.IsAny <CancellationToken>()))
            .ReturnsAsync(response);

            var backupSource         = new DeploymentSecretBackup(DefaultSecretName, DefaultNamespace, DefaultOwner, serde, client.Object);
            var deploymentConfigInfo = await backupSource.ReadFromBackupAsync();

            string returnedJson = serde.Serialize(deploymentConfigInfo);
            string expectedJson = serde.Serialize(ValidConfigInfo1);

            Assert.Equal(expectedJson, returnedJson, ignoreCase: true);
            client.VerifyAll();
        }
        public async void DeserializeFaillureReturnsEmptyConfig()
        {
            ISerde<DeploymentConfigInfo> serde = this.GetSerde();

            var secretData = new Dictionary<string, byte[]>
            {
                ["backup.json"] = System.Text.Encoding.UTF8.GetBytes("{}")
            };
            var secret = new V1Secret(data: secretData);
            var response = new HttpOperationResponse<V1Secret>()
            {
                Body = secret,
                Response = new HttpResponseMessage(HttpStatusCode.OK)
            };

            var client = new Mock<IKubernetes>(MockBehavior.Strict);
            client.Setup(c => c.ReadNamespacedSecretWithHttpMessagesAsync(
                    DefaultSecretName,
                    DefaultNamespace,
                    It.IsAny<string>(), // pretty
                    null, // customHeaders
                    It.IsAny<CancellationToken>()))
                .ReturnsAsync(response);

            var backupSource = new DeploymentSecretBackup(DefaultSecretName, DefaultNamespace, DefaultOwner, serde, client.Object);
            var deploymentConfigInfo = await backupSource.ReadFromBackupAsync();

            Assert.NotNull(deploymentConfigInfo);
            Assert.Equal(DeploymentConfigInfo.Empty, deploymentConfigInfo);
            client.VerifyAll();
        }
Exemplo n.º 3
0
        private void EnsureServiceAccountToken(User user)
        {
            var groupNamespaceName = user.Spec.GetGroupNamespace();
            var tokenName          = $"{user.Metadata.Name}-token";
            var tokens             = _client.ListNamespacedSecret(groupNamespaceName,
                                                                  fieldSelector: $"metadata.name={tokenName}");

            if (!tokens.Items.Any())
            {
                var secret = new V1Secret
                {
                    Metadata = new V1ObjectMeta
                    {
                        Name   = tokenName,
                        Labels = new Dictionary <string, string>()
                        {
                            { "kiamol", "ch20" },
                        },
                        Annotations = new Dictionary <string, string>()
                        {
                            { "kubernetes.io/service-account.name", user.Metadata.Name },
                        }
                    },
                    Type = "kubernetes.io/service-account-token"
                };
                _client.CreateNamespacedSecret(secret, groupNamespaceName);
                Console.WriteLine($"** Created token: {tokenName}, in group namespace: {groupNamespaceName}");
            }
            else
            {
                Console.WriteLine($"** Token exists: {tokenName}, in group namespace: {groupNamespaceName}");
            }
        }
        public async void BackupDeploymentDoesNotThrowOnFailure()
        {
            ISerde <DeploymentConfigInfo> serde = this.GetSerde();

            string expectedJson   = serde.Serialize(ValidConfigInfo1);
            var    readSecretData = new Dictionary <string, byte[]>
            {
                ["backup.json"] = System.Text.Encoding.UTF8.GetBytes(serde.Serialize(ValidConfigInfo2))
            };
            var readSecret        = new V1Secret(data: readSecretData);
            var replaceSecretData = new Dictionary <string, byte[]>
            {
                ["backup.json"] = System.Text.Encoding.UTF8.GetBytes(expectedJson)
            };
            var replaceSecret = new V1Secret(data: readSecretData);
            var readResponse  = new HttpOperationResponse <V1Secret>()
            {
                Body     = readSecret,
                Response = new HttpResponseMessage(HttpStatusCode.OK)
            };

            var client = new Mock <IKubernetes>(MockBehavior.Strict);

            client.Setup(c => c.ReadNamespacedSecretWithHttpMessagesAsync(DefaultSecretName, DefaultNamespace, It.IsAny <bool?>(), It.IsAny <bool?>(), null, null, It.IsAny <CancellationToken>()))
            .ReturnsAsync(readResponse);
            client.Setup(c => c.ReplaceNamespacedSecretWithHttpMessagesAsync(It.IsAny <V1Secret>(), DefaultSecretName, DefaultNamespace, null, null, null, null, It.IsAny <CancellationToken>()))
            .ThrowsAsync(new HttpOperationException("Not Permitted"));

            var backupSource = new DeploymentSecretBackup(DefaultSecretName, DefaultNamespace, DefaultOwner, serde, client.Object);
            await backupSource.BackupDeploymentConfigAsync(ValidConfigInfo1);

            client.VerifyAll();
        }
        public async void BackupDeploymentConfigReplacesSecret()
        {
            ISerde<DeploymentConfigInfo> serde = this.GetSerde();

            string expectedJson = serde.Serialize(ValidConfigInfo1);
            var readSecretData = new Dictionary<string, byte[]>
            {
                ["backup.json"] = System.Text.Encoding.UTF8.GetBytes(serde.Serialize(ValidConfigInfo2))
            };
            var readSecret = new V1Secret(data: readSecretData);
            var replaceSecretData = new Dictionary<string, byte[]>
            {
                ["backup.json"] = System.Text.Encoding.UTF8.GetBytes(expectedJson)
            };
            var replaceSecret = new V1Secret(data: readSecretData);
            var readResponse = new HttpOperationResponse<V1Secret>()
            {
                Body = readSecret,
                Response = new HttpResponseMessage(HttpStatusCode.OK)
            };
            var replaceResponse = new HttpOperationResponse<V1Secret>()
            {
                Body = replaceSecret,
                Response = new HttpResponseMessage(HttpStatusCode.OK)
            };

            byte[] receivedData = default(byte[]);
            var client = new Mock<IKubernetes>(MockBehavior.Strict);
            client.Setup(c => c.ReadNamespacedSecretWithHttpMessagesAsync(
                    DefaultSecretName,
                    DefaultNamespace,
                    It.IsAny<string>(), // pretty
                    null, // customHeaders
                    It.IsAny<CancellationToken>()))
                .ReturnsAsync(readResponse);
            client.Setup(c => c.ReplaceNamespacedSecretWithHttpMessagesAsync(
                    It.IsAny<V1Secret>(),
                    DefaultSecretName,
                    DefaultNamespace,
                    null, // dryRun
                    null, // fieldmanager
                    null, // pretty
                    null, // customHeaders
                    It.IsAny<CancellationToken>()))
                .Callback((V1Secret body, string name, string namespaceParameter, string dryRun, string fieldManager, string pretty, Dictionary<string, List<string>> customHeaders, CancellationToken cancellationToken) =>
                {
                    Assert.True(body.Data != null);
                    Assert.True(body.Data.TryGetValue("backup.json", out receivedData));
                })
                .ReturnsAsync(replaceResponse);

            var backupSource = new DeploymentSecretBackup(DefaultSecretName, DefaultNamespace, DefaultOwner, serde, client.Object);
            await backupSource.BackupDeploymentConfigAsync(ValidConfigInfo1);

            string backupJson = System.Text.Encoding.UTF8.GetString(receivedData);

            Assert.Equal(expectedJson, backupJson, ignoreCase: true);
            client.VerifyAll();
        }
Exemplo n.º 6
0
        public void ReturnsFalseIfFieldsAreDifferent()
        {
            var x = new V1Secret
            {
                Metadata = new V1ObjectMeta
                {
                    Annotations = new Dictionary <string, string>
                    {
                        [KubernetesConstants.K8sEdgeOriginalModuleId] = "Object1"
                    },
                    Labels = new Dictionary <string, string>
                    {
                        [KubernetesConstants.K8sEdgeDeviceLabel]  = "device1",
                        [KubernetesConstants.K8sEdgeHubNameLabel] = "hostname"
                    },
                    Name = "object1"
                },
                Data = new Dictionary <string, byte[]>
                {
                    [KubernetesConstants.K8sPullSecretData] = new byte[] { 1 }
                }
            };
            var y = new V1Secret
            {
                Metadata = new V1ObjectMeta
                {
                    Annotations = new Dictionary <string, string>
                    {
                        [KubernetesConstants.K8sEdgeOriginalModuleId] = "Object1"
                    },
                    Labels = new Dictionary <string, string>
                    {
                        [KubernetesConstants.K8sEdgeDeviceLabel]  = "device1",
                        [KubernetesConstants.K8sEdgeHubNameLabel] = "hostname"
                    },
                    Name = "object1"
                },
                Data = new Dictionary <string, byte[]>
                {
                    [KubernetesConstants.K8sPullSecretData] = new byte[] { 1 }
                }
            };

            Assert.True(Comparer.Equals(x, y));

            y.Metadata.Name = "object2";
            Assert.False(Comparer.Equals(x, y));

            y.Metadata.Name = "object1";
            Assert.True(Comparer.Equals(x, y));

            y.Metadata.Labels = new Dictionary <string, string>
            {
                ["newkey2"] = "Object1"
            };
            Assert.False(Comparer.Equals(x, y));
        }
Exemplo n.º 7
0
        /// <summary>
        /// Converts this <see cref="V1Secret"/> to a <see cref="X509Certificate2"/>.
        /// </summary>
        /// <param name="secret">
        /// A <see cref="V1Secret"/> which represents a Kubernetes TLS secret.
        /// </param>
        /// <returns>
        /// The equivalent <see cref="X509Certificate2"/> value.
        /// </returns>
        public static X509Certificate2 AsX509Certificate2(this V1Secret secret)
        {
            EnsureTlsSecret(secret);

            // Both DER-encoded
            return(X509Certificate2.CreateFromPem(
                       Encoding.UTF8.GetString(secret.Data[TlsCertificate]),
                       Encoding.UTF8.GetString(secret.Data[TlsPrivateKey])));
        }
Exemplo n.º 8
0
        /// <summary>
        /// Converts this <see cref="V1Secret"/> to a <see cref="SignedCms"/>.
        /// </summary>
        /// <param name="secret">
        /// A <see cref="V1Secret"/> which represents CMS signed data.
        /// </param>
        /// <returns>
        /// The equivalent <see cref="SignedCms"/> value.
        /// </returns>
        public static SignedCms AsSignedCms(this V1Secret secret)
        {
            EnsureProvisioningProfileSecret(secret);

            SignedCms cms = new SignedCms();

            cms.Decode(secret.Data[SignedDataContent]);
            return(cms);
        }
Exemplo n.º 9
0
        public Task <V1Secret> UpdatePrometheusScrapeConfigSecretAsync(V1Secret secret, CancellationToken cancellationToken)
        {
            Init();

            return(_client.ReplaceNamespacedSecretAsync(
                       secret,
                       secret.Name(),
                       secret.Namespace(),
                       cancellationToken: cancellationToken));
        }
Exemplo n.º 10
0
        //---------------------------------------------------------------------
        // $note(jefflill):
        //
        // The prebuilder tool is not able to generate the Kubernetes client related extensions
        // defined in [Neon.Kube.KubernetesExtensions] due to a chicken-and-egg situation, so
        // we're just going to implement these here manually.

        /// <summary>
        /// Adds a new Kubernetes secret or updates an existing secret.
        /// </summary>
        /// <param name="secret">The secret.</param>
        /// <param name="namespace">Optionally overrides the default namespace.</param>
        /// <returns>The updated secret.</returns>
        public async Task <V1Secret> UpsertSecretAsync(V1Secret secret, string @namespace = null)
        {
            await SyncContext.Clear;

            return(await NormalizedRetryPolicy.InvokeAsync(
                       async() =>
            {
                return await k8s.UpsertSecretAsync(secret, @namespace);
            }));
        }
Exemplo n.º 11
0
        public void ReferenceComparisonTest()
        {
            var secret1 = new V1Secret();
            var secret2 = secret1;

            Assert.True(Comparer.Equals(secret1, secret2));

            Assert.False(Comparer.Equals(null, secret2));
            Assert.False(Comparer.Equals(secret1, null));
        }
Exemplo n.º 12
0
        private static string SerializeSecretToYaml(V1Secret secret)
        {
            var serializer = new SerializerBuilder()
                             .WithNamingConvention(KubernetesNamingConvention.Instance)
                             .ConfigureDefaultValuesHandling(DefaultValuesHandling.OmitNull)
                             .WithTypeConverter(DateTimeRfc3339Converter.Instance)
                             .WithEventEmitter(nextEmitter => new QuoteSurroundingEventEmitter(nextEmitter))
                             .Build();

            return(serializer.Serialize(secret));
        }
Exemplo n.º 13
0
        public static V1Secret?AsSecret(this PairingRecord?pairingRecord)
        {
            if (pairingRecord == null)
            {
                return(null);
            }

            var secret = new V1Secret()
            {
                ApiVersion = V1Secret.KubeApiVersion,
                Kind       = V1Secret.KubeKind,
                Type       = TlsType,
                Metadata   = new V1ObjectMeta(),
                Data       = new Dictionary <string, byte[]>(),
                Immutable  = true,
            };

            secret.Data[TlsCertificateKey] =
                Encoding.UTF8.GetBytes(
                    PemEncoding.Write(
                        "CERTIFICATE",
                        pairingRecord.HostCertificate.Export(X509ContentType.Cert)));

            secret.Data[TlsPrivateKey] =
                Encoding.UTF8.GetBytes(
                    PemEncoding.Write(
                        "PRIVATE KEY",
                        pairingRecord.HostPrivateKey.ExportPkcs8PrivateKey()));

            secret.Data[CaCertificateKey] =
                Encoding.UTF8.GetBytes(
                    PemEncoding.Write(
                        "CERTIFICATE",
                        pairingRecord.RootCertificate.Export(X509ContentType.Cert)));

            secret.Data[CaPrivateKey] =
                Encoding.UTF8.GetBytes(
                    PemEncoding.Write(
                        "PRIVATE KEY",
                        pairingRecord.RootPrivateKey.ExportPkcs8PrivateKey()));

            secret.Data[DeviceCertificateKey] =
                Encoding.UTF8.GetBytes(
                    PemEncoding.Write(
                        "CERTIFICATE",
                        pairingRecord.DeviceCertificate.Export(X509ContentType.Cert)));

            secret.Data[EscrowBagKey]      = pairingRecord.EscrowBag;
            secret.Data[HostIdKey]         = Encoding.UTF8.GetBytes(pairingRecord.HostId);
            secret.Data[SystemBuidKey]     = Encoding.UTF8.GetBytes(pairingRecord.SystemBUID);
            secret.Data[WifiMacAddressKey] = pairingRecord.WiFiMacAddress == null ? null : Encoding.UTF8.GetBytes(pairingRecord.WiFiMacAddress);

            return(secret);
        }
        public async Task DeleteFileShareSecretAsync(V1Secret secret)
        {
            V1PersistentVolumeList currentPvs = await k8sClient.ListPersistentVolumeAsync(labelSelector : Constants.LabelSelector);

            var existingPvSet = new Set <V1PersistentVolume>(currentPvs.Items
                                                             .Where(pv => pv.Spec?.AzureFile?.SecretName == secret.Metadata.Name)
                                                             .ToDictionary(pv => pv.Metadata.Name));
            var desiredPvSet = Set <V1PersistentVolume> .Empty;
            var diff         = desiredPvSet.Diff(existingPvSet, PvComparer);

            await this.ManagePvs(diff);
        }
Exemplo n.º 15
0
        private static void EnsureProvisioningProfileSecret(V1Secret secret)
        {
            if (secret == null)
            {
                throw new ArgumentNullException(nameof(secret));
            }

            if (secret.Type != SignedDataType || secret.Data == null || !secret.Data.ContainsKey(SignedDataContent))
            {
                throw new InvalidDataException();
            }
        }
Exemplo n.º 16
0
        private static void EnsureTlsSecret(V1Secret secret)
        {
            if (secret == null)
            {
                throw new ArgumentNullException(nameof(secret));
            }

            if (secret.Type != TlsType || secret.Data == null || !secret.Data.ContainsKey(TlsCertificate) || !secret.Data.ContainsKey(TlsPrivateKey))
            {
                throw new InvalidDataException($"The secret {secret?.Metadata?.Name} is not a valid TLS secret.");
            }
        }
Exemplo n.º 17
0
        private async Task HandleAdd(KamusSecret kamusSecret)
        {
            var @namespace     = kamusSecret.Metadata.NamespaceProperty ?? "default";
            var serviceAccount = kamusSecret.ServiceAccount;
            var id             = $"{@namespace}:{serviceAccount}";

            var decryptedItems = new Dictionary <string, string>();

            mLogger.Debug("Starting decrypting KamusSecret items. KamusSecret {name} in namesapce {namespace}",
                          kamusSecret.Metadata.Name,
                          @namespace);

            foreach (var item in kamusSecret.Data)
            {
                try
                {
                    var decrypted = await mKeyManagement.Decrypt(item.Value, id);

                    decryptedItems.Add(item.Key, decrypted);
                }
                catch (Exception e)
                {
                    Log.Error(e, "Failed to decrypt KamusSecret key {key}. KamusSecret {name} in namesapce {namespace}",
                              item.Key,
                              kamusSecret.Metadata.Name,
                              @namespace);

                    return;
                }
            }

            mLogger.Debug("KamusSecret items decrypted successfully. KamusSecret {name} in namesapce {namespace}",
                          kamusSecret.Metadata.Name,
                          @namespace);

            var secret = new V1Secret
            {
                Metadata = new V1ObjectMeta
                {
                    Name = kamusSecret.Metadata.Name,
                    NamespaceProperty = @namespace
                },
                Type       = kamusSecret.Type,
                StringData = decryptedItems
            };

            await mKubernetes.CreateNamespacedSecretAsync(secret, @namespace);

            mAuditLogger.Information("Created a secret from KamusSecret {name} in namesapce {namespace successfully.",
                                     kamusSecret.Metadata.Name,
                                     @namespace);
        }
Exemplo n.º 18
0
        public async Task <V1Secret> GetPrometheusScrapeConfigSecretAsync(CancellationToken cancellationToken)
        {
            Init();

            V1Secret result = null;

            try
            {
                result = await _client.ReadNamespacedSecretAsync(SecretName, SecretNamespace,
                                                                 cancellationToken : cancellationToken);
            }
            catch (Microsoft.Rest.HttpOperationException ex)
                when(ex.Response.StatusCode == HttpStatusCode.NotFound)
                {
                    try
                    {
                        // Check for prometheus server config in the default namespace as a failover
                        result = await _client.ReadNamespacedSecretAsync(SecretName, "default",
                                                                         cancellationToken : cancellationToken);
                    }
                    catch (Microsoft.Rest.HttpOperationException ex2)
                        when(ex.Response.StatusCode == HttpStatusCode.NotFound)
                        {
                            _logger.LogWarning(ex2, "Unable to access scrape config secret");
                        }
                }
            catch (Microsoft.Rest.HttpOperationException ex)
                when(ex.Response.StatusCode == HttpStatusCode.Forbidden)
                {
                    _logger.LogCritical(ex, @$ "
------
Additional Info
------

Headers:
{ex.Response.Headers}

ReasonPhrase:
{ex.Response.ReasonPhrase}

StatusCode:
{ex.Response.StatusCode}

Content:
{ex.Response.Content}
");
                    throw;
                }

            return(result);
        }
Exemplo n.º 19
0
        //TODO
        public V1Job GetEUConverterAppSettingsSecret(int id)
        {
            V1Secret secret = new V1Secret()
            {
                ApiVersion = "batch/v1",
                Kind       = V1Job.KubeKind,
                Metadata   = new V1ObjectMeta()
                {
                    Name = "eu-appsettings-secret"
                },
            };

            return(null);
        }
        private async Task Annotate(V1Secret secret, CertificateDefinition certificate)
        {
            var secretAnnotations =
                new Dictionary <string, string>(secret.Metadata.Annotations ?? new Dictionary <string, string>());
            var original = secretAnnotations.ToDictionary(s => s.Key, s => s.Value);

            var certificateAnnotations =
                new Dictionary <string, string>(certificate.Metadata.Annotations ?? new Dictionary <string, string>());

            if (certificateAnnotations.TryGetValue(Annotations.CertManagerCertificate.SecretReflectionAllowed,
                                                   out var reflectionAllowed))
            {
                secretAnnotations[Annotations.Reflection.Allowed] = reflectionAllowed;
            }
            else
            {
                secretAnnotations.Remove(Annotations.Reflection.Allowed);
            }

            if (certificateAnnotations.TryGetValue(Annotations.CertManagerCertificate.SecretReflectionAllowedNamespaces,
                                                   out var allowedNamespaces))
            {
                secretAnnotations[Annotations.Reflection.AllowedNamespaces] = allowedNamespaces;
            }
            else
            {
                secretAnnotations.Remove(Annotations.Reflection.AllowedNamespaces);
            }


            if (secretAnnotations.Count == original.Count &&
                secretAnnotations.Keys.All(s => original.ContainsKey(s)) &&
                secretAnnotations.All(s => original[s.Key] == s.Value))
            {
                _logger.LogDebug("Secret {secretNs}/{secretName} matches certificate {certNs}/{certName} reflection annotations",
                                 secret.Metadata.NamespaceProperty, secret.Metadata.Name,
                                 certificate.Metadata.NamespaceProperty, certificate.Metadata.Name);
                return;
            }

            _logger.LogInformation(
                "Patching {secretNs}/{secretName} to match certificate {certNs}/{certName} reflection annotations",
                secret.Metadata.NamespaceProperty, secret.Metadata.Name,
                certificate.Metadata.NamespaceProperty, certificate.Metadata.Name);
            var patch = new JsonPatchDocument <V1Secret>();

            patch.Replace(e => e.Metadata.Annotations, secretAnnotations);
            await _apiClient.PatchNamespacedSecretWithHttpMessagesAsync(new V1Patch(patch),
                                                                        secret.Metadata.Name, secret.Metadata.NamespaceProperty);
        }
Exemplo n.º 21
0
        async Task ManageImagePullSecrets(V1SecretList existing, List <V1Secret> desired, CancellationToken token)
        {
            // find difference between desired and existing image pull secrets
            var diff = FindImagePullSecretDiff(desired, existing.Items);

            // Update only those image pull secrets if configurations have not matched
            var updatingTask = diff.Updated
                               .Select(
                update =>
            {
                Events.UpdateImagePullSecret(update.To);

                update.To.Metadata.ResourceVersion = update.From.Metadata.ResourceVersion;
                return(this.client.ReplaceNamespacedSecretAsync(update.To, update.To.Metadata.Name, this.deviceNamespace, cancellationToken: token));
            });
            await Task.WhenAll(updatingTask);

            // Delete all existing image pull secrets that are not in desired list
            var removingTasks = diff.Removed
                                .Select(
                name =>
            {
                Events.DeleteImagePullSecret(name);
                return(this.client.DeleteNamespacedSecretAsync(name, this.deviceNamespace, cancellationToken: token));
            });
            await Task.WhenAll(removingTasks);

            // Create new desired image pull secrets
            foreach (V1Secret secret in diff.Added)
            {
                // Allow user to override image pull secrets even if they were created not by agent (e.g. during installation and/or iotedged)
                try
                {
                    Events.CreateImagePullSecret(secret);
                    await this.client.CreateNamespacedSecretAsync(secret, this.deviceNamespace, cancellationToken : token);
                }
                catch (HttpOperationException e) when(e.Response.StatusCode == HttpStatusCode.Conflict)
                {
                    Events.UpdateExistingImagePullSecret(secret);

                    V1Secret conflictedSecret = await this.client.ReadNamespacedSecretAsync(secret.Metadata.Name, secret.Metadata.NamespaceProperty, cancellationToken : token);

                    conflictedSecret.Data = secret.Data;

                    await this.client.ReplaceNamespacedSecretAsync(conflictedSecret, conflictedSecret.Metadata.Name, conflictedSecret.Metadata.NamespaceProperty, cancellationToken : token);
                }
            }
        }
Exemplo n.º 22
0
        private static void DecodeSecret(V1Secret secret)
        {
            secret.StringData ??= new Dictionary <string, string>();

            if (secret.Data != null)
            {
                foreach (var kvp in secret.Data)
                {
                    var key   = kvp.Key;
                    var value = kvp.Value;
                    secret.StringData[key] = Encoding.UTF8.GetString(value);
                }
            }

            secret.Data = null;
        }
        public async void Execute_UpdatesSecretData_WhenImagePullSecretCreatedNotByAgent()
        {
            string secretName     = "username-docker.io";
            var    existingSecret = new V1Secret
            {
                Data = new Dictionary <string, byte[]> {
                    [KubernetesConstants.K8sPullSecretData] = Encoding.UTF8.GetBytes("Invalid Secret Data")
                },
                Type     = KubernetesConstants.K8sPullSecretType,
                Metadata = new V1ObjectMeta {
                    Name = secretName, NamespaceProperty = Namespace, ResourceVersion = "1"
                }
            };

            IModule dockerModule         = new DockerModule("module1", "v1", ModuleStatus.Running, Core.RestartPolicy.Always, Config1, ImagePullPolicy.OnCreate, Core.Constants.DefaultPriority, DefaultConfigurationInfo, EnvVars);
            var     dockerConfigProvider = new Mock <ICombinedConfigProvider <CombinedDockerConfig> >();

            dockerConfigProvider.Setup(cp => cp.GetCombinedConfig(dockerModule, Runtime))
            .Returns(() => new CombinedDockerConfig("test-image:1", Config1.CreateOptions, Option.None <string>(), Option.Maybe(DockerAuth)));
            var configProvider = new Mock <ICombinedConfigProvider <CombinedKubernetesConfig> >();

            configProvider.Setup(cp => cp.GetCombinedConfig(dockerModule, Runtime))
            .Returns(() => new CombinedKubernetesConfig("test-image:1", CreatePodParameters.Create(image: "test-image:1"), Option.Maybe(ImagePullSecret)));

            var client = new Mock <IKubernetes>();

            client.SetupListSecrets().ReturnsAsync(() => CreateResponse(new V1SecretList {
                Items = new List <V1Secret>()
            }));
            client.SetupCreateSecret().ThrowsAsync(new HttpOperationException {
                Response = new HttpResponseMessageWrapper(new HttpResponseMessage(HttpStatusCode.Conflict), "Conflict")
            });
            V1Secret updatedSecret = null;

            client.SetupUpdateSecret()
            .Callback(
                (V1Secret body, string name, string ns, string dryRun, string fieldManager, string pretty, Dictionary <string, List <string> > customHeaders, CancellationToken token) => { updatedSecret = body; })
            .ReturnsAsync(() => CreateResponse(updatedSecret));
            client.SetupGetSecret(secretName).ReturnsAsync(() => CreateResponse(existingSecret));
            var cmd = new EdgeDeploymentCommand(ResourceName, Selector, Namespace, client.Object, new[] { dockerModule }, Option.None <EdgeDeploymentDefinition>(), Runtime, configProvider.Object, EdgeletModuleOwner);

            await cmd.ExecuteAsync(CancellationToken.None);

            Assert.True(Encoding.UTF8.GetBytes(ImagePullSecret.GenerateSecret()).SequenceEqual(updatedSecret.Data[KubernetesConstants.K8sPullSecretData]));
            Assert.Equal("1", updatedSecret.Metadata.ResourceVersion);
            client.VerifyAll();
        }
Exemplo n.º 24
0
        async Task UpdateImagePullSecrets(IEnumerable <ImagePullSecret> imagePullSecrets, CancellationToken token)
        {
            foreach (var imagePullSecret in imagePullSecrets)
            {
                var secretMeta = new V1ObjectMeta(
                    name: imagePullSecret.Name,
                    namespaceProperty: this.deviceNamespace,
                    ownerReferences: this.moduleOwner.ToOwnerReferences());
                var secretData = new Dictionary <string, byte[]> {
                    [Constants.K8sPullSecretData] = Encoding.UTF8.GetBytes(imagePullSecret.GenerateSecret())
                };
                var newSecret = new V1Secret("v1", secretData, type: Constants.K8sPullSecretType, kind: "Secret", metadata: secretMeta);
                Option <V1Secret> currentSecret;
                try
                {
                    currentSecret = Option.Maybe(await this.client.ReadNamespacedSecretAsync(imagePullSecret.Name, this.deviceNamespace, cancellationToken: token));
                }
                catch (Exception ex) when(!ex.IsFatal())
                {
                    Events.FailedToFindSecret(imagePullSecret.Name, ex);
                    currentSecret = Option.None <V1Secret>();
                }

                try
                {
                    var v1Secret = await currentSecret.Match(
                        async s =>
                    {
                        if (s.Data != null && s.Data.TryGetValue(Constants.K8sPullSecretData, out byte[] pullSecretData) &&
                            pullSecretData.SequenceEqual(secretData[Constants.K8sPullSecretData]))
                        {
                            return(s);
                        }

                        return(await this.client.ReplaceNamespacedSecretAsync(
                                   newSecret,
                                   imagePullSecret.Name,
                                   this.deviceNamespace,
                                   cancellationToken: token));
                    },
                        async() => await this.client.CreateNamespacedSecretAsync(newSecret, this.deviceNamespace, cancellationToken: token));

                    if (v1Secret == null)
                    {
                        throw new InvalidIdentityException("Image pull secret was not properly created");
                    }
                }
Exemplo n.º 25
0
        public static async Task PushNotification(
            WatchEventType eventType,
            HealthCheckResource resource,
            V1Service uiService,
            V1Service notificationService,
            V1Secret endpointSecret,
            ILogger <K8sOperator> logger,
            IHttpClientFactory httpClientFactory)
        {
            var address   = KubernetesAddressFactory.CreateHealthAddress(notificationService, resource);
            var uiAddress = KubernetesAddressFactory.CreateAddress(uiService, resource);

            dynamic healthCheck = new
            {
                Type = eventType,
                notificationService.Metadata.Name,
                Uri = address
            };

            var client = httpClientFactory.CreateClient();

            try
            {
                string type = healthCheck.Type.ToString();
                string name = healthCheck.Name;
                string uri  = healthCheck.Uri;

                logger.LogInformation("[PushService] Namespace {Namespace} - Sending Type: {type} - Service {name} with uri : {uri} to ui endpoint: {address}", resource.Metadata.NamespaceProperty, type, name, uri, uiAddress);

                var key = Encoding.UTF8.GetString(endpointSecret.Data["key"]);

                var response = await client.PostAsync($"{uiAddress}{Constants.PushServicePath}?{Constants.PushServiceAuthKey}={key}",

                                                      new StringContent(JsonSerializer.Serialize(healthCheck, new JsonSerializerOptions
                {
                    PropertyNamingPolicy = JsonNamingPolicy.CamelCase
                }), Encoding.UTF8, "application/json"));


                logger.LogInformation("[PushService] Notification result for {name} - status code: {statuscode}", notificationService.Metadata.Name, response.StatusCode);
            }
            catch (Exception ex)
            {
                logger.LogError("Error notifying healthcheck service: {message}", ex.Message);
            }
        }
Exemplo n.º 26
0
        private static string SerializeSecret(V1Secret secret, OutputType outputType)
        {
            switch (outputType)
            {
            case OutputType.Json:
                return(SerializeSecretToJson(secret));

            case OutputType.Yaml:
                return(SerializeSecretToYaml(secret));

            default:
                throw new ArgumentOutOfRangeException(
                          nameof(outputType),
                          outputType,
                          null);
            }
        }
Exemplo n.º 27
0
        public void AsX509Certificate2_Works()
        {
            // https://github.com/kubernetes-sigs/cluster-api/blob/master/docs/book/src/tasks/certs/using-custom-certificates.md
            V1Secret secret = new V1Secret()
            {
                Data = new Dictionary <string, byte[]>(),
                Type = "kubernetes.io/tls",
            };

            secret.Data["tls.crt"] = File.ReadAllBytes("DeveloperProfiles/tls.crt");
            secret.Data["tls.key"] = File.ReadAllBytes("DeveloperProfiles/tls.key");

            var certificate = secret.AsX509Certificate2();

            Assert.NotNull(certificate);
            Assert.Equal("CN=Test", certificate.Subject);
            Assert.True(certificate.HasPrivateKey);
        }
Exemplo n.º 28
0
        public void AsSignedCms_Works()
        {
            // https://github.com/kubernetes-sigs/cluster-api/blob/master/docs/book/src/tasks/certs/using-custom-certificates.md
            V1Secret secret = new V1Secret()
            {
                Data = new Dictionary <string, byte[]>(),
                Type = "kaponata.io/signedData",
            };

            secret.Data["signedData"] = File.ReadAllBytes("DeveloperProfiles/test.mobileprovision");

            var cms = secret.AsSignedCms();

            var certificate = cms.Certificates[0];

            Assert.NotNull(certificate);
            Assert.Equal("CN=Apple iPhone Certification Authority, OU=Apple Certification Authority, O=Apple Inc., C=US", certificate.Subject);
            Assert.False(certificate.HasPrivateKey);
        }
Exemplo n.º 29
0
        /// <summary>
        /// Converts this <see cref="SignedCms"/> to a <see cref="V1Secret"/>.
        /// </summary>
        /// <param name="signedData">
        /// A <see cref="SignedCms"/> which represents a CMS signed data object.
        /// </param>
        /// <returns>
        /// The equivalent <see cref="V1Secret"/>.
        /// </returns>
        public static V1Secret AsSecret(this SignedCms signedData)
        {
            var secret = new V1Secret()
            {
                ApiVersion = V1Secret.KubeApiVersion,
                Kind       = V1Secret.KubeKind,
                Type       = SignedDataType,
                Metadata   = new V1ObjectMeta()
                {
                    Labels = new Dictionary <string, string>(),
                },
                Data      = new Dictionary <string, byte[]>(),
                Immutable = true,
            };

            secret.Data[SignedDataContent] = signedData.Encode();

            return(secret);
        }
        private void ProcessData(V1Secret item)
        {
            if (item is null)
            {
                Logger?.LogWarning("ConfigMap response is null, no data could be processed");
                return;
            }

            var secretContents = new Dictionary <string, string>(StringComparer.InvariantCultureIgnoreCase);

            if (item?.Data != null)
            {
                foreach (var data in item.Data)
                {
                    secretContents[NormalizeKey(data.Key)] = Encoding.UTF8.GetString(data.Value);
                }
            }

            Data = secretContents;
        }