On 19/06/13 01:32, Adrian Otto wrote:
Yes. I think having a POST method in the API makes perfect sense. Assuming we 
reach agreement on that, the next question that comes up is:

How to do you modify resources that have been created with a POST?

You mention HTTP PUT as an answer to that. Unfortunately PUT is only really 
useful for doing a full resource replacement, not just tweaking something 
that's already there. For that, you really want HTTP PATCH 
(http://tools.ietf.org/html/rfc5789). You can make this really elegant for JSON 
with JSON Patch (http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-10).

We should note that offering API methods to adjust a stack (aka: assembly) 
means that there will be a divergence between what's described in the original 
template, and the actual running state of the stack/assembly created by the 
template, well beyond the results of an autoscale policy. In fact, it would be 
possible to build a stack/assembly with no template at all, if the right API 
methods are present. There are good use cases for this, particularly for higher 
level compatibility layers where it would be awkward to generate permutations 
of templates to immediately feed into an API, rather than just use an API 
method for adjusting the stack/assembly in place. it would be much more 
elegant, for example, to implement a CAMP implementation on top of Heat if Heat 
had a REST API for creating and managing individual resources within a 
stack/assembly. This same argument applies to integrating any other 
orchestration or configuration management system with Heat.

More comments in-line:

On Jun 18, 2013, at 3:44 PM, Christopher Armstrong 
<[email protected]>
  wrote:

tl;dr POST /$tenant/stacks/$stack/resources/ ?

Yes.

== background ==

While thinking about the Autoscaling API, Thomas Hervé and I had the
following consideration:

- autoscaling is implemented as a set of Heat Resources

Autoscaling is *currently* implemented like that.

It's implemented like that as a hack, because the things that those resources are supposed to _represent_ don't exist yet. Conceptually speaking, this is a mess and it's causing us problems. For example, you should be able to reference e.g. an existing launch config that exists outside of the template, as you can with most other kinds of resource (some are suffering from the same issue), but you can't because it's trapped in its little walled garden called a stack.

One of the goals of an Autoscaling API should be to *fix* this, not to reify it for all time in the user interface.

- there are already general APIs for looking at resources generically:
  - resource-show (GET /$tenant/stacks/$stack/resources/$id)
  - resource-metadata (GET /$tenantt/stacks/$stack/resources/$id/metadata)
  - resource-list (GET /$tenant/stacks/$stack/resources/)
- we want to be able to create and configure autoscaling resources
through the API

But we want to do it outside the context of a stack.

By the way, it's worth noting that in the current implementation of Heat, a resource is tied closely to its stack. Resources don't have templates (in the database) for example, they only store state related to the underlying physical resource.

- maybe we should implement POST for resources?

-1

This is basically the gist of the question. I believe the answer
should be the same as the answer about any other type of resource we
might want to manipulate through the API -- it seems best that either
all resource types are manipulated through a generic resource
manipulation API, or they should all have their own specific ReST
collection.

Give them specific collections, so they can be easily specialized.

Actually, I could also imagine a situation where only generic
operations on common resource metadata are allowed via
/$tenant/stacks/$stack/resources/, and resource-specific manipulation
is done via resource-specific collections -- I don't know how ReSTy
that is, though.

I'll get to specifics. There are two ways I can imagine the autoscale
API looking. I'll avoid the word "resource" when referring to ReST
resources and just talk about "collections" and "paths", since
"resource" in this context also means Heat resources.

== resource-specific paths ==

One is basically just like Otter's: http://docs.autoscale.apiary.io/

This provides paths like /$tenant/groups/$id (for an autoscaling
group), /$tenant/groups/$id/policies (for a policy), etc. These
variously support GET for reading as well as POST and PUT for
manipulation.

We can use "/v1.0/{tenantId}/groups/{groupId}/policies" as an example
operation. We POST JSON describing a new scaling policy to create to a
new scaling policy.

The above approach is definitely my preference.

So, I completely agree. But all of this email except for this section is making a justification for the _other_ approach, the one you later call "less elegant" and clarify in a follow up that you "prefer less", but all of your other comments are endorsing that one. So I'm confused ;)

He didn't suggest this as a _way_ of implementing "POST /$tenant/stacks/$stack/resources/"; it's what (IMO) we _should_ do *instead* of implementing that.

== generic paths ==

The alternative is to say that autoscaling groups, policies, etc are
all Just Heat Resources, and Heat resources already have a ReST
collection at /$tenant/resources/.

In this option, the alternative to POSTing to
/$tenant/groups/$id/policies would be to post directly to
/$tenant/resources/, with a body exactly like in the previous example,
but with two more JSON attributes:

- the type of the resource, in this case something like
"AWS::AutoScaling::ScalingPolicy"
- the group ID that the new policy should be associated with, since
it's not specified in the URL.

This is approach is less elegant than resource-specific paths. Bringing in 
types is a whole other layer of complexity that can be avoided when using 
resource-specific paths. You actually still have types, but they are implicit. 
You still have to document them, but you don't have to individually name them.

One concern I have is about how well we can specify a strict schema of
inputs and outputs to the resources/ collection -- I'm particular
interested in JSON hyperschema. I'm not sure how it handles
heterogeneous collections like this.

In the JSON world, that's what documentation is for. Although having a JSON 
Schema can help simplify client development, it is yet another body of code 
that Heat developers will need to maintain. The question here comes down to how 
many developers will work on building clients, and could simplifying their 
development experience help boost adoption of Heat. My suggestion is (even if 
we like the idea of a schema) to start lean without a schema, and add that in 
if we agree it's something we want later. With some discipline, it's possible 
to implement things in a way that lends itself to using a schema even if we 
don't explicitly define, publish, and maintain one.

+1. API schemata are IMO fundamentally uninteresting beyond the extent to which they make it easier to generate documentation. This sounds like it would actually be harder than the current WADL-based documentation system that is standard in OpenStack.

cheers,
Zane.

Maintaining the schema (and the documentation for that matter) should be 
something that all OpenStack development teams feel comfortable with, because 
basically anytime someone changes any of the downstream OpenStack API's, 
there's a good chance it will need to change here too in order to expose 
whatever feature they add. A tweak to a documentation page may be less 
burdensome if you think of it from that perspective.

Adrian


_______________________________________________
OpenStack-dev mailing list
[email protected]
http://lists.openstack.org/cgi-bin/mailman/listinfo/openstack-dev

Reply via email to