コード例 #1
0
        protected override async Task ProcessRecordAsync(CancellationToken cancellationToken)
        {
            await base.ProcessRecordAsync(cancellationToken);

            // TODO do not pass the ContractResolver here once KubeClient allows customizing the serialisation
            var    patch           = new JsonPatchDocument(new List <Operation>(), new PSObjectAwareContractResolver());
            var    comparer        = new KubeResourceComparer(LoggerFactory);
            string apiGroupVersion = (string)Original.ApiVersion;
            string apiVersion      = apiGroupVersion.Split('/').Last();
            string kind            = (string)Original.Kind;
            Type   type            = ModelTypes.GetValueOrDefault((kind, apiVersion));

            if (type == null)
            {
                WriteError(new ErrorRecord(new Exception($"Unknown (kind: {kind}, apiVersion: {apiVersion}). {ModelTypes.Count} Known:\n{String.Join("\n", ModelTypes.Keys)}"), null, ErrorCategory.InvalidData, null));
                return;
            }
            if (ThreeWayFromLastApplied)
            {
                comparer.CreateThreeWayPatchFromLastApplied(
                    current: Original,
                    modified: Modified,
                    type: type,
                    patch: patch,
                    annotate: Annotate
                    );
            }
            else if (Current == null)
            {
                comparer.CreateTwoWayPatch(
                    original: Original,
                    modified: Modified,
                    type: type,
                    patch: patch,
                    ignoreDeletions: IgnoreDeletions,
                    ignoreAdditionsAndModifications: IgnoreAdditionsAndModifications
                    );
            }
            else
            {
                comparer.CreateThreeWayPatch(
                    original: Original,
                    modified: Modified,
                    current: Current,
                    type: type,
                    patch: patch
                    );
            }
            foreach (var operation in patch.Operations)
            {
                WriteObject(operation);
            }
        }
コード例 #2
0
        private async Task updateResource(dynamic modified, CancellationToken cancellationToken)
        {
            if (modified == null)
            {
                throw new ArgumentNullException(nameof(modified));
            }

            string kind = (string)modified.Kind;

            if (String.IsNullOrEmpty(kind))
            {
                throw new Exception("Input object does not have Kind set");
            }
            string apiVersion = (string)modified.ApiVersion;

            if (String.IsNullOrEmpty(apiVersion))
            {
                throw new Exception("Input object does not have ApiVersion set");
            }

            // Figure out the model class - needed for diffing
            if (!ModelTypes.TryGetValue((kind, apiVersion), out Type type))
            {
                WriteError(new ErrorRecord(new Exception($"Unknown (kind: {kind}, apiVersion: {apiVersion}). {ModelTypes.Count} Known:\n{String.Join("\n", ModelTypes.Keys)}"), null, ErrorCategory.InvalidData, Resource));
                return;
            }

            dynamic metadata = modified.Metadata;
            string  name     = (string)metadata.Name;

            if (String.IsNullOrEmpty(name))
            {
                throw new Exception("Input object does not have Metadata.Name set");
            }
            string kubeNamespace = (string)metadata.Namespace;

            // Get current resource state from server
            WriteVerbose($"Getting resource \"{name}\" of kind \"{kind}\" from namespace \"{kubeNamespace}\"");
            object current = await client.Dynamic().Get(name, kind, apiVersion, kubeNamespace, cancellationToken);

            if (current == null)
            {
                WriteError(new ErrorRecord(new Exception($"{kind} ({apiVersion}) \"{name}\" does not exist in namespace \"{kubeNamespace}\""), null, ErrorCategory.InvalidData, Resource));
                return;
            }

            // Generate three-way patch from current to modified
            // TODO do not pass the ContractResolver here once KubeClient allows customizing the serialisation
            var patch    = new JsonPatchDocument(new List <Operation>(), new PSObjectAwareContractResolver());
            var comparer = new KubeResourceComparer(LoggerFactory);

            comparer.CreateThreeWayPatchFromLastApplied(current, modified, type, patch, true);

            WriteVerbose("Patch: " + JsonConvert.SerializeObject(patch, new JsonSerializerSettings {
                Formatting = Formatting.Indented,
                Converters = new[] { new PSObjectJsonConverter() }
            }));

            // Send patch to server
            if (ShouldProcess($"Sending patch for {kind} \"{name}\" in namespace \"{kubeNamespace}\"", $"Send patch for {kind} \"{name}\" in namespace \"{kubeNamespace}\"?", "Confirm"))
            {
                var result = await client.Dynamic().Patch(
                    name: name,
                    kind: kind,
                    apiVersion: apiVersion,
                    patch: patch,
                    kubeNamespace: kubeNamespace,
                    cancellationToken: cancellationToken
                    );

                WriteObject(result);
            }
        }