Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: programmatic API for management layer #29

Merged
merged 28 commits into from
May 29, 2016
Merged

Feature: programmatic API for management layer #29

merged 28 commits into from
May 29, 2016

Conversation

h2non
Copy link
Member

@h2non h2non commented May 22, 2016

The high-level goal is to provide a productive programmatic API for vinxi manager layer supporting different configuration entities: scopes, rules and plugins based on the previous discussions and technical details. Once the programmatic layer is done, it should be easily designed to bind it and expose it at HTTP level for remote configuration.

Disclaimer: I'm intensively working on this in the upcoming days, review it taking into account most things are still in progress or prone to change.

In detail, this PR should cover:

  • Programmatic rules API and configuration
  • Implement basic rules (based on mux matchers, e.g: Path, Vhost, Header...)
  • Programmatic plugins API and configuration
  • Implement basic plugins bindings to existent packages (cors, vhost, balancer etc...)
  • Programmatic scopes API and configuration
  • Basic test coverage (full test coverage should be covered one the API is finally stable and not prone to change too much)

@h2non
Copy link
Member Author

h2non commented May 22, 2016

@groyoh FYI feel free to review this now and in the upcoming days. Implementation details are prone to radically change at this time, but should provide a good enough evidence of intentions and design directions of the overall goal.

@h2non
Copy link
Member Author

h2non commented May 27, 2016

@groyoh I'm supporting a lot of things of different nature in this PR. I understand that doing the review could be harmful, so I would try to simplify this for you. If you're don't have time to answer these or simply are not interested in the project anymore, please let me know since I want to move forward with it without delaying things too much.

There're a lot of features and refactors but in some of them I would really need some feedback about the level of utility of the features and existent API design. The main focus of this PR is creating a both programming and HTTP API layer for the manager package, who is responsible of managing in detail vinxi proxy instance (one or multiple at the same time). To achieve this properly, I've introduced the plugin, rule and scope abstract entities (as we discussed in other issues).

My generic questions are:

  • What do you thing about the current implementation of the plugins/rules/scopes?
  • What do you thing about the current HTTP API?
  • What do you think about the manager programming API?
  • Now we have a mixed concepts between middleware function and plugins which are basically the same but only change their interface and configuration scheme (plugins provides convenient methods to retrieve metadata,configuration params for further introspection and explicit params validator).

I'll work on test everything in the upcoming days and start writing detailed documentation.

@h2non h2non merged commit 808d0a6 into master May 29, 2016
@groyoh
Copy link
Member

groyoh commented Jun 1, 2016

I'll be able to build a proxy prototype tomorrow at work and therefore will give you most my feedback afterward. From what I've been able to check so far both the programming and HTTP API looks fine. The PR was huge though and it was quite hard to review everything but I think I may be able to give some suggestions/input though. In the worst case, I'll be available this weekend to provide some thorough feedback.

@h2non
Copy link
Member Author

h2non commented Jun 1, 2016

That would be great.

@groyoh
Copy link
Member

groyoh commented Jun 4, 2016

I'll add some delayed code review right now and then provide an overview of my thoughts.

@@ -0,0 +1,3 @@
vinxi provides a full-featured programmatic API to easily manage `vinxi` server instance via the `manager` package.
Copy link
Member

Choose a reason for hiding this comment

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

Should we use vinxi or Vinxi (capital "v") throughout the project?

Copy link
Member Author

Choose a reason for hiding this comment

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

I bet for vinxi. I has been using it for a while too.

@h2non
Copy link
Member Author

h2non commented Jun 4, 2016

@groyoh Feel free to do the required changes in the code review in the branch fix/errors:
#42

@groyoh
Copy link
Member

groyoh commented Jun 4, 2016

@h2non will do. I'll still mention it on this PR to keep track of what should be done.


// SendNoContent replies with 204 status code.
func (c *Context) SendNoContent() {
c.Response.WriteHeader(204)
Copy link
Member

Choose a reason for hiding this comment

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

We should use http package constants e.g. http.StatusNoContent.

@groyoh
Copy link
Member

groyoh commented Jun 5, 2016

@h2non So I've reviewed it. Very great job you did here. Concerning your questions:

What do you thing about the current implementation of the plugins/rules/scopes?

They are pretty awesome. I like the concept and I like the implementation. There are definetely a lot of rules and plugins missing but that will come for sure. Also I'm not quite sure I grasp the concept of instances. Maybe you could develop or document a bit on that one. What the point of having two instances for example?

What do you thing about the current HTTP API?

Looks pretty good too. I'm not sure what's the difference between the manager plugin and global plugin:

// Manager admin level plugins routes
route("GET", "/manager", index.Manager)
route("GET", "/manager/plugins", plugins.List)
route("POST", "/manager/plugins", plugins.Create)
route("GET", "/manager/plugins/:plugin", plugins.Get)
route("DELETE", "/manager/plugins/:plugin", plugins.Delete)

// Global plugins routes
route("GET", "/plugins", plugins.List)
route("POST", "/plugins", plugins.Create)
route("GET", "/plugins/:plugin", plugins.Get)
route("DELETE", "/plugins/:plugin", plugins.Delete)

What do you think about the manager programming API?

That's really hard to tell. There is a lot in common with the rest of vinxi API so it looks a bit redundant. Furthermore, there is not enough examples and tests for me to really tell how I feel about it.

Now about the overall project. As I told you, on Thursday I worked a bit on a proxy prototype at work and I found it a bit hard to actually build it. I see three reasons to that:

  • There are not enough examples, especially complex ones.
  • I was not really able to combine all the vinxi power with custom handlers based on our need.
  • I'm not use to Go well enough to easily manage to build this proxy.

I feel that maybe documentation is what's really missing here. A whole bunch a examples on how to use vinxi would probably help.

@groyoh
Copy link
Member

groyoh commented Jun 5, 2016

FYI I'll try to improve test coverage in the next few days.

@h2non
Copy link
Member Author

h2non commented Jun 5, 2016

Also I'm not quite sure I grasp the concept of instances. Maybe you could develop or document a bit on that one. What the point of having two instances for example?

Instances are vinxi proxy instances, so the manager is able to manage multiple proxy instances at the same time.

I'm not sure what's the difference between the manager plugin and global plugin.

Global plugins are plugins that we want to execute in every incoming request for all the managed instances by the manager. Think about it as a hierarchical tree where top nodes are always accessed.

Manager plugins are plugins specifically for the manager HTTP API, so in a future we can support API auth or other features via plugins. I've overloaded the manager server with the same approach we use for vinxi instances via plugins, so we can reuse them as well.

That's really hard to tell. There is a lot in common with the rest of vinxi API so it looks a bit redundant. Furthermore, there is not enough examples and tests for me to really tell how I feel about it.

We need a programmatic API anyway for the CLI implementation and give the ability to developers to create managers programmatically. Not everyone wants to use the HTTP API.

Now about the overall project. As I told you, on Thursday I worked a bit on a proxy prototype at work and I found it a bit hard to actually build it. I see three reasons to that:

Examples are definitively a work in progress and must-have feature. I can work on this soon.
You can also commit some example you've to use in the work.

I was not really able to combine all the vinxi power with custom handlers based on our need.

Can you provide more details? Are you using a multiplexer? What do you want to do?.
I guess this depends on the specific needs, but essentially you can use a generic middleware function and place there what you need.

I'm not use to Go well enough to easily manage to build this proxy.

I guess just writing a main package and configure your proxy should be enough, as you can see in the example. Feel free to share some gist about your use case.

FYI I'll try to improve test coverage in the next few days.

That would be great. I can help you with this. I would like to support tests but during the API design I changed things too much so writing tests at that point could be useless. Now we have a more stable so we should test everything.

@groyoh
Copy link
Member

groyoh commented Jun 5, 2016

Also I'm not quite sure I grasp the concept of instances. Maybe you could develop or document a bit on that one. What the point of having two instances for example?

Instances are vinxi proxy instances, so the manager is able to manage multiple proxy instances at the same time.

In which case would you need multiple instance? I don't have any problem with that but I can't really get the use case.

I was not really able to combine all the vinxi power with custom handlers based on our need.

Can you provide more details? Are you using a multiplexer? What do you want to do?.
I guess this depends on the specific needs, but essentially you can use a generic middleware function and place there what you need.

So what I tried to do use router, intercept, mux and forward. So basically what I need is:

  • have certain prefix forward to different servers with the the prefix remove e.g. http://proxy.example.com/cars/trucks -> http://cars.example.com/trucks.
  • forbid request depending on the client using a specific header e.g. if header Client-Key: com.example.truck only allow the prefix truck.
  • intercept certain requests based on the previous header and the prefix to modify the request and response e.g. if the request is POST http://cars.example.com/trucks and the header is Client-Key: com.example.truck, add a header to the forwarded request.

So I tried to build some custom struct that implements the Handler interface and use these package to achieve these needs. So far, I haven't managed to properly do it. But I guess I'll try again soon.

@h2non
Copy link
Member Author

h2non commented Jun 5, 2016

In which case would you need multiple instance? I don't have any problem with that but I can't really get the use case.

When you have for instance multiple proxy servers running in the same host. It's not common but think about multiple server binds to the network. I thought it would be better to support multiple instance to cover all the scenarios.

So what I tried to do use router, intercept, mux and forward. So basically what I need is:

Try to remove unnecessary layers to remove potential noise... for instance, instead of router you can simply use mux and then register the required middleware, custom or not. You can also compose multiple multiplexers so you can filter in a more accurate way what you need to do.
If you are able to, share a gist with the showcase and I can help you more in detail.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants