Example #1
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);
                }
            }
        }
        async Task ManageImagePullSecrets(CancellationToken token)
        {
            var deviceOnlyLabels = new Dictionary <string, string>
            {
                [KubernetesConstants.K8sEdgeDeviceLabel] = KubeUtils.SanitizeLabelValue(this.resourceName.DeviceId),
            };

            // Modules may share an image pull secret, so only pick unique ones to add to the dictionary.
            List <V1Secret> desiredImagePullSecrets = this.modules
                                                      .Select(module => this.configProvider.GetCombinedConfig(module, this.runtimeInfo))
                                                      .Select(config => config.ImagePullSecret)
                                                      .FilterMap()
                                                      .GroupBy(secret => secret.Name)
                                                      .Select(secretGroup => this.CreateSecret(secretGroup.First(), deviceOnlyLabels))
                                                      .ToList();

            V1SecretList currentImagePullSecrets = await this.client.ListNamespacedSecretAsync(this.deviceNamespace, labelSelector : this.deviceSelector, cancellationToken : token);

            await this.ManageImagePullSecrets(currentImagePullSecrets, desiredImagePullSecrets, token);
        }