Share AMI to multiple OrganizationARNs boto3 - amazon-web-services

Currently I am sharing AMI images via OrganizationalArn. However, I am looking to share to multiple OrganizationalArns. I looked into the boto3 documentaiton, but didn't see any examples or information. It appears one can share to many accounts, but not many organizationalArn's.
gr_org = [{ 'OrganizationArn' : 'arn:aws:organizations::123456789:organization/o-123456789'}, { 'OrganizationArn' : 'arn:aws:organizations::987654321:organization/o-987654321'}]
ec2Client = boto3.client('ec2',region)
ec2Client.modify_image_attribute(ImageId=amiId,LaunchPermission={'Add': gr_org },
OperationType='add',DryRun=False)

You're almost there. All you have to do is add another dict in 'Add', like
LaunchPermissions = {
[
'Add': [
{OrganizationArn: org1},
{OrganizationArn: org2}]
]}
The other way you can do this is to use 'OrganizationArns = [org1, org2]
AWS initially had LaunchPermissions parameter only but that was a bit cumbersome as you have to create a list of dicts for 'Add' or 'Remove' operation.
Now, you can also use parameters like OrganizationArns = [] directly, something like:
modify_image_attribute(Attribute='launchPermission', OrganizationArns=[org1, org2], ImageId=amiId)

Related

Add auto created_by and create_at fields in firestore

I wanna add properties such as "created_by" and "created_at" to each and every object in pretty much every collection in firestore.
The only approaches I can think of so far are.
Add them in the client-side code but verify them on the server side using Security Rules.
or better:
Add them automatically on the server side using Cloud Firestore function triggers onCreate and onWrite events.
However, both approaches sounds like workarounds for a very common task for which I would expect an out-of-the-box solution.
Does anybody know any out-of-the-box approach for that?
There's no built-in solution for this. Cloud Functions sounds redundant as security rules can ensure the values are correct:
allow create: if request.resource.data.created_at == request.time && request.data.created_by == request.auth.uid;
You can use serverTimestamp() for created_at when adding the document so the rules will return true as mentioned in the documentation.
For Firestore write operations that include server-side timestamps, this time (request.time) will be equal to the server timestamp.
You can use withConverter() so you don't have to repeat the same code to add those common fields. Instead, declare the converter once and use it for any read/write operations as required:
const addDefaultFields = {
toFirestore: (docData: any) => {
// TODO: Add created_at and other fields
return {
created_at: serverTimestamp(),
...docData,
}
},
fromFirestore: (snapshot: any, options: any) => {
const data = snapshot.data(options)
return {
id: snapshot.id,
...data,
}
},
}
const docRef = doc(db, 'col', 'alovelace').withConverter(addDefaultFields)

Select where tag end in a or b in Terraform data lookup

I have 3 subnets. They are named:
test-subnet-az-a test-subnet-az-b test-subnet-az-c
I have a datasource like so:
data "aws_subnet_ids" "test" {
vpc_id = "${module.vpc.id}"
tags = {
Name = "test-subnet-az-*"
}
}
This will return a list including all 3 subnets.
How do I return just the first 2, or those ending in a or b?
Terraform data sources are generally constrained by the capabilities of whatever underlying system they are querying, so the filtering supported by aws_subnet_ids is the same filtering supported by the underlying API, and so reviewing that API (EC2's DescribeSubnets) may show some variants you could try.
With that said, if you can use the data source in a way that is close enough to reduce the resultset down to a manageable size (which you seem to have achieved here) then you can filter the rest of the way using a for expression within the Terraform language itself:
data "aws_subnet_ids" "too_many" {
vpc_id = "${module.vpc.id}"
tags = {
Name = "test-subnet-az-*"
}
}
locals {
want_suffixes = toset(["a", "b"])
subnet_ids = toset([
for s in data.aws_subnet_ids.too_many.ids : s
if contains(local.want_suffixes, substr(s, length(s)-1, 1))
])
}
You can place any condition expression you like after if in that for expression to apply additional filters to the result, and then use local.subnet_ids elsewhere in the configuration to access that reduced set.
I used toset here to preserve the fact that aws_subnet_ids returns a set of strings value rather than a list of strings, but that's not particularly important unless you intend to use the result with a Terraform feature that requires a set, such as the for_each argument within resource and data blocks (which is not yet released as I write this, but should be released soon.)

How can I do a "where in" type query using ember-data

How can I perform a where-in type query using ember-data?
Say I have a list of tags - how can I use the store to query the API to get all relevant records where they have one of the tags present?
Something like this:
return this.store.find('tags', {
name: {
"in": ['tag1', 'tag2', 'tag3']
}
})
There isn't built in support for something like that. And, I don't think its needed.
The result that you are after can be obtained in two steps.
return this.store.find('posts'); // I guess its a blog
and then in your controller you use a computed property
filteredPosts: function('model', function() {
var tags = ['tag1', 'tag2', 'tag3'];
return this.get('model').filter(function(post) {
if ( /* post has one of tags */ ) {
}
return false;
});
});
Update: What if there are tens of thousands of tags?!
Amother option is to send a list of tags as a single argument to the back end. You'll have to do a bit of data processing before sending a request and before querying.
return this.store.find('tags', {
tags: ['tag1', 'tag2', 'tag3'].join(', ')
})
In your API you'll know that the tags argument needs to be converted into an array before querying the DB.
So, this is better because you avoid the very expensive nested loop caused by the use of filter. (expensive !== bad, it has its benefits)
It is a concern to think that there will be tens of thousands of tags, if those are going to be available in your Ember app they'll have a big memory footprint and maybe something much more advanced is needed in terms of app design.

Create / Update multiple objects from one API response

all new jsfiddle: http://jsfiddle.net/vJxvc/2/
Currently, i query an api that will return JSON like this. The API cannot be changed for now, which is why I need to work around that.
[
{"timestamp":1406111961, "values":[1236.181, 1157.695, 698.231]},
{"timestamp":1406111970, "values":[1273.455, 1153.577, 693.591]}
]
(could be a lot more lines, of course)
As you can see, each line has a timestamp and then an array of values. My problem is, that i would actually like to transpose that. Looking at the first line alone:
{"timestamp":1406111961, "values":[1236.181, 1157.695, 698.231]}
It contains a few measurements taken at the same time. This would need to become this in my ember project:
{
"sensor_id": 1, // can be derived from the array index
"timestamp": 1406111961,
"value": 1236.181
},
{
"sensor_id": 2,
"timestamp": 1406111961,
"value": 1157.695
},
{
"sensor_id": 3,
"timestamp": 1406111961,
"value": 698.231
}
And those values would have to be pushed into the respective sensor models.
The transformation itself is trivial, but i have no idea where i would put it in ember and how i could alter many ember models at the same time.
you could make your model an array and override the normalize method on your adapter. The normalize method is where you do the transformation, and since your json is an array, an Ember.Array as a model would work.
I am not a ember pro but looking at the manual I would think of something like this:
a = [
{"timestamp":1406111961, "values":[1236.181, 1157.695, 698.231]},
{"timestamp":1406111970, "values":[1273.455, 1153.577, 693.591]}
];
b = [];
a.forEach(function(item) {
item.values.forEach(function(value, sensor_id) {
b.push({
sensor_id: sensor_id,
timestamp: item.timestamp,
value: value
});
});
});
console.log(b);
Example http://jsfiddle.net/kRUV4/
Update
Just saw your jsfiddle... You can geht the store like this: How to get Ember Data's "store" from anywhere in the application so that I can do store.find()?

Adding Targets to Target Lists using REST API with SugarCRM

I'm trying to add targets to target lists in Sugar via REST service calls. I'm getting a positive response from Sugar but records are not added. The service method I'm using is *set_relationship*:
{
"session":"3ece4lmn5rtweq9vm5581jht",
"module_name":"ProspectLists",
"module_id":"cb13b96f-8334-733c-1548-52c27a5b8b99",
"link_field_name":"prospects",
"name_value_list":[],
"related_ids":["534f894a-4265-143d-c94b-52be908685b1"],
"delete":0
}
I also tried it the other way around:
{
"session":"3ece4lmn5rtweq9vm5581jht",
"module_name":"Prospects",
"module_id":"cb13b96f-8334-733c-1548-52c27a5b8b99",
"link_field_name":"prospect_lists",
"name_value_list":[],
"related_ids":["534f894a-4265-143d-c94b-52be908685b1"],
"delete":0
}
In both cases I get a promising response:
{"created":1,"failed":0,"deleted":0}
...but when I check the target list I can't find any added targets. I also checked the database but there is no trace either.
My Sugar Version is 6.5.16 CE and I'm using the SuiteCRM 7.0.1 extension but I don't think this makes a difference here.
Any hint is highly appreciated. Thanks!
I finally figured it out. It seems like set_relationship is very picky about the parameter order. The parameter naming doesn't even mean a thing. This worked in the end for me:
{
"session":"3ece4lmn5rtweq9vm5581jht",
"module_name":"Prospects",
"module_id":"cb13b96f-8334-733c-1548-52c27a5b8b99",
"link_field_name":"prospect_lists",
"related_ids":["534f894a-4265-143d-c94b-52be908685b1"],
"delete":0
}
Working Python code (API v4.1):
import sugarcrm
import json
import requests
crm_session = sugarcrm.Session(CRM_HOST, CRM_USER, CRM_PASS)
payload = {
"method": "set_relationship",
"input_type": "JSON",
"response_type": "JSON",
"rest_data": json.dumps({
"session": crm_session.session_id,
"module_name": "Prospects",
# ID of the record you're creating relationship FROM
# In my case it is a record from module "Prospects"
"module_id": "cb13b96f-8334-733c-1548-52c27a5b8b99",
"link_field_name": "events_prospects",
# ID of the record you're creating relationship FOR
# In my case it is a record from module "events"
"related_ids": ["534f894a-4265-143d-c94b-52be908685b1"],
"name_value_list": [],
"delete": 0
})
}
result = requests.post(CRM_HOST, data=payload)
#Till is right, be careful with the order of "rest_data" parameters. In my case placing name_value_list before related_ids has been producing positive results with no actual relationship created.
p.s. I'm using this library: https://pypi.python.org/pypi/sugarcrm/0.1