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
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
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
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]
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'
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.