public override async Task <Tfplugin5.PrepareProviderConfig.Types.Response> PrepareProviderConfig(
            Tfplugin5.PrepareProviderConfig.Types.Request request, ServerCallContext context)
        {
            _log.LogDebug(">>>{method}>>>", nameof(PrepareProviderConfig));
            _log.LogTrace($"->input[{nameof(request)}] = {{@request}}", request);
            _log.LogTrace($"->input[{nameof(context)}] = {{@context}}", context);

            try
            {
                var response = new Tfplugin5.PrepareProviderConfig.Types.Response();

                // Default prepared config to incoming config
                response.PreparedConfig = request.Config;

                var plugin = SchemaHelper.GetPluginDetails(PluginAssembly);
                _ProviderInstance = DynamicValue.Unmarshal(plugin.Provider, request.Config);

                if (typeof(IHasPrepareProviderConfig).IsAssignableFrom(plugin.Provider))
                {
                    var invokeInput = new PrepareProviderConfigInput();

                    var invokeResult = (_ProviderInstance as IHasPrepareProviderConfig).PrepareConfig(invokeInput);
                    if (invokeResult == null)
                    {
                        throw new Exception("invocation result returned null");
                    }

                    var diagnostics = invokeResult.Diagnostics;
                    if (diagnostics.Count() > 0)
                    {
                        response.Diagnostics.Add(diagnostics.All());
                    }

                    response.PreparedConfig = DynamicValue.Marshal(plugin.Provider, _ProviderInstance);
                }

                _log.LogTrace("<-result = {@response}", response);
                return(await Task.FromResult(response));
            }
            catch (Exception ex)
            {
                _log.LogError(ex, "<!exception = ");
                throw;
            }
        }
        public override async Task <Tfplugin5.ImportResourceState.Types.Response> ImportResourceState(
            Tfplugin5.ImportResourceState.Types.Request request, ServerCallContext context)
        {
            _log.LogDebug(">>>{method}>>>", nameof(ImportResourceState));
            _log.LogTrace($"->input[{nameof(request)}] = {{@request}}", request);
            _log.LogTrace($"->input[{nameof(context)}] = {{@context}}", context);

            try
            {
                var response = new Tfplugin5.ImportResourceState.Types.Response();

                var plugin  = SchemaHelper.GetPluginDetails(PluginAssembly);
                var resType = plugin.Resources.Where(x =>
                                                     request.TypeName == x.GetCustomAttribute <TFResourceAttribute>()?.Name).First();
                var invokeType = typeof(IHasImportResourceState <>).MakeGenericType(resType);
                if (invokeType.IsAssignableFrom(plugin.Provider))
                {
                    var invokeInputType  = typeof(ImportResourceStateInput <>).MakeGenericType(resType);
                    var invokeResultType = typeof(ImportResourceStateResult <>).MakeGenericType(resType);

                    // Construct and populate the input type instance from the request
                    var invokeInput = Activator.CreateInstance(invokeInputType);

                    invokeInputType.GetProperty(nameof(request.Id)).SetValue(invokeInput, request.Id);

                    // Invoke the functional method
                    var invokeMethod = invokeType.GetMethod(nameof(IHasImportResourceState <object> .ImportResource));
                    var invokeResult = invokeMethod.Invoke(_ProviderInstance, new[] { invokeInput });
                    if (invokeResult == null)
                    {
                        throw new Exception("invocation result returned null");
                    }
                    if (!invokeResultType.IsAssignableFrom(invokeResult.GetType()))
                    {
                        throw new Exception("invocation result not of expected type or subclass");
                    }

                    // Deconstruct the result to response type
                    var diagnostics = ((TFDiagnostics)invokeResultType.GetProperty(nameof(response.Diagnostics))
                                       .GetValue(invokeResult));
                    if (diagnostics.Count() > 0)
                    {
                        response.Diagnostics.Add(diagnostics.All());
                    }

                    var importedEnum = invokeResultType.GetProperty(nameof(response.ImportedResources))
                                       .GetValue(invokeResult);

                    if (importedEnum != null)
                    {
                        var importedType = typeof(ImportedResourceState <>).MakeGenericType(resType);
                        var privateProp  = importedType.GetProperty(nameof(ImportedResource.Private));
                        var stateProp    = importedType.GetProperty(nameof(ImportedResource.State));

                        var importedResult = new List <ImportedResource>();
                        foreach (var imported in ((System.Collections.IEnumerable)importedEnum))
                        {
                            importedResult.Add(new ImportedResource
                            {
                                // We assume the outgoing is the same as incoming
                                TypeName = request.TypeName,
                                // Convert over private and schema-defined state
                                Private = ByteString.CopyFrom((byte[])privateProp.GetValue(imported)),
                                State   = DynamicValue.Marshal(resType, stateProp.GetValue(imported)),
                            });
                        }
                        response.ImportedResources.Add(importedResult);
                    }
                }

                _log.LogTrace("<-result = {@response}", response);
                return(await Task.FromResult(response));
            }
            catch (Exception ex)
            {
                _log.LogError(ex, "<!exception = ");
                throw;
            }
        }
Пример #3
0
        public override async Task <Tfplugin5.PlanResourceChange.Types.Response> PlanResourceChange(
            Tfplugin5.PlanResourceChange.Types.Request request, ServerCallContext context)
        {
            _log.LogDebug(">>>{method}>>>", nameof(PlanResourceChange));
            _log.LogTrace($"->input[{nameof(request)}] = {{@request}}", request);
            _log.LogTrace($"->input[{nameof(context)}] = {{@context}}", context);

            try
            {
                var response = new Tfplugin5.PlanResourceChange.Types.Response();

                var plugin  = SchemaHelper.GetPluginDetails(PluginAssembly);
                var resType = plugin.Resources.Where(x =>
                                                     request.TypeName == x.GetCustomAttribute <TFResourceAttribute>()?.Name).First();
                var invokeType = typeof(IHasPlanResourceChange <>).MakeGenericType(resType);
                if (invokeType.IsAssignableFrom(plugin.Provider))
                {
                    var invokeInputType  = typeof(PlanResourceChangeInput <>).MakeGenericType(resType);
                    var invokeResultType = typeof(PlanResourceChangeResult <>).MakeGenericType(resType);

                    // Construct and populate the input type instance from the request
                    var invokeInput = Activator.CreateInstance(invokeInputType);

                    var config           = DynamicValue.Unmarshal(resType, request.Config);
                    var priorState       = DynamicValue.Unmarshal(resType, request.PriorState);
                    var priorPrivate     = request.PriorPrivate.ToByteArray();
                    var proposedNewState = DynamicValue.Unmarshal(resType, request.ProposedNewState);

                    var changeType = ResourceChangeType.Unknown;
                    if (priorState != null)
                    {
                        if (config == null)
                        {
                            changeType = ResourceChangeType.Delete;
                        }
                        else
                        {
                            changeType = ResourceChangeType.Update;
                        }
                    }
                    else
                    if (config != null)
                    {
                        changeType = ResourceChangeType.Create;
                    }
                    else
                    {
                        _log.LogWarning("Planning NULL -> NULL : You Should Never See This!");
                    }

                    _log.LogDebug("Planning " + changeType.ToString().ToUpper());

                    invokeInputType.GetProperty(nameof(PlanResourceChangeInput <object> .ChangeType))
                    .SetValue(invokeInput, changeType);
                    invokeInputType.GetProperty(nameof(request.Config))
                    .SetValue(invokeInput, config);
                    invokeInputType.GetProperty(nameof(request.PriorState))
                    .SetValue(invokeInput, priorState);
                    invokeInputType.GetProperty(nameof(request.PriorPrivate))
                    .SetValue(invokeInput, priorPrivate);
                    invokeInputType.GetProperty(nameof(request.ProposedNewState))
                    .SetValue(invokeInput, proposedNewState);

                    // Invoke the functional method
                    var invokeMethod = invokeType.GetMethod(nameof(IHasPlanResourceChange <object> .PlanChange));
                    var invokeResult = invokeMethod.Invoke(_ProviderInstance, new[] { invokeInput });
                    if (invokeResult == null)
                    {
                        throw new Exception("invocation result returned null");
                    }
                    if (!invokeResultType.IsAssignableFrom(invokeResult.GetType()))
                    {
                        throw new Exception("invocation result not of expected type or subclass");
                    }

                    // Deconstruct the result to response type
                    var diagnostics = ((TFDiagnostics)invokeResultType
                                       .GetProperty(nameof(response.Diagnostics)).GetValue(invokeResult));
                    var plannedPrivate = invokeResultType
                                         .GetProperty(nameof(response.PlannedPrivate)).GetValue(invokeResult);
                    var plannedState = invokeResultType
                                       .GetProperty(nameof(response.PlannedState)).GetValue(invokeResult);
                    var requiresReplace = invokeResultType
                                          .GetProperty(nameof(response.RequiresReplace)).GetValue(invokeResult);

                    if (diagnostics.Count() > 0)
                    {
                        response.Diagnostics.Add(diagnostics.All());
                    }
                    if (plannedPrivate != null)
                    {
                        response.PlannedPrivate = ByteString.CopyFrom((byte[])plannedPrivate);
                    }
                    if (plannedState != null)
                    {
                        response.PlannedState = DynamicValue.Marshal(resType, plannedState);
                    }


                    if (requiresReplace != null)
                    {
                        // Translates our internal representation of ValuePath to AttributePath
                        var paths = (IEnumerable <TFSteps>)requiresReplace;
                        response.RequiresReplace.Add(TFAttributePaths.ToPaths(paths));
                    }
                }

                _log.LogTrace("<-result = {@response}", response);
                return(await Task.FromResult(response));
            }
            catch (Exception ex)
            {
                _log.LogError(ex, "<!exception = ");
                throw;
            }
        }
Пример #4
0
        public override async Task <Tfplugin5.ReadResource.Types.Response> ReadResource(
            Tfplugin5.ReadResource.Types.Request request, ServerCallContext context)
        {
            _log.LogDebug(">>>{method}>>>", nameof(ReadResource));
            _log.LogTrace($"->input[{nameof(request)}] = {{@request}}", request);
            _log.LogTrace($"->input[{nameof(context)}] = {{@context}}", context);

            try
            {
                var response = new Tfplugin5.ReadResource.Types.Response();

                var plugin  = SchemaHelper.GetPluginDetails(PluginAssembly);
                var resType = plugin.Resources.Where(x =>
                                                     request.TypeName == x.GetCustomAttribute <TFResourceAttribute>()?.Name).First();
                var invokeType = typeof(IHasReadResource <>).MakeGenericType(resType);
                if (invokeType.IsAssignableFrom(plugin.Provider))
                {
                    var invokeInputType  = typeof(ReadResourceInput <>).MakeGenericType(resType);
                    var invokeResultType = typeof(ReadResourceResult <>).MakeGenericType(resType);

                    // Construct and populate the input type instance from the request
                    var invokeInput = Activator.CreateInstance(invokeInputType);

                    invokeInputType.GetProperty(nameof(request.CurrentState)).SetValue(invokeInput,
                                                                                       DynamicValue.Unmarshal(resType, request.CurrentState));

                    // Invoke the functional method
                    var invokeMethod = invokeType.GetMethod(nameof(IHasReadResource <object> .Read));
                    var invokeResult = invokeMethod.Invoke(_ProviderInstance, new[] { invokeInput });
                    if (invokeResult == null)
                    {
                        throw new Exception("invocation result returned null");
                    }
                    if (!invokeResultType.IsAssignableFrom(invokeResult.GetType()))
                    {
                        throw new Exception("invocation result not of expected type or subclass");
                    }

                    // Deconstruct the result to response type
                    var diagnostics = ((TFDiagnostics)invokeResultType.GetProperty(nameof(response.Diagnostics))
                                       .GetValue(invokeResult));
                    if (diagnostics.Count() > 0)
                    {
                        response.Diagnostics.Add(diagnostics.All());
                    }

                    var newState = invokeResultType.GetProperty(nameof(response.NewState))
                                   .GetValue(invokeResult);
                    if (newState != null)
                    {
                        response.NewState = DynamicValue.Marshal(resType, newState);
                    }
                }

                _log.LogTrace("<-result = {@response}", response);
                return(await Task.FromResult(response));
            }
            catch (Exception ex)
            {
                _log.LogError(ex, "<!exception = ");
                throw;
            }
        }