type definition for the AWS policy - aws-sdk-go

Where can i find the type (structure) definition of an AWS policy? For eg, for a policy like this
firstly := "{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "VisualEditor0",
"Effect": "Allow",
"Action": "s3:ListBucket",
"Resource": "arn:aws:s3:::amit",
"Condition": {
"StringLike": {
"s3:prefix": "Development/*"
}
}
},
{
"Sid": "VisualEditor1",
"Effect": "Allow",
"Action": [
"s3:PutObject",
"s3:GetObject"
],
"Resource": "arn:aws:s3:::amit/Development/*"
}
]
}
I am currently doing the following to access the field inside:
var temp interface{}
json.Unmarshal([]byte(firstKey), &temp)
c := temp.(map[string]interface{})
fmt.Println(c)
#
map[Version:2012-10-17 Statement:[map[Resource:arn:aws:s3:::amit Condition:map[StringLike:map[s3:prefix:Development/*]] Sid:VisualEditor0 Effect:Allow Action:s3:ListBucket] map[Sid:VisualEditor1 Effect:Allow Action:[s3:PutObject s3:GetObject] Resource:arn:aws:s3:::amit/Development/*]]]
I would like to have a struct like
type Policy {
Version string,
Statement []blah
}
and on unmarshaling, able to access like Policy.Version.

Check out https://mholt.github.io/json-to-go/. Using your example, it gave me (I changed the struct name to Policy; forgive the formatting) :
type Policy struct {
Version string `json:"Version"`
Statement []struct {
Sid string `json:"Sid"`
Effect string `json:"Effect"`
Action string `json:"Action"`
Resource string `json:"Resource"`
Condition struct {
StringLike struct {
S3Prefix string `json:"s3:prefix"`
} `json:"StringLike"`
} `json:"Condition,omitempty"`
} `json:"Statement"`
}
I saved your policy in a file, policy.json, and ran:
contents, err := ioutil.ReadFile("policy.json")
if err != nil {
os.Exit(1)
}
var thePolicy Policy
json.Unmarshal(contents, &thePolicy)
fmt.Println("Version: ", thePolicy.Version)
And got:
Version: 2012-10-17

Use separated structs to keep your code more organized.
condition := struct {
StringLike map[string]string
}
statement := []struct {
Sid string
Effect string
Action []string
Resource []string
Condition interface{}
}
policyStruct, _ := json.Marshal(struct {
Version string
Statement interface{}
}
UPDATE: If you need to document it on Swagger, I strongly recommend using OpenAPi. It generates the server/client code and also the struct definition.
Example:
---
openapi: 3.0.3
info:
version: "1.0.0"
title: OpenAPI AWS Policy Map
security:
- bearerAuth: []
paths:
/policy-statements:
get:
operationId: listPolicyStatements
description: Returns all existing policy statements
responses:
"200":
description: A list of policy statements
content:
application/json:
schema:
type: array
items:
$ref: "#/components/schemas/PolicyStatement"
components:
schemas:
PolicyStatement:
type: object
required:
- sid
- effect
- action
- resource
properties:
sid:
type: string
effect:
type: string
action:
type: array
items:
type: string
resource:
type: array
items:
type: string
example:
sid: bucketWrite
effect: Allow
action:
- s3:List*
- s3:Get*
- s3:Put*
resource:
- arn:aws:s3:::xxxxxx/*
- arn:aws:s3:::yyyyyy/*

Related

Bicep variable creation from module output

I-m trying to create multiple app services with bicep using a for loop on a module.
The module has the following output:
output id string = appServiceAppResource.id
output name string = appServiceAppResource.name
output vnetIntegrationOn bool = allowVnetIntegration[appServicePlan.sku.name]
output principalId string = appServiceAppResource.identity.principalId // <-- important
After this, i want to create a key vault, and provide "get" access to all the app services previously created using an access policy:
...
param appServices object
...
module appServicePlanModules 'modules/appServicePlan.bicep' = [for appServicesConfig in appServicePlans.appServicesConfig: {
name: '${appServicesConfig.name}-appserviceplan-module'
params: {
location: location
name: appServicesConfig.name
sku: appServicesConfig.sku
}
}]
...
var accessPolicy = [ for i in range(0, appServices.instanceCount) : {
objectId: appServiceModule[i].outputs.principalId
permissions: {
secrets: ['get']
}
tenantId: subscription().tenantId
}]
module keyValutModule 'modules/keyvault.bicep' = {
name: 'key-valut-module'
dependsOn: [appServiceModule]
params: {
location: location
accessPolicies: accessPolicy
publicNetworkAccess: keyvault.publicNetworkAccess
keyVaultName: keyvault.name
}
}
The problem is that when i try to create that access policy, it fails
What puzzles me is that, this is working:
var accessPolicy = [{
objectId: appServiceModule[0].outputs.principalId
permissions: {
secrets: ['get']
}
tenantId: subscription().tenantId
}
{
objectId: appServiceModule[1].outputs.principalId
permissions: {
secrets: ['get']
}
tenantId: subscription().tenantId
}]
And also this:
var accessPolicies = [ for i in range(0,1):{
objectId: '52xxxxxx-25xx-4xxf-axxx-xxdxx3axxdff'
permissions: {
secrets: ['get']
}
tenantId: subscription().tenantId
}]
Since I want to use this template for multiple env, I want it to be more generic (so that i can have 1 or 5 service apps), so that for loop wold be very useful for me.
I'm not sure why, if I use a for loop in combination of a module output this is not working.
Do you have any idea why, or of there is a workaround on this.
Thank you!
Best regards,
Dorin

RDSDataService not recognizing `typeHint` in `batchExecuteStatement` method

I'm trying to run the batchExecuteStatement method. For some kind of reason, passing as parameter (besides the sql string and the resource configuration)
[
[
{ name: 'id', value: { stringValue: 'uuidString' }, typeHint: 'UUID' },
{ name: 'meta', value: { stringValue: '{}' }, typeHint: 'JSON' }
]
]
results in the method throwing this exception UnexpectedParameter: Unexpected key 'typeHint' found in params.parameterSets[0][0].
I do not understand why, since the query parameters look the same as in the aws doc.
The query is a simple INSERT INTO alarms_log VALUES(:id, :meta); statement
Source doc link: https://docs.aws.amazon.com/AWSJavaScriptSDK/latest/AWS/RDSDataService.html#batchExecuteStatement-property

Specify Dynamic keys in openapi yaml

I want to create a response structure like this where either fieldProfile (profile type) or summaryProfile is optional. i.e outer key is dynamic and optional
{
"fieldProfile": [
"metric1",
"metric2",
"metric3"
],
"summaryProfile": [
"metric1",
"metric2",
"metric3"
]
}
Or
{
"fieldProfile": [
"metric1",
"metric2",
"metric3"
]
} // Here Summary Profile is removed, similarly we can have a response of summaryProfile or have both in response
I am creating the response schema like this, but here I want the metricType (fieldProfile/summaryProfile) to be the key for metrics (metric list).
ProfileMetrics:
description: List of metrics available in Field Profile
type: object
required:
- metricType
- metrics
properties:
metrics:
type: array
items:
type: object
required:
- metricName
properties:
metricName:
type: string
Any help is appreciated
Your schema can be defined as follows:
MySchema:
type: object
properties:
fieldProfile:
type: array
items:
type: string
summaryProfile:
type: array
items:
type: string
# At least fieldProfile or summaryProfile (or both) must be present
minProperties: 1
Instead of minProperties: 1, you can use this anyOf + required construct, it will achieve the same effect in this example:
anyOf:
- required: [fieldProfile]
- required: [summaryProfile]

openapi 3.0 - change from array to dictionary/hashmap

This is basically the inventory example from Swagger Hub with a few items changed inside the array. Here is what the response looks like when I make a Python request to my SwaggerHub URL:
[{
"hostname": "server",
"ip_addr": "192.168.0.12",
"app_name": "generic",
"app_code": 12345678,
"xmx": "5678",
"jvm_version": "1.0.0",
"xms": "1234"
}]
How can I change the code so that it's a dictionary? I can't believe how many lines of YAML it takes to do what Flask or Falcon can do in about 5 lines of code.
Anyways, here is the template:
openapi: 3.0.0
# Added by API Auto Mocking Plugin
servers:
- description: SwaggerHub API Auto Mocking
url: https://virtserver.swaggerhub.com/james_test/test/1.0.0
info:
description: This is a simple API
version: "1.0.0"
title: Simple Inventory API
contact:
email: you#your-company.com
license:
name: Apache 2.0
url: 'http://www.apache.org/licenses/LICENSE-2.0.html'
tags:
- name: admins
description: Secured Admin-only calls
- name: developers
description: Operations available to regular developers
paths:
/data:
get:
tags:
- developers
summary: get random data from james_test API
operationId: searchInventory
description: |
By passing in the appropriate options, you can search for
available inventory in the system
responses:
'200':
description: search results matching criteria
content:
application/json:
schema:
type: array
items:
$ref: '#/components/schemas/state_data'
'400':
description: bad input parameter
components:
schemas:
state_data:
type: object
required:
- app_code
- app_name
- jvm_version
- hostname
- ip_addr
- xms
- xmx
properties:
app_code:
type: integer
format: int64
example: 12345678
app_name:
type: string
example: generic
jvm_version:
type: string
format: string
example: '1.0.0'
hostname:
type: string
format: hostname
example: 'server'
ip_addr:
type: string
format: ipv4
example: '192.168.0.12'
xms:
type: string
format: string
example: '1234'
xmx:
type: string
format: string
example: '5678'
Thank you all.
Edit:
I was hoping to get the response like this:
{
"hostname": "server",
"ip_addr": "192.168.0.12",
"app_name": "generic",
"app_code": 12345678,
"xmx": "5678",
"jvm_version": "1.0.0",
"xms": "1234"
}
SwaggerHub mock server returns an array because your response is defined as an array:
content:
application/json:
schema:
type: array # <----
items:
$ref: '#/components/schemas/state_data'
To get an object response, use:
content:
application/json:
schema:
$ref: '#/components/schemas/state_data'

Sequelize.js - How to create non-trivial associations without raw SQL?

Here is my situation:
I'm using postgres 9.4, Sequelize ORM and have following models:
Service
serviceCode - primary key, string of 6 characters
serviceTitle - string
ServiceGroup
serviceCodePrefixes - array of strings that are prefixes for Service.serviceCode
serviceGroupTitle - string
Task
serviceCode - reference to Service
I need to build Task object populated with Service and ServiceGroup objects. Example:
In database:
Service {
serviceCode: '123232',
serviceTitle: 'svc title #1',
}
ServiceGroup {
serviceCodePrefix: ['12', '13', '92', ...],
serviceGroupTitle: 'svc grp title #1',
}
Task {
serviceCode: '123232',
}
Result:
Task {
service: {
serviceTitle: 'svc title #1',
},
serviceGroup: {
serviceGroupTitle: 'svc grp title #1',
},
}
The problem is that serviceCodePrefix contains not simple IDs, which can be used to create association using hasOne/belongsTo/etc., but prefix for ID.
So questions is: how this can be done without raw sql?
Turns out that right now Sequelize has experimental feature: 'on' option for 'include'. This option allows users to customize joining conditions. So my problem can be solved this way:
const Service = sequelize.define('service', {
serviceTitle: Sequelize.STRING,
serviceCode: Sequelize.STRING,
});
const ServiceGroup = sequelize.define('service_group', {
serviceGroupTitle: Sequelize.STRING,
// Array of prefixes (e.g. ['01%', '023%'])
serviceCodePrefix: Sequelize.ARRAY(Sequelize.STRING),
});
const Task = sequelize.define('task', {
taskTitle: Sequelize.STRING,
serviceCode: Sequelize.STRING,
});
Task.belongsTo(Service, { foreignKey: 'serviceCode' });
// Hack needed to allow 'include' option to work
Task.hasMany(ServiceGroup, { foreignKey: 'serviceCodePrefix', constraints: false });
// And finally
Task.findAll({
include: [
{ model: Service },
{
model: ServiceGroup,
on: [' "task"."serviceCode" LIKE ANY("serviceGroup"."serviceCodePrefix") '],
},
],
});
Not sure about the performance though.