Пример #1
0
        public override Task <Tfplugin5.GetProviderSchema.Types.Response> GetSchema(
            Tfplugin5.GetProviderSchema.Types.Request request, ServerCallContext context)
        {
            _log.LogDebug(">>>{method}>>>", nameof(GetSchema));
            _log.LogTrace($"->input[{nameof(request)}] = {{@request}}", request);
            _log.LogTrace($"->input[{nameof(context)}] = {{@context}}", context);

            try
            {
                var response = new Tfplugin5.GetProviderSchema.Types.Response();
                response.Provider = SchemaHelper.GetProviderSchema(PluginAssembly);
                response.DataSourceSchemas.Add(SchemaHelper.GetDataSourceSchemas());
                response.ResourceSchemas.Add(SchemaHelper.GetResourceSchemas());

                _log.LogTrace("Provider schema: {@schema}", response.Provider);

                _log.LogTrace("Data Source schemas: ({count})", response.DataSourceSchemas.Count);
                foreach (var rs in response.DataSourceSchemas)
                {
                    _log.LogInformation("  * {dsType}={@dsSchema}", rs.Key, rs.Value);
                }

                _log.LogTrace("Resource schemas: ({count})", response.ResourceSchemas.Count);
                foreach (var rs in response.ResourceSchemas)
                {
                    _log.LogInformation("  * {resType}={@resSchema}", rs.Key, rs.Value);
                }

                _log.LogTrace("<-result = {@response}", response);
                return(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.ValidateResourceTypeConfig.Types.Response> ValidateResourceTypeConfig(
            Tfplugin5.ValidateResourceTypeConfig.Types.Request request, ServerCallContext context)
        {
            _log.LogDebug(">>>{method}>>>", nameof(ValidateResourceTypeConfig));
            _log.LogTrace($"->input[{nameof(request)}] = {{@request}}", request);
            _log.LogTrace($"->input[{nameof(context)}] = {{@context}}", context);

            try
            {
                if (_ProviderInstance == null)
                {
                    throw new Exception("provider instance was not configured previously");
                }

                var response = new Tfplugin5.ValidateResourceTypeConfig.Types.Response();
                // ProviderHelper.ValidateResourceTypeConfig(_providerInstance, request.TypeName,
                //     request.Config, PluginAssembly);

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

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

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

                    // Invoke the functional method
                    var invokeMethod = invokeType.GetMethod(nameof(IHasValidateResourceTypeConfig <object> .ValidateConfig));
                    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());
                    }
                }

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