CloudCustodian sends 0 value to cloudwatch - cloudcustodian

I am trying to send metrics to CloudWatch using put-metrics action, but It's sends 0 every time (but there are resources which are not compliant). Policy example:
vars:
common-filters: &default-filters
- "tag.team_name": absent
- "tag.product_name": absent
- "tag.application_name": absent
- "tag.service_name": absent
- "tag.group": absent
default-mode: &default-mode
type: pull
# type: periodic
# schedule: "cron(0 */12 * * ? *)"
policies:
- name: tags-rds
resource: aws.rds
mode: *default-mode
filters:
- and: *default-filters
actions:
- type: put-metric
key: DBClusters[].DBClusterIdentifier
namespace: CloudCustodian
metric_name: RDSTaggingCompliance
op: count
units: Count
But If we will check CloudWatch, It shows 0:
From the permission side all is ok and cloudcustodian finished successfully. Does anybody know what's wrong with that?

Related

GCP API Gateway: Path parameters are being passed as query params

I'm trying to use GCP API Gateway to create a single endpoint for a couple of my backend services (A,B,C,D), each with their own path structure. I have the Gateway configured for one of the services as follows:
swagger: '2.0'
info:
title: <TITLE>
description: <DESC>
version: 1.0.0
schemes:
- https
produces:
- application/json
paths:
/service_a/match/{id_}:
get:
summary: <SUMMARY>
description: <DESC>
operationId: match_id_
parameters:
- required: true
type: string
name: id_
in: path
- required: true
type: boolean
default: false
name: bool_first
in: query
- required: false
type: boolean
default: false
name: bool_Second
in: query
x-google-backend:
address: <cloud_run_url>/match/{id_}
deadline: 60.0
responses:
'200':
description: Successful Response
'422':
description: Validation
This deploys just fine. But when I hit the endpoint gateway_url/service_a/match/123, it gets routed to cloud_run_url/match/%7Bid_%7D?id_=123 instead of cloud_run_url/match/123.
How can I fix this?
Editing my answer as I misunderstood the issue.
It seems like the { are getting leaked from your configuration as ASCII code, so when you call
x-google-backend:
address: <cloud_run_url>/match/{id_}
deadline: 60.0
it doesn't show the correct ID.
So this should be a leak issue from your yaml file and you can approach this the same way as in this thread about using path params

How can I declare the response array type for OpenAPI definition with JAX-RS?

I'm building a REST service with JAX-RS, Microprofile and Payara 5. My method returns an object of type Response. The response itself contains a List of MyClass. The implementation looks like this:
import org.eclipse.microprofile.openapi.annotations.enums.SchemaType;
import org.eclipse.microprofile.openapi.annotations.media.Content;
import org.eclipse.microprofile.openapi.annotations.media.Schema;
import org.eclipse.microprofile.openapi.annotations.responses.APIResponse;
#GET
#Path("/{a}/{b}/{c}")
#APIResponse(content = #Content(schema = #Schema(type = SchemaType.ARRAY, implementation = MyClass.class)))
public Response getMyClass(#PathParam("a") String a,
#PathParam("b") String b,
#PathParam("c") String c) {
return Response
.ok()
.entity(new ArrayList<>())
.build();
}
The generated OpenAPI definition looks like this:
/api/translations/{a}/{b}/{c}:
get:
operationId: getMyClass
parameters:
- name: a
in: path
required: true
style: simple
schema:
type: string
- [...]
responses:
default:
description: Default Response.
content:
'*/*':
schema:
type: array
items: {}
As you can see, the definition of MyClass.class is missing in the response type. How can I add that type to the definition? Is the #ApiResponse annotation the correct way to achieve this?
I tested this today with the newest payara 5.191 and it did not worked for me too.
It seems that there is a bug in the current payara implementation, because I checked the example on this page guide-microprofile-openapi
The same implementation has 2 different openapi generations (Payara and OpenLiberty)
Payara:
openapi: 3.0.0
info:
title: Deployed Resources
version: 1.0.0
servers:
- url: https://10.0.0.72:8080/ipma
description: Default Server.
paths:
/resources/server:
get:
summary: List servers.
description: 'Returns all servers '
operationId: getServers
responses:
default:
description: Special description
content:
application/json:
schema:
type: array
/resources/server/{id}:
get:
summary: get server by id.
description: 'return one server with the specified id'
operationId: getServerById
parameters:
- name: id
in: query
style: simple
schema:
type: number
responses:
default:
description: Special description
content:
application/json:
schema:
$ref: '#/components/schemas/Server'
components:
schemas:
Server:
properties:
name:
type: string
example: test
id:
type: number
example: "0"
description: foo
OpenLiberty:
openapi: 3.0.0
info:
title: Deployed APIs
version: 1.0.0
servers:
- url: http://localhost:9080
paths:
/resources/server/{id}:
get:
summary: get server by id.
description: 'return one server with the specified id'
operationId: getServerById
parameters:
- name: id
in: query
schema:
type: integer
format: int64
responses:
default:
description: Special description
content:
application/json:
schema:
$ref: '#/components/schemas/Server'
/resources/server:
get:
summary: List servers.
description: 'Returns all servers '
operationId: getServers
responses:
default:
description: Special description
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/Server'
components:
schemas:
Server:
required:
- id
- name
type: object
properties:
id:
type: integer
format: int64
example: 0
name:
type: string
example: test
description: foo

Giving OriginAccessIdentity reference in CloudFormation or serverless.yml

I want to have a CloudFront distribution with access to a private S3 bucket. For that, I have to create an origin access identity. Manually, I can do that using the AWS console, but I wanted to create it via a CloudFormation script or with Serverless (using serverless.yml). While doing this, I am able to add a physical Id of the origin access identity to my CloudFront distribution (using one script).
Relevant documentation: https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/quickref-cloudfront.html
I tried this:
myDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName:bucket.s3.amazonaws.com
Id: myS3Origin
S3OriginConfig: {
OriginAccessIdentity:origin-access-identity/cloudfront/ !Ref cloudfrontoriginaccessidentity
}
Enabled: 'true'
Comment: Some comment
DefaultCacheBehavior:
ForwardedValues:
QueryString: 'false'
Cookies:
Forward: none
AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: myS3Origin
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_200
ViewerCertificate:
CloudFrontDefaultCertificate: 'true'
cloudfrontoriginaccessidentity:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: "some comment"
I have to create an origin access identity and a CloudFront distribution having this identity. Can we do both of these things in one CloudFormation script or with Serverless (using serverless.yml)?
You definitely can create an origin access identity and the CloudFront distribution in the same serverless.yml.
I've modified your scenario and changed the OriginAccessIdentity to use Fn::Join.
myDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName:bucket.s3.amazonaws.com
Id: myS3Origin
S3OriginConfig:
OriginAccessIdentity:
Fn::Join:
- ''
-
- 'origin-access-identity/cloudfront/'
- Ref: cloudfrontoriginaccessidentity
Enabled: 'true'
Comment: Some comment
DefaultCacheBehavior:
ForwardedValues:
QueryString: 'false'
Cookies:
Forward: none
AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: myS3Origin
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_200
ViewerCertificate:
CloudFrontDefaultCertificate: 'true'
cloudfrontoriginaccessidentity:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: "some comment"
The serverless examples repo has a great example of this too: https://github.com/serverless/examples/blob/master/aws-node-single-page-app-via-cloudfront/serverless.yml
Yes, you can create both in the same CloudFormation template. The cloudfrontoriginaccessidentity is a separate resource so needs to be moved out from underneath myDistribution.
myDistribution:
Type: AWS::CloudFront::Distribution
Properties:
DistributionConfig:
Origins:
- DomainName:bucket.s3.amazonaws.com
Id: myS3Origin
S3OriginConfig: {
OriginAccessIdentity:origin-access-identity/cloudfront/ !Ref cloudfrontoriginaccessidentity
}
Enabled: 'true'
Comment: Some comment
DefaultCacheBehavior:
ForwardedValues:
QueryString: 'false'
Cookies:
Forward: none
AllowedMethods:
- GET
- HEAD
- OPTIONS
TargetOriginId: myS3Origin
ViewerProtocolPolicy: redirect-to-https
PriceClass: PriceClass_200
ViewerCertificate:
CloudFrontDefaultCertificate: 'true'
cloudfrontoriginaccessidentity:
Type: AWS::CloudFront::CloudFrontOriginAccessIdentity
Properties:
CloudFrontOriginAccessIdentityConfig:
Comment: "toyoguard-acces-identity"
Dont forget to add the s3 policy and bucket to your dependsOn list

Error creating BucketPolicy in CloudFormation yaml

I'm trying to use the following yaml to create an S3 Bucket Policy in CloudFormation:
cloudTrailBucketPolicy:
Type: "AWS::S3::BucketPolicy"
Properties:
Bucket:
Ref: cloudtrailBucket
PolicyDocument:
-
Action:
- "s3:GetBucketAcl"
Effect: Allow
Resource:
Fn::Join:
- ""
-
- "arn:aws:s3:::"
-
Ref: cloudtrailBucket
- "/*"
Principal: "*"
-
Action:
- "s3:PutObject"
Effect: Allow
Resource:
Fn::Join:
- ""
-
- "arn:aws:s3:::"
-
Ref: cloudtrailBucket
- "/*"
Principal:
Service: cloudtrail.amazonaws.com
When I try to do this, I get a message that "Value of property PolicyDocument must be an object"
Anyone have any ideas?
Looks like you solved the issue, but for readability you can compress your formatting by using !Sub and knowing that action allows single values as well as list. One of the main reasons I like yaml is that you use less vertical.
PolicyDocument:
-
Action: "s3:GetBucketAcl"
Effect: Allow
Resource: !Sub arn:aws:s3:::${cloudtrailBucket}
Principal: "*"
-
Action: "s3:PutObject"
Effect: Allow
Resource: !Sub arn:aws:s3:::${cloudtrailBucket}/*
Principal:
Service: cloudtrail.amazonaws.com
The PolicyDocument property of the AWS::S3::BucketPolicy Resource has a required type of JSON Object. The YAML template in your question incorrectly provides a JSON Array containing two JSON Objects as the value of the PolicyDocument property, hence the error message you received.
To fix this error, the objects should be properly nested within a Statement element which is missing from the current template.
Refer to the IAM Policy Elements Reference for more detail on IAM Policy Document syntax.
Ahhh. s3:GetBucketAcl is an action on a bucket. I removed the /* in the first statement and it worked. Gee. Super helpful error message.

YAML Syntax Error: Incomplete explicit mapping pair; a key node is missed at

I'm writing swagger spec in YAML and getting vague errors. I've mapped my paths and definitions I think correctly, and not sure what this error means:
YAML Syntax Error Incomplete explicit mapping pair; a key node is
missed at line 66, column 30: format: int64schema: ^t
Lines:
Line 65: type: integer
Line 66: format: int64
Swagger:
/product/{productId}:
get:
tags:
- content
summary: Find product item by ID
description: Returns a product item when ID < 10. ID > 10 or nonintegers will simulate API error conditions
operationId: getProductItemByID
produces:
- application/json
- application/xml
parameters:
- in: path
name: productId
description: ID of menu item that needs to be fetched
required: true
type: integer
format: int64
schema:
$ref: "#/definitions/Product"
responses:
"404":
description: Product item not found
"200":
description: successful operation
schema:
$ref: "#/definitions/Product"
"400":
description: Invalid ID supplied
security:
- api_key: []
- my_auth:
- write
- read
Then at bottom of swagger file in definitions:
definitions:
Product:
type: object
properties:
id:
type: integer
format: int64
category:
$ref: '#/definitions/Category'
name:
type: string
detail:
type: string
From swagger 2.0 spec, if 'in' parameter is a "path" you can't use a schema.
I think there is a mistake and you should use :
/product/{productId}:
get:
tags:
- content
summary: Find product item by ID
description: Returns a product item when ID < 10. ID > 10 or nonintegers will simulate API error conditions
operationId: getProductItemByID
produces:
- application/json
- application/xml
parameters:
- in: path
name: productId
description: ID of menu item that needs to be fetched
required: true
type: integer
format: int64
responses:
"404":
description: Product item not found
"200":
description: successful operation
schema:
$ref: "#/definitions/Product"
"400":
description: Invalid ID supplied
...