cmr: Capture remote space info when creating a remote application #7340

Merged
merged 1 commit into from May 16, 2017

Conversation

Projects
None yet
3 participants
Member

babbageclunk commented May 15, 2017

Description of change

Change the Application facade to capture information (from the provider) about the spaces for a remote application when a remote relation is created or an offer is consumed. This will be used in other parts of the system to decide whether connections between units in each endpoint can use cloud-local addresses rather than going via the public internet (we're calling this short-circuiting).

This required rejigging the apiserver/application code to pass application offers around, since we now have spaces and bindings on them as well as the other information that was being passed around individually.

QA steps

Smoke test bootstrapping and making a remote relation.
No behaviour change yet - a future PR will add ProviderSpaceInfo support to a provider (probably ec2) and then adding a remote relation will capture space info for the remote application.

Member

babbageclunk commented May 15, 2017

!!build!!

Some initial thoughts....

apiserver/application/application.go
result.Endpoints = append(result.Endpoints, params.RemoteEndpoint{
Name: ep.Name,
Interface: ep.Interface,
Role: ep.Role,
Scope: ep.Scope,
Limit: ep.Limit,
})
+ spaceNames.Add(appBindings[ep.Name])
@wallyworld

wallyworld May 15, 2017

Owner

Shouldn't we check that appBindings contains the ep.Name?
Or is that always guaranteed? Will appBindings always contain at the very list an entry for every ep.Name, where that entry may point to the default space? Maybe a comment to explain that? Though I think it would still be better to do a space, ok := appBindings[ep.Name] and error if ok=false just in case?

@babbageclunk

babbageclunk May 15, 2017

Member

My thinking was that if it didn't contain the endpoint then the result would be "" anyway, which is what we'd want here, because we want to get the provider info for the default space in that case. I think it warrants a comment, but I don't want to error if there's no binding. (I'll do a check to confirm that there isn't always an entry for an endpoint if it hasn't been explicitly bound.)

@babbageclunk

babbageclunk May 15, 2017

Member

I'll change it to be more explicit, otherwise it's relying on DefaultSpaceName being "".

@babbageclunk

babbageclunk May 15, 2017

Member

From reading the code of Application.EndpointBindings, if there are no bindings it returns the default bindings for the charm - each endpoint will be mapped to "". It's not so clear reading the code for endpoint_bindings.go:mergeBindings (called from State.AddApplication), but I think the intent there is the same. So I think you're right, it should be an error if the binding isn't found. I'll do that.

apiserver/application/application.go
- releaser()
- }
- }()
+func (api *API) collectRemoteSpaces(st *state.State, spaceNames []string) (map[string]params.RemoteSpace, error) {
@wallyworld

wallyworld May 15, 2017

Owner

this function warrants a comment i think

@babbageclunk

babbageclunk May 15, 2017

Member

Yup, I'll add one.

apiserver/application/application.go
+ results := make(map[string]params.RemoteSpace)
+ for _, name := range spaceNames {
+ space := environs.DefaultSpaceInfo
+ if name != "" {
@wallyworld

wallyworld May 15, 2017

Owner

I thought there was a DefaultSpaceName const somewhere?

@babbageclunk

babbageclunk May 15, 2017

Member

I had a DefaultProviderSpaceId, but I replaced it with DefaultSpaceInfo when I changed the signature of Environ.ProviderSpaceInfo. I'll add another for DefaultSpaceName.

apiserver/application/application.go
+ continue
+ }
+ remoteSpace := ParamsFromProviderSpaceInfo(providerSpace)
+ // Use the name from state in case provider and state disagree.
@wallyworld

wallyworld May 15, 2017

Owner

When would the disagreement happen?
If we are to use the state name, maybe pass it in as an arg to ParamsFromProviderSpaceInfo
But it does seem wrong to expect any difference?

@babbageclunk

babbageclunk May 15, 2017

Member

I'm not sure - I think it could happen if the spaces had been discovered and then renamed in MAAS? Maybe that's not possible, but matching up the bindings wouldn't work unless the names match so it seems like reasonable defensive coding to enforce it.

apiserver/application/conversions.go
@@ -0,0 +1,85 @@
+// Copyright 2015 Canonical Ltd.
@babbageclunk

babbageclunk May 15, 2017

Member

Gah! Dumb cutting and pasting headers!

apiserver/application/conversions.go
+
+// ParamsFromProviderSpaceInfo converts a ProviderSpaceInfo into the
+// equivalent params.RemoteSpace.
+func ParamsFromProviderSpaceInfo(info *environs.ProviderSpaceInfo) params.RemoteSpace {
@wallyworld

wallyworld May 15, 2017

Owner

do these really need to be exported?

@babbageclunk

babbageclunk May 15, 2017

Member

No, they don't, good call - holdover from when they were in apiserver/common/crossmodelcommon.

@@ -238,7 +238,7 @@ func (s *Suite) TestAdoptResources(c *gc.C) {
st := s.Factory.MakeModel(c, nil)
defer st.Close()
- env := mockEnviron{Stub: &testing.Stub{}}
+ env := mockzEnviron{Stub: &testing.Stub{}}
@babbageclunk

babbageclunk May 15, 2017

Member

Doh, yup. Must have mashed the keyboard after running the tests but before committing. :( I should really rerun just before pushing to avoid that.

Can you also ensure dump-model handles the new remote application fields? And also migrate model?
Extra points for replacing "" with DefaultSpaceName in other places

apiserver/application/application.go
- releaser()
- }
- }()
+// collectRemoteSpaces gets provider information about all of the
@wallyworld

wallyworld May 16, 2017

Owner

maybe also explain why they are called "Remote" spaces

Member

babbageclunk commented May 16, 2017

Machine got killed. :|

!!build!!

Capture space information from the remote provider
...when a remote application is created.

Rearranged application API remote application code to make more use of
ApplicationOffer - now that we can rely on an offer existing we don't
need to synthesise one from the application. Use offer endpoints rather
than the application's (ensures we only create remote endpoints for the
offered ones).

Rather than passing the source model tag around separately, use the one
from the params.ApplicationOffer.

Creating the params.ApplicationOffer inside
sameControllerOfferedApplication simplifies the logic for ensuring that
the offering model gets released to the pool.

We pass space info into the provider because we can't rely on the
provider to know which subnets are in a space - MAAS is the only
provider which does. Passing the space info from the state database in
allows the other providers to return sensible ProviderSpaceInfos
including the provider-specific information they have.

Use environs.DefaultSpaceName in EndpointBindings and define a local
defaultEndpointName constant for the places using empty string as a
binding key.
Member

babbageclunk commented May 16, 2017

$$merge$$

Contributor

jujubot commented May 16, 2017

Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju

Contributor

jujubot commented May 16, 2017

Build failed: Tests failed
build url: http://juju-ci.vapour.ws:8080/job/github-merge-juju/10891

Member

babbageclunk commented May 16, 2017

Nil pointer error in agent tests. :(
$$merge$$

Contributor

jujubot commented May 16, 2017

Status: merge request accepted. Url: http://juju-ci.vapour.ws:8080/job/github-merge-juju

@jujubot jujubot merged commit 63e0440 into juju:develop May 16, 2017

1 check passed

github-check-merge-juju Built PR, ran unit tests, and tested LXD deploy. Use !!.*!! to request another build. IE, !!build!!, !!retry!!
Details

@babbageclunk babbageclunk deleted the babbageclunk:capture-space-info branch May 16, 2017

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