diff --git a/CHANGELOG.rst b/CHANGELOG.rst index e704aa19c0..4abeef9176 100644 --- a/CHANGELOG.rst +++ b/CHANGELOG.rst @@ -1,6 +1,40 @@ Changelog ========= +0.0.7 - 2015-02-05 +------------------ + +* feature:Resources: Enable support for Amazon Glacier. +* feature:Resources: Support plural references and nested JMESPath + queries for data members when building parameters and identifiers. + (`issue 52 `__) +* feature:Resources: Update to the latest resource JSON format. + (`issue 51 `__) +* feature:Resources: Make ``resource.meta`` a proper object. This allows + you to do things like ``resource.meta.client``. This is a **backward- + incompatible** change. + (`issue 45 `__) +* feature:Dependency: Update to JMESPath 0.6.1 +* feature:Botocore: Update to Botocore 0.86.0 + + * Add support for AWS CloudHSM + * Add support for Amazon EC2 and Autoscaling ClassicLink + * Add support for Amazon EC2 Container Service (ECS) + * Add support for encryption at rest and CloudHSM to Amazon RDS + * Add support for Amazon DynamoDB online indexing. + * Add support for AWS ImportExport ``get_shipping_label``. + * Add support for Amazon Glacier. + * Add waiters for AWS ElastiCache. + (`botocore issue 443 `__) + * Fix an issue with Amazon CloudFront waiters. + (`botocore issue 426 `_) + * Allow binary data to be passed to ``UserData``. + (`botocore issue 416 `_) + * Fix Amazon EMR endpoints for ``eu-central-1`` and ``cn-north-1``. + (`botocore issue 423 `__) + * Fix issue with base64 encoding of blob types for Amazon EMR. + (`botocore issue 413 `__) + 0.0.6 - 2014-12-18 ------------------ @@ -15,7 +49,7 @@ Changelog * Update Amazon Simple Workflow Service (SWF) to the latest version * Update AWS Storage Gateway to the latest version - * Update AWS Elastic MapReduce (EMR) to the latest version + * Update Amazon Elastic MapReduce (EMR) to the latest version * Update AWS Elastic Transcoder to the latest version * Enable use of ``page_size`` for clients (`botocore issue 408 `__) diff --git a/boto3/__init__.py b/boto3/__init__.py index 50eb9632c1..22d28f3143 100644 --- a/boto3/__init__.py +++ b/boto3/__init__.py @@ -17,7 +17,7 @@ __author__ = 'Amazon Web Services' -__version__ = '0.0.6' +__version__ = '0.0.7' # The default Boto3 session; autoloaded when needed. diff --git a/boto3/data/resources/cloudformation-2010-05-15.resources.json b/boto3/data/resources/cloudformation-2010-05-15.resources.json index 1c2f72dc56..6b3a5b92e8 100644 --- a/boto3/data/resources/cloudformation-2010-05-15.resources.json +++ b/boto3/data/resources/cloudformation-2010-05-15.resources.json @@ -6,7 +6,25 @@ "resource": { "type": "Stack", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "StackName" } + { "target": "Name", "source": "requestParameter", "path": "StackName" } + ] + } + } + }, + "has": { + "Event": { + "resource": { + "type": "Event", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "Stack": { + "resource": { + "type": "Stack", + "identifiers": [ + { "target": "Name", "source": "input" } ] } } @@ -17,7 +35,7 @@ "resource": { "type": "Stack", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "Stacks[].StackName" } + { "target": "Name", "source": "response", "path": "Stacks[].StackName" } ] } } @@ -39,7 +57,7 @@ "request": { "operation": "DescribeStacks", "params": [ - { "target": "StackName", "sourceType": "identifier", "source": "Name" } + { "target": "StackName", "source": "identifier", "name": "Name" } ] }, "path": "Stacks[0]" @@ -49,7 +67,7 @@ "request": { "operation": "CancelUpdateStack", "params": [ - { "target": "StackName", "sourceType": "identifier", "source": "Name" } + { "target": "StackName", "source": "identifier", "name": "Name" } ] } }, @@ -57,7 +75,7 @@ "request": { "operation": "DeleteStack", "params": [ - { "target": "StackName", "sourceType": "identifier", "source": "Name" } + { "target": "StackName", "source": "identifier", "name": "Name" } ] } }, @@ -65,7 +83,18 @@ "request": { "operation": "UpdateStack", "params": [ - { "target": "StackName", "sourceType": "identifier", "source": "Name" } + { "target": "StackName", "source": "identifier", "name": "Name" } + ] + } + } + }, + "has": { + "Resource": { + "resource": { + "type": "StackResource", + "identifiers": [ + { "target": "StackName", "source": "identifier", "name": "Name" }, + { "target": "StackName", "source": "input" } ] } } @@ -75,13 +104,13 @@ "request": { "operation": "DescribeStackEvents", "params": [ - { "target": "StackName", "sourceType": "identifier", "source": "Name" } + { "target": "StackName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "Event", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "StackEvents[].EventId" } + { "target": "Id", "source": "response", "path": "StackEvents[].EventId" } ], "path": "StackEvents[]" } @@ -90,22 +119,18 @@ "request": { "operation": "ListStackResources", "params": [ - { "target": "StackName", "sourceType": "identifier", "source": "Name" } + { "target": "StackName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "StackResourceSummary", "identifiers": [ - { "target": "LogicalId", "sourceType": "responsePath", "source": "StackResourceSummaries[].LogicalResourceId" }, - { "target": "StackName", "sourceType": "requestParameter", "source": "StackName" } + { "target": "LogicalId", "source": "response", "path": "StackResourceSummaries[].LogicalResourceId" }, + { "target": "StackName", "source": "requestParameter", "path": "StackName" } ], "path": "StackResourceSummaries[]" } } - }, - "subResources": { - "resources": [ "StackResource" ], - "identifiers": { "Name": "StackName" } } }, "StackResource": { @@ -118,11 +143,21 @@ "request": { "operation": "DescribeStackResource", "params": [ - { "target": "LogicalResourceId", "sourceType": "identifier", "source": "LogicalId" }, - { "target": "StackName", "sourceType": "identifier", "source": "StackName" } + { "target": "LogicalResourceId", "source": "identifier", "name": "LogicalId" }, + { "target": "StackName", "source": "identifier", "name": "StackName" } ] }, "path": "StackResourceDetail" + }, + "has": { + "Stack": { + "resource": { + "type": "Stack", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "StackName" } + ] + } + } } }, "StackResourceSummary": { @@ -131,13 +166,13 @@ { "name": "StackName" } ], "shape": "StackResourceSummary", - "belongsTo": { + "has": { "Resource": { "resource": { "type": "StackResource", "identifiers": [ - { "target": "LogicalId", "sourceType": "identifier", "source": "LogicalId" }, - { "target": "StackName", "sourceType": "identifier", "source": "StackName" } + { "target": "LogicalId", "source": "identifier", "name": "LogicalId" }, + { "target": "StackName", "source": "identifier", "name": "StackName" } ] } } diff --git a/boto3/data/resources/ec2-2014-10-01.resources.json b/boto3/data/resources/ec2-2014-10-01.resources.json index df0816b095..0d860e7747 100644 --- a/boto3/data/resources/ec2-2014-10-01.resources.json +++ b/boto3/data/resources/ec2-2014-10-01.resources.json @@ -6,7 +6,7 @@ "resource": { "type": "DhcpOptions", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "DhcpOptions.DhcpOptionsId" } + { "target": "Id", "source": "response", "path": "DhcpOptions.DhcpOptionsId" } ], "path": "DhcpOptions" } @@ -16,7 +16,7 @@ "resource": { "type": "Instance", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Instances[].InstanceId" } + { "target": "Id", "source": "response", "path": "Instances[].InstanceId" } ], "path": "Instances[]" } @@ -26,7 +26,7 @@ "resource": { "type": "InternetGateway", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "InternetGateway.InternetGatewayId" } + { "target": "Id", "source": "response", "path": "InternetGateway.InternetGatewayId" } ], "path": "InternetGateway" } @@ -36,7 +36,7 @@ "resource": { "type": "KeyPair", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "KeyName" } + { "target": "Name", "source": "response", "path": "KeyName" } ] } }, @@ -45,7 +45,7 @@ "resource": { "type": "NetworkAcl", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkAcl.NetworkAclId" } + { "target": "Id", "source": "response", "path": "NetworkAcl.NetworkAclId" } ], "path": "NetworkAcl" } @@ -55,7 +55,7 @@ "resource": { "type": "NetworkInterface", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkInterface.NetworkInterfaceId" } + { "target": "Id", "source": "response", "path": "NetworkInterface.NetworkInterfaceId" } ], "path": "NetworkInterface" } @@ -65,7 +65,7 @@ "resource": { "type": "PlacementGroup", "identifiers": [ - { "target": "Id", "sourceType": "requestParameter", "source": "GroupName" } + { "target": "Id", "source": "requestParameter", "path": "GroupName" } ] } }, @@ -74,7 +74,7 @@ "resource": { "type": "RouteTable", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "RouteTable.RouteTableId" } + { "target": "Id", "source": "response", "path": "RouteTable.RouteTableId" } ], "path": "RouteTable" } @@ -84,7 +84,7 @@ "resource": { "type": "SecurityGroup", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "GroupId" } + { "target": "Id", "source": "response", "path": "GroupId" } ] } }, @@ -93,9 +93,9 @@ "resource": { "type": "Snapshot", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "SnapshotId" } + { "target": "Id", "source": "response", "path": "SnapshotId" } ], - "path": "$" + "path": "@" } }, "CreateSubnet": { @@ -103,7 +103,7 @@ "resource": { "type": "Subnet", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Subnet.SubnetId" } + { "target": "Id", "source": "response", "path": "Subnet.SubnetId" } ], "path": "Subnet" } @@ -113,9 +113,9 @@ "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "requestParameter", "source": "Resources[]" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "requestParameter", "path": "Resources[]" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -124,9 +124,9 @@ "resource": { "type": "Image", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "VolumeId" } + { "target": "Id", "source": "response", "path": "VolumeId" } ], - "path": "$" + "path": "@" } }, "CreateVpc": { @@ -134,7 +134,7 @@ "resource": { "type": "Vpc", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Vpc.VpcId" } + { "target": "Id", "source": "response", "path": "Vpc.VpcId" } ], "path": "Vpc" } @@ -144,7 +144,7 @@ "resource": { "type": "VpcPeeringConnection", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "VpcPeeringConnection.VpcPeeringConnectionId" } + { "target": "Id", "source": "response", "path": "VpcPeeringConnection.VpcPeeringConnectionId" } ], "path": "VpcPeeringConnection" } @@ -157,7 +157,7 @@ "resource": { "type": "KeyPair", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "KeyName" } + { "target": "Name", "source": "response", "path": "KeyName" } ] } }, @@ -166,7 +166,137 @@ "resource": { "type": "Image", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "ImageId" } + { "target": "Id", "source": "response", "path": "ImageId" } + ] + } + } + }, + "has": { + "DhcpOptions": { + "resource": { + "type": "DhcpOptions", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "Image": { + "resource": { + "type": "Image", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "Instance": { + "resource": { + "type": "Instance", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "InternetGateway": { + "resource": { + "type": "InternetGateway", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "KeyPair": { + "resource": { + "type": "KeyPair", + "identifiers": [ + { "target": "Name", "source": "input" } + ] + } + }, + "NetworkAcl": { + "resource": { + "type": "NetworkAcl", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "NetworkInterface": { + "resource": { + "type": "NetworkInterface", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "PlacementGroup": { + "resource": { + "type": "PlacementGroup", + "identifiers": [ + { "target": "Name", "source": "input" } + ] + } + }, + "RouteTable": { + "resource": { + "type": "RouteTable", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "RouteTableAssociation": { + "resource": { + "type": "RouteTableAssociation", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "SecurityGroup": { + "resource": { + "type": "SecurityGroup", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "Snapshot": { + "resource": { + "type": "Snapshot", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "Subnet": { + "resource": { + "type": "Subnet", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "Volume": { + "resource": { + "type": "Volume", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "Vpc": { + "resource": { + "type": "Vpc", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "VpcPeeringConnection": { + "resource": { + "type": "VpcPeeringConnection", + "identifiers": [ + { "target": "Id", "source": "input" } ] } } @@ -177,7 +307,7 @@ "resource": { "type": "DhcpOptions", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "DhcpOptions[].DhcpOptionsId" } + { "target": "Id", "source": "response", "path": "DhcpOptions[].DhcpOptionsId" } ], "path": "DhcpOptions[]" } @@ -187,7 +317,7 @@ "resource": { "type": "Image", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Images[].ImageId" } + { "target": "Id", "source": "response", "path": "Images[].ImageId" } ], "path": "Images[]" } @@ -197,7 +327,7 @@ "resource": { "type": "Instance", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Reservations[].Instances[].InstanceId" } + { "target": "Id", "source": "response", "path": "Reservations[].Instances[].InstanceId" } ], "path": "Reservations[].Instances[]" } @@ -207,7 +337,7 @@ "resource": { "type": "InternetGateway", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "InternetGateways[].InternetGatewayId" } + { "target": "Id", "source": "response", "path": "InternetGateways[].InternetGatewayId" } ], "path": "InternetGateways[]" } @@ -217,7 +347,7 @@ "resource": { "type": "KeyPair", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "KeyPairs[].KeyName" } + { "target": "Name", "source": "response", "path": "KeyPairs[].KeyName" } ], "path": "KeyPairs[]" } @@ -227,7 +357,7 @@ "resource": { "type": "NetworkAcl", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkAcls[].NetworkAclId" } + { "target": "Id", "source": "response", "path": "NetworkAcls[].NetworkAclId" } ], "path": "NetworkAcls[]" } @@ -237,7 +367,7 @@ "resource": { "type": "NetworkInterface", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkInterfaces[].NetworkInterfaceId" } + { "target": "Id", "source": "response", "path": "NetworkInterfaces[].NetworkInterfaceId" } ], "path": "NetworkInterfaces[]" } @@ -247,7 +377,7 @@ "resource": { "type": "PlacementGroup", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "PlacementGroups[].GroupName" } + { "target": "Name", "source": "response", "path": "PlacementGroups[].GroupName" } ], "path": "PlacementGroups[]" } @@ -257,7 +387,7 @@ "resource": { "type": "RouteTable", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "RouteTables[].RouteTableId" } + { "target": "Id", "source": "response", "path": "RouteTables[].RouteTableId" } ], "path": "RouteTables[]" } @@ -267,7 +397,7 @@ "resource": { "type": "SecurityGroup", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "SecurityGroups[].GroupId" } + { "target": "Id", "source": "response", "path": "SecurityGroups[].GroupId" } ], "path": "SecurityGroups[]" } @@ -277,7 +407,7 @@ "resource": { "type": "Snapshot", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Snapshots[].SnapshotId" } + { "target": "Id", "source": "response", "path": "Snapshots[].SnapshotId" } ], "path": "Snapshots[]" } @@ -287,7 +417,7 @@ "resource": { "type": "Subnet", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Subnets[].SubnetId" } + { "target": "Id", "source": "response", "path": "Subnets[].SubnetId" } ], "path": "Subnets[]" } @@ -297,7 +427,7 @@ "resource": { "type": "Volume", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Volumes[].VolumeId" } + { "target": "Id", "source": "response", "path": "Volumes[].VolumeId" } ], "path": "Volumes[]" } @@ -307,7 +437,7 @@ "resource": { "type": "VpcPeeringConnection", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "VpcPeeringConnections[].VpcPeeringConnectionId" } + { "target": "Id", "source": "response", "path": "VpcPeeringConnections[].VpcPeeringConnectionId" } ], "path": "VpcPeeringConnections[]" } @@ -317,7 +447,7 @@ "resource": { "type": "Vpc", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Vpcs[].VpcId" } + { "target": "Id", "source": "response", "path": "Vpcs[].VpcId" } ], "path": "Vpcs[]" } @@ -337,7 +467,7 @@ "request": { "operation": "DescribeDhcpOptions", "params": [ - { "target": "DhcpOptionsIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "DhcpOptionsIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "DhcpOptions[0]" @@ -347,7 +477,7 @@ "request": { "operation": "AssociateDhcpOptions", "params": [ - { "target": "DhcpOptionsId", "sourceType": "identifier", "source": "Id" } + { "target": "DhcpOptionsId", "source": "identifier", "name": "Id" } ] } }, @@ -355,15 +485,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -371,7 +501,7 @@ "request": { "operation": "DeleteDhcpOptions", "params": [ - { "target": "DhcpOptionsId", "sourceType": "identifier", "source": "Id" } + { "target": "DhcpOptionsId", "source": "identifier", "name": "Id" } ] } } @@ -389,7 +519,7 @@ "request": { "operation": "DescribeImages", "params": [ - { "target": "ImageIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "ImageIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "Images[0]" @@ -399,15 +529,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -415,7 +545,7 @@ "request": { "operation": "DeregisterImage", "params": [ - { "target": "ImageId", "sourceType": "identifier", "source": "Id" } + { "target": "ImageId", "source": "identifier", "name": "Id" } ] } }, @@ -423,7 +553,7 @@ "request": { "operation": "DescribeImageAttribute", "params": [ - { "target": "ImageId", "sourceType": "identifier", "source": "Id" } + { "target": "ImageId", "source": "identifier", "name": "Id" } ] } }, @@ -431,7 +561,7 @@ "request": { "operation": "ModifyImageAttribute", "params": [ - { "target": "ImageId", "sourceType": "identifier", "source": "Id" } + { "target": "ImageId", "source": "identifier", "name": "Id" } ] } }, @@ -439,7 +569,7 @@ "request": { "operation": "ResetImageAttribute", "params": [ - { "target": "ImageId", "sourceType": "identifier", "source": "Id" } + { "target": "ImageId", "source": "identifier", "name": "Id" } ] } } @@ -457,7 +587,7 @@ "request": { "operation": "DescribeInstances", "params": [ - { "target": "InstanceIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "Reservations[0].Instances[0]" @@ -467,7 +597,7 @@ "request": { "operation": "AttachVolume", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceId", "source": "identifier", "name": "Id" } ] } }, @@ -475,7 +605,7 @@ "request": { "operation": "GetConsoleOutput", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceId", "source": "identifier", "name": "Id" } ] } }, @@ -483,13 +613,13 @@ "request": { "operation": "CreateImage", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Image", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "ImageId" } + { "target": "Id", "source": "response", "path": "ImageId" } ] } }, @@ -497,15 +627,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -513,7 +643,7 @@ "request": { "operation": "DescribeInstanceAttribute", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceId", "source": "identifier", "name": "Id" } ] } }, @@ -521,7 +651,7 @@ "request": { "operation": "DetachVolume", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceId", "source": "identifier", "name": "Id" } ] } }, @@ -529,7 +659,7 @@ "request": { "operation": "ModifyInstanceAttribute", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceId", "source": "identifier", "name": "Id" } ] } }, @@ -537,7 +667,7 @@ "request": { "operation": "MonitorInstances", "params": [ - { "target": "InstanceIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[0]", "source": "identifier", "name": "Id" } ] } }, @@ -545,7 +675,7 @@ "request": { "operation": "GetPasswordData", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceId", "source": "identifier", "name": "Id" } ] } }, @@ -553,7 +683,7 @@ "request": { "operation": "RebootInstances", "params": [ - { "target": "InstanceIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[0]", "source": "identifier", "name": "Id" } ] } }, @@ -561,7 +691,7 @@ "request": { "operation": "ReportInstanceStatus", "params": [ - { "target": "Instances[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Instances[0]", "source": "identifier", "name": "Id" } ] } }, @@ -569,7 +699,7 @@ "request": { "operation": "ResetInstanceAttribute", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceId", "source": "identifier", "name": "Id" } ] } }, @@ -577,8 +707,8 @@ "request": { "operation": "ResetInstanceAttribute", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Attribute", "sourceType": "string", "source": "kernel" } + { "target": "InstanceId", "source": "identifier", "name": "Id" }, + { "target": "Attribute", "source": "string", "value": "kernel" } ] } }, @@ -586,8 +716,8 @@ "request": { "operation": "ResetInstanceAttribute", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Attribute", "sourceType": "string", "source": "ramdisk" } + { "target": "InstanceId", "source": "identifier", "name": "Id" }, + { "target": "Attribute", "source": "string", "value": "ramdisk" } ] } }, @@ -595,8 +725,8 @@ "request": { "operation": "ResetInstanceAttribute", "params": [ - { "target": "InstanceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Attribute", "sourceType": "string", "source": "sourceDestCheck" } + { "target": "InstanceId", "source": "identifier", "name": "Id" }, + { "target": "Attribute", "source": "string", "value": "sourceDestCheck" } ] } }, @@ -604,7 +734,7 @@ "request": { "operation": "StartInstances", "params": [ - { "target": "InstanceIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[0]", "source": "identifier", "name": "Id" } ] } }, @@ -612,7 +742,7 @@ "request": { "operation": "StopInstances", "params": [ - { "target": "InstanceIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[0]", "source": "identifier", "name": "Id" } ] } }, @@ -620,7 +750,7 @@ "request": { "operation": "TerminateInstances", "params": [ - { "target": "InstanceIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[0]", "source": "identifier", "name": "Id" } ] } }, @@ -628,7 +758,7 @@ "request": { "operation": "UnmonitorInstances", "params": [ - { "target": "InstanceIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[0]", "source": "identifier", "name": "Id" } ] } } @@ -638,7 +768,7 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[]", "source": "identifier", "name": "Id" } ] } }, @@ -646,7 +776,7 @@ "request": { "operation": "MonitorInstances", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ] } }, @@ -654,7 +784,7 @@ "request": { "operation": "RebootInstances", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ] } }, @@ -662,7 +792,7 @@ "request": { "operation": "StartInstances", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ] } }, @@ -670,7 +800,7 @@ "request": { "operation": "StopInstances", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ] } }, @@ -678,7 +808,7 @@ "request": { "operation": "TerminateInstances", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ] } }, @@ -686,7 +816,7 @@ "request": { "operation": "UnmonitorInstances", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ] } } @@ -695,49 +825,31 @@ "Running": { "waiterName": "InstanceRunning", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ], "path": "Reservations[0].Instances[0]" }, "Stopped": { "waiterName": "InstanceStopped", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ], "path": "Reservations[0].Instances[0]" }, "Terminated": { "waiterName": "InstanceTerminated", "params": [ - { "target": "InstanceIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "InstanceIds[]", "source": "identifier", "name": "Id" } ], "path": "Reservations[0].Instances[0]" } }, - "hasMany": { - "Volumes": { - "request": { - "operation": "DescribeVolumes", - "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "attachment.instance-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } - ] - }, - "resource": { - "type": "Volume", - "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Volumes[].VolumeId" } - ], - "path": "Volumes[]" - } - } - }, - "belongsTo": { + "has": { "Image": { "resource": { "type": "Image", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "ImageId" } + { "target": "Id", "source": "data", "path": "ImageId" } ] } }, @@ -745,7 +857,7 @@ "resource": { "type": "KeyPair", "identifiers": [ - { "target": "Name", "sourceType": "dataMember", "source": "KeyName" } + { "target": "Name", "source": "data", "path": "KeyName" } ] } }, @@ -753,7 +865,7 @@ "resource": { "type": "PlacementGroup", "identifiers": [ - { "target": "Name", "sourceType": "dataMember", "source": "Placement.GroupName" } + { "target": "Name", "source": "data", "path": "Placement.GroupName" } ] } }, @@ -761,7 +873,7 @@ "resource": { "type": "Subnet", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "SubnetId" } + { "target": "Id", "source": "data", "path": "SubnetId" } ] } }, @@ -769,8 +881,26 @@ "resource": { "type": "Vpc", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "VpcId" } + { "target": "Id", "source": "data", "path": "VpcId" } + ] + } + } + }, + "hasMany": { + "Volumes": { + "request": { + "operation": "DescribeVolumes", + "params": [ + { "target": "Filters[0].Name", "source": "string", "value": "attachment.instance-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] + }, + "resource": { + "type": "Volume", + "identifiers": [ + { "target": "Id", "source": "response", "path": "Volumes[].VolumeId" } + ], + "path": "Volumes[]" } } } @@ -787,7 +917,7 @@ "request": { "operation": "DescribeInternetGateways", "params": [ - { "target": "InternetGatewayIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "InternetGatewayIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "InternetGateways[0]" @@ -797,7 +927,7 @@ "request": { "operation": "AttachInternetGateway", "params": [ - { "target": "InternetGatewayId", "sourceType": "identifier", "source": "Id" } + { "target": "InternetGatewayId", "source": "identifier", "name": "Id" } ] } }, @@ -805,15 +935,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -821,7 +951,7 @@ "request": { "operation": "DeleteInternetGateway", "params": [ - { "target": "InternetGatewayId", "sourceType": "identifier", "source": "Id" } + { "target": "InternetGatewayId", "source": "identifier", "name": "Id" } ] } }, @@ -829,7 +959,7 @@ "request": { "operation": "DetachInternetGateway", "params": [ - { "target": "InternetGatewayId", "sourceType": "identifier", "source": "Id" } + { "target": "InternetGatewayId", "source": "identifier", "name": "Id" } ] } } @@ -847,7 +977,7 @@ "request": { "operation": "DescribeKeyPairs", "params": [ - { "target": "KeyNames[0]", "sourceType": "identifier", "source": "Name" } + { "target": "KeyNames[0]", "source": "identifier", "name": "Name" } ] }, "path": "KeyPairs[0]" @@ -857,7 +987,7 @@ "request": { "operation": "DeleteKeyPair", "params": [ - { "target": "KeyName", "sourceType": "identifier", "source": "Name" } + { "target": "KeyName", "source": "identifier", "name": "Name" } ] } } @@ -875,7 +1005,7 @@ "request": { "operation": "DescribeNetworkAcls", "params": [ - { "target": "NetworkAclIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkAclIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "NetworkAcls[0]" @@ -885,7 +1015,7 @@ "request": { "operation": "CreateNetworkAclEntry", "params": [ - { "target": "NetworkAclId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkAclId", "source": "identifier", "name": "Id" } ] } }, @@ -893,15 +1023,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -909,7 +1039,7 @@ "request": { "operation": "DeleteNetworkAcl", "params": [ - { "target": "NetworkAclId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkAclId", "source": "identifier", "name": "Id" } ] } }, @@ -917,7 +1047,7 @@ "request": { "operation": "DeleteNetworkAclEntry", "params": [ - { "target": "NetworkAclId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkAclId", "source": "identifier", "name": "Id" } ] } }, @@ -925,7 +1055,7 @@ "request": { "operation": "ReplaceNetworkAclAssociation", "params": [ - { "target": "NetworkAclId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkAclId", "source": "identifier", "name": "Id" } ] } }, @@ -933,17 +1063,17 @@ "request": { "operation": "ReplaceNetworkAclEntry", "params": [ - { "target": "NetworkAclId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkAclId", "source": "identifier", "name": "Id" } ] } } }, - "belongsTo": { + "has": { "Vpc": { "resource": { "type": "Vpc", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "VpcId" } + { "target": "Id", "source": "data", "path": "VpcId" } ] } } @@ -961,7 +1091,7 @@ "request": { "operation": "DescribeNetworkInterfaces", "params": [ - { "target": "NetworkInterfaceIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkInterfaceIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "NetworkInterfaces[0]" @@ -971,7 +1101,7 @@ "request": { "operation": "AssignPrivateIpAddresses", "params": [ - { "target": "NetworkInterfaceId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkInterfaceId", "source": "identifier", "name": "Id" } ] } }, @@ -979,7 +1109,7 @@ "request": { "operation": "AttachNetworkInterface", "params": [ - { "target": "NetworkInterfaceId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkInterfaceId", "source": "identifier", "name": "Id" } ] } }, @@ -987,15 +1117,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -1003,7 +1133,7 @@ "request": { "operation": "DeleteNetworkInterface", "params": [ - { "target": "NetworkInterfaceId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkInterfaceId", "source": "identifier", "name": "Id" } ] } }, @@ -1011,7 +1141,7 @@ "request": { "operation": "DescribeNetworkInterfaceAttribute", "params": [ - { "target": "NetworkInterfaceId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkInterfaceId", "source": "identifier", "name": "Id" } ] } }, @@ -1019,7 +1149,7 @@ "request": { "operation": "DetachNetworkInterface", "params": [ - { "target": "AttachmentId", "sourceType": "dataMember", "source": "Attachment.AttachmentId" } + { "target": "AttachmentId", "source": "data", "path": "Attachment.AttachmentId" } ] } }, @@ -1027,7 +1157,7 @@ "request": { "operation": "ModifyNetworkInterfaceAttribute", "params": [ - { "target": "NetworkInterfaceId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkInterfaceId", "source": "identifier", "name": "Id" } ] } }, @@ -1035,7 +1165,7 @@ "request": { "operation": "ResetNetworkInterfaceAttribute", "params": [ - { "target": "NetworkInterfaceId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkInterfaceId", "source": "identifier", "name": "Id" } ] } }, @@ -1043,17 +1173,17 @@ "request": { "operation": "UnassignPrivateIpAddresses", "params": [ - { "target": "NetworkInterfaceId", "sourceType": "identifier", "source": "Id" } + { "target": "NetworkInterfaceId", "source": "identifier", "name": "Id" } ] } } }, - "belongsTo": { + "has": { "Subnet": { "resource": { "type": "Subnet", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "SubnetId" } + { "target": "Id", "source": "data", "path": "SubnetId" } ] } }, @@ -1061,7 +1191,7 @@ "resource": { "type": "Vpc", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "VpcId" } + { "target": "Id", "source": "data", "path": "VpcId" } ] } } @@ -1079,7 +1209,7 @@ "request": { "operation": "DescribePlacementGroups", "params": [ - { "target": "GroupNames[0]", "sourceType": "identifier", "source": "Name" } + { "target": "GroupNames[0]", "source": "identifier", "name": "Name" } ] }, "path": "PlacementGroups[0]" @@ -1089,7 +1219,7 @@ "request": { "operation": "DeletePlacementGroup", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] } } @@ -1099,14 +1229,14 @@ "request": { "operation": "DescribeInstances", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "placement-group-name" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Name" } + { "target": "Filters[0].Name", "source": "string", "value": "placement-group-name" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "Instance", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Reservations[].Instances[].InstanceId" } + { "target": "Id", "source": "response", "path": "Reservations[].Instances[].InstanceId" } ], "path": "Reservations[].Instances[]" } @@ -1125,7 +1255,7 @@ "request": { "operation": "DescribeRouteTables", "params": [ - { "target": "RouteTableIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "RouteTableIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "RouteTables[0]" @@ -1135,13 +1265,13 @@ "request": { "operation": "AssociateRouteTable", "params": [ - { "target": "RouteTableId", "sourceType": "identifier", "source": "Id" } + { "target": "RouteTableId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "RouteTableAssociation", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "AssociationId" } + { "target": "Id", "source": "response", "path": "AssociationId" } ] } }, @@ -1149,7 +1279,7 @@ "request": { "operation": "CreateRoute", "params": [ - { "target": "RouteTableId", "sourceType": "identifier", "source": "Id" } + { "target": "RouteTableId", "source": "identifier", "name": "Id" } ] } }, @@ -1157,15 +1287,25 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } + ] + } + } + }, + "has": { + "Vpc": { + "resource": { + "type": "Vpc", + "identifiers": [ + { "target": "Id", "source": "data", "path": "VpcId" } ] } } @@ -1175,27 +1315,17 @@ "request": { "operation": "DescribeRouteTables", "params": [ - { "target": "RouteTableIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "RouteTableIds[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "RouteTableAssociation", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "RouteTables[0].Associations[].RouteTableAssociationId" } + { "target": "Id", "source": "response", "path": "RouteTables[0].Associations[].RouteTableAssociationId" } ], "path": "RouteTables[0].Associations[]" } } - }, - "belongsTo": { - "Vpc": { - "resource": { - "type": "Vpc", - "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "VpcId" } - ] - } - } } }, "RouteTableAssociation": { @@ -1211,7 +1341,7 @@ "request": { "operation": "DisassociateRouteTable", "params": [ - { "target": "AssociationId", "sourceType": "identifier", "source": "Id" } + { "target": "AssociationId", "source": "identifier", "name": "Id" } ] } }, @@ -1219,23 +1349,23 @@ "request": { "operation": "ReplaceRouteTableAssociation", "params": [ - { "target": "AssociationId", "sourceType": "identifier", "source": "Id" } + { "target": "AssociationId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "RouteTableAssociation", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NewAssociationId" } + { "target": "Id", "source": "response", "path": "NewAssociationId" } ] } } }, - "belongsTo": { + "has": { "RouteTable": { "resource": { "type": "RouteTable", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "RouteTableId" } + { "target": "Id", "source": "data", "path": "RouteTableId" } ] } }, @@ -1243,7 +1373,7 @@ "resource": { "type": "Subnet", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "SubnetId" } + { "target": "Id", "source": "data", "path": "SubnetId" } ] } } @@ -1261,7 +1391,7 @@ "request": { "operation": "DescribeSecurityGroups", "params": [ - { "target": "GroupIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "GroupIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "SecurityGroups[0]" @@ -1271,7 +1401,7 @@ "request": { "operation": "AuthorizeSecurityGroupEgress", "params": [ - { "target": "GroupId", "sourceType": "identifier", "source": "Id" } + { "target": "GroupId", "source": "identifier", "name": "Id" } ] } }, @@ -1279,7 +1409,7 @@ "request": { "operation": "AuthorizeSecurityGroupIngress", "params": [ - { "target": "GroupId", "sourceType": "identifier", "source": "Id" } + { "target": "GroupId", "source": "identifier", "name": "Id" } ] } }, @@ -1287,15 +1417,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -1303,7 +1433,7 @@ "request": { "operation": "DeleteSecurityGroup", "params": [ - { "target": "GroupId", "sourceType": "identifier", "source": "Id" } + { "target": "GroupId", "source": "identifier", "name": "Id" } ] } }, @@ -1311,7 +1441,7 @@ "request": { "operation": "RevokeSecurityGroupEgress", "params": [ - { "target": "GroupId", "sourceType": "identifier", "source": "Id" } + { "target": "GroupId", "source": "identifier", "name": "Id" } ] } }, @@ -1319,7 +1449,7 @@ "request": { "operation": "RevokeSecurityGroupIngress", "params": [ - { "target": "GroupId", "sourceType": "identifier", "source": "Id" } + { "target": "GroupId", "source": "identifier", "name": "Id" } ] } } @@ -1337,7 +1467,7 @@ "request": { "operation": "DescribeSnapshots", "params": [ - { "target": "SnapshotIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "SnapshotIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "Snapshots[0]" @@ -1347,7 +1477,7 @@ "request": { "operation": "CopySnapshot", "params": [ - { "target": "SourceSnapshotId", "sourceType": "identifier", "source": "Id" } + { "target": "SourceSnapshotId", "source": "identifier", "name": "Id" } ] } }, @@ -1355,15 +1485,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -1371,7 +1501,7 @@ "request": { "operation": "DeleteSnapshot", "params": [ - { "target": "SnapshotId", "sourceType": "identifier", "source": "Id" } + { "target": "SnapshotId", "source": "identifier", "name": "Id" } ] } }, @@ -1379,7 +1509,7 @@ "request": { "operation": "DescribeSnapshotAttribute", "params": [ - { "target": "SnapshotId", "sourceType": "identifier", "source": "Id" } + { "target": "SnapshotId", "source": "identifier", "name": "Id" } ] } }, @@ -1387,7 +1517,7 @@ "request": { "operation": "ModifySnapshotAttribute", "params": [ - { "target": "SnapshotId", "sourceType": "identifier", "source": "Id" } + { "target": "SnapshotId", "source": "identifier", "name": "Id" } ] } }, @@ -1395,17 +1525,17 @@ "request": { "operation": "ResetSnapshotAttribute", "params": [ - { "target": "SnapshotId", "sourceType": "identifier", "source": "Id" } + { "target": "SnapshotId", "source": "identifier", "name": "Id" } ] } } }, - "belongsTo": { + "has": { "Volume": { "resource": { "type": "Volume", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "VolumeId" } + { "target": "Id", "source": "data", "path": "VolumeId" } ] } } @@ -1423,7 +1553,7 @@ "request": { "operation": "DescribeSubnets", "params": [ - { "target": "SubnetIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "SubnetIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "Subnets[0]" @@ -1433,13 +1563,13 @@ "request": { "operation": "RunInstances", "params": [ - { "target": "SubnetId", "sourceType": "identifier", "source": "Id" } + { "target": "SubnetId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Instance", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Instances[].InstanceId" } + { "target": "Id", "source": "response", "path": "Instances[].InstanceId" } ], "path": "Instances[]" } @@ -1448,13 +1578,13 @@ "request": { "operation": "CreateNetworkInterface", "params": [ - { "target": "SubnetId", "sourceType": "identifier", "source": "Id" } + { "target": "SubnetId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "NetworkInterface", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkInterface.NetworkInterfaceId" } + { "target": "Id", "source": "response", "path": "NetworkInterface.NetworkInterfaceId" } ], "path": "NetworkInterface" } @@ -1463,15 +1593,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -1479,7 +1609,17 @@ "request": { "operation": "DeleteSubnet", "params": [ - { "target": "SubnetId", "sourceType": "identifier", "source": "Id" } + { "target": "SubnetId", "source": "identifier", "name": "Id" } + ] + } + } + }, + "has": { + "Vpc": { + "resource": { + "type": "Vpc", + "identifiers": [ + { "target": "Id", "source": "data", "path": "VpcId" } ] } } @@ -1489,14 +1629,14 @@ "request": { "operation": "DescribeInstances", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "subnet-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "subnet-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Instance", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Reservations[].Instances[].InstanceId" } + { "target": "Id", "source": "response", "path": "Reservations[].Instances[].InstanceId" } ], "path": "Reservations[].Instances[]" } @@ -1505,28 +1645,18 @@ "request": { "operation": "DescribeNetworkInterfaces", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "subnet-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "subnet-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "NetworkInterface", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkInterfaces[].NetworkInterfaceId" } + { "target": "Id", "source": "response", "path": "NetworkInterfaces[].NetworkInterfaceId" } ], "path": "NetworkInterfaces[]" } } - }, - "belongsTo": { - "Vpc": { - "resource": { - "type": "Vpc", - "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "VpcId" } - ] - } - } } }, "Tag": { @@ -1549,10 +1679,10 @@ "request": { "operation": "DescribeTags", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "key" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Key" }, - { "target": "Filters[1].Name", "sourceType": "string", "source": "value" }, - { "target": "Filters[1].Values[0]", "sourceType": "identifier", "source": "Value" } + { "target": "Filters[0].Name", "source": "string", "value": "key" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Key" }, + { "target": "Filters[1].Name", "source": "string", "value": "value" }, + { "target": "Filters[1].Values[0]", "source": "identifier", "name": "Value" } ] }, "path": "Tags[0]" @@ -1562,9 +1692,9 @@ "request": { "operation": "DeleteTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "ResourceId" }, - { "target": "Tags[0].Key", "sourceType": "identifier", "source": "Key" }, - { "target": "Tags[0].Value", "sourceType": "identifier", "source": "Value" } + { "target": "Resources[0]", "source": "identifier", "name": "ResourceId" }, + { "target": "Tags[0].Key", "source": "identifier", "name": "Key" }, + { "target": "Tags[0].Value", "source": "identifier", "name": "Value" } ] } } @@ -1574,9 +1704,9 @@ "request": { "operation": "DeleteTags", "params": [ - { "target": "Resources[]", "sourceType": "identifier", "source": "ResourceId" }, - { "target": "Tags[*].Key", "sourceType": "identifier", "source": "Key" }, - { "target": "Tags[*].Value", "sourceType": "identifier", "source": "Value" } + { "target": "Resources[]", "source": "identifier", "name": "ResourceId" }, + { "target": "Tags[*].Key", "source": "identifier", "name": "Key" }, + { "target": "Tags[*].Value", "source": "identifier", "name": "Value" } ] } } @@ -1594,7 +1724,7 @@ "request": { "operation": "DescribeVolumes", "params": [ - { "target": "VolumeIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "VolumeIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "Volumes[0]" @@ -1604,7 +1734,7 @@ "request": { "operation": "AttachVolume", "params": [ - { "target": "VolumeId", "sourceType": "identifier", "source": "Id" } + { "target": "VolumeId", "source": "identifier", "name": "Id" } ] } }, @@ -1612,30 +1742,30 @@ "request": { "operation": "CreateSnapshot", "params": [ - { "target": "VolumeId", "sourceType": "identifier", "source": "Id" } + { "target": "VolumeId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Snapshot", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "SnapshotId" } + { "target": "Id", "source": "response", "path": "SnapshotId" } ], - "path": "$" + "path": "@" } }, "CreateTags": { "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -1643,7 +1773,7 @@ "request": { "operation": "DescribeVolumeAttribute", "params": [ - { "target": "VolumeId", "sourceType": "identifier", "source": "Id" } + { "target": "VolumeId", "source": "identifier", "name": "Id" } ] } }, @@ -1651,7 +1781,7 @@ "request": { "operation": "DescribeVolumeStatus", "params": [ - { "target": "VolumeIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "VolumeIds[0]", "source": "identifier", "name": "Id" } ] } }, @@ -1659,7 +1789,7 @@ "request": { "operation": "DetachVolume", "params": [ - { "target": "VolumeId", "sourceType": "identifier", "source": "Id" } + { "target": "VolumeId", "source": "identifier", "name": "Id" } ] } }, @@ -1667,7 +1797,7 @@ "request": { "operation": "EnableVolumeIO", "params": [ - { "target": "VolumeId", "sourceType": "identifier", "source": "Id" } + { "target": "VolumeId", "source": "identifier", "name": "Id" } ] } }, @@ -1675,7 +1805,7 @@ "request": { "operation": "ModifyVolumeAttribute", "params": [ - { "target": "VolumeId", "sourceType": "identifier", "source": "Id" } + { "target": "VolumeId", "source": "identifier", "name": "Id" } ] } } @@ -1685,14 +1815,14 @@ "request": { "operation": "DescribeSnapshots", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "volume-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "volume-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Snapshot", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Snapshots[].SnapshotId" } + { "target": "Id", "source": "response", "path": "Snapshots[].SnapshotId" } ], "path": "Snapshots[]" } @@ -1711,7 +1841,7 @@ "request": { "operation": "DescribeVpcs", "params": [ - { "target": "VpcIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "VpcIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "Vpcs[0]" @@ -1721,7 +1851,7 @@ "request": { "operation": "AssociateDhcpOptions", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] } }, @@ -1729,7 +1859,7 @@ "request": { "operation": "AttachInternetGateway", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] } }, @@ -1737,13 +1867,13 @@ "request": { "operation": "CreateNetworkAcl", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "NetworkAcl", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkAcl.NetworkAclId" } + { "target": "Id", "source": "response", "path": "NetworkAcl.NetworkAclId" } ], "path": "NetworkAcl" } @@ -1752,13 +1882,13 @@ "request": { "operation": "CreateRouteTable", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "RouteTable", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "RouteTable.RouteTableId" } + { "target": "Id", "source": "response", "path": "RouteTable.RouteTableId" } ], "path": "RouteTable" } @@ -1767,13 +1897,13 @@ "request": { "operation": "CreateSecurityGroup", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "SecurityGroup", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "GroupId" } + { "target": "Id", "source": "response", "path": "GroupId" } ] } }, @@ -1781,13 +1911,13 @@ "request": { "operation": "CreateSubnet", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Subnet", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Subnet.SubnetId" } + { "target": "Id", "source": "response", "path": "Subnet.SubnetId" } ], "path": "Subnet" } @@ -1796,15 +1926,15 @@ "request": { "operation": "CreateTags", "params": [ - { "target": "Resources[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Resources[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Tag", "identifiers": [ - { "target": "ResourceId", "sourceType": "identifier", "source": "Id" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Tags[].Key" }, - { "target": "Value", "sourceType": "requestParameter", "source": "Tags[].Value" } + { "target": "ResourceId", "source": "identifier", "name": "Id" }, + { "target": "Key", "source": "requestParameter", "path": "Tags[].Key" }, + { "target": "Value", "source": "requestParameter", "path": "Tags[].Value" } ] } }, @@ -1812,7 +1942,7 @@ "request": { "operation": "DeleteVpc", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] } }, @@ -1820,7 +1950,7 @@ "request": { "operation": "DescribeVpcAttribute", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] } }, @@ -1828,7 +1958,7 @@ "request": { "operation": "DetachInternetGateway", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] } }, @@ -1836,7 +1966,7 @@ "request": { "operation": "ModifyVpcAttribute", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] } }, @@ -1844,31 +1974,41 @@ "request": { "operation": "CreateVpcPeeringConnection", "params": [ - { "target": "VpcId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "VpcPeeringConnection", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "VpcPeeringConnection.VpcPeeringConnectionId" } + { "target": "Id", "source": "response", "path": "VpcPeeringConnection.VpcPeeringConnectionId" } ], "path": "VpcPeeringConnection" } } }, + "has": { + "DhcpOptions": { + "resource": { + "type": "DhcpOptions", + "identifiers": [ + { "target": "Id", "source": "data", "path": "DhcpOptionsId" } + ] + } + } + }, "hasMany": { "AcceptedVpcPeeringConnections": { "request": { "operation": "DescribeVpcPeeringConnections", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "accepter-vpc-info.vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "accepter-vpc-info.vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "VpcPeeringConnection", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "VpcPeeringConnections[].VpcPeeringConnectionId" } + { "target": "Id", "source": "response", "path": "VpcPeeringConnections[].VpcPeeringConnectionId" } ], "path": "VpcPeeringConnections[]" } @@ -1877,14 +2017,14 @@ "request": { "operation": "DescribeInstances", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Instance", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Reservations[].Instances[].InstanceId" } + { "target": "Id", "source": "response", "path": "Reservations[].Instances[].InstanceId" } ], "path": "Reservations[].Instances[]" } @@ -1893,14 +2033,14 @@ "request": { "operation": "DescribeInternetGateways", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "attachment.vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "attachment.vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "InternetGateway", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "InternetGateways[].InternetGatewayId" } + { "target": "Id", "source": "response", "path": "InternetGateways[].InternetGatewayId" } ], "path": "InternetGateways[]" } @@ -1909,14 +2049,14 @@ "request": { "operation": "DescribeNetworkAcls", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "NetworkAcl", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkAcls[].NetworkAclId" } + { "target": "Id", "source": "response", "path": "NetworkAcls[].NetworkAclId" } ], "path": "NetworkAcls[]" } @@ -1925,14 +2065,14 @@ "request": { "operation": "DescribeNetworkInterfaces", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "NetworkInterface", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "NetworkInterfaces[].NetworkInterfaceId" } + { "target": "Id", "source": "response", "path": "NetworkInterfaces[].NetworkInterfaceId" } ], "path": "NetworkInterfaces[]" } @@ -1941,14 +2081,14 @@ "request": { "operation": "DescribeVpcPeeringConnections", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "requester-vpc-info.vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "requester-vpc-info.vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "VpcPeeringConnection", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "VpcPeeringConnections[].VpcPeeringConnectionId" } + { "target": "Id", "source": "response", "path": "VpcPeeringConnections[].VpcPeeringConnectionId" } ], "path": "VpcPeeringConnections[]" } @@ -1957,14 +2097,14 @@ "request": { "operation": "DescribeRouteTables", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "RouteTable", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "RouteTables[].RouteTableId" } + { "target": "Id", "source": "response", "path": "RouteTables[].RouteTableId" } ], "path": "RouteTables[]" } @@ -1973,14 +2113,14 @@ "request": { "operation": "DescribeSecurityGroups", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "SecurityGroup", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "SecurityGroups[].GroupId" } + { "target": "Id", "source": "response", "path": "SecurityGroups[].GroupId" } ], "path": "SecurityGroups[]" } @@ -1989,28 +2129,18 @@ "request": { "operation": "DescribeSubnets", "params": [ - { "target": "Filters[0].Name", "sourceType": "string", "source": "vpc-id" }, - { "target": "Filters[0].Values[0]", "sourceType": "identifier", "source": "Id" } + { "target": "Filters[0].Name", "source": "string", "value": "vpc-id" }, + { "target": "Filters[0].Values[0]", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Subnet", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Subnets[].SubnetId" } + { "target": "Id", "source": "response", "path": "Subnets[].SubnetId" } ], "path": "Subnets[]" } } - }, - "belongsTo": { - "DhcpOptions": { - "resource": { - "type": "DhcpOptions", - "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "DhcpOptionsId" } - ] - } - } } }, "VpcPeeringConnection": { @@ -2025,7 +2155,7 @@ "request": { "operation": "DescribeVpcPeeringConnections", "params": [ - { "target": "VpcPeeringConnectionIds[0]", "sourceType": "identifier", "source": "Id" } + { "target": "VpcPeeringConnectionIds[0]", "source": "identifier", "name": "Id" } ] }, "path": "VpcPeeringConnections[0]" @@ -2035,7 +2165,7 @@ "request": { "operation": "AcceptVpcPeeringConnection", "params": [ - { "target": "VpcPeeringConnectionId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcPeeringConnectionId", "source": "identifier", "name": "Id" } ] } }, @@ -2043,7 +2173,7 @@ "request": { "operation": "DeleteVpcPeeringConnection", "params": [ - { "target": "VpcPeeringConnectionId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcPeeringConnectionId", "source": "identifier", "name": "Id" } ] } }, @@ -2051,17 +2181,17 @@ "request": { "operation": "RejectVpcPeeringConnection", "params": [ - { "target": "VpcPeeringConnectionId", "sourceType": "identifier", "source": "Id" } + { "target": "VpcPeeringConnectionId", "source": "identifier", "name": "Id" } ] } } }, - "belongsTo": { + "has": { "AccepterVpc": { "resource": { "type": "Vpc", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "AccepterVpcInfo.VpcId" } + { "target": "Id", "source": "data", "path": "AccepterVpcInfo.VpcId" } ] } }, @@ -2069,7 +2199,7 @@ "resource": { "type": "Vpc", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "RequesterVpcInfo.VpcId" } + { "target": "Id", "source": "data", "path": "RequesterVpcInfo.VpcId" } ] } } diff --git a/boto3/data/resources/glacier-2012-06-01.resources.json b/boto3/data/resources/glacier-2012-06-01.resources.json index de902ee499..ceec9a3ac2 100644 --- a/boto3/data/resources/glacier-2012-06-01.resources.json +++ b/boto3/data/resources/glacier-2012-06-01.resources.json @@ -5,14 +5,24 @@ "request": { "operation": "CreateVault", "params": [ - { "target": "accountId", "sourceType": "string", "source": "-" } + { "target": "accountId", "source": "string", "value": "-" } ] }, "resource": { "type": "Vault", "identifiers": [ - { "target": "AccountId", "sourceType": "requestParameter", "source": "accountId" }, - { "target": "Name", "sourceType": "requestParameter", "source": "vaultName" } + { "target": "AccountId", "source": "requestParameter", "path": "accountId" }, + { "target": "Name", "source": "requestParameter", "path": "vaultName" } + ] + } + } + }, + "has": { + "Account": { + "resource": { + "type": "Account", + "identifiers": [ + { "target": "Id", "source": "input" } ] } } @@ -22,14 +32,14 @@ "request": { "operation": "ListVaults", "params": [ - { "target": "accountId", "sourceType": "string", "source": "-" } + { "target": "accountId", "source": "string", "value": "-" } ] }, "resource": { "type": "Vault", "identifiers": [ - { "target": "AccountId", "sourceType": "requestParameter", "source": "accountId" }, - { "target": "Name", "sourceType": "responsePath", "source": "VaultList[].VaultName" } + { "target": "AccountId", "source": "requestParameter", "path": "accountId" }, + { "target": "Name", "source": "response", "path": "VaultList[].VaultName" } ], "path": "VaultList[]" } @@ -43,12 +53,28 @@ ], "actions": { "CreateVault": { - "request": { "operation": "CreateVault" }, + "request": { + "operation": "CreateVault", + "params": [ + { "target": "accountId", "source": "identifier", "name": "Id" } + ] + }, + "resource": { + "type": "Vault", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "Id" }, + { "target": "Name", "source": "requestParameter", "path": "vaultName" } + ] + } + } + }, + "has": { + "Vault": { "resource": { "type": "Vault", "identifiers": [ - { "target": "AccountId", "sourceType": "identifier", "source": "Id" }, - { "target": "Name", "sourceType": "requestParameter", "source": "vaultName" } + { "target": "AccountId", "source": "identifier", "name": "Id" }, + { "target": "Name", "source": "input" } ] } } @@ -59,16 +85,12 @@ "resource": { "type": "Vault", "identifiers": [ - { "target": "AccountId", "sourceType": "requestParameter", "source": "accountId" }, - { "target": "Name", "sourceType": "responsePath", "source": "VaultList[].VaultName" } + { "target": "AccountId", "source": "requestParameter", "path": "accountId" }, + { "target": "Name", "source": "response", "path": "VaultList[].VaultName" } ], "path": "VaultList[]" } } - }, - "subResources": { - "resources": [ "Vault" ], - "identifiers": { "Id": "AccountId" } } }, "Archive": { @@ -82,9 +104,9 @@ "request": { "operation": "DeleteArchive", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" }, - { "target": "archiveId", "sourceType": "identifier", "source": "Id" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" }, + { "target": "archiveId", "source": "identifier", "name": "Id" } ] } }, @@ -92,18 +114,29 @@ "request": { "operation": "InitiateJob", "params": [ - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "jobParameters.Type", "sourceType": "string", "source": "archive-retrieval" }, - { "target": "jobParameters.ArchiveId", "sourceType": "identifier", "source": "Id" } + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "jobParameters.Type", "source": "string", "value": "archive-retrieval" }, + { "target": "jobParameters.ArchiveId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Job", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "jobId" }, - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" } + { "target": "Id", "source": "response", "path": "jobId" }, + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" } + ] + } + } + }, + "has": { + "Vault": { + "resource": { + "type": "Vault", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "Name", "source": "identifier", "name": "VaultName" } ] } } @@ -123,21 +156,32 @@ "request": { "operation": "DescribeJob", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" }, - { "target": "jobId", "sourceType": "identifier", "source": "Id" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" }, + { "target": "jobId", "source": "identifier", "name": "Id" } ] }, - "path": "$" + "path": "@" }, "actions": { "GetOutput": { "request": { "operation": "GetJobOutput", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" }, - { "target": "jobId", "sourceType": "identifier", "source": "Id" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" }, + { "target": "jobId", "source": "identifier", "name": "Id" } + ] + } + } + }, + "has": { + "Vault": { + "resource": { + "type": "Vault", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "Name", "source": "identifier", "name": "VaultName" } ] } } @@ -158,9 +202,9 @@ "request": { "operation": "AbortMultipartUpload", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" }, - { "target": "uploadId", "sourceType": "identifier", "source": "Id" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" }, + { "target": "uploadId", "source": "identifier", "name": "Id" } ] } }, @@ -168,9 +212,9 @@ "request": { "operation": "CompleteMultipartUpload", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" }, - { "target": "uploadId", "sourceType": "identifier", "source": "Id" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" }, + { "target": "uploadId", "source": "identifier", "name": "Id" } ] } }, @@ -178,9 +222,9 @@ "request": { "operation": "ListParts", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" }, - { "target": "uploadId", "sourceType": "identifier", "source": "Id" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" }, + { "target": "uploadId", "source": "identifier", "name": "Id" } ] } }, @@ -188,9 +232,20 @@ "request": { "operation": "UploadMultipartPart", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" }, - { "target": "uploadId", "sourceType": "identifier", "source": "Id" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" }, + { "target": "uploadId", "source": "identifier", "name": "Id" } + ] + } + } + }, + "has": { + "Vault": { + "resource": { + "type": "Vault", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "Name", "source": "identifier", "name": "VaultName" } ] } } @@ -206,8 +261,8 @@ "request": { "operation": "GetVaultNotifications", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" } ] }, "path": "vaultNotificationConfig" @@ -217,8 +272,8 @@ "request": { "operation": "DeleteVaultNotifications", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" } ] } }, @@ -226,8 +281,19 @@ "request": { "operation": "SetVaultNotifications", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "VaultName" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "VaultName" } + ] + } + } + }, + "has": { + "Vault": { + "resource": { + "type": "Vault", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "Name", "source": "identifier", "name": "VaultName" } ] } } @@ -246,19 +312,19 @@ "request": { "operation": "DescribeVault", "params": [ - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" } + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "accountId", "source": "identifier", "name": "AccountId" } ] }, - "path": "$" + "path": "@" }, "actions": { "Create": { "request": { "operation": "CreateVault", "params": [ - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" } + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "accountId", "source": "identifier", "name": "AccountId" } ] } }, @@ -266,8 +332,8 @@ "request": { "operation": "DeleteVault", "params": [ - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" } + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "accountId", "source": "identifier", "name": "AccountId" } ] } }, @@ -275,17 +341,17 @@ "request": { "operation": "InitiateJob", "params": [ - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "jobParameters.Type", "sourceType": "string", "source": "inventory-retrieval" } + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "jobParameters.Type", "source": "string", "value": "inventory-retrieval" } ] }, "resource": { "type": "Job", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "jobId" }, - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" } + { "target": "Id", "source": "response", "path": "jobId" }, + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" } ] } }, @@ -293,16 +359,16 @@ "request": { "operation": "InitiateMultipartUpload", "params": [ - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" } + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "accountId", "source": "identifier", "name": "AccountId" } ] }, "resource": { "type": "MultipartUpload", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "uploadId" }, - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" } + { "target": "Id", "source": "response", "path": "uploadId" }, + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" } ] } }, @@ -310,16 +376,65 @@ "request": { "operation": "UploadArchive", "params": [ - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" } + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "accountId", "source": "identifier", "name": "AccountId" } ] }, "resource": { "type": "Archive", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "archiveId" }, - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" } + { "target": "Id", "source": "response", "path": "archiveId" }, + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" } + ] + } + } + }, + "has": { + "Account": { + "resource": { + "type": "Account", + "identifiers": [ + { "target": "Id", "source": "identifier", "name": "AccountId" } + ] + } + }, + "Archive": { + "resource": { + "type": "Archive", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "input" } + ] + } + }, + "Job": { + "resource": { + "type": "Job", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "input" } + ] + } + }, + "MultipartUpload": { + "resource": { + "type": "MultipartUpload", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "input" } + ] + } + }, + "Notification": { + "resource": { + "type": "Notification", + "identifiers": [ + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" } ] } } @@ -329,17 +444,17 @@ "request": { "operation": "ListJobs", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "completed", "sourceType": "string", "source": "true" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "completed", "source": "string", "value": "true" } ] }, "resource": { "type": "Job", "identifiers": [ - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "Id", "sourceType": "responsePath", "source": "JobList[].JobId" } + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "JobList[].JobId" } ], "path": "JobList[]" } @@ -348,17 +463,17 @@ "request": { "operation": "ListJobs", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "statuscode", "sourceType": "string", "source": "Failed" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "statuscode", "source": "string", "value": "Failed" } ] }, "resource": { "type": "Job", "identifiers": [ - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "Id", "sourceType": "responsePath", "source": "JobList[].JobId" } + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "JobList[].JobId" } ], "path": "JobList[]" } @@ -367,16 +482,16 @@ "request": { "operation": "ListJobs", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "Name" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "Job", "identifiers": [ - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "Id", "sourceType": "responsePath", "source": "JobList[].JobId" } + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "JobList[].JobId" } ], "path": "JobList[]" } @@ -385,17 +500,17 @@ "request": { "operation": "ListJobs", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "statuscode", "sourceType": "string", "source": "InProgress" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "statuscode", "source": "string", "value": "InProgress" } ] }, "resource": { "type": "Job", "identifiers": [ - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "Id", "sourceType": "responsePath", "source": "JobList[].JobId" } + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "JobList[].JobId" } ], "path": "JobList[]" } @@ -404,16 +519,16 @@ "request": { "operation": "ListMultipartUploads", "params": [ - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" } + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "accountId", "source": "identifier", "name": "AccountId" } ] }, "resource": { "type": "MultipartUpload", "identifiers": [ - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "Id", "sourceType": "responsePath", "source": "UploadsList[].MultipartUploadId" } + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "UploadsList[].MultipartUploadId" } ], "path": "UploadsList[]" } @@ -422,33 +537,21 @@ "request": { "operation": "ListJobs", "params": [ - { "target": "accountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "vaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "statuscode", "sourceType": "string", "source": "Succeeded" } + { "target": "accountId", "source": "identifier", "name": "AccountId" }, + { "target": "vaultName", "source": "identifier", "name": "Name" }, + { "target": "statuscode", "source": "string", "value": "Succeeded" } ] }, "resource": { "type": "Job", "identifiers": [ - { "target": "AccountId", "sourceType": "identifier", "source": "AccountId" }, - { "target": "VaultName", "sourceType": "identifier", "source": "Name" }, - { "target": "Id", "sourceType": "responsePath", "source": "JobList[].JobId" } + { "target": "AccountId", "source": "identifier", "name": "AccountId" }, + { "target": "VaultName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "JobList[].JobId" } ], "path": "JobList[]" } } - }, - "subResources": { - "resources": [ - "Notification", - "Job", - "Archive", - "MultipartUpload" - ], - "identifiers": { - "AccountId": "AccountId", - "Name": "VaultName" - } } } } diff --git a/boto3/data/resources/iam-2010-05-08.resources.json b/boto3/data/resources/iam-2010-05-08.resources.json index 0f59b576aa..8ec78e2748 100644 --- a/boto3/data/resources/iam-2010-05-08.resources.json +++ b/boto3/data/resources/iam-2010-05-08.resources.json @@ -5,13 +5,7 @@ "request": { "operation": "ChangePassword" } }, "CreateAccountAlias": { - "request": { "operation": "CreateAccountAlias" }, - "resource": { - "type": "AccountAlias", - "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "AccountAlias" } - ] - } + "request": { "operation": "CreateAccountAlias" } }, "CreateAccountPasswordPolicy": { "request": { "operation": "UpdateAccountPasswordPolicy" }, @@ -25,7 +19,7 @@ "resource": { "type": "Group", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "GroupName" } + { "target": "Name", "source": "requestParameter", "path": "GroupName" } ], "path": "Group" } @@ -35,7 +29,7 @@ "resource": { "type": "InstanceProfile", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "InstanceProfileName" } + { "target": "Name", "source": "requestParameter", "path": "InstanceProfileName" } ], "path": "InstanceProfile" } @@ -45,7 +39,7 @@ "resource": { "type": "Role", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "RoleName" } + { "target": "Name", "source": "requestParameter", "path": "RoleName" } ], "path": "Role" } @@ -55,7 +49,7 @@ "resource": { "type": "SamlProvider", "identifiers": [ - { "target": "Arn", "sourceType": "responsePath", "source": "SAMLProviderArn" } + { "target": "Arn", "source": "response", "path": "SAMLProviderArn" } ] } }, @@ -64,7 +58,7 @@ "resource": { "type": "ServerCertificate", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "ServerCertificateName" } + { "target": "Name", "source": "requestParameter", "path": "ServerCertificateName" } ] } }, @@ -73,7 +67,7 @@ "resource": { "type": "SigningCertificate", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Certificate.CertificateId" } + { "target": "Id", "source": "response", "path": "Certificate.CertificateId" } ], "path": "Certificate" } @@ -83,7 +77,7 @@ "resource": { "type": "User", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "UserName" } + { "target": "Name", "source": "requestParameter", "path": "UserName" } ], "path": "User" } @@ -93,28 +87,95 @@ "resource": { "type": "VirtualMfaDevice", "identifiers": [ - { "target": "SerialNumber", "sourceType": "responsePath", "source": "VirtualMFADevice.SerialNumber" } + { "target": "SerialNumber", "source": "response", "path": "VirtualMFADevice.SerialNumber" } ], "path": "VirtualMFADevice" } } }, - "hasMany": { - "AccountAliases": { - "request": { "operation": "ListAccountAliases" }, + "has": { + "AccountPasswordPolicy": { + "resource": { + "type": "AccountPasswordPolicy", + "identifiers": [ ] + } + }, + "AccountSummary": { + "resource": { + "type": "AccountSummary", + "identifiers": [ ] + } + }, + "CurrentUser": { + "resource": { + "type": "CurrentUser", + "identifiers": [ ] + } + }, + "Group": { + "resource": { + "type": "Group", + "identifiers": [ + { "target": "Name", "source": "input" } + ] + } + }, + "InstanceProfile": { + "resource": { + "type": "InstanceProfile", + "identifiers": [ + { "target": "Name", "source": "input" } + ] + } + }, + "Role": { + "resource": { + "type": "Role", + "identifiers": [ + { "target": "Name", "source": "input" } + ] + } + }, + "SamlProvider": { + "resource": { + "type": "SamlProvider", + "identifiers": [ + { "target": "Arn", "source": "input" } + ] + } + }, + "ServerCertificate": { "resource": { - "type": "AccountAlias", + "type": "ServerCertificate", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "AccountAliases[]" } + { "target": "Name", "source": "input" } ] } }, + "User": { + "resource": { + "type": "User", + "identifiers": [ + { "target": "Name", "source": "input" } + ] + } + }, + "VirtualMfaDevice": { + "resource": { + "type": "VirtualMfaDevice", + "identifiers": [ + { "target": "SerialNumber", "source": "input" } + ] + } + } + }, + "hasMany": { "Groups": { "request": { "operation": "ListGroups" }, "resource": { "type": "Group", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "Groups[].GroupName" } + { "target": "Name", "source": "response", "path": "Groups[].GroupName" } ], "path": "Groups[]" } @@ -124,7 +185,7 @@ "resource": { "type": "InstanceProfile", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "InstanceProfiles[].InstanceProfileName" } + { "target": "Name", "source": "response", "path": "InstanceProfiles[].InstanceProfileName" } ], "path": "InstanceProfiles[]" } @@ -134,7 +195,7 @@ "resource": { "type": "Role", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "Roles[].RoleName" } + { "target": "Name", "source": "response", "path": "Roles[].RoleName" } ], "path": "Roles[]" } @@ -144,7 +205,7 @@ "resource": { "type": "SamlProvider", "identifiers": [ - { "target": "Arn", "sourceType": "responsePath", "source": "SAMLProviderList[].Arn" } + { "target": "Arn", "source": "response", "path": "SAMLProviderList[].Arn" } ] } }, @@ -153,26 +214,16 @@ "resource": { "type": "ServerCertificate", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "ServerCertificateMetadataList[].ServerCertificateName" } + { "target": "Name", "source": "response", "path": "ServerCertificateMetadataList[].ServerCertificateName" } ] } }, - "SigningCertificates": { - "request": { "operation": "ListSigningCertificates" }, - "resource": { - "type": "SigningCertificate", - "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Certificates[].CertificateId" } - ], - "path": "Certificates[]" - } - }, "Users": { "request": { "operation": "ListUsers" }, "resource": { "type": "User", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "Users[].UserName" } + { "target": "Name", "source": "response", "path": "Users[].UserName" } ], "path": "Users[]" } @@ -182,7 +233,7 @@ "resource": { "type": "VirtualMfaDevice", "identifiers": [ - { "target": "SerialNumber", "sourceType": "responsePath", "source": "VirtualMFADevices[].SerialNumber" } + { "target": "SerialNumber", "source": "response", "path": "VirtualMFADevices[].SerialNumber" } ], "path": "VirtualMFADevices[]" } @@ -192,18 +243,24 @@ "resources": { "AccessKey": { "identifiers": [ - { "name": "UserName" }, - { "name": "Id" } + { + "name": "UserName", + "memberName": "UserName" + }, + { + "name": "Id", + "memberName": "AccessKeyId" + } ], - "shape": "AccessKey", + "shape": "AccessKeyMetadata", "actions": { "Activate": { "request": { "operation": "UpdateAccessKey", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "AccessKeyId", "sourceType": "identifier", "source": "Id" }, - { "target": "Status", "sourceType": "string", "source": "Active" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "AccessKeyId", "source": "identifier", "name": "Id" }, + { "target": "Status", "source": "string", "value": "Active" } ] } }, @@ -211,9 +268,9 @@ "request": { "operation": "UpdateAccessKey", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "AccessKeyId", "sourceType": "identifier", "source": "Id" }, - { "target": "Status", "sourceType": "string", "source": "Inactive" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "AccessKeyId", "source": "identifier", "name": "Id" }, + { "target": "Status", "source": "string", "value": "Inactive" } ] } }, @@ -221,23 +278,66 @@ "request": { "operation": "DeleteAccessKey", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "AccessKeyId", "sourceType": "identifier", "source": "Id" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "AccessKeyId", "source": "identifier", "name": "Id" } + ] + } + } + }, + "has": { + "User": { + "resource": { + "type": "User", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "UserName" } ] } } } }, - "AccountAlias": { + "AccessKeyPair": { "identifiers": [ - { "name": "Name" } + { + "name": "UserName", + "memberName": "UserName" + }, + { + "name": "Id", + "memberName": "AccessKeyId" + }, + { + "name": "Secret", + "memberName": "SecretAccessKey" + } ], + "shape": "AccessKey", "actions": { + "Activate": { + "request": { + "operation": "UpdateAccessKey", + "params": [ + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "AccessKeyId", "source": "identifier", "name": "Id" }, + { "target": "Status", "source": "string", "value": "Active" } + ] + } + }, + "Deactivate": { + "request": { + "operation": "UpdateAccessKey", + "params": [ + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "AccessKeyId", "source": "identifier", "name": "Id" }, + { "target": "Status", "source": "string", "value": "Inactive" } + ] + } + }, "Delete": { "request": { - "operation": "DeleteAccountAlias", + "operation": "DeleteAccessKey", "params": [ - { "target": "AccountAlias", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "AccessKeyId", "source": "identifier", "name": "Id" } ] } } @@ -264,19 +364,84 @@ "shape": "GetAccountSummaryResponse", "load": { "request": { "operation": "GetAccountSummary" }, - "path": "$" + "path": "@" + } + }, + "AssumeRolePolicy": { + "identifiers": [ + { "name": "RoleName" } + ], + "actions": { + "Update": { + "request": { + "operation": "UpdateAssumeRolePolicy", + "params": [ + { "target": "RoleName", "source": "identifier", "name": "Name" } + ] + } + } + }, + "has": { + "Role": { + "resource": { + "type": "Role", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "RoleName" } + ] + } + } + } + }, + "CurrentUser": { + "hasMany": { + "AccessKeys": { + "request": { "operation": "ListAccessKeys" }, + "resource": { + "type": "AccessKey", + "identifiers": [ + { "target": "UserName", "source": "response", "path": "AccessKeyMetadata[].UserName" }, + { "target": "Id", "source": "response", "path": "AccessKeyMetadata[].AccessKeyId" } + ], + "path": "AccessKeyMetadata[]" + } + }, + "MfaDevices": { + "request": { "operation": "ListMFADevices" }, + "resource": { + "type": "MfaDevice", + "identifiers": [ + { "target": "UserName", "source": "response", "path": "MFADevices[].UserName" }, + { "target": "SerialNumber", "source": "response", "path": "MFADevices[].SerialNumber" } + ], + "path": "MFADevices[]" + } + }, + "SigningCertificates": { + "request": { "operation": "ListSigningCertificates" }, + "resource": { + "type": "SigningCertificate", + "identifiers": [ + { "target": "UserName", "source": "response", "path": "Certificates[].UserName" }, + { "target": "Id", "source": "response", "path": "Certificates[].CertificateId" } + ], + "path": "Certificates[]" + } + } } }, "Group": { "identifiers": [ - { "name": "Name" } + { + "name": "Name", + "memberName": "GroupName" + } ], "shape": "Group", "load": { "request": { "operation": "GetGroup", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] }, "path": "Group" @@ -286,7 +451,7 @@ "request": { "operation": "AddUserToGroup", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] } }, @@ -294,22 +459,29 @@ "request": { "operation": "CreateGroup", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] + }, + "resource": { + "type": "Group", + "identifiers": [ + { "target": "Name", "source": "requestParameter", "path": "GroupName" } + ], + "path": "Group" } }, "CreatePolicy": { "request": { "operation": "PutGroupPolicy", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "GroupPolicy", "identifiers": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" }, - { "target": "Name", "sourceType": "requestParameter", "source": "PolicyName" } + { "target": "GroupName", "source": "identifier", "name": "Name" }, + { "target": "Name", "source": "requestParameter", "path": "PolicyName" } ] } }, @@ -317,7 +489,7 @@ "request": { "operation": "DeleteGroup", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] } }, @@ -325,7 +497,7 @@ "request": { "operation": "RemoveUserFromGroup", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] } }, @@ -333,13 +505,24 @@ "request": { "operation": "UpdateGroup", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "Group", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "NewGroupName" } + { "target": "Name", "source": "requestParameter", "path": "NewGroupName" } + ] + } + } + }, + "has": { + "Policy": { + "resource": { + "type": "GroupPolicy", + "identifiers": [ + { "target": "GroupName", "source": "identifier", "name": "Name" }, + { "target": "Name", "source": "input" } ] } } @@ -349,14 +532,14 @@ "request": { "operation": "ListGroupPolicies", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "GroupPolicy", "identifiers": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" }, - { "target": "Name", "sourceType": "responsePath", "source": "PolicyNames[]" } + { "target": "GroupName", "source": "identifier", "name": "Name" }, + { "target": "Name", "source": "response", "path": "PolicyNames[]" } ] } }, @@ -364,46 +547,48 @@ "request": { "operation": "GetGroup", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "User", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "Users[].UserName" } + { "target": "Name", "source": "response", "path": "Users[].UserName" } ], "path": "Users[]" } } - }, - "subResources": { - "resources": [ "GroupPolicy" ], - "identifiers": { "Name": "GroupName" } } }, "GroupPolicy": { "identifiers": [ - { "name": "GroupName" }, - { "name": "Name" } + { + "name": "GroupName", + "memberName": "GroupName" + }, + { + "name": "Name", + "memberName": "PolicyName" + } ], "shape": "GetGroupPolicyResponse", "load": { "request": { "operation": "GetGroupPolicy", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "GroupName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "GroupName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteGroupPolicy", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "GroupName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "GroupName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } ] } }, @@ -411,8 +596,18 @@ "request": { "operation": "PutGroupPolicy", "params": [ - { "target": "GroupName", "sourceType": "identifier", "source": "GroupName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "GroupName", "source": "identifier", "name": "GroupName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } + ] + } + } + }, + "has": { + "Group": { + "resource": { + "type": "Group", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "GroupName" } ] } } @@ -420,14 +615,17 @@ }, "InstanceProfile": { "identifiers": [ - { "name": "Name" } + { + "name": "Name", + "memberName": "InstanceProfileName" + } ], "shape": "InstanceProfile", "load": { "request": { "operation": "GetInstanceProfile", "params": [ - { "target": "InstanceProfileName", "sourceType": "identifier", "source": "Name" } + { "target": "InstanceProfileName", "source": "identifier", "name": "Name" } ] }, "path": "InstanceProfile" @@ -437,7 +635,7 @@ "request": { "operation": "AddRoleToInstanceProfile", "params": [ - { "target": "InstanceProfileName", "sourceType": "identifier", "source": "Name" } + { "target": "InstanceProfileName", "source": "identifier", "name": "Name" } ] } }, @@ -445,7 +643,7 @@ "request": { "operation": "DeleteInstanceProfile", "params": [ - { "target": "InstanceProfileName", "sourceType": "identifier", "source": "Name" } + { "target": "InstanceProfileName", "source": "identifier", "name": "Name" } ] } }, @@ -453,17 +651,17 @@ "request": { "operation": "RemoveRoleFromInstanceProfile", "params": [ - { "target": "InstanceProfileName", "sourceType": "identifier", "source": "Name" } + { "target": "InstanceProfileName", "source": "identifier", "name": "Name" } ] } } }, - "belongsTo": { + "has": { "Roles": { "resource": { "type": "Role", "identifiers": [ - { "target": "Name", "sourceType": "dataMember", "source": "Roles[].RoleName" } + { "target": "Name", "source": "data", "path": "Roles[].RoleName" } ], "path": "Roles[]" } @@ -472,14 +670,17 @@ }, "LoginProfile": { "identifiers": [ - { "name": "UserName" } + { + "name": "UserName", + "memberName": "UserName" + } ], "shape": "LoginProfile", "load": { "request": { "operation": "GetLoginProfile", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" } + { "target": "UserName", "source": "identifier", "name": "UserName" } ] }, "path": "LoginProfile" @@ -489,15 +690,22 @@ "request": { "operation": "CreateLoginProfile", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" } + { "target": "UserName", "source": "identifier", "name": "UserName" } ] + }, + "resource": { + "type": "LoginProfile", + "identifiers": [ + { "target": "UserName", "source": "response", "path": "LoginProfile.UserName" } + ], + "path": "LoginProfile" } }, "Delete": { "request": { "operation": "DeleteLoginProfile", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" } + { "target": "UserName", "source": "identifier", "name": "UserName" } ] } }, @@ -505,7 +713,17 @@ "request": { "operation": "UpdateLoginProfile", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" } + { "target": "UserName", "source": "identifier", "name": "UserName" } + ] + } + } + }, + "has": { + "User": { + "resource": { + "type": "User", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "UserName" } ] } } @@ -513,26 +731,32 @@ }, "MfaDevice": { "identifiers": [ - { "name": "UserName" }, - { "name": "SerialNumber" } + { + "name": "UserName", + "memberName": "UserName" + }, + { + "name": "SerialNumber", + "memberName": "SerialNumber" + } ], "shape": "MFADevice", "actions": { - "Deactivate": { + "Associate": { "request": { - "operation": "DeactivateMFADevice", + "operation": "EnableMFADevice", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "SerialNumber", "sourceType": "identifier", "source": "SerialNumber" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "SerialNumber", "source": "identifier", "name": "SerialNumber" } ] } }, - "Enable": { + "Disassociate": { "request": { - "operation": "EnableMFADevice", + "operation": "DeactivateMFADevice", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "SerialNumber", "sourceType": "identifier", "source": "SerialNumber" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "SerialNumber", "source": "identifier", "name": "SerialNumber" } ] } }, @@ -540,8 +764,18 @@ "request": { "operation": "ResyncMFADevice", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "SerialNumber", "sourceType": "identifier", "source": "SerialNumber" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "SerialNumber", "source": "identifier", "name": "SerialNumber" } + ] + } + } + }, + "has": { + "User": { + "resource": { + "type": "User", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "UserName" } ] } } @@ -549,14 +783,17 @@ }, "Role": { "identifiers": [ - { "name": "Name" } + { + "name": "Name", + "memberName": "RoleName" + } ], "shape": "Role", "load": { "request": { "operation": "GetRole", "params": [ - { "target": "RoleName", "sourceType": "identifier", "source": "Name" } + { "target": "RoleName", "source": "identifier", "name": "Name" } ] }, "path": "Role" @@ -566,15 +803,26 @@ "request": { "operation": "DeleteRole", "params": [ - { "target": "RoleName", "sourceType": "identifier", "source": "Name" } + { "target": "RoleName", "source": "identifier", "name": "Name" } + ] + } + } + }, + "has": { + "AssumeRolePolicy": { + "resource": { + "type": "AssumeRolePolicy", + "identifiers": [ + { "target": "RoleName", "source": "identifier", "name": "Name" } ] } }, - "UpdateAssumeRolePolicy": { - "request": { - "operation": "UpdateAssumeRolePolicy", - "params": [ - { "target": "RoleName", "sourceType": "identifier", "source": "Name" } + "Policy": { + "resource": { + "type": "RolePolicy", + "identifiers": [ + { "target": "RoleName", "source": "identifier", "name": "Name" }, + { "target": "Name", "source": "input" } ] } } @@ -584,13 +832,13 @@ "request": { "operation": "ListInstanceProfilesForRole", "params": [ - { "target": "RoleName", "sourceType": "identifier", "source": "Name" } + { "target": "RoleName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "InstanceProfile", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "InstanceProfiles[].InstanceProfileName" } + { "target": "Name", "source": "response", "path": "InstanceProfiles[].InstanceProfileName" } ], "path": "InstanceProfiles[]" } @@ -599,46 +847,48 @@ "request": { "operation": "ListRolePolicies", "params": [ - { "target": "RoleName", "sourceType": "identifier", "source": "Name" } + { "target": "RoleName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "RolePolicy", "identifiers": [ - { "target": "RoleName", "sourceType": "identifier", "source": "Name" }, - { "target": "Name", "sourceType": "responsePath", "source": "PolicyNames[]" } + { "target": "RoleName", "source": "identifier", "name": "Name" }, + { "target": "Name", "source": "response", "path": "PolicyNames[]" } ] } } - }, - "subResources": { - "resources": [ "RolePolicy" ], - "identifiers": { "Name": "RoleName" } } }, "RolePolicy": { "identifiers": [ - { "name": "RoleName" }, - { "name": "Name" } + { + "name": "RoleName", + "memberName": "RoleName" + }, + { + "name": "Name", + "memberName": "PolicyName" + } ], "shape": "GetRolePolicyResponse", "load": { "request": { "operation": "GetRolePolicy", "params": [ - { "target": "RoleName", "sourceType": "identifier", "source": "RoleName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "RoleName", "source": "identifier", "name": "RoleName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteRolePolicy", "params": [ - { "target": "RoleName", "sourceType": "identifier", "source": "RoleName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "RoleName", "source": "identifier", "name": "RoleName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } ] } }, @@ -646,8 +896,18 @@ "request": { "operation": "PutRolePolicy", "params": [ - { "target": "RoleName", "sourceType": "identifier", "source": "RoleName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "RoleName", "source": "identifier", "name": "RoleName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } + ] + } + } + }, + "has": { + "Role": { + "resource": { + "type": "Role", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "RoleName" } ] } } @@ -662,17 +922,17 @@ "request": { "operation": "GetSAMLProvider", "params": [ - { "target": "SAMLProviderArn", "sourceType": "identifier", "source": "Arn" } + { "target": "SAMLProviderArn", "source": "identifier", "name": "Arn" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteSAMLProvider", "params": [ - { "target": "SAMLProviderArn", "sourceType": "identifier", "source": "Arn" } + { "target": "SAMLProviderArn", "source": "identifier", "name": "Arn" } ] } }, @@ -680,7 +940,7 @@ "request": { "operation": "UpdateSAMLProvider", "params": [ - { "target": "SAMLProviderArn", "sourceType": "identifier", "source": "Arn" } + { "target": "SAMLProviderArn", "source": "identifier", "name": "Arn" } ] } } @@ -695,7 +955,7 @@ "request": { "operation": "GetServerCertificate", "params": [ - { "target": "ServerCertificateName", "sourceType": "identifier", "source": "Name" } + { "target": "ServerCertificateName", "source": "identifier", "name": "Name" } ] }, "path": "ServerCertificate" @@ -705,7 +965,7 @@ "request": { "operation": "DeleteServerCertificate", "params": [ - { "target": "ServerCertificateName", "sourceType": "identifier", "source": "Name" } + { "target": "ServerCertificateName", "source": "identifier", "name": "Name" } ] } }, @@ -713,13 +973,13 @@ "request": { "operation": "UpdateServerCertificate", "params": [ - { "target": "ServerCertificateName", "sourceType": "identifier", "source": "Name" } + { "target": "ServerCertificateName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "ServerCertificate", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "NewServerCertificateName" } + { "target": "Name", "source": "requestParameter", "path": "NewServerCertificateName" } ] } } @@ -727,7 +987,14 @@ }, "SigningCertificate": { "identifiers": [ - { "name": "Id" } + { + "name": "UserName", + "memberName": "UserName" + }, + { + "name": "Id", + "memberName": "CertificateId" + } ], "shape": "SigningCertificate", "actions": { @@ -735,8 +1002,9 @@ "request": { "operation": "UpdateSigningCertificate", "params": [ - { "target": "CertificateId", "sourceType": "identifier", "source": "Id" }, - { "target": "Status", "sourceType": "string", "source": "Active" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "CertificateId", "source": "identifier", "name": "Id" }, + { "target": "Status", "source": "string", "value": "Active" } ] } }, @@ -744,8 +1012,9 @@ "request": { "operation": "UpdateSigningCertificate", "params": [ - { "target": "CertificateId", "sourceType": "identifier", "source": "Id" }, - { "target": "Status", "sourceType": "string", "source": "Inactive" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "CertificateId", "source": "identifier", "name": "Id" }, + { "target": "Status", "source": "string", "value": "Inactive" } ] } }, @@ -753,7 +1022,18 @@ "request": { "operation": "DeleteSigningCertificate", "params": [ - { "target": "CertificateId", "sourceType": "identifier", "source": "Id" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "CertificateId", "source": "identifier", "name": "Id" } + ] + } + } + }, + "has": { + "User": { + "resource": { + "type": "User", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "UserName" } ] } } @@ -761,14 +1041,17 @@ }, "User": { "identifiers": [ - { "name": "Name" } + { + "name": "Name", + "memberName": "UserName" + } ], "shape": "User", "load": { "request": { "operation": "GetUser", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "path": "User" @@ -778,38 +1061,69 @@ "request": { "operation": "AddUserToGroup", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] } }, - "CreateAccessKey": { + "Create": { + "request": { + "operation": "CreateUser", + "params": [ + { "target": "UserName", "source": "identifier", "name": "Name" } + ] + }, + "resource": { + "type": "User", + "identifiers": [ + { "target": "Name", "source": "requestParameter", "path": "UserName" } + ], + "path": "User" + } + }, + "CreateAccessKeyPair": { "request": { "operation": "CreateAccessKey", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "resource": { - "type": "AccessKey", + "type": "AccessKeyPair", "identifiers": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" }, - { "target": "Id", "sourceType": "responsePath", "source": "AccessKey.AccessKeyId" } + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "AccessKey.AccessKeyId" }, + { "target": "Secret", "source": "response", "path": "AccessKey.SecretAccessKey" } ], "path": "AccessKey" } }, + "CreateLoginProfile": { + "request": { + "operation": "CreateLoginProfile", + "params": [ + { "target": "UserName", "source": "identifier", "name": "Name" } + ] + }, + "resource": { + "type": "LoginProfile", + "identifiers": [ + { "target": "UserName", "source": "response", "path": "LoginProfile.UserName" } + ], + "path": "LoginProfile" + } + }, "CreatePolicy": { "request": { "operation": "PutUserPolicy", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "UserPolicy", "identifiers": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" }, - { "target": "Name", "sourceType": "requestParameter", "source": "PolicyName" } + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "Name", "source": "requestParameter", "path": "PolicyName" } ] } }, @@ -817,7 +1131,7 @@ "request": { "operation": "DeleteUser", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] } }, @@ -825,14 +1139,14 @@ "request": { "operation": "EnableMFADevice", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "MfaDevice", "identifiers": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" }, - { "target": "SerialNumber", "sourceType": "requestParameter", "source": "SerialNumber" } + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "SerialNumber", "source": "requestParameter", "path": "SerialNumber" } ] } }, @@ -840,7 +1154,7 @@ "request": { "operation": "RemoveUserFromGroup", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] } }, @@ -848,13 +1162,59 @@ "request": { "operation": "UpdateUser", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "User", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "NewUserName" } + { "target": "Name", "source": "requestParameter", "path": "NewUserName" } + ] + } + } + }, + "has": { + "AccessKey": { + "resource": { + "type": "AccessKey", + "identifiers": [ + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "input" } + ] + } + }, + "LoginProfile": { + "resource": { + "type": "LoginProfile", + "identifiers": [ + { "target": "UserName", "source": "identifier", "name": "Name" } + ] + } + }, + "MfaDevice": { + "resource": { + "type": "MfaDevice", + "identifiers": [ + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "SerialNumber", "source": "input" } + ] + } + }, + "Policy": { + "resource": { + "type": "UserPolicy", + "identifiers": [ + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "Name", "source": "input" } + ] + } + }, + "SigningCertificate": { + "resource": { + "type": "SigningCertificate", + "identifiers": [ + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "input" } ] } } @@ -864,14 +1224,14 @@ "request": { "operation": "ListAccessKeys", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "AccessKey", "identifiers": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" }, - { "target": "Id", "sourceType": "responsePath", "source": "AccessKeyMetadata[].AccessKeyId" } + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "AccessKeyMetadata[].AccessKeyId" } ], "path": "AccessKeyMetadata[]" } @@ -880,13 +1240,13 @@ "request": { "operation": "ListGroupsForUser", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "Group", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "Groups[].GroupName" } + { "target": "Name", "source": "response", "path": "Groups[].GroupName" } ], "path": "Groups[]" } @@ -895,14 +1255,14 @@ "request": { "operation": "ListMFADevices", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "MfaDevice", "identifiers": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" }, - { "target": "SerialNumber", "sourceType": "responsePath", "source": "MFADevices[].SerialNumber" } + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "SerialNumber", "source": "response", "path": "MFADevices[].SerialNumber" } ], "path": "MFADevices[]" } @@ -911,51 +1271,64 @@ "request": { "operation": "ListUserPolicies", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "UserPolicy", "identifiers": [ - { "target": "UserName", "sourceType": "identifier", "source": "Name" }, - { "target": "Name", "sourceType": "responsePath", "source": "PolicyNames[]" } + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "Name", "source": "response", "path": "PolicyNames[]" } ] } + }, + "SigningCertificates": { + "request": { + "operation": "ListSigningCertificates", + "params": [ + { "target": "UserName", "source": "identifier", "name": "Name" } + ] + }, + "resource": { + "type": "SigningCertificate", + "identifiers": [ + { "target": "UserName", "source": "identifier", "name": "Name" }, + { "target": "Id", "source": "response", "path": "Certificates[].CertificateId" } + ], + "path": "Certificates[]" + } } - }, - "subResources": { - "resources": [ - "AccessKey", - "LoginProfile", - "MfaDevice", - "UserPolicy" - ], - "identifiers": { "Name": "UserName" } } }, "UserPolicy": { "identifiers": [ - { "name": "UserName" }, - { "name": "Name" } + { + "name": "UserName", + "memberName": "UserName" + }, + { + "name": "Name", + "memberName": "PolicyName" + } ], "shape": "GetUserPolicyResponse", "load": { "request": { "operation": "GetUserPolicy", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteUserPolicy", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } ] } }, @@ -963,8 +1336,18 @@ "request": { "operation": "PutUserPolicy", "params": [ - { "target": "UserName", "sourceType": "identifier", "source": "UserName" }, - { "target": "PolicyName", "sourceType": "identifier", "source": "Name" } + { "target": "UserName", "source": "identifier", "name": "UserName" }, + { "target": "PolicyName", "source": "identifier", "name": "Name" } + ] + } + } + }, + "has": { + "User": { + "resource": { + "type": "User", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "UserName" } ] } } @@ -972,7 +1355,10 @@ }, "VirtualMfaDevice": { "identifiers": [ - { "name": "SerialNumber" } + { + "name": "SerialNumber", + "memberName": "SerialNumber" + } ], "shape": "VirtualMFADevice", "actions": { @@ -980,17 +1366,17 @@ "request": { "operation": "DeleteVirtualMFADevice", "params": [ - { "target": "SerialNumber", "sourceType": "identifier", "source": "SerialNumber" } + { "target": "SerialNumber", "source": "identifier", "name": "SerialNumber" } ] } } }, - "belongsTo": { + "has": { "User": { "resource": { "type": "User", "identifiers": [ - { "target": "Name", "sourceType": "dataMember", "source": "User.UserName" } + { "target": "Name", "source": "data", "path": "User.UserName" } ] } } diff --git a/boto3/data/resources/opsworks-2013-02-18.resources.json b/boto3/data/resources/opsworks-2013-02-18.resources.json index 6bb03347e0..0435b13bc0 100644 --- a/boto3/data/resources/opsworks-2013-02-18.resources.json +++ b/boto3/data/resources/opsworks-2013-02-18.resources.json @@ -6,7 +6,25 @@ "resource": { "type": "Stack", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "StackId" } + { "target": "Id", "source": "response", "path": "StackId" } + ] + } + } + }, + "has": { + "Layer": { + "resource": { + "type": "Layer", + "identifiers": [ + { "target": "Id", "source": "input" } + ] + } + }, + "Stack": { + "resource": { + "type": "Stack", + "identifiers": [ + { "target": "Id", "source": "input" } ] } } @@ -17,7 +35,7 @@ "resource": { "type": "Stack", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Stacks[].StackId" } + { "target": "Id", "source": "response", "path": "Stacks[].StackId" } ], "path": "Stacks[]" } @@ -34,7 +52,7 @@ "request": { "operation": "DescribeLayers", "params": [ - { "target": "LayerIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "LayerIds[]", "source": "identifier", "name": "Id" } ] }, "path": "Layers[0]" @@ -44,17 +62,17 @@ "request": { "operation": "DeleteLayer", "params": [ - { "target": "LayerId", "sourceType": "identifier", "source": "Id" } + { "target": "LayerId", "source": "identifier", "name": "Id" } ] } } }, - "belongsTo": { + "has": { "Stack": { "resource": { "type": "Stack", "identifiers": [ - { "target": "Id", "sourceType": "dataMember", "source": "StackId" } + { "target": "Id", "source": "data", "path": "StackId" } ] } } @@ -69,7 +87,7 @@ "request": { "operation": "DescribeStacks", "params": [ - { "target": "StackIds[]", "sourceType": "identifier", "source": "Id" } + { "target": "StackIds[]", "source": "identifier", "name": "Id" } ] }, "path": "Stacks[0]" @@ -79,13 +97,13 @@ "request": { "operation": "CreateLayer", "params": [ - { "target": "StackId", "sourceType": "identifier", "source": "Id" } + { "target": "StackId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Layer", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "LayerId" } + { "target": "Id", "source": "response", "path": "LayerId" } ] } }, @@ -93,7 +111,17 @@ "request": { "operation": "DeleteStack", "params": [ - { "target": "StackId", "sourceType": "identifier", "source": "Id" } + { "target": "StackId", "source": "identifier", "name": "Id" } + ] + } + } + }, + "has": { + "Summary": { + "resource": { + "type": "StackSummary", + "identifiers": [ + { "target": "StackId", "source": "identifier", "name": "Id" } ] } } @@ -103,21 +131,17 @@ "request": { "operation": "DescribeLayers", "params": [ - { "target": "StackId", "sourceType": "identifier", "source": "Id" } + { "target": "StackId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Layer", "identifiers": [ - { "target": "Id", "sourceType": "responsePath", "source": "Layers[].LayerId" } + { "target": "Id", "source": "response", "path": "Layers[].LayerId" } ], "path": "Layers[]" } } - }, - "subResources": { - "resources": [ "StackSummary" ], - "identifiers": { "Id": "StackId" } } }, "StackSummary": { @@ -129,10 +153,20 @@ "request": { "operation": "DescribeStackSummary", "params": [ - { "target": "StackId", "sourceType": "identifier", "source": "StackId" } + { "target": "StackId", "source": "identifier", "name": "StackId" } ] }, "path": "StackSummary" + }, + "has": { + "Stack": { + "resource": { + "type": "Stack", + "identifiers": [ + { "target": "Id", "source": "identifier", "name": "StackId" } + ] + } + } } } } diff --git a/boto3/data/resources/s3-2006-03-01.resources.json b/boto3/data/resources/s3-2006-03-01.resources.json index 527817772f..508a9a9d87 100644 --- a/boto3/data/resources/s3-2006-03-01.resources.json +++ b/boto3/data/resources/s3-2006-03-01.resources.json @@ -6,7 +6,17 @@ "resource": { "type": "Bucket", "identifiers": [ - { "target": "Name", "sourceType": "requestParameter", "source": "Bucket" } + { "target": "Name", "source": "requestParameter", "path": "Bucket" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "input" } ] } } @@ -17,7 +27,7 @@ "resource": { "type": "Bucket", "identifiers": [ - { "target": "Name", "sourceType": "responsePath", "source": "Buckets[].Name" } + { "target": "Name", "source": "response", "path": "Buckets[].Name" } ], "path": "Buckets[]" } @@ -35,7 +45,7 @@ "request": { "operation": "CreateBucket", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] } }, @@ -43,7 +53,7 @@ "request": { "operation": "DeleteBucket", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] } }, @@ -51,7 +61,7 @@ "request": { "operation": "DeleteObjects", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] } }, @@ -59,14 +69,14 @@ "request": { "operation": "PutObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "Object", "identifiers": [ - { "target": "BucketName", "sourceType": "identifier", "source": "Name" }, - { "target": "Key", "sourceType": "requestParameter", "source": "Key" } + { "target": "BucketName", "source": "identifier", "name": "Name" }, + { "target": "Key", "source": "requestParameter", "path": "Key" } ] } } @@ -75,30 +85,121 @@ "Exists": { "waiterName": "BucketExists", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] }, "NotExists": { "waiterName": "BucketNotExists", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] } }, + "has": { + "Acl": { + "resource": { + "type": "BucketAcl", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "Cors": { + "resource": { + "type": "BucketCors", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "Lifecycle": { + "resource": { + "type": "BucketLifecycle", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "Logging": { + "resource": { + "type": "BucketLogging", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "Notification": { + "resource": { + "type": "BucketNotification", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "Object": { + "resource": { + "type": "Object", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" }, + { "target": "Key", "source": "input" } + ] + } + }, + "Policy": { + "resource": { + "type": "BucketPolicy", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "RequestPayment": { + "resource": { + "type": "BucketRequestPayment", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "Tagging": { + "resource": { + "type": "BucketTagging", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "Versioning": { + "resource": { + "type": "BucketVersioning", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + }, + "Website": { + "resource": { + "type": "BucketWebsite", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "Name" } + ] + } + } + }, "hasMany": { "MultipartUploads": { "request": { "operation": "ListMultipartUploads", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "MultipartUpload", "identifiers": [ - { "target": "BucketName", "sourceType": "identifier", "source": "Name" }, - { "target": "ObjectKey", "sourceType": "responsePath", "source": "Uploads[].Key" }, - { "target": "Id", "sourceType": "responsePath", "source": "Uploads[].UploadId" } + { "target": "BucketName", "source": "identifier", "name": "Name" }, + { "target": "ObjectKey", "source": "response", "path": "Uploads[].Key" }, + { "target": "Id", "source": "response", "path": "Uploads[].UploadId" } ], "path": "Uploads[]" } @@ -107,15 +208,15 @@ "request": { "operation": "ListObjectVersions", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] }, "resource": { "type": "ObjectVersion", "identifiers": [ - { "target": "BucketName", "sourceType": "identifier", "source": "Name" }, - { "target": "ObjectKey", "sourceType": "responsePath", "source": "[Versions,DeleteMarkers]|[].Key" }, - { "target": "Id", "sourceType": "responsePath", "source": "[Versions,DeleteMarkers]|[].VersionId" } + { "target": "BucketName", "source": "identifier", "name": "Name" }, + { "target": "ObjectKey", "source": "response", "path": "[Versions,DeleteMarkers]|[].Key" }, + { "target": "Id", "source": "response", "path": "[Versions,DeleteMarkers]|[].VersionId" } ], "path": "[Versions,DeleteMarkers]|[]" } @@ -124,33 +225,18 @@ "request": { "operation": "ListObjects", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "Name" } + { "target": "Bucket", "source": "identifier", "name": "Name" } ] }, "resource": { - "type": "Object", + "type": "ObjectSummary", "identifiers": [ - { "target": "BucketName", "sourceType": "identifier", "source": "Name" }, - { "target": "Key", "sourceType": "responsePath", "source": "Contents[].Key" } - ] + { "target": "BucketName", "source": "identifier", "name": "Name" }, + { "target": "Key", "source": "response", "path": "Contents[].Key" } + ], + "path": "Contents[]" } } - }, - "subResources": { - "resources": [ - "BucketAcl", - "BucketCors", - "BucketLifecycle", - "BucketLogging", - "BucketPolicy", - "BucketNotification", - "BucketRequestPayment", - "BucketTagging", - "BucketVersioning", - "BucketWebsite", - "Object" - ], - "identifiers": { "Name": "BucketName" } } }, "BucketAcl": { @@ -162,17 +248,27 @@ "request": { "operation": "GetBucketAcl", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Put": { "request": { "operation": "PutBucketAcl", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -187,17 +283,17 @@ "request": { "operation": "GetBucketCors", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteBucketCors", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] } }, @@ -205,7 +301,17 @@ "request": { "operation": "PutBucketCors", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -220,17 +326,17 @@ "request": { "operation": "GetBucketLifecycle", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteBucketLifecycle", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] } }, @@ -238,7 +344,17 @@ "request": { "operation": "PutBucketLifecycle", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -253,17 +369,27 @@ "request": { "operation": "GetBucketLogging", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Put": { "request": { "operation": "PutBucketLogging", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -278,17 +404,27 @@ "request": { "operation": "GetBucketNotification", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Put": { "request": { "operation": "PutBucketNotification", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -303,17 +439,17 @@ "request": { "operation": "GetBucketPolicy", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteBucketPolicy", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] } }, @@ -321,7 +457,17 @@ "request": { "operation": "PutBucketPolicy", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -336,17 +482,27 @@ "request": { "operation": "GetBucketRequestPayment", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Put": { "request": { "operation": "PutBucketRequestPayment", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -361,17 +517,17 @@ "request": { "operation": "GetBucketTagging", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteBucketTagging", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] } }, @@ -379,7 +535,17 @@ "request": { "operation": "PutBucketTagging", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -394,18 +560,18 @@ "request": { "operation": "GetBucketVersioning", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Enable": { "request": { "operation": "PutBucketVersioning", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "VersioningConfiguration.Status", "sourceType": "string", "source": "Enabled" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "VersioningConfiguration.Status", "source": "string", "value": "Enabled" } ] } }, @@ -413,7 +579,7 @@ "request": { "operation": "PutBucketVersioning", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] } }, @@ -421,8 +587,18 @@ "request": { "operation": "PutBucketVersioning", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "VersioningConfiguration.Status", "sourceType": "string", "source": "Suspended" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "VersioningConfiguration.Status", "source": "string", "value": "Suspended" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -437,17 +613,17 @@ "request": { "operation": "GetBucketWebsite", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteBucketWebsite", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } ] } }, @@ -455,7 +631,17 @@ "request": { "operation": "PutBucketWebsite", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" } + ] + } + } + }, + "has": { + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } ] } } @@ -473,9 +659,9 @@ "request": { "operation": "AbortMultipartUpload", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "UploadId", "sourceType": "identifier", "source": "Id" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "UploadId", "source": "identifier", "name": "Id" } ] } }, @@ -483,16 +669,38 @@ "request": { "operation": "CompleteMultipartUpload", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "UploadId", "sourceType": "identifier", "source": "Id" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "UploadId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "Object", "identifiers": [ - { "target": "BucketName", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" } + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" } + ] + } + } + }, + "has": { + "Object": { + "resource": { + "type": "Object", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" } + ] + } + }, + "Part": { + "resource": { + "type": "MultipartUploadPart", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "MultipartUploadId", "source": "identifier", "name": "Id" }, + { "target": "ObjectKey", "source": "identifier", "name": "ObjectKey" }, + { "target": "PartNumber", "source": "input" } ] } } @@ -502,30 +710,22 @@ "request": { "operation": "ListParts", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "UploadId", "sourceType": "identifier", "source": "Id" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "UploadId", "source": "identifier", "name": "Id" } ] }, "resource": { "type": "MultipartUploadPart", "identifiers": [ - { "target": "BucketName", "sourceType": "requestParameter", "source": "Bucket" }, - { "target": "ObjectKey", "sourceType": "requestParameter", "source": "Key" }, - { "target": "MultipartUploadId", "sourceType": "requestParameter", "source": "UploadId" }, - { "target": "PartNumber", "sourceType": "responsePath", "source": "Parts[].PartNumber" } + { "target": "BucketName", "source": "requestParameter", "path": "Bucket" }, + { "target": "ObjectKey", "source": "requestParameter", "path": "Key" }, + { "target": "MultipartUploadId", "source": "requestParameter", "path": "UploadId" }, + { "target": "PartNumber", "source": "response", "path": "Parts[].PartNumber" } ], "path": "Parts[]" } } - }, - "subResources": { - "resources": [ "MultipartUploadPart" ], - "identifiers": { - "BucketName": "BucketName", - "Id": "MultipartUploadId", - "ObjectKey": "ObjectKey" - } } }, "MultipartUploadPart": { @@ -545,10 +745,10 @@ "request": { "operation": "UploadPartCopy", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "UploadId", "sourceType": "identifier", "source": "MultipartUploadId" }, - { "target": "PartNumber", "sourceType": "identifier", "source": "PartNumber" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "UploadId", "source": "identifier", "name": "MultipartUploadId" }, + { "target": "PartNumber", "source": "identifier", "name": "PartNumber" } ] } }, @@ -556,10 +756,22 @@ "request": { "operation": "UploadPart", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "UploadId", "sourceType": "identifier", "source": "MultipartUploadId" }, - { "target": "PartNumber", "sourceType": "identifier", "source": "PartNumber" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "UploadId", "source": "identifier", "name": "MultipartUploadId" }, + { "target": "PartNumber", "source": "identifier", "name": "PartNumber" } + ] + } + } + }, + "has": { + "MultipartUpload": { + "resource": { + "type": "MultipartUpload", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "Id", "source": "identifier", "name": "MultipartUploadId" }, + { "target": "ObjectKey", "source": "identifier", "name": "ObjectKey" } ] } } @@ -575,19 +787,19 @@ "request": { "operation": "HeadObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } ] }, - "path": "$" + "path": "@" }, "actions": { "CopyFrom": { "request": { "operation": "CopyObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } ] } }, @@ -595,8 +807,8 @@ "request": { "operation": "DeleteObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } ] } }, @@ -604,8 +816,8 @@ "request": { "operation": "GetObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } ] } }, @@ -613,16 +825,16 @@ "request": { "operation": "CreateMultipartUpload", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } ] }, "resource": { "type": "MultipartUpload", "identifiers": [ - { "target": "BucketName", "sourceType": "identifier", "source": "BucketName" }, - { "target": "ObjectKey", "sourceType": "identifier", "source": "Key" }, - { "target": "Id", "sourceType": "responsePath", "source": "UploadId" } + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "ObjectKey", "source": "identifier", "name": "Key" }, + { "target": "Id", "source": "response", "path": "UploadId" } ] } }, @@ -630,8 +842,8 @@ "request": { "operation": "PutObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } ] } } @@ -641,8 +853,8 @@ "request": { "operation": "DeleteObjects", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Delete.Objects[].Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Delete.Objects[].Key", "source": "identifier", "name": "Key" } ] } } @@ -651,27 +863,55 @@ "Exists": { "waiterName": "ObjectExists", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } ] }, "NotExists": { "waiterName": "ObjectNotExists", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "Key" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } ] } }, - "subResources": { - "resources": [ - "ObjectAcl", - "ObjectVersion", - "MultipartUpload" - ], - "identifiers": { - "BucketName": "BucketName", - "Key": "ObjectKey" + "has": { + "Acl": { + "resource": { + "type": "ObjectAcl", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "ObjectKey", "source": "identifier", "name": "Key" } + ] + } + }, + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } + ] + } + }, + "MultipartUpload": { + "resource": { + "type": "MultipartUpload", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "ObjectKey", "source": "identifier", "name": "Key" }, + { "target": "Id", "source": "input" } + ] + } + }, + "Version": { + "resource": { + "type": "ObjectVersion", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "ObjectKey", "source": "identifier", "name": "Key" }, + { "target": "Id", "source": "input" } + ] + } } } }, @@ -685,19 +925,167 @@ "request": { "operation": "GetObjectAcl", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" } ] }, - "path": "$" + "path": "@" }, "actions": { "Put": { "request": { "operation": "PutObjectAcl", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" } + ] + } + } + }, + "has": { + "Object": { + "resource": { + "type": "Object", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" } + ] + } + } + } + }, + "ObjectSummary": { + "identifiers": [ + { "name": "BucketName" }, + { "name": "Key" } + ], + "shape": "Object", + "actions": { + "CopyFrom": { + "request": { + "operation": "CopyObject", + "params": [ + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } + ] + } + }, + "Delete": { + "request": { + "operation": "DeleteObject", + "params": [ + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } + ] + } + }, + "Get": { + "request": { + "operation": "GetObject", + "params": [ + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } + ] + } + }, + "InitiateMultipartUpload": { + "request": { + "operation": "CreateMultipartUpload", + "params": [ + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } + ] + }, + "resource": { + "type": "MultipartUpload", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "ObjectKey", "source": "identifier", "name": "Key" }, + { "target": "Id", "source": "response", "path": "UploadId" } + ] + } + }, + "Put": { + "request": { + "operation": "PutObject", + "params": [ + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } + ] + } + } + }, + "batchActions": { + "Delete": { + "request": { + "operation": "DeleteObjects", + "params": [ + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Delete.Objects[].Key", "source": "identifier", "name": "Key" } + ] + } + } + }, + "waiters": { + "Exists": { + "waiterName": "ObjectExists", + "params": [ + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } + ] + }, + "NotExists": { + "waiterName": "ObjectNotExists", + "params": [ + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } + ] + } + }, + "has": { + "Acl": { + "resource": { + "type": "ObjectAcl", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "ObjectKey", "source": "identifier", "name": "Key" } + ] + } + }, + "Bucket": { + "resource": { + "type": "Bucket", + "identifiers": [ + { "target": "Name", "source": "identifier", "name": "BucketName" } + ] + } + }, + "MultipartUpload": { + "resource": { + "type": "MultipartUpload", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "ObjectKey", "source": "identifier", "name": "Key" }, + { "target": "Id", "source": "input" } + ] + } + }, + "Object": { + "resource": { + "type": "Object", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "Key" } + ] + } + }, + "Version": { + "resource": { + "type": "ObjectVersion", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "ObjectKey", "source": "identifier", "name": "Key" }, + { "target": "Id", "source": "input" } ] } } @@ -715,9 +1103,9 @@ "request": { "operation": "DeleteObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "VersionId", "sourceType": "identifier", "source": "Id" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "VersionId", "source": "identifier", "name": "Id" } ] } }, @@ -725,9 +1113,9 @@ "request": { "operation": "GetObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "VersionId", "sourceType": "identifier", "source": "Id" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "VersionId", "source": "identifier", "name": "Id" } ] } }, @@ -735,9 +1123,9 @@ "request": { "operation": "HeadObject", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "VersionId", "sourceType": "identifier", "source": "Id" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "VersionId", "source": "identifier", "name": "Id" } ] } } @@ -747,9 +1135,20 @@ "request": { "operation": "DeleteObjects", "params": [ - { "target": "Bucket", "sourceType": "identifier", "source": "BucketName" }, - { "target": "Delete.Objects[*].Key", "sourceType": "identifier", "source": "ObjectKey" }, - { "target": "Delete.Objects[*].VersionId", "sourceType": "identifier", "source": "Id" } + { "target": "Bucket", "source": "identifier", "name": "BucketName" }, + { "target": "Delete.Objects[*].Key", "source": "identifier", "name": "ObjectKey" }, + { "target": "Delete.Objects[*].VersionId", "source": "identifier", "name": "Id" } + ] + } + } + }, + "has": { + "Object": { + "resource": { + "type": "Object", + "identifiers": [ + { "target": "BucketName", "source": "identifier", "name": "BucketName" }, + { "target": "Key", "source": "identifier", "name": "ObjectKey" } ] } } diff --git a/boto3/data/resources/sns-2010-03-31.resources.json b/boto3/data/resources/sns-2010-03-31.resources.json index b7c7c0e045..053d608ddc 100644 --- a/boto3/data/resources/sns-2010-03-31.resources.json +++ b/boto3/data/resources/sns-2010-03-31.resources.json @@ -6,7 +6,7 @@ "resource": { "type": "PlatformApplication", "identifiers": [ - { "target": "Arn", "sourceType": "responsePath", "source": "PlatformApplicationArn" } + { "target": "Arn", "source": "response", "path": "PlatformApplicationArn" } ] } }, @@ -15,7 +15,41 @@ "resource": { "type": "Topic", "identifiers": [ - { "target": "Arn", "sourceType": "responsePath", "source": "TopicArn" } + { "target": "Arn", "source": "response", "path": "TopicArn" } + ] + } + } + }, + "has": { + "PlatformApplication": { + "resource": { + "type": "PlatformApplication", + "identifiers": [ + { "target": "Arn", "source": "input" } + ] + } + }, + "PlatformEndpoint": { + "resource": { + "type": "PlatformEndpoint", + "identifiers": [ + { "target": "Arn", "source": "input" } + ] + } + }, + "Subscription": { + "resource": { + "type": "Subscription", + "identifiers": [ + { "target": "Arn", "source": "input" } + ] + } + }, + "Topic": { + "resource": { + "type": "Topic", + "identifiers": [ + { "target": "Arn", "source": "input" } ] } } @@ -26,7 +60,7 @@ "resource": { "type": "PlatformApplication", "identifiers": [ - { "target": "Arn", "sourceType": "responsePath", "source": "PlatformApplications[].PlatformApplicationArn" } + { "target": "Arn", "source": "response", "path": "PlatformApplications[].PlatformApplicationArn" } ] } }, @@ -35,8 +69,7 @@ "resource": { "type": "Subscription", "identifiers": [ - { "target": "TopicArn", "sourceType": "responsePath", "source": "Subscriptions[].TopicArn" }, - { "target": "Arn", "sourceType": "responsePath", "source": "Subscriptions[].SubscriptionArn" } + { "target": "Arn", "source": "response", "path": "Subscriptions[].SubscriptionArn" } ] } }, @@ -45,7 +78,7 @@ "resource": { "type": "Topic", "identifiers": [ - { "target": "Arn", "sourceType": "responsePath", "source": "Topics[].TopicArn" } + { "target": "Arn", "source": "response", "path": "Topics[].TopicArn" } ] } } @@ -61,24 +94,24 @@ "request": { "operation": "GetPlatformApplicationAttributes", "params": [ - { "target": "PlatformApplicationArn", "sourceType": "identifier", "source": "Arn" } + { "target": "PlatformApplicationArn", "source": "identifier", "name": "Arn" } ] }, - "path": "$" + "path": "@" }, "actions": { "CreatePlatformEndpoint": { "request": { "operation": "CreatePlatformEndpoint", "params": [ - { "target": "PlatformApplicationArn", "sourceType": "identifier", "source": "Arn" } + { "target": "PlatformApplicationArn", "source": "identifier", "name": "Arn" } ] }, "resource": { "type": "PlatformEndpoint", "identifiers": [ - { "target": "PlatformApplicationArn", "sourceType": "identifier", "source": "Arn" }, - { "target": "Arn", "sourceType": "responsePath", "source": "EndpointArn" } + { "target": "PlatformApplicationArn", "source": "identifier", "name": "Arn" }, + { "target": "Arn", "source": "response", "path": "EndpointArn" } ] } }, @@ -86,7 +119,7 @@ "request": { "operation": "DeletePlatformApplication", "params": [ - { "target": "PlatformApplicationArn", "sourceType": "identifier", "source": "Arn" } + { "target": "PlatformApplicationArn", "source": "identifier", "name": "Arn" } ] } }, @@ -94,7 +127,7 @@ "request": { "operation": "SetPlatformApplicationAttributes", "params": [ - { "target": "PlatformApplicationArn", "sourceType": "identifier", "source": "Arn" } + { "target": "PlatformApplicationArn", "source": "identifier", "name": "Arn" } ] } } @@ -104,13 +137,13 @@ "request": { "operation": "ListEndpointsByPlatformApplication", "params": [ - { "target": "PlatformApplicationArn", "sourceType": "identifier", "source": "Arn" } + { "target": "PlatformApplicationArn", "source": "identifier", "name": "Arn" } ] }, "resource": { "type": "PlatformEndpoint", "identifiers": [ - { "target": "Arn", "sourceType": "responsePath", "source": "Endpoints[].EndpointArn" } + { "target": "Arn", "source": "response", "path": "Endpoints[].EndpointArn" } ] } } @@ -125,17 +158,17 @@ "request": { "operation": "GetEndpointAttributes", "params": [ - { "target": "EndpointArn", "sourceType": "identifier", "source": "Arn" } + { "target": "EndpointArn", "source": "identifier", "name": "Arn" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "DeleteEndpoint", "params": [ - { "target": "EndpointArn", "sourceType": "identifier", "source": "Arn" } + { "target": "EndpointArn", "source": "identifier", "name": "Arn" } ] } }, @@ -143,7 +176,7 @@ "request": { "operation": "Publish", "params": [ - { "target": "TargetArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TargetArn", "source": "identifier", "name": "Arn" } ] } }, @@ -151,7 +184,7 @@ "request": { "operation": "SetEndpointAttributes", "params": [ - { "target": "EndpointArn", "sourceType": "identifier", "source": "Arn" } + { "target": "EndpointArn", "source": "identifier", "name": "Arn" } ] } } @@ -159,7 +192,6 @@ }, "Subscription": { "identifiers": [ - { "name": "TopicArn" }, { "name": "Arn" } ], "shape": "GetSubscriptionAttributesResponse", @@ -167,17 +199,17 @@ "request": { "operation": "GetSubscriptionAttributes", "params": [ - { "target": "SubscriptionArn", "sourceType": "identifier", "source": "Arn" } + { "target": "SubscriptionArn", "source": "identifier", "name": "Arn" } ] }, - "path": "$" + "path": "@" }, "actions": { "Delete": { "request": { "operation": "Unsubscribe", "params": [ - { "target": "SubscriptionArn", "sourceType": "identifier", "source": "Arn" } + { "target": "SubscriptionArn", "source": "identifier", "name": "Arn" } ] } }, @@ -185,7 +217,7 @@ "request": { "operation": "SetSubscriptionAttributes", "params": [ - { "target": "SubscriptionArn", "sourceType": "identifier", "source": "Arn" } + { "target": "SubscriptionArn", "source": "identifier", "name": "Arn" } ] } } @@ -200,17 +232,17 @@ "request": { "operation": "GetTopicAttributes", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] }, - "path": "$" + "path": "@" }, "actions": { "AddPermission": { "request": { "operation": "AddPermission", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] } }, @@ -218,14 +250,13 @@ "request": { "operation": "ConfirmSubscription", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] }, "resource": { "type": "Subscription", "identifiers": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" }, - { "target": "Arn", "sourceType": "responsePath", "source": "SubscriptionArn" } + { "target": "Arn", "source": "response", "path": "SubscriptionArn" } ] } }, @@ -233,7 +264,7 @@ "request": { "operation": "DeleteTopic", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] } }, @@ -241,7 +272,7 @@ "request": { "operation": "Publish", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] } }, @@ -249,7 +280,7 @@ "request": { "operation": "RemovePermission", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] } }, @@ -257,7 +288,7 @@ "request": { "operation": "SetTopicAttributes", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] } }, @@ -265,14 +296,13 @@ "request": { "operation": "Subscribe", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] }, "resource": { "type": "Subscription", "identifiers": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" }, - { "target": "Arn", "sourceType": "responsePath", "source": "SubscriptionArn" } + { "target": "Arn", "source": "response", "path": "SubscriptionArn" } ] } } @@ -282,21 +312,16 @@ "request": { "operation": "ListSubscriptionsByTopic", "params": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" } + { "target": "TopicArn", "source": "identifier", "name": "Arn" } ] }, "resource": { "type": "Subscription", "identifiers": [ - { "target": "TopicArn", "sourceType": "identifier", "source": "Arn" }, - { "target": "Arn", "sourceType": "responsePath", "source": "Subscriptions[].SubscriptionArn" } + { "target": "Arn", "source": "response", "path": "Subscriptions[].SubscriptionArn" } ] } } - }, - "subResources": { - "resources": [ "Subscription" ], - "identifiers": { "Arn": "TopicArn" } } } } diff --git a/boto3/data/resources/sqs-2012-11-05.resources.json b/boto3/data/resources/sqs-2012-11-05.resources.json index 9b061fbf3f..84b4528ffc 100644 --- a/boto3/data/resources/sqs-2012-11-05.resources.json +++ b/boto3/data/resources/sqs-2012-11-05.resources.json @@ -6,7 +6,7 @@ "resource": { "type": "Queue", "identifiers": [ - { "target": "Url", "sourceType": "responsePath", "source": "QueueUrl" } + { "target": "Url", "source": "response", "path": "QueueUrl" } ] } }, @@ -15,7 +15,17 @@ "resource": { "type": "Queue", "identifiers": [ - { "target": "Url", "sourceType": "responsePath", "source": "QueueUrl" } + { "target": "Url", "source": "response", "path": "QueueUrl" } + ] + } + } + }, + "has": { + "Queue": { + "resource": { + "type": "Queue", + "identifiers": [ + { "target": "Url", "source": "input" } ] } } @@ -26,7 +36,7 @@ "resource": { "type": "Queue", "identifiers": [ - { "target": "Url", "sourceType": "responsePath", "source": "QueueUrls[]" } + { "target": "Url", "source": "response", "path": "QueueUrls[]" } ] } } @@ -36,7 +46,10 @@ "Message": { "identifiers": [ { "name": "QueueUrl" }, - { "name": "ReceiptHandle", "memberName": "ReceiptHandle" } + { + "name": "ReceiptHandle", + "memberName": "ReceiptHandle" + } ], "shape": "Message", "actions": { @@ -44,8 +57,8 @@ "request": { "operation": "ChangeMessageVisibility", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "QueueUrl" }, - { "target": "ReceiptHandle", "sourceType": "identifier", "source": "ReceiptHandle" } + { "target": "QueueUrl", "source": "identifier", "name": "QueueUrl" }, + { "target": "ReceiptHandle", "source": "identifier", "name": "ReceiptHandle" } ] } }, @@ -53,8 +66,8 @@ "request": { "operation": "DeleteMessage", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "QueueUrl" }, - { "target": "ReceiptHandle", "sourceType": "identifier", "source": "ReceiptHandle" } + { "target": "QueueUrl", "source": "identifier", "name": "QueueUrl" }, + { "target": "ReceiptHandle", "source": "identifier", "name": "ReceiptHandle" } ] } } @@ -64,9 +77,19 @@ "request": { "operation": "DeleteMessageBatch", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "QueueUrl" }, - { "target": "Entries[*].Id", "sourceType": "dataMember", "source": "MessageId" }, - { "target": "Entries[*].ReceiptHandle", "sourceType": "identifier", "source": "ReceiptHandle" } + { "target": "QueueUrl", "source": "identifier", "name": "QueueUrl" }, + { "target": "Entries[*].Id", "source": "data", "path": "MessageId" }, + { "target": "Entries[*].ReceiptHandle", "source": "identifier", "name": "ReceiptHandle" } + ] + } + } + }, + "has": { + "Queue": { + "resource": { + "type": "Queue", + "identifiers": [ + { "target": "Url", "source": "identifier", "name": "QueueUrl" } ] } } @@ -81,18 +104,18 @@ "request": { "operation": "GetQueueAttributes", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" }, - { "target": "AttributeNames[]", "sourceType": "string", "source": "All" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" }, + { "target": "AttributeNames[]", "source": "string", "value": "All" } ] }, - "path": "$" + "path": "@" }, "actions": { "AddPermission": { "request": { "operation": "AddPermission", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } }, @@ -100,7 +123,7 @@ "request": { "operation": "ChangeMessageVisibilityBatch", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } }, @@ -108,7 +131,7 @@ "request": { "operation": "DeleteQueue", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } }, @@ -116,7 +139,7 @@ "request": { "operation": "DeleteMessageBatch", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } }, @@ -124,7 +147,7 @@ "request": { "operation": "PurgeQueue", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } }, @@ -132,14 +155,14 @@ "request": { "operation": "ReceiveMessage", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] }, "resource": { "type": "Message", "identifiers": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" }, - { "target": "ReceiptHandle", "sourceType": "responsePath", "source": "Messages[].ReceiptHandle" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" }, + { "target": "ReceiptHandle", "source": "response", "path": "Messages[].ReceiptHandle" } ], "path": "Messages[]" } @@ -148,7 +171,7 @@ "request": { "operation": "RemovePermission", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } }, @@ -156,7 +179,7 @@ "request": { "operation": "SendMessage", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } }, @@ -164,7 +187,7 @@ "request": { "operation": "SendMessageBatch", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } }, @@ -172,27 +195,34 @@ "request": { "operation": "SetQueueAttributes", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] } } }, - "subResources": { - "resources": [ "Message" ], - "identifiers": { "Url": "QueueUrl" } + "has": { + "Message": { + "resource": { + "type": "Message", + "identifiers": [ + { "target": "QueueUrl", "source": "identifier", "name": "Url" }, + { "target": "ReceiptHandle", "source": "input" } + ] + } + } }, - "hasMany" : { + "hasMany": { "DeadLetterSourceQueues": { "request": { "operation": "ListDeadLetterSourceQueues", "params": [ - { "target": "QueueUrl", "sourceType": "identifier", "source": "Url" } + { "target": "QueueUrl", "source": "identifier", "name": "Url" } ] }, "resource": { "type": "Queue", "identifiers": [ - { "target": "Url", "sourceType": "responsePath", "source": "QueueUrls[]" } + { "target": "Url", "source": "response", "path": "QueueUrls[]" } ] } } diff --git a/boto3/docs.py b/boto3/docs.py index 2c6f6032cb..02ab776d81 100644 --- a/boto3/docs.py +++ b/boto3/docs.py @@ -87,6 +87,7 @@ def py_default(type_name): 'timestamp': 'datetime(2015, 1, 1)', }.get(type_name, '...') + def html_to_rst(html, indent=0, indentFirst=False): """ Use bcdoc to convert html to rst. @@ -104,6 +105,7 @@ def html_to_rst(html, indent=0, indentFirst=False): # TODO: Remove me, temp workaround to fix doc building # because of smart quotes that aren't currently supported. html = html.replace(u'\u2019', "'") + html = html.replace(u'\u2014', '-') doc.include_doc_string(html) rst = doc.getvalue().decode('utf-8') @@ -345,7 +347,7 @@ def document_resource(service_name, official_name, resource_model, docs += document_action(action, service_name, resource_model, service_model) - if resource_model.sub_resources or is_service_resource: + if resource_model.subresources: docs += (' .. rst-class:: admonition-title\n\n Sub-resources\n\n' ' Sub-resources are methods that create a new instance of a' ' child resource. This resource\'s identifiers get passed' @@ -353,34 +355,26 @@ def document_resource(service_name, official_name, resource_model, preset = len(resource_model.identifiers) - if resource_model.sub_resources: - for resource in sorted(resource_model.sub_resources.resources, - key=lambda i: i.name): - docs += ' .. py:method:: {0}({1})\n\n'.format( - resource.name, - ', '.join([xform_name(i.name) for i in \ - resource.identifiers[preset:]])) - docs += (' Create a :py:class:`{0}.{1}`' - ' instance.\n\n').format(service_name, resource.name) - - if is_service_resource: - # TODO: expose service-level subresources via the model - for name, resource_def in sorted(resource_model._resource_defs.items()): + if resource_model.subresources: + for subresource in sorted(resource_model.subresources, + key=lambda i: i.name): + identifiers = [ + xform_name(i.target) for i in \ + subresource.resource.identifiers if i.source == 'input'] docs += ' .. py:method:: {0}({1})\n\n'.format( - name, - ', '.join([xform_name(i['name']) for i in \ - resource_def['identifiers'][preset:]])) + subresource.name, + ', '.join(identifiers)) docs += (' Create a :py:class:`{0}.{1}`' - ' instance.\n\n').format(service_name, name) + ' instance.\n\n').format(service_name, + subresource.resource.type) docs += '\n\n' - refs = resource_model.references + resource_model.reverse_references - if sorted(refs, key=lambda i: i.name): + if resource_model.references: docs += (' .. rst-class:: admonition-title\n\n References\n\n' ' References are related resource instances that have' ' a belongs-to relationship.\n\n') - for ref in refs: + for ref in sorted(resource_model.references, key=lambda i: i.name): docs += (' .. py:attribute:: {0}\n\n ' '(:py:class:`{1}.{2}`) The related {3} if set,' ' otherwise ``None``.\n\n').format( diff --git a/boto3/resources/action.py b/boto3/resources/action.py index f4ac96af3d..3e68d8f12b 100644 --- a/boto3/resources/action.py +++ b/boto3/resources/action.py @@ -71,10 +71,10 @@ def __call__(self, parent, *args, **kwargs): params = create_request_parameters(parent, self._action_model.request) params.update(kwargs) - logger.info('Calling %s:%s with %r', parent.meta['service_name'], + logger.info('Calling %s:%s with %r', parent.meta.service_name, operation_name, params) - response = getattr(parent.meta['client'], operation_name)(**params) + response = getattr(parent.meta.client, operation_name)(**params) logger.debug('Response: %r', response) @@ -125,9 +125,9 @@ def __call__(self, parent, *args, **kwargs): # or low-level client from a collection, so we get # these from the first resource in the collection. if service_name is None: - service_name = resource.meta['service_name'] + service_name = resource.meta.service_name if client is None: - client = resource.meta['client'] + client = resource.meta.client create_request_parameters( resource, self._action_model.request, params=params) @@ -186,10 +186,10 @@ def __call__(self, parent, *args, **kwargs): params.update(kwargs) logger.info('Calling %s:%s with %r', - parent.meta['service_name'], + parent.meta.service_name, self._waiter_resource_name, params) - client = parent.meta['client'] + client = parent.meta.client waiter = client.get_waiter(client_waiter_name) response = waiter.wait(**params) diff --git a/boto3/resources/base.py b/boto3/resources/base.py index 847a6bb697..c8c5bf4a03 100644 --- a/boto3/resources/base.py +++ b/boto3/resources/base.py @@ -11,9 +11,53 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. +import logging + import boto3 +logger = logging.getLogger(__name__) + + +class ResourceMeta(object): + """ + An object containing metadata about a resource. + """ + def __init__(self, service_name, identifiers=None, client=None, + data=None): + #: (``string``) The service name, e.g. 's3' + self.service_name = service_name + + if identifiers is None: + identifiers = [] + #: (``list``) List of identifier names + self.identifiers = identifiers + + #: (:py:class:`~botocore.client.BaseClient`) Low-level Botocore client + self.client = client + #: (``dict``) Loaded resource data attributes + self.data = data + + def __repr__(self): + return 'ResourceMeta(\'{0}\', identifiers={1})'.format( + self.service_name, self.identifiers) + + def __eq__(self, other): + # Two metas are equal if their components are all equal + if other.__class__.__name__ != self.__class__.__name__: + return False + + return self.__dict__ == other.__dict__ + + def copy(self): + """ + Create a copy of this metadata object. + """ + params = self.__dict__.copy() + service_name = params.pop('service_name') + return ResourceMeta(service_name, **params) + + class ServiceResource(object): """ A base class for resources. @@ -29,11 +73,13 @@ class ServiceResource(object): from when the instance was hydrated. For example:: # Get a low-level client from a resource instance - client = resource.meta['client'] + client = resource.meta.client response = client.operation(Param='foo') # Print the resource instance's service short name - print(resource.meta['service_name']) + print(resource.meta.service_name) + + See :py:class:`ResourceMeta` for more information. """ def __init__(self, *args, **kwargs): @@ -43,14 +89,14 @@ def __init__(self, *args, **kwargs): # Create a default client if none was passed if kwargs.get('client') is not None: - self.meta['client'] = kwargs.get('client') + self.meta.client = kwargs.get('client') else: - self.meta['client'] = boto3.client(self.meta['service_name']) + self.meta.client = boto3.client(self.meta.service_name) # Allow setting identifiers as positional arguments in the order # in which they were defined in the ResourceJSON. for i, value in enumerate(args): - setattr(self, self.meta['identifiers'][i], value) + setattr(self, self.meta.identifiers[i], value) # Allow setting identifiers via keyword arguments. Here we need # extra logic to ignore other keyword arguments like ``client``. @@ -58,20 +104,20 @@ def __init__(self, *args, **kwargs): if name == 'client': continue - if name not in self.meta['identifiers']: + if name not in self.meta.identifiers: raise ValueError('Unknown keyword argument: {0}'.format(name)) setattr(self, name, value) # Validate that all identifiers have been set. - for identifier in self.meta['identifiers']: + for identifier in self.meta.identifiers: if getattr(self, identifier) is None: raise ValueError( 'Required parameter {0} not set'.format(identifier)) def __repr__(self): identifiers = [] - for identifier in self.meta['identifiers']: + for identifier in self.meta.identifiers: identifiers.append('{0}={1}'.format( identifier, repr(getattr(self, identifier)))) return "{0}({1})".format( @@ -86,7 +132,7 @@ def __eq__(self, other): # Each of the identifiers should have the same value in both # instances, e.g. two buckets need the same name to be equal. - for identifier in self.meta['identifiers']: + for identifier in self.meta.identifiers: if getattr(self, identifier) != getattr(other, identifier): return False diff --git a/boto3/resources/collection.py b/boto3/resources/collection.py index bbbb406729..483c754676 100644 --- a/boto3/resources/collection.py +++ b/boto3/resources/collection.py @@ -54,7 +54,7 @@ def __repr__(self): self.__class__.__name__, self._parent, '{0}.{1}'.format( - self._parent.meta['service_name'], + self._parent.meta.service_name, self._model.resource.type ) ) @@ -131,7 +131,7 @@ def pages(self): :rtype: list(:py:class:`~boto3.resources.base.ServiceResource`) :return: List of resource instances """ - client = self._parent.meta['client'] + client = self._parent.meta.client cleaned_params = self._params.copy() limit = cleaned_params.pop('limit', None) page_size = cleaned_params.pop('page_size', None) @@ -147,14 +147,14 @@ def pages(self): # the page size parameter. if client.can_paginate(self._py_operation_name): logger.info('Calling paginated %s:%s with %r', - self._parent.meta['service_name'], + self._parent.meta.service_name, self._py_operation_name, params) paginator = client.get_paginator(self._py_operation_name) pages = paginator.paginate( max_items=limit, page_size=page_size, **params) else: logger.info('Calling %s:%s with %r', - self._parent.meta['service_name'], + self._parent.meta.service_name, self._py_operation_name, params) pages = [getattr(client, self._py_operation_name)(**params)] @@ -321,7 +321,7 @@ def __repr__(self): self.__class__.__name__, self._parent, '{0}.{1}'.format( - self._parent.meta['service_name'], + self._parent.meta.service_name, self._model.resource.type ) ) diff --git a/boto3/resources/factory.py b/boto3/resources/factory.py index 7b8926b1cb..5962d602ee 100644 --- a/boto3/resources/factory.py +++ b/boto3/resources/factory.py @@ -18,10 +18,10 @@ from .action import ServiceAction from .action import WaiterAction -from .base import ServiceResource +from .base import ResourceMeta, ServiceResource from .collection import CollectionFactory from .model import ResourceModel -from .response import all_not_none, build_identifiers +from .response import build_identifiers, ResourceHandler from ..exceptions import ResourceLoadException @@ -65,11 +65,7 @@ def load_from_definition(self, service_name, resource_name, model, :return: The service or resource class. """ # Set some basic info - meta = { - 'service_name': service_name, - 'identifiers': [], - 'data': None, - } + meta = ResourceMeta(service_name) attrs = { 'meta': meta, } @@ -79,15 +75,13 @@ def load_from_definition(self, service_name, resource_name, model, resource_model = ResourceModel(resource_name, model, resource_defs) self._load_identifiers(attrs, meta, resource_model) - self._load_subresources(attrs, service_name, resource_name, - resource_model, resource_defs, service_model) self._load_actions(attrs, resource_model, resource_defs, service_model) self._load_attributes(attrs, meta, resource_model, service_model) self._load_collections(attrs, resource_model, resource_defs, service_model) - self._load_references(attrs, service_name, resource_name, - resource_model, resource_defs, service_model) + self._load_has_relations(attrs, service_name, resource_name, + resource_model, resource_defs, service_model) self._load_waiters(attrs, resource_model) # Create the name based on the requested service and resource @@ -107,36 +101,9 @@ def _load_identifiers(self, attrs, meta, model): snake_cased = xform_name(identifier.name) snake_cased = self._check_allowed_name( attrs, snake_cased, 'identifier', model.name) - meta['identifiers'].append(snake_cased) + meta.identifiers.append(snake_cased) attrs[snake_cased] = None - def _load_subresources(self, attrs, service_name, resource_name, - model, resource_defs, service_model): - """ - Creates subresource classes which hang off the instance. Each - subresource is a bound partial method that returns a resource - instance which shares the client and identifiers of the parent. - """ - # Create dangling classes, e.g. SQS.Queue, SQS.Message - if service_name == resource_name: - # This is a service, so dangle all the resource_defs as if - # they were subresources of the service itself. - for name, resource_def in resource_defs.items(): - cls = self.load_from_definition( - service_name, name, resource_defs.get(name, {}), - resource_defs, service_model) - attrs[name] = self._create_class_partial(cls) - - # For non-services, subresources are explicitly listed - if model.sub_resources: - identifiers = model.sub_resources.identifiers - for name in model.sub_resources.resource_names: - cls = self.load_from_definition( - service_name, name, resource_defs.get(name, {}), - resource_defs, service_model) - attrs[name] = self._create_class_partial( - cls, identifiers=identifiers) - def _load_actions(self, attrs, model, resource_defs, service_model): """ Actions on the resource become methods, with the ``load`` method @@ -168,7 +135,7 @@ def _load_attributes(self, attrs, meta, model, service_model): for name, member in shape.members.items(): snake_cased = xform_name(name) - if snake_cased in meta['identifiers']: + if snake_cased in meta.identifiers: # Skip identifiers, these are set through other means continue @@ -190,31 +157,41 @@ def _load_collections(self, attrs, model, resource_defs, service_model): attrs, snake_cased, 'collection', model.name) attrs[snake_cased] = self._create_collection( - attrs['meta']['service_name'], model.name, snake_cased, + attrs['meta'].service_name, model.name, snake_cased, collection_model, resource_defs, service_model) - def _load_references(self, attrs, service_name, resource_name, - model, resource_defs, service_model): + def _load_has_relations(self, attrs, service_name, resource_name, + model, resource_defs, service_model): """ - Load references, which are related resource instances. For example, - an EC2 instance would have a ``vpc`` reference, which is an instance - of an EC2 VPC resource. + Load related resources, which are defined via a ``has`` + relationship but conceptually come in two forms: + + 1. A reference, which is a related resource instance and can be + ``None``, such as an EC2 instance's ``vpc``. + 2. A subresource, which is a resource constructor that will always + return a resource instance which shares identifiers/data with + this resource, such as ``s3.Bucket('name').Object('key')``. """ for reference in model.references: - snake_cased = xform_name(reference.resource.type) + # This is a dangling reference, i.e. we have all + # the data we need to create the resource, so + # this instance becomes an attribute on the class. + snake_cased = xform_name(reference.name) snake_cased = self._check_allowed_name( attrs, snake_cased, 'reference', model.name) attrs[snake_cased] = self._create_reference( - reference.resource.type, snake_cased, reference, service_name, - resource_name, model, resource_defs, service_model) + reference.resource.type, snake_cased, reference, + service_name, resource_name, model, resource_defs, + service_model) + + for subresource in model.subresources: + # This is a sub-resource class you can create + # by passing in an identifier, e.g. s3.Bucket(name). + name = subresource.resource.type + attrs[name] = self._create_class_partial( + name, subresource, service_name, resource_name, model, + resource_defs, service_model) - for reference in model.reverse_references: - snake_cased = xform_name(reference.resource.type) - snake_cased = self._check_allowed_name( - attrs, snake_cased, 'reference', model.name) - attrs[snake_cased] = self._create_reference( - reference.resource.type, snake_cased, reference, service_name, - resource_name, model, resource_defs, service_model) def _load_waiters(self, attrs, model): """ @@ -272,14 +249,14 @@ def _create_autoload_property(factory_self, name, snake_cased): # it first checks to see if it CAN be loaded (raise if not), then # calls the load before returning the value. def property_loader(self): - if self.meta['data'] is None: + if self.meta.data is None: if hasattr(self, 'load'): self.load() else: raise ResourceLoadException( '{0} has no load method'.format(self.__class__.__name__)) - return self.meta['data'].get(name) + return self.meta.data.get(name) property_loader.__name__ = str(snake_cased) property_loader.__doc__ = 'TODO' @@ -322,30 +299,27 @@ def _create_reference(factory_self, name, snake_cased, reference, """ Creates a new property on the resource to lazy-load a reference. """ + # References are essentially an action with no request + # or response, so we can re-use the response handlers to + # build up resources from identifiers and data members. + handler = ResourceHandler('', factory_self, resource_defs, + service_model, reference.resource) + def get_reference(self): # We need to lazy-evaluate the reference to handle circular # references between resources. We do this by loading the class # when first accessed. # First, though, we need to see if we have the required # identifiers to instantiate the resource reference. - identifiers = build_identifiers( - reference.resource.identifiers, self, {}, {}) - resource = None - if all_not_none(identifiers.values()): - # Identifiers are present, so now we can create the resource - # instance using them. - resource_type = reference.resource.type - cls = factory_self.load_from_definition( - service_name, name, resource_defs.get(resource_type), - resource_defs, service_model) - resource = cls(**identifiers) - return resource + return handler(self, {}, {}) get_reference.__name__ = str(snake_cased) get_reference.__doc__ = 'TODO' return property(get_reference) - def _create_class_partial(factory_self, resource_cls, identifiers=None): + def _create_class_partial(factory_self, name, subresource, + service_name, resource_name, model, + resource_defs, service_model): """ Creates a new method which acts as a functools.partial, passing along the instance's low-level `client` to the new resource @@ -354,36 +328,28 @@ def _create_class_partial(factory_self, resource_cls, identifiers=None): # We need a new method here because we want access to the # instance's client. def create_resource(self, *args, **kwargs): - pargs = [] + positional_args = [] + + # We lazy-load the class to handle circular references. + resource_cls = factory_self.load_from_definition( + service_name, name, resource_defs.get(name, {}), + resource_defs, service_model) # Assumes that identifiers are in order, which lets you do # e.g. ``sqs.Queue('foo').Message('bar')`` to create a new message # linked with the ``foo`` queue and which has a ``bar`` receipt # handle. If we did kwargs here then future positional arguments # would lead to failure. + identifiers = subresource.resource.identifiers if identifiers is not None: - for key, value in identifiers.items(): - pargs.append(getattr(self, xform_name(key))) - - return partial(resource_cls, *pargs, - client=self.meta.get('client'))(*args, **kwargs) - - # Generate documentation about required and optional params - doc = 'Create a new instance of {0}\n\nRequired identifiers:\n' - - for identifier in resource_cls.meta['identifiers']: - doc += ':type {0}: string\n'.format(identifier) - doc += ':param {0}: {0} identifier\n'.format(identifier) - - doc += '\nOptional params:\n' - doc += ':type client: botocore.client\n' - doc += ':param client: Low-level Botocore client instance\n' + for identifier, value in build_identifiers(identifiers, self): + positional_args.append(value) - doc += '\n:rtype: {0}\n'.format(resource_cls) - doc += ':return: A new resource instance' + return partial(resource_cls, *positional_args, + client=self.meta.client)(*args, **kwargs) - create_resource.__name__ = str(resource_cls.__name__) - create_resource.__doc__ = doc.format(resource_cls) + create_resource.__name__ = str(name) + create_resource.__doc__ = 'TODO' return create_resource def _create_action(factory_self, snake_cased, action_model, resource_defs, @@ -405,7 +371,7 @@ def _create_action(factory_self, snake_cased, action_model, resource_defs, # instance via ``self``. def do_action(self, *args, **kwargs): response = action(self, *args, **kwargs) - self.meta['data'] = response + self.meta.data = response else: # We need a new method here because we want access to the # instance via ``self``. @@ -416,7 +382,7 @@ def do_action(self, *args, **kwargs): # Clear cached data. It will be reloaded the next # time that an attribute is accessed. # TODO: Make this configurable in the future? - self.meta['data'] = None + self.meta.data = None return response diff --git a/boto3/resources/model.py b/boto3/resources/model.py index d1b3019a71..0eb49a8fbf 100644 --- a/boto3/resources/model.py +++ b/boto3/resources/model.py @@ -93,8 +93,7 @@ def params(self): params = [] for item in self._definition.get('params', []): - params.append( - Parameter(item['target'], item['sourceType'], item['source'])) + params.append(Parameter(**item)) return params @@ -112,13 +111,22 @@ class Parameter(object): :type source: string :param source: The source name, e.g. ``Url`` """ - def __init__(self, target, source_type, source): + def __init__(self, target, source, name=None, path=None, value=None, + **kwargs): #: (``string``) The destination parameter name self.target = target #: (``string``) Where the source is defined - self.source_type = source_type - #: (``string``) The source name self.source = source + #: (``string``) The name of the source, if given + self.name = name + #: (``string``) The JMESPath query of the source + self.path = path + #: (``string|int|float|bool``) The source constant value + self.value = value + + # Complain if we encounter any unknown values. + if kwargs: + logger.warning('Unknown parameter options found: %s', kwargs) class Request(DefinitionWithParams): @@ -187,7 +195,7 @@ def identifiers(self): for item in self._definition.get('identifiers', []): identifiers.append( - Parameter(item['target'], item['sourceType'], item['source'])) + Parameter(**item)) return identifiers @@ -225,43 +233,6 @@ def batch_actions(self): return self.resource.model.batch_actions -class SubResourceList(object): - """ - A list of information about sub-resources. It includes access - to identifiers as well as resource names and models. - - :type definition: dict - :param definition: The JSON definition - :type resource_defs: dict - :param resource_defs: All resources defined in the service - """ - def __init__(self, definition, resource_defs): - self._definition = definition - self._resource_defs = resource_defs - - #: (``dict``) Identifier key:value pairs - self.identifiers = definition.get('identifiers', {}) - #: (``list``) A list of resource names - self.resource_names = definition.get('resources', []) - - @property - def resources(self): - """ - Get a list of resource models contained in this sub-resource - entry. - - :type: list(:py:class:`ResourceModel`) - """ - resources = [] - - for name in self.resource_names: - resources.append( - ResourceModel(name, self._resource_defs.get(name, {}), - self._resource_defs)) - - return resources - - class ResourceModel(object): """ A model representing a resource, defined via a JSON description @@ -284,11 +255,6 @@ def __init__(self, name, definition, resource_defs): self.name = name #: (``string``) The service shape name for this resource or ``None`` self.shape = definition.get('shape') - #: (:py:class:`SubResourceList`) Sub-resource information or ``None`` - self.sub_resources = None - if 'subResources' in definition: - self.sub_resources = SubResourceList( - definition.get('subResources', {}), resource_defs) @property def identifiers(self): @@ -346,63 +312,50 @@ def batch_actions(self): return actions - @property - def references(self): + def _get_related_resources(self, subresources): """ - Get a list of reference resources. + Get a list of sub-resources or references. - :type: list(:py:class:`ResponseResource`) - """ - references = [] - - for key in ['belongsTo']: - for name, definition in self._definition.get(key, {}).items(): - references.append( - Action(name, definition, self._resource_defs)) - - return references - - @property - def reverse_references(self): - """ - Get a list of reverse reference resources. E.g. an S3 object has - a ``bucket_name`` identifier that can be used to instantiate a - bucket resource instance. + :type subresources: bool + :param subresources: ``True`` to get sub-resources, ``False`` to + get references. + :rtype: list(:py:class:`ResponseResource`) """ - references = [] + resources = [] - # First, we search for possible reverse references based on the - # defined sub-resources in each resource. If the name of this - # resource is present, then we are a child. Next, we use the - # identifiers to construct a reference definition, append it - # to the list of references and return. + for name, definition in self._definition.get('has', {}).items(): + action = Action(name, definition, self._resource_defs) - for name, definition in self._resource_defs.items(): - sub_resources = definition.get('subResources', {}) - resource_names = sub_resources.get('resources', []) + data_required = False + for identifier in action.resource.identifiers: + if identifier.source == 'data': + data_required = True + break - if self.name in resource_names: - logger.debug('Discovered reverse reference from {0}' - ' to {1}'.format(self.name, name)) + if subresources and not data_required: + resources.append(action) + elif not subresources and data_required: + resources.append(action) - identifiers = sub_resources.get('identifiers', {}) + return resources - has_one_def = { - 'resource': { - 'type': name, - 'identifiers': [] - } - } + @property + def subresources(self): + """ + Get a list of sub-resources. - for target, source in identifiers.items(): - has_one_def['resource']['identifiers'].append( - {'target': target, 'sourceType': 'identifier', - 'source': source}) + :type: list(:py:class`ResponseResource`) + """ + return self._get_related_resources(True) - references.append( - Action(name, has_one_def, self._resource_defs)) + @property + def references(self): + """ + Get a list of reference resources. - return references + :type: list(:py:class:`ResponseResource`) + """ + return self._get_related_resources(False) @property def collections(self): diff --git a/boto3/resources/params.py b/boto3/resources/params.py index 7d3c56c7f2..95e4660366 100644 --- a/boto3/resources/params.py +++ b/boto3/resources/params.py @@ -13,12 +13,41 @@ import re +import jmespath from botocore import xform_name +from ..exceptions import ResourceLoadException + INDEX_RE = re.compile('\[(.*)\]$') +def get_data_member(parent, path): + """ + Get a data member from a parent using a JMESPath search query, + loading the parent if required. If the parent cannot be loaded + and no data is present then an exception is raised. + + :type parent: ServiceResource + :param parent: The resource instance to which contains data we + are interested in. + :type path: string + :param path: The JMESPath expression to query + :raises ResourceLoadException: When no data is present and the + resource cannot be loaded. + :returns: The queried data or ``None``. + """ + # Ensure the parent has its data loaded, if possible. + if parent.meta.data is None: + if hasattr(parent, 'load'): + parent.load() + else: + raise ResourceLoadException( + '{0} has no load method!'.format(parent.__class__.__name__)) + + return jmespath.search(path, parent.meta.data) + + def create_request_parameters(parent, request_model, params=None): """ Handle request parameters that can be filled in from identifiers, @@ -43,20 +72,24 @@ def create_request_parameters(parent, request_model, params=None): for param in request_model.params: source = param.source - source_type = param.source_type target = param.target - if source_type in ['identifier', 'dataMember']: + if source == 'identifier': # Resource identifier, e.g. queue.url - # If this is a dataMember then it may incur a load + value = getattr(parent, xform_name(param.name)) + elif source == 'data': + # If this is a data member then it may incur a load # action before returning the value. - value = getattr(parent, xform_name(source)) - elif source_type in ['string', 'integer', 'boolean']: + value = get_data_member(parent, param.path) + elif source in ['string', 'integer', 'boolean']: # These are hard-coded values in the definition - value = source + value = param.value + elif source == 'input': + # This is provided by the user, so ignore it here + continue else: raise NotImplementedError( - 'Unsupported source type: {0}'.format(source_type)) + 'Unsupported source type: {0}'.format(source)) build_param_structure(params, target, value) diff --git a/boto3/resources/response.py b/boto3/resources/response.py index 2834e836db..35d63eae3b 100644 --- a/boto3/resources/response.py +++ b/boto3/resources/response.py @@ -14,6 +14,9 @@ import jmespath from botocore import xform_name +from ..exceptions import ResourceLoadException +from .params import get_data_member + def all_not_none(iterable): """ @@ -27,7 +30,7 @@ def all_not_none(iterable): return True -def build_identifiers(identifiers, parent, params, raw_response): +def build_identifiers(identifiers, parent, params=None, raw_response=None): """ Builds a mapping of identifier names to values based on the identifier source location, type, and target. Identifier @@ -43,26 +46,33 @@ def build_identifiers(identifiers, parent, params, raw_response): :param params: Request parameters sent to the service. :type raw_response: dict :param raw_response: Low-level operation response. + :rtype: list + :return: An ordered list of ``(name, value)`` identifier tuples. """ - results = {} + results = [] for identifier in identifiers: source = identifier.source - source_type = identifier.source_type target = identifier.target - if source_type == 'responsePath': - value = jmespath.search(source, raw_response) - results[xform_name(target)] = value - elif source_type in ['identifier', 'dataMember']: - value = getattr(parent, xform_name(source)) - results[xform_name(target)] = value - elif source_type == 'requestParameter': - value = params[source] - results[xform_name(target)] = value + if source == 'response': + value = jmespath.search(identifier.path, raw_response) + elif source == 'requestParameter': + value = jmespath.search(identifier.path, params) + elif source == 'identifier': + value = getattr(parent, xform_name(identifier.name)) + elif source == 'data': + # If this is a data member then it may incur a load + # action before returning the value. + value = get_data_member(parent, identifier.path) + elif source == 'input': + # This value is set by the user, so ignore it here + continue else: raise NotImplementedError( - 'Unsupported source type: {0}'.format(source_type)) + 'Unsupported source type: {0}'.format(source)) + + results.append((xform_name(target), value)) return results @@ -77,7 +87,7 @@ def build_empty_response(search_path, operation_name, service_model): :type search_path: string :param search_path: JMESPath expression to search in the response :type operation_name: string - :param operation_name: Name of the underlying service operation + :param operation_name: Name of the underlying service operation. :type service_model: :ref:`botocore.model.ServiceModel` :param service_model: The Botocore service model :rtype: dict, list, or None @@ -163,12 +173,13 @@ class ResourceHandler(object): :type resource_model: :py:class:`~boto3.resources.model.ResponseResource` :param resource_model: Response resource model. :type operation_name: string - :param operation_name: Name of the underlying service operation + :param operation_name: Name of the underlying service operation, if it + exists. :rtype: ServiceResource or list :return: New resource instance(s). """ def __init__(self, search_path, factory, resource_defs, service_model, - resource_model, operation_name): + resource_model, operation_name=None): self.search_path = search_path self.factory = factory self.resource_defs = resource_defs @@ -187,7 +198,7 @@ def __call__(self, parent, params, response): """ resource_name = self.resource_model.type resource_cls = self.factory.load_from_definition( - parent.meta['service_name'], resource_name, + parent.meta.service_name, resource_name, self.resource_defs.get(resource_name), self.resource_defs, self.service_model) @@ -196,7 +207,7 @@ def __call__(self, parent, params, response): # Anytime a path is defined, it means the response contains the # resource's attributes, so resource_data gets set here. It - # eventually ends up in resource.meta['data'], which is where + # eventually ends up in resource.meta.data, which is where # the attribute properties look for data. if self.search_path: search_response = jmespath.search(self.search_path, raw_response) @@ -206,9 +217,9 @@ def __call__(self, parent, params, response): # will have one item consumed from the front of the list for each # resource that is instantiated. Items which are not a list will # be set as the same value on each new resource instance. - identifiers = build_identifiers( + identifiers = dict(build_identifiers( self.resource_model.identifiers, parent, params, - raw_response) + raw_response)) # If any of the identifiers is a list, then the response is plural plural = [v for v in identifiers.values() if isinstance(v, list)] @@ -233,10 +244,16 @@ def __call__(self, parent, params, response): response = self.handle_response_item(resource_cls, parent, identifiers, search_response) else: - # The response is should be empty, but that may mean an - # empty dict, list, or None. - response = build_empty_response(self.search_path, - self.operation_name, self.service_model) + # The response should be empty, but that may mean an + # empty dict, list, or None based on whether we make + # a remote service call and what shape it is expected + # to return. + response = None + if self.operation_name is not None: + # A remote service call was made, so try and determine + # its shape. + response = build_empty_response(self.search_path, + self.operation_name, self.service_model) return response @@ -258,7 +275,7 @@ def handle_response_item(self, resource_cls, parent, identifiers, :return: New resource instance. """ kwargs = { - 'client': parent.meta.get('client'), + 'client': parent.meta.client, } for name, value in identifiers.items(): @@ -271,6 +288,6 @@ def handle_response_item(self, resource_cls, parent, identifiers, resource = resource_cls(**kwargs) if resource_data is not None: - resource.meta['data'] = resource_data + resource.meta.data = resource_data return resource diff --git a/boto3/session.py b/boto3/session.py index 4f47e921cf..efd9fb7faf 100644 --- a/boto3/session.py +++ b/boto3/session.py @@ -143,10 +143,6 @@ def get_available_resources(self): service_names = set() for path in self._get_resource_files(): - # TODO: Glacier is not yet supported by Botocore. - if 'glacier' in path: - continue - # 'foo-bar-2006-03-01' => 'foo-bar' service_names.add('-'.join(path.split('-')[:-3])) diff --git a/docs/source/guide/clients.rst b/docs/source/guide/clients.rst index 4a8ed2d671..2e2feda234 100644 --- a/docs/source/guide/clients.rst +++ b/docs/source/guide/clients.rst @@ -22,7 +22,7 @@ resource:: sqs_resource = boto3.resource('sqs') # Get the client from the resource - sqs = sqs_resource.meta['client'] + sqs = sqs_resource.meta.client Service Operations ------------------ diff --git a/setup.py b/setup.py index a96e9498b4..ac2beab5d0 100644 --- a/setup.py +++ b/setup.py @@ -26,9 +26,9 @@ def get_version(): ] requires = [ - 'botocore==0.80.0', + 'botocore==0.86.0', 'bcdoc==0.12.2', - 'jmespath==0.5.0', + 'jmespath==0.6.1', ] setup( diff --git a/tests/integration/test_s3.py b/tests/integration/test_s3.py index 197de819d1..233ccff8b7 100644 --- a/tests/integration/test_s3.py +++ b/tests/integration/test_s3.py @@ -36,7 +36,7 @@ def create_bucket_resource(self, bucket_name, region=None): return bucket def test_s3(self): - client = self.s3.meta['client'] + client = self.s3.meta.client # Create a bucket (resource action with a resource response) bucket = self.create_bucket_resource(self.bucket_name) diff --git a/tests/unit/resources/test_action.py b/tests/unit/resources/test_action.py index 8420c6525b..8eb3db49a9 100644 --- a/tests/unit/resources/test_action.py +++ b/tests/unit/resources/test_action.py @@ -12,6 +12,7 @@ # language governing permissions and limitations under the License. from boto3.resources.action import BatchAction, ServiceAction, WaiterAction +from boto3.resources.base import ResourceMeta from boto3.resources.model import Action, Waiter from tests import BaseTestCase, mock @@ -35,10 +36,7 @@ def action(self): return_value={}) def test_service_action_creates_params(self, params_mock): resource = mock.Mock() - resource.meta = { - 'service_name': 'test', - 'client': mock.Mock(), - } + resource.meta = ResourceMeta('test', client=mock.Mock()) action = ServiceAction(self.action) @@ -51,11 +49,8 @@ def test_service_action_creates_params(self, params_mock): return_value={'bar': 'baz'}) def test_service_action_calls_operation(self, params_mock): resource = mock.Mock() - resource.meta = { - 'service_name': 'test', - 'client': mock.Mock(), - } - operation = resource.meta['client'].get_frobs + resource.meta = ResourceMeta('test', client=mock.Mock()) + operation = resource.meta.client.get_frobs operation.return_value = 'response' action = ServiceAction(self.action) @@ -71,11 +66,8 @@ def test_service_action_calls_operation(self, params_mock): @mock.patch('boto3.resources.action.RawHandler') def test_service_action_calls_raw_handler(self, handler_mock, params_mock): resource = mock.Mock() - resource.meta = { - 'service_name': 'test', - 'client': mock.Mock(), - } - operation = resource.meta['client'].get_frobs + resource.meta = ResourceMeta('test', client=mock.Mock()) + operation = resource.meta.client.get_frobs operation.return_value = 'response' action = ServiceAction(self.action) @@ -97,11 +89,8 @@ def test_service_action_calls_resource_handler(self, handler_mock, params_mock): } resource = mock.Mock() - resource.meta = { - 'service_name': 'test', - 'client': mock.Mock(), - } - operation = resource.meta['client'].get_frobs + resource.meta = ResourceMeta('test', client=mock.Mock()) + operation = resource.meta.client.get_frobs operation.return_value = 'response' factory = mock.Mock() @@ -142,10 +131,7 @@ def waiter(self): return_value={}) def test_service_waiter_creates_params(self, params_mock): resource = mock.Mock() - resource.meta = { - 'service_name': 'test', - 'client': mock.Mock(), - } + resource.meta = ResourceMeta('test', client=mock.Mock()) action = WaiterAction(self.waiter, self.waiter_resource_name) @@ -158,11 +144,8 @@ def test_service_waiter_creates_params(self, params_mock): return_value={'bar': 'baz'}) def test_service_action_calls_operation(self, params_mock): resource = mock.Mock() - resource.meta = { - 'service_name': 'test', - 'client': mock.Mock(), - } - get_waiter = resource.meta['client'].get_waiter + resource.meta = ResourceMeta('test', client=mock.Mock()) + get_waiter = resource.meta.client.get_waiter mock_waiter = mock.Mock() get_waiter.return_value = mock_waiter @@ -200,25 +183,24 @@ def test_batch_action_gets_pages_from_collection(self): def test_batch_action_creates_parameters_from_items(self): self.action_def['request']['params'] = [ - {'target': 'Bucket', 'sourceType': 'dataMember', - 'source': 'BucketName'}, - {'target': 'Delete.Objects[].Key', 'sourceType': 'dataMember', - 'source': 'Key'} + {'target': 'Bucket', 'source': 'data', 'path': 'BucketName'}, + {'target': 'Delete.Objects[].Key', 'source': 'data', + 'path': 'Key'} ] client = mock.Mock() item1 = mock.Mock() - item1.meta = { - 'service_name': 'test', - 'client': client - } - item1.bucket_name = 'bucket' - item1.key = 'item1' + item1.meta = ResourceMeta('test', client=client, data={ + 'BucketName': 'bucket', + 'Key': 'item1' + }) item2 = mock.Mock() - item2.bucket_name = 'bucket' - item2.key = 'item2' + item2.meta = ResourceMeta('test', client=client, data={ + 'BucketName': 'bucket', + 'Key': 'item2' + }) collection = mock.Mock() collection.pages.return_value = [[item1, item2]] @@ -242,10 +224,7 @@ def test_batch_action_skips_operation(self, crp_mock): client = mock.Mock() item = mock.Mock() - item.meta = { - 'service_name': 'test', - 'client': client - } + item.meta = ResourceMeta('test', client=client) collection = mock.Mock() collection.pages.return_value = [[item]] @@ -269,10 +248,7 @@ def side_effect(resource, model, params=None): client = mock.Mock() item = mock.Mock() - item.meta = { - 'service_name': 'test', - 'client': client - } + item.meta = ResourceMeta('test', client=client) collection = mock.Mock() collection.pages.return_value = [[item]] diff --git a/tests/unit/resources/test_collection.py b/tests/unit/resources/test_collection.py index 7f7a116bc6..4eec2b8153 100644 --- a/tests/unit/resources/test_collection.py +++ b/tests/unit/resources/test_collection.py @@ -14,6 +14,7 @@ from botocore.model import ServiceModel from boto3.resources.collection import CollectionFactory, CollectionManager, \ ResourceCollection +from boto3.resources.base import ResourceMeta from boto3.resources.factory import ResourceFactory from boto3.resources.model import Collection from tests import BaseTestCase, mock @@ -25,12 +26,8 @@ def setUp(self): self.client = mock.Mock() self.client.can_paginate.return_value = False - meta = { - 'client': self.client, - 'service_name': 'test' - } self.parent = mock.Mock() - self.parent.meta = meta + self.parent.meta = ResourceMeta('test', client=self.client) self.resource_factory = ResourceFactory() self.service_model = ServiceModel({}) @@ -129,12 +126,8 @@ def setUp(self): } self.client = mock.Mock() self.client.can_paginate.return_value = False - meta = { - 'client': self.client, - 'service_name': 'test' - } self.parent = mock.Mock() - self.parent.meta = meta + self.parent.meta = ResourceMeta('test', client=self.client) self.factory = ResourceFactory() self.service_model = ServiceModel({}) @@ -185,8 +178,8 @@ def test_iteration_non_paginated(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } @@ -217,8 +210,8 @@ def test_limit_param_non_paginated(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } @@ -249,8 +242,8 @@ def test_limit_method_non_paginated(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } @@ -301,8 +294,8 @@ def test_page_iterator_returns_pages_of_items(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } @@ -337,8 +330,8 @@ def test_page_iterator_page_size(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } @@ -362,8 +355,8 @@ def test_iteration_paginated(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } @@ -405,8 +398,8 @@ def test_limit_param_paginated(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } @@ -443,8 +436,8 @@ def test_limit_method_paginated(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } @@ -518,8 +511,8 @@ def test_chaining(self): 'identifiers': [ { 'target': 'Id', - 'sourceType': 'responsePath', - 'source': 'Frobs[].Id' + 'source': 'response', + 'path': 'Frobs[].Id' } ] } diff --git a/tests/unit/resources/test_factory.py b/tests/unit/resources/test_factory.py index b9059dacaf..ad63bc3373 100644 --- a/tests/unit/resources/test_factory.py +++ b/tests/unit/resources/test_factory.py @@ -44,7 +44,7 @@ def test_get_resource_returns_resource_class(self): def test_factory_sets_service_name(self): QueueResource = self.load('test', 'Queue', {}, {}, None) - self.assertEqual(QueueResource.meta['service_name'], 'test', + self.assertEqual(QueueResource.meta.service_name, 'test', 'Service name not set') def test_factory_sets_identifiers(self): @@ -57,11 +57,9 @@ def test_factory_sets_identifiers(self): MessageResource = self.load('test', 'Message', model, {}, None) - self.assertTrue('identifiers' in MessageResource.meta, - 'Class has no identifiers') - self.assertIn('queue_url', MessageResource.meta['identifiers'], + self.assertIn('queue_url', MessageResource.meta.identifiers, 'Missing queue_url identifier from model') - self.assertIn('receipt_handle', MessageResource.meta['identifiers'], + self.assertIn('receipt_handle', MessageResource.meta.identifiers, 'Missing receipt_handle identifier from model') def test_identifiers_in_repr(self): @@ -87,12 +85,33 @@ def test_identifiers_in_repr(self): self.assertIn("'handle'", repr(resource)) def test_factory_creates_dangling_resources(self): + model = { + 'has': { + 'Queue': { + 'resource': { + 'type': 'Queue', + 'identifiers': [ + {'target': 'Url', 'source': 'input'} + ] + } + }, + 'Message': { + 'resource': { + 'type': 'Message', + 'identifiers': [ + {'target': 'QueueUrl', 'source': 'input'}, + {'target': 'Handle', 'source': 'input'} + ] + } + } + } + } defs = { 'Queue': {}, 'Message': {} } - TestResource = self.load('test', 'test', {}, defs, None) + TestResource = self.load('test', 'test', model, defs, None) self.assertTrue(hasattr(TestResource, 'Queue'), 'Missing Queue class from model') @@ -166,112 +185,6 @@ def test_can_instantiate_service_resource(self): self.assertIsInstance(resource, ServiceResource, 'Object is not an instance of ServiceResource') - def test_dangling_resources_create_resource_instance(self): - defs = { - 'Queue': { - 'identifiers': [ - {'name': 'Url'} - ] - } - } - - resource = self.load('test', 'test', {}, defs, None)() - q = resource.Queue('test') - - self.assertIsInstance(q, ServiceResource, - 'Dangling resource instance not a ServiceResource') - - def test_dangling_resource_create_with_kwarg(self): - defs = { - 'Queue': { - 'identifiers': [ - {'name': 'Url'} - ] - } - } - - resource = self.load('test', 'test', {}, defs, None)() - q = resource.Queue(url='test') - - self.assertIsInstance(q, ServiceResource, - 'Dangling resource created with kwargs is not a ServiceResource') - - def test_dangling_resource_shares_client(self): - defs = { - 'Queue': { - 'identifiers': [ - {'name': 'Url'} - ] - } - } - - resource = self.load('test', 'test', {}, defs, None)() - q = resource.Queue('test') - - self.assertEqual(resource.meta['client'], q.meta['client'], - 'Client was not shared to dangling resource instance') - - def test_dangling_resource_requires_identifier(self): - defs = { - 'Queue': { - 'identifiers': [ - {'name': 'Url'} - ] - } - } - - resource = self.load('test', 'test', {}, defs, None)() - - with self.assertRaises(ValueError): - resource.Queue() - - def test_dangling_resource_raises_for_unknown_arg(self): - defs = { - 'Queue': { - 'identifiers': [ - {'name': 'Url'} - ] - } - } - - resource = self.load('test', 'test', {}, defs, None)() - - with self.assertRaises(ValueError): - resource.Queue(url='foo', bar='baz') - - def test_dangling_resource_equality(self): - defs = { - 'Queue': { - 'identifiers': [{'name': 'Url'}] - } - } - - resource = self.load('test', 'test', {}, defs, None)() - - q1 = resource.Queue('url') - q2 = resource.Queue('url') - - self.assertEqual(q1, q2) - - def test_dangling_resource_inequality(self): - defs = { - 'Queue': { - 'identifiers': [{'name': 'Url'}] - }, - 'Message': { - 'identifiers': [{'name': 'QueueUrl'}, {'name': 'Handle'}] - } - } - - resource = self.load('test', 'test', {}, defs, None)() - - q1 = resource.Queue('url') - q2 = resource.Queue('different') - m = resource.Message('url', 'handle') - - self.assertNotEqual(q1, q2) - self.assertNotEqual(q1, m) - def test_non_service_resource_missing_defs(self): # Only services should get dangling defs defs = { @@ -301,9 +214,17 @@ def test_subresource_requires_only_identifier(self): 'identifiers': [ {'name': 'Url'} ], - 'subResources': { - 'resources': ['Message'], - 'identifiers': {'Url': 'QueueUrl'} + 'has': { + 'Message': { + 'resource': { + 'type': 'Message', + 'identifiers': [ + {'target': 'QueueUrl', 'source': 'identifier', + 'name': 'Url'}, + {'target': 'ReceiptHandle', 'source': 'input'} + ] + } + } } }, 'Message': { @@ -337,13 +258,20 @@ def test_resource_meta_unique(self): self.assertEqual(queue1.meta, queue2.meta, 'Queue meta copies not equal after creation') - queue1.meta['data'] = {'id': 'foo'} - queue2.meta['data'] = {'id': 'bar'} + queue1.meta.data = {'id': 'foo'} + queue2.meta.data = {'id': 'bar'} self.assertNotEqual(queue_cls.meta, queue1.meta, 'Modified queue instance data should not modify the class data') self.assertNotEqual(queue1.meta, queue2.meta, 'Queue data should be unique to queue instance') + self.assertNotEqual(queue1.meta, 'bad-value') + + def test_resource_meta_repr(self): + queue_cls = self.load('test', 'Queue', {}, {}, None) + queue = queue_cls() + self.assertEqual(repr(queue.meta), + 'ResourceMeta(\'test\', identifiers=[])') @mock.patch('boto3.resources.factory.ServiceAction') def test_resource_calls_action(self, action_cls): @@ -384,13 +312,13 @@ def test_resource_action_clears_data(self, action_cls): queue = self.load('test', 'Queue', model, {}, None)() # Simulate loaded data - queue.meta['data'] = {'some': 'data'} + queue.meta.data = {'some': 'data'} # Perform a call queue.get_message_status() # Cached data should be cleared - self.assertIsNone(queue.meta['data']) + self.assertIsNone(queue.meta.data) @mock.patch('boto3.resources.factory.ServiceAction') def test_resource_action_leaves_data(self, action_cls): @@ -409,13 +337,13 @@ def test_resource_action_leaves_data(self, action_cls): queue = self.load('test', 'Queue', model, {}, None)() # Simulate loaded data - queue.meta['data'] = {'some': 'data'} + queue.meta.data = {'some': 'data'} # Perform a call queue.get_message_status() # Cached data should not be cleared - self.assertEqual(queue.meta['data'], {'some': 'data'}) + self.assertEqual(queue.meta.data, {'some': 'data'}) @mock.patch('boto3.resources.factory.ServiceAction') def test_resource_lazy_loads_properties(self, action_cls): @@ -455,8 +383,8 @@ def test_resource_lazy_loads_properties(self, action_cls): action.assert_called_once() # Both params should have been loaded into the data bag - self.assertIn('ETag', resource.meta['data']) - self.assertIn('LastModified', resource.meta['data']) + self.assertIn('ETag', resource.meta.data) + self.assertIn('LastModified', resource.meta.data) # Accessing another property should use cached value # instead of making a second call. @@ -495,28 +423,33 @@ def test_resource_loads_references(self): model = { 'shape': 'InstanceShape', 'identifiers': [{'name': 'GroupId'}], - 'belongsTo': { + 'has': { 'Subnet': { 'resource': { 'type': 'Subnet', 'identifiers': [ - {'target': 'Id', 'sourceType': 'dataMember', - 'source': 'SubnetId'} + {'target': 'Id', 'source': 'data', + 'path': 'SubnetId'} + ] + } + }, + 'Vpcs': { + 'resource': { + 'type': 'Vpc', + 'identifiers': [ + {'target': 'Id', 'source': 'data', + 'path': 'Vpcs[].Id'} ] } } } } defs = { - 'Group': { - 'identifiers': [{'name': 'Id'}], - 'subResources': { - 'identifiers': {'Id': 'GroupId'}, - 'resources': ['Instance'] - } - }, 'Subnet': { 'identifiers': [{'name': 'Id'}] + }, + 'Vpc': { + 'identifiers': [{'name': 'Id'}] } } service_model = ServiceModel({ @@ -524,9 +457,6 @@ def test_resource_loads_references(self): 'InstanceShape': { 'type': 'structure', 'members': { - 'GroupId': { - 'shape': 'String' - }, 'SubnetId': { 'shape': 'String' } @@ -542,20 +472,34 @@ def test_resource_loads_references(self): service_model)('group-id') # Load the resource with no data - resource.meta['data'] = {} + resource.meta.data = {} - self.assertTrue(hasattr(resource, 'subnet'), - 'Resource should have a subnet reference') - self.assertIsNone(resource.subnet, - 'Missing identifier, should return None') - self.assertTrue(hasattr(resource, 'group'), - 'Resource should have a group reverse ref') + self.assertTrue( + hasattr(resource, 'subnet'), + 'Resource should have a subnet reference') + self.assertIsNone( + resource.subnet, + 'Missing identifier, should return None') + self.assertIsNone(resource.vpcs) # Load the resource with data to instantiate a reference - resource.meta['data'] = {'SubnetId': 'abc123'} + resource.meta.data = { + 'SubnetId': 'abc123', + 'Vpcs': [ + {'Id': 'vpc1'}, + {'Id': 'vpc2'} + ] + } + self.assertIsInstance(resource.subnet, ServiceResource) self.assertEqual(resource.subnet.id, 'abc123') + vpcs = resource.vpcs + self.assertIsInstance(vpcs, list) + self.assertEqual(len(vpcs), 2) + self.assertEqual(vpcs[0].id, 'vpc1') + self.assertEqual(vpcs[1].id, 'vpc2') + @mock.patch('boto3.resources.model.Collection') def test_resource_loads_collections(self, mock_model): model = { @@ -589,8 +533,8 @@ def test_resource_loads_waiters(self): "Exists": { "waiterName": "BucketExists", "params": [ - {"target": "Bucket", "sourceType": "identifier", - "source": "Name"}] + {"target": "Bucket", "source": "identifier", + "name": "Name"}] } } } @@ -612,8 +556,8 @@ def test_resource_waiter_calls_waiter_method(self, waiter_action_cls): "Exists": { "waiterName": "BucketExists", "params": [ - {"target": "Bucket", "sourceType": "identifier", - "source": "Name"}] + {"target": "Bucket", "source": "identifier", + "name": "Name"}] } } } @@ -628,3 +572,101 @@ def test_resource_waiter_calls_waiter_method(self, waiter_action_cls): resource.wait_until_exists('arg1', arg2=2) waiter_action.assert_called_with(resource, 'arg1', arg2=2) + + +class TestResourceFactoryDanglingResource(TestResourceFactory): + def setUp(self): + super(TestResourceFactoryDanglingResource, self).setUp() + + self.model = { + 'has': { + 'Queue': { + 'resource': { + 'type': 'Queue', + 'identifiers': [ + {'target': 'Url', 'source': 'input'} + ] + } + } + } + } + + self.defs = { + 'Queue': { + 'identifiers': [ + {'name': 'Url'} + ] + } + } + + def test_dangling_resources_create_resource_instance(self): + resource = self.load('test', 'test', self.model, self.defs, None)() + q = resource.Queue('test') + + self.assertIsInstance(q, ServiceResource, + 'Dangling resource instance not a ServiceResource') + + def test_dangling_resource_create_with_kwarg(self): + resource = self.load('test', 'test', self.model, self.defs, None)() + q = resource.Queue(url='test') + + self.assertIsInstance(q, ServiceResource, + 'Dangling resource created with kwargs is not a ServiceResource') + + def test_dangling_resource_shares_client(self): + resource = self.load('test', 'test', self.model, self.defs, None)() + q = resource.Queue('test') + + self.assertEqual(resource.meta.client, q.meta.client, + 'Client was not shared to dangling resource instance') + + def test_dangling_resource_requires_identifier(self): + resource = self.load('test', 'test', self.model, self.defs, None)() + + with self.assertRaises(ValueError): + resource.Queue() + + def test_dangling_resource_raises_for_unknown_arg(self): + resource = self.load('test', 'test', self.model, self.defs, None)() + + with self.assertRaises(ValueError): + resource.Queue(url='foo', bar='baz') + + def test_dangling_resource_equality(self): + resource = self.load('test', 'test', self.model, self.defs, None)() + + q1 = resource.Queue('url') + q2 = resource.Queue('url') + + self.assertEqual(q1, q2) + + def test_dangling_resource_inequality(self): + self.defs = { + 'Queue': { + 'identifiers': [{'name': 'Url'}], + 'has': { + 'Message': { + 'resource': { + 'type': 'Message', + 'identifiers': [ + {'target': 'QueueUrl', 'source': 'identifier', + 'name': 'Url'}, + {'target': 'Handle', 'source': 'input'} + ] + } + } + } + }, + 'Message': { + 'identifiers': [{'name': 'QueueUrl'}, {'name': 'Handle'}] + } + } + + resource = self.load('test', 'test', self.model, self.defs, None)() + + q1 = resource.Queue('url') + q2 = resource.Queue('different') + m = q1.Message('handle') + + self.assertNotEqual(q1, q2) + self.assertNotEqual(q1, m) diff --git a/tests/unit/resources/test_model.py b/tests/unit/resources/test_model.py index d53e103013..f1e9a5e0e9 100644 --- a/tests/unit/resources/test_model.py +++ b/tests/unit/resources/test_model.py @@ -11,8 +11,7 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. -from boto3.resources.model import ResourceModel, Action, SubResourceList,\ - Collection, Waiter +from boto3.resources.model import ResourceModel, Action, Collection, Waiter from tests import BaseTestCase @@ -47,8 +46,8 @@ def test_resource_action_raw(self): 'request': { 'operation': 'GetFrobsOperation', 'params': [ - {'target': 'FrobId', 'sourceType': 'identifier', - 'source': 'Id'} + {'target': 'FrobId', 'source': 'identifier', + 'name': 'Id'} ] }, 'path': 'Container.Frobs[]' @@ -65,8 +64,8 @@ def test_resource_action_raw(self): self.assertIsInstance(action.request.params, list) self.assertEqual(len(action.request.params), 1) self.assertEqual(action.request.params[0].target, 'FrobId') - self.assertEqual(action.request.params[0].source_type, 'identifier') - self.assertEqual(action.request.params[0].source, 'Id') + self.assertEqual(action.request.params[0].source, 'identifier') + self.assertEqual(action.request.params[0].name, 'Id') self.assertEqual(action.path, 'Container.Frobs[]') def test_resource_action_response_resource(self): @@ -127,32 +126,39 @@ def test_resource_batch_action(self): def test_sub_resources(self): model = ResourceModel('test', { - 'subResources': { - 'identifiers': { - 'FrobId': 'Id' - }, - 'resources': ['Frob'] + 'has': { + 'Frob': { + 'resource': { + 'type': 'Frob', + 'identifiers': [ + {'target': 'Id', 'source': 'input'} + ] + } + } } }, { 'Frob': {} }) - self.assertIsInstance(model.sub_resources, SubResourceList) - self.assertEqual(model.sub_resources.identifiers['FrobId'], 'Id') - self.assertEqual(model.sub_resources.resource_names[0], 'Frob') + self.assertIsInstance(model.subresources, list) - resource = model.sub_resources.resources[0] - self.assertEqual(resource.name, 'Frob') + action = model.subresources[0] + resource = action.resource + + self.assertEqual(action.name, 'Frob') + self.assertEqual(resource.identifiers[0].target, 'Id') + self.assertEqual(resource.identifiers[0].source, 'input') + self.assertEqual(resource.type, 'Frob') def test_resource_references(self): model_def = { - 'belongsTo': { + 'has': { 'Frob': { 'resource': { 'type': 'Frob', 'identifiers': [ - {'target':'Id', 'sourceType':'dataMember', - 'source':'FrobId'} + {'target':'Id', 'source':'data', + 'path':'FrobId'} ] } } @@ -170,46 +176,8 @@ def test_resource_references(self): self.assertEqual(ref.name, 'Frob') self.assertEqual(ref.resource.type, 'Frob') self.assertEqual(ref.resource.identifiers[0].target, 'Id') - self.assertEqual(ref.resource.identifiers[0].source_type, - 'dataMember') - self.assertEqual(ref.resource.identifiers[0].source, 'FrobId') - - def test_reverse_reference(self): - # Here the Code resource has no explicit ``hasOne`` defined, however - # by accessing the model's ``reverse_references`` you can see that - # it provides such a relation to Frob based on the Code resource's - # own identifiers (FrobId in this case). - resource_defs = { - 'Frob': { - 'identifiers': [{'name': 'Id'}], - 'subResources': { - 'identifiers': {'FrobId': 'Id'}, - 'resources': ['Code'] - } - }, - 'Code': { - 'identifiers': [ - {'name': 'FrobId'}, - {'name': 'Id'} - ] - } - } - model_def = resource_defs['Code'] - model = ResourceModel('Code', model_def, resource_defs) - - references = model.reverse_references - - self.assertIsInstance(references, list) - self.assertEqual(len(references), 1, - 'Code should have a single reverse ref to Frob') - - ref = references[0] - self.assertEqual(ref.name, 'Frob') - self.assertEqual(ref.resource.type, 'Frob') - self.assertEqual(ref.resource.identifiers[0].target, 'FrobId') - self.assertEqual(ref.resource.identifiers[0].source_type, - 'identifier') - self.assertEqual(ref.resource.identifiers[0].source, 'Id') + self.assertEqual(ref.resource.identifiers[0].source, 'data') + self.assertEqual(ref.resource.identifiers[0].path, 'FrobId') def test_resource_collections(self): model = ResourceModel('test', { diff --git a/tests/unit/resources/test_params.py b/tests/unit/resources/test_params.py index f7774304e8..c0b58a0aa6 100644 --- a/tests/unit/resources/test_params.py +++ b/tests/unit/resources/test_params.py @@ -11,6 +11,8 @@ # ANY KIND, either express or implied. See the License for the specific # language governing permissions and limitations under the License. +from boto3.exceptions import ResourceLoadException +from boto3.resources.base import ResourceMeta, ServiceResource from boto3.resources.model import Request from boto3.resources.params import create_request_parameters, \ build_param_structure @@ -23,8 +25,8 @@ def test_service_action_params_identifier(self): 'params': [ { 'target': 'WarehouseUrl', - 'sourceType': 'identifier', - 'source': 'Url' + 'source': 'identifier', + 'name': 'Url' } ] }) @@ -43,38 +45,87 @@ def test_service_action_params_data_member(self): 'params': [ { 'target': 'WarehouseUrl', - 'sourceType': 'dataMember', - 'source': 'some_member' + 'source': 'data', + 'path': 'SomeMember' } ] }) parent = mock.Mock() - parent.some_member = 'w-url' + parent.meta = ResourceMeta('test', data={ + 'SomeMember': 'w-url' + }) params = create_request_parameters(parent, request_model) self.assertEqual(params['WarehouseUrl'], 'w-url', 'Parameter not set from resource property') + def test_service_action_params_data_member_missing(self): + request_model = Request({ + 'operation': 'GetFrobs', + 'params': [ + { + 'target': 'WarehouseUrl', + 'source': 'data', + 'path': 'SomeMember' + } + ] + }) + + parent = mock.Mock() + + def load_data(): + parent.meta.data = { + 'SomeMember': 'w-url' + } + + parent.load.side_effect = load_data + parent.meta = ResourceMeta('test') + + params = create_request_parameters(parent, request_model) + + parent.load.assert_called_with() + self.assertEqual(params['WarehouseUrl'], 'w-url', + 'Parameter not set from resource property') + + def test_service_action_params_data_member_missing_no_load(self): + request_model = Request({ + 'operation': 'GetFrobs', + 'params': [ + { + 'target': 'WarehouseUrl', + 'source': 'data', + 'path': 'SomeMember' + } + ] + }) + + # This mock has no ``load`` method. + parent = mock.Mock(spec=ServiceResource) + parent.meta = ResourceMeta('test', data=None) + + with self.assertRaises(ResourceLoadException): + params = create_request_parameters(parent, request_model) + def test_service_action_params_constants(self): request_model = Request({ 'operation': 'GetFrobs', 'params': [ { 'target': 'Param1', - 'sourceType': 'string', - 'source': 'param1' + 'source': 'string', + 'value': 'param1' }, { 'target': 'Param2', - 'sourceType': 'integer', - 'source': 123 + 'source': 'integer', + 'value': 123 }, { 'target': 'Param3', - 'sourceType': 'boolean', - 'source': True + 'source': 'boolean', + 'value': True } ] }) @@ -88,14 +139,28 @@ def test_service_action_params_constants(self): self.assertEqual(params['Param3'], True, 'Parameter not set from boolean constant') + def test_service_action_params_input(self): + request_model = Request({ + 'operation': 'GetFrobs', + 'params': [ + {'target': 'Param1', 'source': 'input'} + ] + }) + + params = create_request_parameters(None, request_model) + self.assertEqual(params, {}) + + params['param1'] = 'myinput' + params = create_request_parameters(None, request_model, params=params) + self.assertEqual(params, {'param1': 'myinput'}) + def test_service_action_params_invalid(self): request_model = Request({ 'operation': 'GetFrobs', 'params': [ { 'target': 'Param1', - 'sourceType': 'invalid', - 'source': 'param1' + 'source': 'invalid' } ] }) @@ -109,8 +174,8 @@ def test_service_action_params_list(self): 'params': [ { 'target': 'WarehouseUrls[0]', - 'sourceType': 'string', - 'source': 'w-url' + 'source': 'string', + 'value': 'w-url' } ] }) @@ -130,17 +195,21 @@ def test_service_action_params_reuse(self): 'params': [ { 'target': 'Delete.Objects[].Key', - 'sourceType': 'dataMember', - 'source': 'Key' + 'source': 'data', + 'path': 'Key' } ] }) item1 = mock.Mock() - item1.key = 'item1' + item1.meta = ResourceMeta('test', data={ + 'Key': 'item1' + }) item2 = mock.Mock() - item2.key = 'item2' + item2.meta = ResourceMeta('test', data={ + 'Key': 'item2' + }) # Here we create params and then re-use it to build up a more # complex structure over multiple calls. diff --git a/tests/unit/resources/test_response.py b/tests/unit/resources/test_response.py index 369b6a36fd..94801d039a 100644 --- a/tests/unit/resources/test_response.py +++ b/tests/unit/resources/test_response.py @@ -12,7 +12,7 @@ # language governing permissions and limitations under the License. from tests import BaseTestCase, mock -from boto3.resources.base import ServiceResource +from boto3.resources.base import ResourceMeta, ServiceResource from boto3.resources.model import ResponseResource, Parameter from boto3.resources.factory import ResourceFactory from boto3.resources.response import build_identifiers, build_empty_response,\ @@ -21,8 +21,8 @@ class TestBuildIdentifiers(BaseTestCase): def test_build_identifier_from_res_path_scalar(self): - identifiers = [Parameter(target='Id', source_type='responsePath', - source='Container.Frob.Id')] + identifiers = [Parameter(target='Id', source='response', + path='Container.Frob.Id')] parent = mock.Mock() params = {} @@ -36,12 +36,12 @@ def test_build_identifier_from_res_path_scalar(self): values = build_identifiers(identifiers, parent, params, response) - self.assertEqual(values['id'], 'response-path', + self.assertEqual(values[0][1], 'response-path', 'Identifier loaded from responsePath scalar not set') def test_build_identifier_from_res_path_list(self): - identifiers = [Parameter(target='Id', source_type='responsePath', - source='Container.Frobs[].Id')] + identifiers = [Parameter(target='Id', source='response', + path='Container.Frobs[].Id')] parent = mock.Mock() params = {} @@ -57,12 +57,12 @@ def test_build_identifier_from_res_path_list(self): values = build_identifiers(identifiers, parent, params, response) - self.assertEqual(values['id'], ['response-path'], + self.assertEqual(values[0][1], ['response-path'], 'Identifier loaded from responsePath list not set') def test_build_identifier_from_parent_identifier(self): - identifiers = [Parameter(target='Id', source_type='identifier', - source='Id')] + identifiers = [Parameter(target='Id', source='identifier', + name='Id')] parent = mock.Mock() parent.id = 'identifier' @@ -75,15 +75,17 @@ def test_build_identifier_from_parent_identifier(self): values = build_identifiers(identifiers, parent, params, response) - self.assertEqual(values['id'], 'identifier', + self.assertEqual(values[0][1], 'identifier', 'Identifier loaded from parent identifier not set') def test_build_identifier_from_parent_data_member(self): - identifiers = [Parameter(target='Id', source_type='dataMember', - source='Member')] + identifiers = [Parameter(target='Id', source='data', + path='Member')] parent = mock.Mock() - parent.member = 'data-member' + parent.meta = ResourceMeta('test', data={ + 'Member': 'data-member' + }) params = {} response = { 'Container': { @@ -93,12 +95,12 @@ def test_build_identifier_from_parent_data_member(self): values = build_identifiers(identifiers, parent, params, response) - self.assertEqual(values['id'], 'data-member', + self.assertEqual(values[0][1], 'data-member', 'Identifier loaded from parent data member not set') def test_build_identifier_from_req_param(self): - identifiers = [Parameter(target='Id', source_type='requestParameter', - source='Param')] + identifiers = [Parameter(target='Id', source='requestParameter', + path='Param')] parent = mock.Mock() params = { @@ -112,12 +114,11 @@ def test_build_identifier_from_req_param(self): values = build_identifiers(identifiers, parent, params, response) - self.assertEqual(values['id'], 'request-param', + self.assertEqual(values[0][1], 'request-param', 'Identifier loaded from request parameter not set') def test_build_identifier_from_invalid_source_type(self): - identifiers = [Parameter(target='Id', source_type='invalid', - source='abc')] + identifiers = [Parameter(target='Id', source='invalid')] parent = mock.Mock() params = {} @@ -295,7 +296,7 @@ def test_raw_handler_response_path(self): class TestResourceHandler(BaseTestCase): def setUp(self): super(TestResourceHandler, self).setUp() - self.identifier_source = '' + self.identifier_path = '' self.factory = ResourceFactory() self.resource_defs = { 'Frob': { @@ -327,18 +328,15 @@ def setUp(self): self.service_model.operation_model.return_value = operation_model self.parent = mock.Mock() - self.parent.meta = { - 'service_name': 'test', - 'client': mock.Mock(), - } + self.parent.meta = ResourceMeta('test', client=mock.Mock()) self.params = {} def get_resource(self, search_path, response): request_resource_def = { 'type': 'Frob', 'identifiers': [ - {'target': 'Id', 'sourceType': 'responsePath', - 'source': self.identifier_source}, + {'target': 'Id', 'source': 'response', + 'path': self.identifier_path}, ] } resource_model = ResponseResource( @@ -350,7 +348,7 @@ def get_resource(self, search_path, response): return handler(self.parent, self.params, response) def test_create_resource_scalar(self): - self.identifier_source = 'Container.Id' + self.identifier_path = 'Container.Id' search_path = 'Container' response = { 'Container': { @@ -365,7 +363,7 @@ def test_create_resource_scalar(self): @mock.patch('boto3.resources.response.build_empty_response') def test_missing_data_scalar_builds_empty_response(self, build_mock): - self.identifier_source = 'Container.Id' + self.identifier_path = 'Container.Id' search_path = 'Container' response = { 'something': 'irrelevant' @@ -379,7 +377,7 @@ def test_missing_data_scalar_builds_empty_response(self, build_mock): 'build_empty_response return value was not returned') def test_create_resource_list(self): - self.identifier_source = 'Container.Frobs[].Id' + self.identifier_path = 'Container.Frobs[].Id' search_path = 'Container.Frobs[]' response = { 'Container': { @@ -406,7 +404,7 @@ def test_create_resource_list(self): 'List items are not resource instances') def test_create_resource_list_no_search_path(self): - self.identifier_source = '[].Id' + self.identifier_path = '[].Id' search_path = '' response = [ { @@ -426,7 +424,7 @@ def test_create_resource_list_no_search_path(self): @mock.patch('boto3.resources.response.build_empty_response') def test_missing_data_list_builds_empty_response(self, build_mock): - self.identifier_source = 'Container.Frobs[].Id' + self.identifier_path = 'Container.Frobs[].Id' search_path = 'Container.Frobs[]' response = { 'something': 'irrelevant'