how to query attributes inside a role in chef? - deployment

I am using chef version 10.16.2
I have a role (in ruby format). I need to access an attrubute set in one of the cookbooks
eg.
name "basebox"
description "A basic box with some packages, ruby and rbenv installed"
deployers = node['users']['names'].find {|k,v| v['role'] == "deploy" }
override_attributes {
{"rbenv" => {
"group_users" => deployers
}
}
}
run_list [
"recipe[users]",
"recipe[packages]",
"recipe[nginx]",
"recipe[ruby]"
]
I am using chef-solo so i cannot use search as given on http://wiki.opscode.com/display/chef/Search#Search-FindNodeswithaRoleintheExpandedRunList
How do i access node attributes in a role definition ?

Roles are JSON data.
That is, when you upload the role Ruby file to the server with knife, they are converted to JSON. Consider this role:
name "gaming-system"
description "Systems used for gaming"
run_list(
"recipe[steam::installer]",
"recipe[teamspeak3::client]"
)
When I upload it with knife role from file gaming-system.rb, I have this on the server:
{
"name": "gaming-system",
"description": "Systems used for gaming",
"json_class": "Chef::Role",
"default_attributes": {
},
"override_attributes": {
},
"chef_type": "role",
"run_list": [
"recipe[steam::installer]",
"recipe[teamspeak3::client]"
],
"env_run_lists": {
}
}
The reason for the Ruby DSL is that it is "nicer" or "easier" to write than the JSON. Compare the lines and syntax, and it's easy to see which is preferable to new users (who may not be familiar with JSON).
That data is consumed through the API. If you need to do any logic with attributes on your node, do it in a recipe.

Not sure if I 100% follow, but if you want to access an attribute which is set by a role from a recipe, then you just call it like any other node attribute. For example, in the case you presented, assuming the node has the basebox role in its run_list, you would just call:
node['rbenv']['group_users']
The role attributes are merged into the node.
HTH

Related

Firestore rules and data structure

I have a question regarding data structure and rules ... I have content on which users can vote. Something like this:
Firestore object:
{
name: "Cat",
description: "A cat named Cat",
votes: 56
}
Now ... I want authenticated users to be able to have update access to the votes, but not to any other values of the object and of course read rights since the content has to be displayed.
I did this because I wanted to avoid additional queries when displaying the content.
Should I create another collection "votes" maybe where the votes are kept and for each document make an additional request to get them?
In rules, you have access to the state of the data both before and after the writes - so you can test specific fields to be sure they have not changed:
function existing() {
return resource.data;
}
function resulting() {
return request.resource.data;
}
function matchField(fieldName) {
return existing()[fieldName] == resulting()[fieldName];
}
....
allow update: if matchField("name") && matchField("description")
....
The functions just make the rule easier to read.

Compound queries

I have a RESTful service that accepts a custom query, like this:
/entities/User?actions=
{
"$link": {
"entityType": "Manager",
"entity": {
"name": "John Smith"
},
"linkName": "managers",
"backLinkName": "account",
"$set": {
"propertyName": "aclWrite",
"propertyValue": {
"$ref": {
"propertyName": "entityId"
}
}
}
}
}
Which simply means:
Create a new Entity of type User
Create a new Entity of type Manager with the field name, linking the User to be created to this Manager through link name "managers"
Then back-linking the Manager entity to be created to the User with a link name "account" and setting the Manager entity write ACL (Access Control List) to the ID of the User to be created.
I created this query structure because I can't find any suitable Query language that can seem to support such action/procedure.
The question here is are there any Query language that can support such compound action/procedure or can GraphQL handle such?
As a specification, GraphQL doesn't care what fields your schema defines, what arguments those fields take or what your field resolvers do with those arguments. So it's perfectly feasible to design a schema that would let the client compose an equivalent mutation:
mutation {
link(
entityType: "Manager"
entity: {
name: "John Smith"
}
linkName: "managers"
backLinkName: "account"
set: {
propertyName: "aclWrite"
propertyValue: {
ref: {
propertyName: "entityId"
}
}
}
) {
# some fields here to return in the response
}
}
GraphQL does not support references to other nodes inside the same query, so you would still probably want a single mutation whose input mirrored your existing API. That said, using GraphQL for this may still be preferable because of request validation, which is all the more important with complex requests like this. Having an IDE like GraphiQL or GraphQL Playground that lets you write your queries using autocomplete is a big plus too.

How to pass owner attribute when creating user story using Rally API?

I am trying to pass the owner attribute to create a user story in rally using rally API But I am encountering below error.
{
"CreateResult": {
"_rallyAPIMajor": "2",
"_rallyAPIMinor": "0",
"Errors": [
"Cannot parse object reference from \"{\"Owner\": {\"_refObjectName\": \"Ron\"}}\""
],
"Warnings": [
"Ignored JSON element HierarchicalRequirement.PortfolioItem during the processing of this request."
]
}
}
My request payload
{
"HierarchicalRequirement":{
"Name": "hello Wrold",
"Description":" 123 test description",
"Workspace": "/workspace/18686460234",
"Project":"/project/1025697468602323",
"PortfolioItem":"",
"Owner":{"_refObjectName":"Ron"},
"ScheduleState":"Defined"
}
}
Any thoughts?
In general, when referring to an object property that itself is an object (as in this case with the User object), you pass in the actual value of _ref, not another object. If you have previously been passed the reference to the user as a full blown URI, then you can still pass that in and the SDK will convert it to a _ref.
If you go to the webservice docs (https://rally1.rallydev.com/slm/doc/webservice/) for your subscription and go down to the User section, you can get the docs to fetch you some examples of users. The _ref will come back something like:
https://rally1.rallydev.com/slm/webservice/v2.0/user/39776836851
I believe that you can either use that, or just truncate it to the number at the end. So the code will need to be changed so that the Owner line reads:
"Owner" : "https://rally1.rallydev.com/slm/webservice/v2.0/user/39776836851"

GraphQL schema from a single object JSON file in Gatsby

So I'd like to query a single JSON file which is not an array from Gatsby's GraphQL but I don't really know how to do it.
As far as I understand gatsby-transformer-json docs - it only supports loading arrays and have them accessible via allFileNameJson schema.
My gatsby-config plugins (only the necessary ones for this question):
{
resolve: 'gatsby-source-filesystem',
options: {
name: 'data',
path: `${__dirname}/src/data`
}
},
'gatsby-transformer-json'
And then let's say in src/data i have a something.json file, like this:
{
"key": "value"
}
Now I'd like to query the data from something.json file, but there is no somethingJson schema i can query (tried with Gatsby's GraphiQL).
Could someone point out what am I doing wrong or how can I solve this problem?
Ok, so it is possible to query single-object files as long as they have a parent (folder).
Let's take these parameters:
gatsby-source-filesystem configured to src/data
test.json file positioned at src/data/test.json with { "key": "value" } content in it
Now as the test.json file actually has a parent (data folder) - you can query the fields from test.json like this:
{
dataJson {
key
}
}
But putting those directly in your root folder is a bad practice, because when you will store another json file, i.e. secondtest.json with { "key2": "value2" } content, and will query it with the same query as above, you will get data only from a single node (not sure if it takes first, or last encountered node),
So, the perfect solution for this case is to have your single-object json files stored in separate folders with just one json per folder.
For example you have some "About Me" data:
create a about folder in your src/data
create an index.json file with i.e. { "name": "John" }
query your data
Like this:
{
aboutJson {
name
}
}
That's it.

breeze metadata when multiple types has/share the same short name

I generate the metadata from the database following the http://www.breezejs.com/documentation/load-metadata-script
My question is : How can I generate the metadata for two entities that has the same name but a different shema in the database ?
I tried to use a qualified name for my entities like this : ...
"entityType": [
{
"name": "Admin.RefactorColumn",
"key": {
"propertyRef": {
"name": "Id"
}
},
"property": [
{
"name": "Id",
"type": "Edm.Int32",
"nullable": "false",
"annotation:StoreGeneratedPattern": "Identity"
}, ...
...
the problem is that when I make entityManager.saveChanges() and return the saveResult(also made by hand) from server breeze look for an entity with the name RefactorColumn:#Admin ... instead of Admin.RefactorColumn:#...
I have no issue if name is just "RefactorColumn" instead of "Admin.RefactorColumn"
Can I solve this issue changing the metadata format or the saveResult format ?
Thank for any help !
All breeze EntityTypes have a concept of a namespace qualified name. This name is a composition of a 'shortName' and a 'namespace'. As of breeze 1.4.16 a qualified name can be created by calling the EntityType.qualifyTypeName static function. i.e.
var shortName = "Employee";
var namespace = "My.Qualified.Namespace";
var qualifiedName = breeze.EntityType.qualifyTypeName(shortName, namespace);
// qualifiedTypeName will be => "Employee:#My.Qualified.Namespace"
In general, all breeze APIs will accept either a shortName OR a qualified name. If a shortName is provided then breeze will internally convert it to a qualified name by finding the first qualified name within the local metadataStore with a matching shortName.
Breeze metadata for each entity type can either be retrieved from a server or defined on the client. If defined on the client your entityType would be defined something like this:
myMetadataStore.addEntityType({
shortName: "RefactorColumn",
namespace: "Admin",
autoGeneratedKeyType: breeze.AutoGeneratedKeyType.Identity,
dataProperties: {
id: { dataType: DataType.Int32, isPartOfKey: true, isNullable: false },
// additional properties here:
},
});
There are several examples of this technique in the DocCode sample in the breeze.js.samples GitHub repo.
Alternatively, if you are defining metadata by returning json from the server you have two options, you can either return a valid OData metadata definition ( which it appears to be what you are trying to return above) OR you can use breeze's native metadata format, which is MUCH simpler. The simplest way to see what this would look like is to create the metadata on the client as shown above and the call
var exportedMetadata = myMetadataStore.exportMetadata();
The contents of the exportedMetadata will be in 'native' breeze metadata format, which is basically just a jsonified version of the internal entityType definition.