如何使用AWS CDK将“ PolicyDocument”对象附加到TopicPolicy?

时间:2019-01-17 16:17:52

标签: c# aws-cdk

请原谅,这是我第一次问堆栈溢出问题。我会尽力使这一点尽可能清楚。

问题:

当尝试使用AWS CDK合成堆栈时,我得到了这个command line error。我使用C#作为我的语言,并且只是在本地计算机上玩耍。

在基于this文档构建主题策略对象时,似乎没有传递“策略文档”对象。在文档的“ CfnTopicPolicyProps(界面)”下,它同时显示了一个主题对象和一个 policyDocument 对象。但是,在Visual Studio中,当我查看接口的定义时,它仅包含 topics 对象。我在下面包括了我对接口的使用以及一些类,接口及其父级的定义。我是一个相对较新的开发人员,但我完全不知所措。我在这里想念什么?

在此先感谢大家提供的帮助或建议。

CLI错误输出

C:\MyRepository\awsCdkApp1>cdk synth Test-Stack-1
Unhandled Exception: Amazon.JSII.Runtime.JsiiException: While synthesizing Test-Stack-1/topicPolicy/Resource: Supplied properties not correct for "CfnTopicPolicyProps"
  policyDocument: required but missing
   at Amazon.JSII.Runtime.Services.Client.TryDeserialize[TResponse](String responseJson)
   at Amazon.JSII.Runtime.Services.Client.ReceiveResponse[TResponse]()
   at Amazon.JSII.Runtime.Deputy.DeputyBase.<InvokeMethodCore>g__GetResult|18_0[T](<>c__DisplayClass18_0`1& )
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeMethodCore[T](JsiiMethodAttribute methodAttribute, Object[] arguments, Func`3 beginFunc, Func`3 invokeFunc)
   at Amazon.JSII.Runtime.Deputy.DeputyBase.InvokeInstanceMethod[T](Object[] arguments, String methodName)
   at Amazon.CDK.App.Run()
   at HelloCdk.Program.Main(String[] args) in C:\MyRepository/Program.cs:line 19
(node:16396) UnhandledPromiseRejectionWarning: Error: EPIPE: broken pipe, write
    at Object.writeSync (fs.js:569:3)
    at t.SyncStdio.writeBuffer (C:\Users\username\AppData\Local\Temp\4k3fctka.rty\jsii-runtime.js:1:165352)
    at t.SyncStdio.writeLine (C:\Users\username\AppData\Local\Temp\4k3fctka.rty\jsii-runtime.js:1:164892)
    at t.InputOutput.write (C:\Users\username\AppData\Local\Temp\4k3fctka.rty\jsii-runtime.js:1:164341)
    at t.KernelHost.writeError (C:\Users\username\AppData\Local\Temp\4k3fctka.rty\jsii-runtime.js:1:79440)
    at i.then.catch.e (C:\Users\username\AppData\Local\Temp\4k3fctka.rty\jsii-runtime.js:1:79101)
(node:16396) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1)
(node:16396) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.
Subprocess exited with error 3762504530

界面使用情况:

var topic = new Topic(this, "myTopic", new TopicProps
        {
            DisplayName = "myTopic",
            TopicName = "myTopic"
        });

        var topicRef = TopicRef.Import(this, "reference", new TopicRefProps
        {
            TopicArn = topic.TopicArn,
            TopicName = topic.TopicName,
        });

        var policyStatement1 = new PolicyStatement(0);
        policyStatement1.Describe("Default");
        policyStatement1.AddAwsPrincipal("*");
        policyStatement1.AddActions("- SNS:Publish\n " +
                                   "- SNS:RemovePermission\n" +
                                   "- SNS:SetTopicAttributes\n" +
                                   "- SNS:DeleteTopic\n" +
                                   "- SNS:ListSubscriptionsByTopic\n" +
                                   "- SNS:GetTopicAttributes\n" +
                                   "- SNS:Receive\n" +
                                   "- SNS:AddPermission\n" +
                                   "- SNS:Subscribe\n");
        policyStatement1.AddCondition("StringEquals", "sOmEtHiNg");
        policyStatement1.AddResource(topic.TopicArn);

        var policyStatement2 = new PolicyStatement(0);
        policyStatement2.Describe("ProviderBucketAllow");
        policyStatement2.AddAwsPrincipal("*");
        policyStatement2.AddAction("- SNS:Publish");
        policyStatement2.AddCondition("StringEquals", @"sOmEtHiNg");
        policyStatement2.AddResource(topic.TopicArn);

        var policyDocument = new PolicyDocument("PolicyDocument");
        policyDocument.AddStatement(policyStatement1);
        policyDocument.AddStatement(policyStatement2);

        //Generate the topic policy resource
        var topicPolicy = new TopicPolicy(this, "topicPolicy", new TopicPolicyProps
        {
            //Here is where I would imagine I pass the policyDocument Object?
            //If I try to pass policyDocument, I get a ton of errors...
            Topics = new[] {topicRef}
        });

TopicRefProps定义:

using Amazon.JSII.Runtime.Deputy;

namespace Amazon.CDK.AWS.SNS
{
    public class TopicRefProps : DeputyBase, ITopicRefProps
    {
        public TopicRefProps();

        [JsiiProperty("topicArn", "{\"primitive\":\"string\"}", true)]
        public string TopicArn { get; set; }
        [JsiiProperty("topicName", "{\"primitive\":\"string\"}", true)]
        public string TopicName { get; set; }
    }
}

ITopicRefProps定义:

using Amazon.JSII.Runtime.Deputy;

namespace Amazon.CDK.AWS.SNS
{
    [JsiiInterface(typeof(ITopicRefProps), "@aws-cdk/aws-sns.TopicRefProps")]
    public interface ITopicRefProps
    {
        [JsiiProperty("topicArn", "{\"primitive\":\"string\"}", false)]
        string TopicArn { get; set; }
        [JsiiProperty("topicName", "{\"primitive\":\"string\"}", false)]
        string TopicName { get; set; }
    }
}

代理基本定义:

using System;
using System.Runtime.CompilerServices;

namespace Amazon.JSII.Runtime.Deputy
{
    public abstract class DeputyBase
    {
        protected DeputyBase(DeputyProps props = null);
        protected DeputyBase(ByRefValue reference);

        public ByRefValue Reference { get; }

        protected static T GetStaticProperty<T>(Type type, [CallerMemberName] string propertyName = null);
        protected static T InvokeStaticMethod<T>(Type type, object[] arguments, [CallerMemberName] string methodName = null);
        protected static void InvokeStaticVoidMethod(Type type, object[] arguments, [CallerMemberName] string methodName = null);
        protected static void SetStaticProperty<T>(Type type, T value, [CallerMemberName] string propertyName = null);
        protected T GetInstanceProperty<T>([CallerMemberName] string propertyName = null);
        protected T InvokeInstanceMethod<T>(object[] arguments, [CallerMemberName] string methodName = null);
        protected void InvokeInstanceVoidMethod(object[] arguments, [CallerMemberName] string methodName = null);
        protected void SetInstanceProperty<T>(T value, [CallerMemberName] string propertyName = null);

        public sealed class DeputyProps
        {
            public DeputyProps(object[] arguments = null);

            public object[] Arguments { get; }
        }
    }
}

1 个答案:

答案 0 :(得分:0)

这里有几件事...

  1. Topic类是有效的TopicRef,因此您不必在这里进行TopicRef.import舞蹈。
  2. 您可以使用Topic#addToResourcePolicy将语句添加到Topic的策略中,而不必自己创建TopicPolicy资源。

所以您的代码可能最终类似于:

var topic = new Topic(this, "myTopic", new TopicProps
{
    DisplayName = "myTopic",
    TopicName = "myTopic"
});

topic.AddToResourcePolicy(new PolicyStatement()
    .Describe("Default")
    .AddAwsPrincipal("*")
    .AddActions("sns:Publish",
                "sns:RemovePermission",
                "sns:SetTopicAttributes",
                "sns:DeleteTopic",
                "sns:ListSubscriptionsByTopic",
                "sns:GetTopicAttributes",
                "sns:Receive",
                "sns:AddPermission",
                "sns:Subscribe")
    .AddCondition("StringEquals", /* needs to be a map of condition key to value */);
topic.AddToResourcePolicy(new PolicyStatement()
    .Describe("ProviderBucketAllow")
    .AddAwsPrincipal("*")
    .AddAction("sns:Publish")
    .AddCondition("StringEquals", /* needs to be a map of condition key to value */);