Skip to content
This repository has been archived by the owner on Sep 17, 2022. It is now read-only.

Edge services integration #1

Closed
wants to merge 13 commits into from
Closed

Conversation

noahdietz
Copy link

This is the first pass at EdgeServices integration, many things are still in flux. I would like basic/functional code review. Integration testing is impossible currently due to outstanding permissions issues in Turbo.

To consider during review:

  • we don't have a default target for EdgeServices yet, thus I have a flag --edgeserviceshost so that i can toggle between running the server locally and the one in GKE. This will be removed.
  • this integration only works when a token is passed via --token...the other built-in option is basic auth, which Turbo doesn't support, so we need to generate a token when those options are used.
  • the --preserve-policies option maintains the proxy policies, and changes the node source in Trireme...should we just import a new application revision and update the deployment when using EdgeServices? Currently not supporting this
  • how chatty should this command be when building an image, deploying an app, etc.? default is silence, but I don't like that it just hangs for 1-2 minutes...thoughts?

},
runtime: {
name: 'Runtime to deploy the Node.js app to',
shortOption: 'B',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What short option as -B?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment as below, there are few option shorthands left to pick from that made sense to me.

},
'node-version': {
name: 'Version of node to use in EdgeServices',
shortOption: 'x',

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What -x?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are so many options already in use, i just started picking random ones...do an apigeetool deploynodeapp --help and itll list them, plus there are parent flags. Not really sure how to pick from the remaining.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I get ya. I think if the short flag is not relevant to the long flag than we probably just leave it out. Especially for something like node-version that probably wont get set in all cases.

shortOption: 'B',
required: false
},
stream: {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be rolled into a verbose option? If verbose is set then stream?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great idea, should've done that sooner! Thanks.

// we need the XML for a HostedTarget (or whatever)...this is just a place holder that isn't a ScriptTarget
if (opts.runtime === EdgeServicesRuntimeOption) {
targetDoc = mustache.render(
'<TargetEndpoint name="default">' +

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Won't we need the policy to get the routing key from the KVM? Not sure if this is the right place.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed, this policy stuff will have to change. Because we have little idea what the policy will look like I added a place holder so I could test all the steps (sans deployment).

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sounds good. However at this point it should look pretty close to the policies the old shipyardctl used right? We are still just using a KVM and routing key in it. Keys and TargetEndpoint url will be different.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We used the ScriptContainer tag which I believe pulled the routing key from the KVM, so that will be the same functionally...will it have to target a different KVM map? I forget how that actually worked. It also targeted the LB in front of our cluster for us...not sure we can just drop it in. Is there a specific change you'd like to see here? I'm not sure what to do without an actually policy to use, but happy to do whatever.

@AdamMagaluk
Copy link

Overall looks great. For --preserve-policies im not sure the best approach, but that sounds like a decent plan. Deploy a new edge services incase you already had a policy that did other things but had the edge services policy already in it. I think it doesn't matter too much because at the end of the day this would be driven by Edge when the integrations are done.

@noahdietz
Copy link
Author

@AdamMagaluk Agreed, its not a HUGE deal. But its also easy to implement (I think). If the routing stuff / the associated policies don't need to be changed to accommodate a new version of the application being deployed, then it should be as easy as building a revision & updating(?) a deployment.

* folds --stream into --verbose
* adds better shortOption choices
function deployEdgeServicesApplication(opts, request, imported, cb) {
var uri = util.format('http://%s/environments/%s:%s/deployments', opts.edgeserviceshost, opts.organization, opts.environments);
var payload = {
name: opts.api,

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name is optional. If we're setting name == application we might want to just leave name out.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah good point...I don't think we need to expose the configurable deployment name in this CLI.

So I can leave the name out of the deployment payload and it'll be set to the application?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup!

return cb(new Error('bad request, there was a missing parameter'));
} else if (res.statusCode === 409) {
return cb(new Error('a deployment with these parametes already exists. cancelling'));
} else if (res.statusCode === 200) {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Creating a deployment is going to return a 201 created not a 200 on success.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! I was going off of the Swagger. I'll change it in here to check for a 201.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. I've updated the swagger in a PR https://github.com/apigee-internal/turbo/pull/138

* makes deployment check for 201
* removes --node-version shortOption
@jbowen93
Copy link

LGTM

Copy link

@whitlockjc whitlockjc left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There are a few things that need changes and/or explanation.

var unzip = require('node-unzip-2');
var targz = require('tar.gz')({}, {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we going to still use tar.gz?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we support tar, tgz, zip and i wrote this code before we had zip support as that was a newer addition.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They will never see the temporary archive, so I don't think it matters, personally.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good enough for me.


var DeploymentDelay = 60;
var ProxyBase = 'apiproxy';
var TriremeRuntimeOption = 'trireme';
var EdgeServicesRuntimeOption = 'edgeServices'
var DefaultNodeVersion = '7'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should use an LTS version like 4.x or 6.x. I'd almost say use the newest version that is in LTS, which would be 6.x.

@@ -72,6 +80,31 @@ var descriptor = defaults.defaultDescriptor({
name: 'Preserve policies from previous revision',
shortOption: 'P',
toggle: true
},
runtime: {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any way to set a default value and have it be node?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is for toggling trireme | edge-services as defined in the design doc. There was offline conversation to change from backend to runtime.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh, I got you. Since --runtime is a term we use in Turbo for choosing your base image, maybe we could use something different. I remember liking --backend=[edge-services|trireme] but the more I think about it, we could use a flag like --edge-services as well. The more I think about it, I like the flag because it's really just a simple boolean. I don't see us having more backends for this stuff.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like that better too, just a flag for toggling on the edge-services runtime. @AdamMagaluk @jbowen93 what do you think?

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Works for me.

shortOption: 'r',
required: false
},
'node-version': {

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be runtime-version, not node-version. We don't want to have to change this when we get multi-language support.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Offline conversation resulted in a change to the DD from runtime-version to node-vesrion.

Also, this command is deploynodeapp so there should never be another Turbo supported runtime deployed through this, hence the name node-version

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Oh yeah, that's right. This is a node.js-specific command. I guess I can live with it for now.

required: false,
array: true
},
edgeserviceshost: { // for testing while we don't have proxy

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should make this an environment variable like get_script and others do.

@@ -425,6 +517,223 @@ function proxyCreationDone(err, req, body, opts, done) {
}
}

function getToken(opts, cb) {
var ssoURL = opts.baseuri && opts.baseuri.indexOf('e2e') > -1 ? 'https://login.e2e.apigee.net/oauth/token' : 'https://login.apigee.com/oauth/token'

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use the same approach that the get_token script does by using the SSO_LOGIN_URL environment variable.

opts['base-path'] = (opts['base-path'] ? opts['base-path'] : '/'+opts.api);

opts['env-var'] = opts['env-var'] === undefined ? [] : opts['env-var'];
opts['config-var'] = opts['config-var'] === undefined ? [] : opts['config-var'];

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any time you're using an undefined check (this line and a few above) to use a default value, just use something like this:

opts['config-var'] = opts['config-var'] || [];

I realize that there are cases where the first case can pass where you might not want it to but since we own this code, that seems unlikely and this is much simpler to read. Better yet, use underscore#defaults.

@@ -495,14 +804,16 @@ function handleUploadResult(err, req, fileName, itemDone) {

// Create a target endpoint that references the Node.js script
function createTarget(opts, request, done) {
var targetDoc = mustache.render(

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Did you mean to remove this? Shouldn't createTarget generate a template based on the appropriate backend?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes it was intentional. I moved away from using this createTarget method entirely.

Instead, when edge-services is targeted, it builds the proxy bundle all at once and uploads it, rather than doing 1 file at a time like the trireme impl does here.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

But the Trireme implementation isn't changed is it? That's why I asked.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Correct, the original implementation didn't change. This is a weird diff, see this earlier commit that has the removal of a control structure in this function for template rendering.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks.

@noahdietz noahdietz closed this Sep 11, 2017
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
4 participants