Admin workflow - IAM PERMISSIONS md, utils module etc. (#1323)
* IAM PERMISSIONS md, utils module etc. * IAM PERMISSIONS md, utils module etc. * IAM PERMISSIONS md, utils module etc. * IAM PERMISSIONS md, utils module etc. * IAM PERMISSIONS md, utils module etc. * IAM PERMISSIONS md, utils module etc. * IAM PERMISSIONS md, utils module etc.
This commit is contained in:
+266
@@ -0,0 +1,266 @@
|
|||||||
|
# IAM Permissions for Admin Approval Workflow sample
|
||||||
|
|
||||||
|
Create IAM user or role with the following permissions.
|
||||||
|
|
||||||
|
> **Before using these policies**, replace every occurrence of `YOUR_ACCOUNT_ID` with your 12-digit AWS account ID.
|
||||||
|
> Run the following command to find it:
|
||||||
|
> ```bash
|
||||||
|
> aws sts get-caller-identity --query Account --output text
|
||||||
|
> ```
|
||||||
|
> Then do a find-and-replace of `YOUR_ACCOUNT_ID` in the JSON below before attaching the policy.
|
||||||
|
|
||||||
|
## Policy for AWS Agent Registry access (Administrator)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Sid": "AllowCreatingAndListingRegistries",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"bedrock-agentcore:CreateRegistry",
|
||||||
|
"bedrock-agentcore:ListRegistries"
|
||||||
|
],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AllowGetUpdateDeleteRegistry",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"bedrock-agentcore:GetRegistry",
|
||||||
|
"bedrock-agentcore:UpdateRegistry",
|
||||||
|
"bedrock-agentcore:DeleteRegistry"
|
||||||
|
],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:registry/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AllowCreatingAndListingRegistryRecords",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"bedrock-agentcore:CreateRegistryRecord",
|
||||||
|
"bedrock-agentcore:ListRegistryRecords"
|
||||||
|
],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:registry/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AllowRecordLevelOperations",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"bedrock-agentcore:GetRegistryRecord",
|
||||||
|
"bedrock-agentcore:UpdateRegistryRecord",
|
||||||
|
"bedrock-agentcore:DeleteRegistryRecord",
|
||||||
|
"bedrock-agentcore:SubmitRegistryRecordForApproval"
|
||||||
|
],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:registry/*/record/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AllowApproveRejectDeprecateRecords",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["bedrock-agentcore:UpdateRegistryRecordStatus"],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:registry/*/record/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AdditionalPermissionForRegistryManagedWorkloadIdentity",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["bedrock-agentcore:*WorkloadIdentity"],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:workload-identity-directory/default/workload-identity/*"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Policy for AWS Agent Registry access (Publisher)
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Sid": "AllowListingAllRegistries",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["bedrock-agentcore:ListRegistries"],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AllowGetRegistry",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["bedrock-agentcore:GetRegistry"],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:registry/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AllowCreatingAndListingRegistryRecords",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"bedrock-agentcore:CreateRegistryRecord",
|
||||||
|
"bedrock-agentcore:ListRegistryRecords"
|
||||||
|
],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:registry/*"]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "AllowRecordLevelOperations",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"bedrock-agentcore:GetRegistryRecord",
|
||||||
|
"bedrock-agentcore:UpdateRegistryRecord",
|
||||||
|
"bedrock-agentcore:DeleteRegistryRecord",
|
||||||
|
"bedrock-agentcore:SubmitRegistryRecordForApproval"
|
||||||
|
],
|
||||||
|
"Resource": ["arn:aws:bedrock-agentcore:*:YOUR_ACCOUNT_ID:registry/*/record/*"]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
## Permissions Required to deploy the required CI/CD stack such as DynamoDB and AWS Lambda etc.
|
||||||
|
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"Version": "2012-10-17",
|
||||||
|
"Statement": [
|
||||||
|
{
|
||||||
|
"Sid": "STSCallerIdentity",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["sts:GetCallerIdentity"],
|
||||||
|
"Resource": "*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "CloudFormationValidate",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["cloudformation:ValidateTemplate"],
|
||||||
|
"Resource": "*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "CloudFormationStackManagement",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"cloudformation:CreateStack",
|
||||||
|
"cloudformation:UpdateStack",
|
||||||
|
"cloudformation:DeleteStack",
|
||||||
|
"cloudformation:DescribeStacks",
|
||||||
|
"cloudformation:DescribeStackEvents",
|
||||||
|
"cloudformation:DescribeStackResources",
|
||||||
|
"cloudformation:GetTemplate",
|
||||||
|
"cloudformation:ListStackResources",
|
||||||
|
"cloudformation:CreateChangeSet",
|
||||||
|
"cloudformation:DescribeChangeSet",
|
||||||
|
"cloudformation:ExecuteChangeSet",
|
||||||
|
"cloudformation:DeleteChangeSet"
|
||||||
|
],
|
||||||
|
"Resource": "arn:aws:cloudformation:*:YOUR_ACCOUNT_ID:stack/*/*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "S3StagingBucketManagement",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"s3:CreateBucket",
|
||||||
|
"s3:DeleteBucket",
|
||||||
|
"s3:HeadBucket",
|
||||||
|
"s3:PutBucketPublicAccessBlock",
|
||||||
|
"s3:GetBucketPublicAccessBlock",
|
||||||
|
"s3:ListBucket",
|
||||||
|
"s3:DeleteObject",
|
||||||
|
"s3:PutObject",
|
||||||
|
"s3:GetObject"
|
||||||
|
],
|
||||||
|
"Resource": [
|
||||||
|
"arn:aws:s3:::*",
|
||||||
|
"arn:aws:s3:::*/*"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "LambdaFunctionManagement",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"lambda:CreateFunction",
|
||||||
|
"lambda:UpdateFunctionCode",
|
||||||
|
"lambda:UpdateFunctionConfiguration",
|
||||||
|
"lambda:DeleteFunction",
|
||||||
|
"lambda:GetFunction",
|
||||||
|
"lambda:GetFunctionConfiguration",
|
||||||
|
"lambda:AddPermission",
|
||||||
|
"lambda:RemovePermission"
|
||||||
|
],
|
||||||
|
"Resource": "arn:aws:lambda:*:YOUR_ACCOUNT_ID:function:*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "LambdaLayerManagement",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"lambda:PublishLayerVersion",
|
||||||
|
"lambda:DeleteLayerVersion",
|
||||||
|
"lambda:GetLayerVersion",
|
||||||
|
"lambda:ListLayerVersions"
|
||||||
|
],
|
||||||
|
"Resource": "arn:aws:lambda:*:YOUR_ACCOUNT_ID:layer:*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "IAMRoleManagement",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"iam:CreateRole",
|
||||||
|
"iam:DeleteRole",
|
||||||
|
"iam:GetRole",
|
||||||
|
"iam:PassRole",
|
||||||
|
"iam:AttachRolePolicy",
|
||||||
|
"iam:DetachRolePolicy",
|
||||||
|
"iam:PutRolePolicy",
|
||||||
|
"iam:DeleteRolePolicy",
|
||||||
|
"iam:GetRolePolicy",
|
||||||
|
"iam:ListRolePolicies",
|
||||||
|
"iam:ListAttachedRolePolicies"
|
||||||
|
],
|
||||||
|
"Resource": "arn:aws:iam::YOUR_ACCOUNT_ID:role/*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "KMSCreateKey",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": ["kms:CreateKey"],
|
||||||
|
"Resource": "*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "KMSManageTaggedKeys",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"kms:DescribeKey",
|
||||||
|
"kms:EnableKeyRotation",
|
||||||
|
"kms:GetKeyPolicy",
|
||||||
|
"kms:PutKeyPolicy",
|
||||||
|
"kms:ScheduleKeyDeletion",
|
||||||
|
"kms:CancelKeyDeletion",
|
||||||
|
"kms:TagResource",
|
||||||
|
"kms:UntagResource"
|
||||||
|
],
|
||||||
|
"Resource": "*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "DynamoDBTableManagement",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"dynamodb:CreateTable",
|
||||||
|
"dynamodb:DeleteTable",
|
||||||
|
"dynamodb:DescribeTable",
|
||||||
|
"dynamodb:UpdateTable",
|
||||||
|
"dynamodb:DescribeContinuousBackups",
|
||||||
|
"dynamodb:DescribeTimeToLive"
|
||||||
|
],
|
||||||
|
"Resource": "arn:aws:dynamodb:*:YOUR_ACCOUNT_ID:table/*"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Sid": "EventBridgeManagement",
|
||||||
|
"Effect": "Allow",
|
||||||
|
"Action": [
|
||||||
|
"events:PutRule",
|
||||||
|
"events:DeleteRule",
|
||||||
|
"events:DescribeRule",
|
||||||
|
"events:PutTargets",
|
||||||
|
"events:RemoveTargets",
|
||||||
|
"events:ListTargetsByRule"
|
||||||
|
],
|
||||||
|
"Resource": "arn:aws:events:*:YOUR_ACCOUNT_ID:rule/*"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
@@ -67,7 +67,7 @@ As an Administrator, you can use the **AWS CLI** commands included in the notifi
|
|||||||
|
|
||||||
## Prerequisites
|
## Prerequisites
|
||||||
|
|
||||||
- IAM credentials with appropriate permissions (see [`IAM_PERMISSIONS.md`](../../IAM_PERMISSIONS.md)). This tutorial requires both admin and publisher permissions. In addition, the following permissions are required to deploy and destroy the CI/CD stack:
|
- IAM credentials with appropriate permissions (see [`IAM_PERMISSIONS.md`](./IAM_PERMISSIONS.md)). In addition to Agent Registry related operations, the following permissions are being used:
|
||||||
|
|
||||||
| Service | Permissions |
|
| Service | Permissions |
|
||||||
|:--------|:------------|
|
|:--------|:------------|
|
||||||
|
|||||||
+19
-61
@@ -59,17 +59,19 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"source": [
|
"source": [
|
||||||
"## Prerequisites\n",
|
"## Prerequisites\n",
|
||||||
"- IAM credentials with appropriate permissions (see [`IAM_PERMISSIONS.md`](../../IAM_PERMISSIONS.md)). This tutorial requires both admin and publisher permissions. In addition, the following permissions are required to deploy and destroy the CI/CD stack:\n",
|
"- IAM credentials with appropriate permissions (see [`IAM_PERMISSIONS.md`](./IAM_PERMISSIONS.md)). In addition to Agent Registry related operations, the following permissions are being used:\n",
|
||||||
"\n",
|
"\n",
|
||||||
" | Service | Permissions |\n",
|
"| Service | Permissions |\n",
|
||||||
" |:--------|:------------|\n",
|
"|:--------|:------------|\n",
|
||||||
" | **Amazon S3** | `CreateBucket`, `HeadBucket`, `PutPublicAccessBlock`, `DeleteBucket`, `ListBucket`, `PutObject`, `GetObject`, `DeleteObject` |\n",
|
"| **Amazon S3** | `CreateBucket`, `HeadBucket`, `PutPublicAccessBlock`, `DeleteBucket`, `ListBucket`, `PutObject`, `GetObject`, `DeleteObject` |\n",
|
||||||
" | **AWS CloudFormation** | `CreateStack`, `UpdateStack`, `DeleteStack`, `DescribeStacks`, `CreateChangeSet`, `ExecuteChangeSet`, `DescribeChangeSet`, `DeleteChangeSet` |\n",
|
"| **AWS CloudFormation** | `CreateStack`, `UpdateStack`, `DeleteStack`, `DescribeStacks`, `CreateChangeSet`, `ExecuteChangeSet`, `DescribeChangeSet`, `DeleteChangeSet` |\n",
|
||||||
" | **AWS Lambda** | `CreateFunction`, `UpdateFunctionCode`, `UpdateFunctionConfiguration`, `GetFunction`, `DeleteFunction`, `PublishLayerVersion`, `DeleteLayerVersion`, `AddPermission`, `RemovePermission` |\n",
|
"| **AWS Lambda** | `CreateFunction`, `UpdateFunctionCode`, `UpdateFunctionConfiguration`, `GetFunction`, `DeleteFunction`, `PublishLayerVersion`, `DeleteLayerVersion`, `AddPermission`, `RemovePermission` |\n",
|
||||||
" | **AWS IAM** | `CreateRole`, `GetRole`, `DeleteRole`, `PassRole`, `AttachRolePolicy`, `DetachRolePolicy`, `PutRolePolicy`, `DeleteRolePolicy` |\n",
|
"| **AWS IAM** | `CreateRole`, `GetRole`, `DeleteRole`, `PassRole`, `AttachRolePolicy`, `DetachRolePolicy`, `PutRolePolicy`, `DeleteRolePolicy` |\n",
|
||||||
" | **AWS EventBridge** | `PutRule`, `DescribeRule`, `DeleteRule`, `PutTargets`, `RemoveTargets` |\n",
|
"| **AWS EventBridge** | `PutRule`, `DescribeRule`, `DeleteRule`, `PutTargets`, `RemoveTargets` |\n",
|
||||||
" | **Amazon DynamoDB** | `CreateTable`, `DeleteTable`, `DescribeTable` |\n",
|
"| **Amazon DynamoDB** | `CreateTable`, `DeleteTable`, `DescribeTable` |\n",
|
||||||
" | **AWS CloudWatch Logs** | `CreateLogGroup`, `CreateLogStream`, `PutLogEvents`, `DeleteLogGroup` |- Python 3.9+ with `boto3` installed\n",
|
"| **AWS CloudWatch Logs** | `CreateLogGroup`, `CreateLogStream`, `PutLogEvents`, `DeleteLogGroup` |\n",
|
||||||
|
"\n",
|
||||||
|
"- Python 3.9+ with `boto3` installed\n",
|
||||||
"\n",
|
"\n",
|
||||||
"- [uv](https://docs.astral.sh/uv/getting-started/installation/) package manager (for installing python dependencies)\n",
|
"- [uv](https://docs.astral.sh/uv/getting-started/installation/) package manager (for installing python dependencies)\n",
|
||||||
"- A Slack workspace with an [incoming webhook](https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks/) configured. Note down the webhook URL and channel name.\n",
|
"- A Slack workspace with an [incoming webhook](https://docs.slack.dev/messaging/sending-messages-using-incoming-webhooks/) configured. Note down the webhook URL and channel name.\n",
|
||||||
@@ -98,6 +100,8 @@
|
|||||||
"import subprocess\n",
|
"import subprocess\n",
|
||||||
"import botocore.exceptions\n",
|
"import botocore.exceptions\n",
|
||||||
"import time\n",
|
"import time\n",
|
||||||
|
"import os\n",
|
||||||
|
"from utils import wait_for_registry_ready, wait_for_record_draft\n",
|
||||||
"\n",
|
"\n",
|
||||||
"print(f\"Boto3 version: {boto3.__version__}\")\n",
|
"print(f\"Boto3 version: {boto3.__version__}\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -159,19 +163,8 @@
|
|||||||
"metadata": {},
|
"metadata": {},
|
||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"#wait for registry to get to Ready status (takes around ~2 minutes)\n",
|
"# wait for registry to get to Ready status (takes around ~2 minutes)\n",
|
||||||
"registryStatus = 'Checking'\n",
|
"wait_for_registry_ready(cp_client, REGISTRY_ID)"
|
||||||
"while registryStatus.lower() != 'ready':\n",
|
|
||||||
" getRegistry = cp_client.get_registry(registryId=REGISTRY_ID)\n",
|
|
||||||
"\n",
|
|
||||||
" registryStatus = getRegistry['status']\n",
|
|
||||||
"\n",
|
|
||||||
" if registryStatus.lower() == 'ready':\n",
|
|
||||||
" print(\"Verified: Registry is in Ready state\")\n",
|
|
||||||
" else:\n",
|
|
||||||
" print(f\"Registry is in {registryStatus} state. Waiting for it to be in Ready state\")\n",
|
|
||||||
"\n",
|
|
||||||
" time.sleep(10)"
|
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@@ -307,19 +300,8 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Wait for the record to be in Draft state\n",
|
"# Wait for the record to be in Draft state\n",
|
||||||
"recordStatus = 'Checking'\n",
|
"wait_for_record_draft(cp_client, REGISTRY_ID, A2A_RECORD_ID)\n",
|
||||||
"while recordStatus.lower() != 'draft':\n",
|
|
||||||
" getRegistryRecord = cp_client.get_registry_record(registryId=REGISTRY_ID, recordId=A2A_RECORD_ID)\n",
|
|
||||||
" recordStatus = getRegistryRecord['status']\n",
|
|
||||||
" metadata = getRegistryRecord.get(\"ResponseMetadata\", {})\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
" if recordStatus.lower() == 'draft':\n",
|
|
||||||
" print(\"Verified: Registry record is in Draft state. Ready to be submitted for Approval\")\n",
|
|
||||||
" print(f\"Metadata | RequestId: {metadata['HTTPHeaders']['x-amzn-requestid']}, Timestamp: {metadata['HTTPHeaders']['date']}\")\n",
|
|
||||||
" else:\n",
|
|
||||||
" print(f\"Registry record is in {recordStatus} state. Waiting for it to be in Draft state\")\n",
|
|
||||||
"\n",
|
|
||||||
" time.sleep(2)\n",
|
|
||||||
"submit_resp = cp_client.submit_registry_record_for_approval(registryId=REGISTRY_ID, recordId=A2A_RECORD_ID)\n",
|
"submit_resp = cp_client.submit_registry_record_for_approval(registryId=REGISTRY_ID, recordId=A2A_RECORD_ID)\n",
|
||||||
"print(\"Record submitted for approval\")\n",
|
"print(\"Record submitted for approval\")\n",
|
||||||
"\n",
|
"\n",
|
||||||
@@ -381,19 +363,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Wait for the record to be in Draft state\n",
|
"# Wait for the record to be in Draft state\n",
|
||||||
"recordStatus = 'Checking'\n",
|
"wait_for_record_draft(cp_client, REGISTRY_ID, MCP_RECORD_ID)\n",
|
||||||
"while recordStatus.lower() != 'draft':\n",
|
|
||||||
" getRegistryRecord = cp_client.get_registry_record(registryId=REGISTRY_ID, recordId=MCP_RECORD_ID)\n",
|
|
||||||
" recordStatus = getRegistryRecord['status']\n",
|
|
||||||
" metadata = getRegistryRecord.get(\"ResponseMetadata\", {})\n",
|
|
||||||
"\n",
|
|
||||||
" if recordStatus.lower() == 'draft':\n",
|
|
||||||
" print(\"Verified: Registry record is in Draft state. Ready to be submitted for Approval\")\n",
|
|
||||||
" print(f\"RequestId: {metadata['HTTPHeaders']['x-amzn-requestid']}, Timestamp: {metadata['HTTPHeaders']['date']}\")\n",
|
|
||||||
" else:\n",
|
|
||||||
" print(f\"Registry record is in {recordStatus} state. Waiting for it to be in Draft state\")\n",
|
|
||||||
"\n",
|
|
||||||
" time.sleep(2)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"#Submit for approval\n",
|
"#Submit for approval\n",
|
||||||
"submit_resp = cp_client.submit_registry_record_for_approval(registryId=REGISTRY_ID, recordId=MCP_RECORD_ID)\n",
|
"submit_resp = cp_client.submit_registry_record_for_approval(registryId=REGISTRY_ID, recordId=MCP_RECORD_ID)\n",
|
||||||
@@ -448,19 +418,7 @@
|
|||||||
"outputs": [],
|
"outputs": [],
|
||||||
"source": [
|
"source": [
|
||||||
"# Wait for the record to be in Draft state\n",
|
"# Wait for the record to be in Draft state\n",
|
||||||
"recordStatus = 'Checking'\n",
|
"wait_for_record_draft(cp_client, REGISTRY_ID, CUSTOM_RECORD_ID)\n",
|
||||||
"while recordStatus.lower() != 'draft':\n",
|
|
||||||
" getRegistryRecord = cp_client.get_registry_record(registryId=REGISTRY_ID, recordId=CUSTOM_RECORD_ID)\n",
|
|
||||||
" recordStatus = getRegistryRecord['status']\n",
|
|
||||||
" metadata = getRegistryRecord.get(\"ResponseMetadata\", {})\n",
|
|
||||||
"\n",
|
|
||||||
" if recordStatus.lower() == 'draft':\n",
|
|
||||||
" print(\"Verified: Registry record is in Draft state. Ready to be submitted for Approval\")\n",
|
|
||||||
" print(f\"RequestId: {metadata['HTTPHeaders']['x-amzn-requestid']}, Timestamp: {metadata['HTTPHeaders']['date']}\")\n",
|
|
||||||
" else:\n",
|
|
||||||
" print(f\"Registry record is in {recordStatus} state. Waiting for it to be in Draft state\")\n",
|
|
||||||
"\n",
|
|
||||||
" time.sleep(2)\n",
|
|
||||||
"\n",
|
"\n",
|
||||||
"#Submit for approval\n",
|
"#Submit for approval\n",
|
||||||
"submit_resp = cp_client.submit_registry_record_for_approval(registryId=REGISTRY_ID, recordId=CUSTOM_RECORD_ID)\n",
|
"submit_resp = cp_client.submit_registry_record_for_approval(registryId=REGISTRY_ID, recordId=CUSTOM_RECORD_ID)\n",
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
"""Utility helpers for Agent Registry polling operations."""
|
||||||
|
|
||||||
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
def wait_for_registry_ready(cp_client, registry_id, poll_interval=10):
|
||||||
|
"""Poll until the registry reaches READY status."""
|
||||||
|
status = "Checking"
|
||||||
|
while status.lower() != "ready":
|
||||||
|
resp = cp_client.get_registry(registryId=registry_id)
|
||||||
|
status = resp["status"]
|
||||||
|
if status.lower() == "ready":
|
||||||
|
print("Verified: Registry is in Ready state")
|
||||||
|
else:
|
||||||
|
print(f"Registry is in {status} state. Waiting for it to be in Ready state")
|
||||||
|
time.sleep(poll_interval)
|
||||||
|
|
||||||
|
|
||||||
|
def wait_for_record_draft(cp_client, registry_id, record_id, poll_interval=2):
|
||||||
|
"""Poll until the registry record reaches DRAFT status."""
|
||||||
|
status = "Checking"
|
||||||
|
while status.lower() != "draft":
|
||||||
|
resp = cp_client.get_registry_record(registryId=registry_id, recordId=record_id)
|
||||||
|
status = resp["status"]
|
||||||
|
metadata = resp.get("ResponseMetadata", {})
|
||||||
|
if status.lower() == "draft":
|
||||||
|
print(
|
||||||
|
"Verified: Registry record is in Draft state. "
|
||||||
|
"Ready to be submitted for Approval"
|
||||||
|
)
|
||||||
|
headers = metadata.get("HTTPHeaders", {})
|
||||||
|
request_id = headers.get("x-amzn-requestid", "")
|
||||||
|
date = headers.get("date", "")
|
||||||
|
print(f"RequestId: {request_id}, Timestamp: {date}")
|
||||||
|
else:
|
||||||
|
print(
|
||||||
|
f"Registry record is in {status} state. "
|
||||||
|
"Waiting for it to be in Draft state"
|
||||||
|
)
|
||||||
|
time.sleep(poll_interval)
|
||||||
Reference in New Issue
Block a user