Merge lp:~axwalk/juju-core/api-disable-secrets-pushing into lp:~go-bot/juju-core/trunk

Proposed by Andrew Wilkins
Status: Merged
Approved by: Andrew Wilkins
Approved revision: no longer in the source branch.
Merged at revision: 2126
Proposed branch: lp:~axwalk/juju-core/api-disable-secrets-pushing
Merge into: lp:~go-bot/juju-core/trunk
Diff against target: 220 lines (+26/-66)
7 files modified
environs/cloudinit_test.go (+0/-1)
environs/config.go (+6/-16)
environs/config_test.go (+0/-1)
juju/api.go (+0/-36)
juju/apiconn_test.go (+2/-5)
juju/conn_test.go (+18/-6)
juju/export_test.go (+0/-1)
To merge this branch: bzr merge lp:~axwalk/juju-core/api-disable-secrets-pushing
Reviewer Review Type Date Requested Status
Juju Engineering Pending
Review via email: mp+197673@code.launchpad.net

Commit message

Remove secrets-pushing for new bootstraps, API

- environs/BootstrapConfig now no longer removes
  secret attributes from configuration. This is
  on account of configuration not being populated
  into cloud-init config now.
- juju/NewAPIConn now no longer pushes secrets,
  as it is not necessary. This was not present in
  1.16, so it is not a compatibility concern.

If we're okay with disabling new CLI from initialising
an old juju server, then we can also remove secrets
pushing from juju/NewConn. Doing this would allow us
to drop all notion of "secret attributes".

https://codereview.appspot.com/37090043/

Description of the change

Remove secrets-pushing for new bootstraps, API

- environs/BootstrapConfig now no longer removes
  secret attributes from configuration. This is
  on account of configuration not being populated
  into cloud-init config now.
- juju/NewAPIConn now no longer pushes secrets,
  as it is not necessary. This was not present in
  1.16, so it is not a compatibility concern.

If we're okay with disabling new CLI from initialising
an old juju server, then we can also remove secrets
pushing from juju/NewConn. Doing this would allow us
to drop all notion of "secret attributes".

https://codereview.appspot.com/37090043/

To post a comment you must log in.
Revision history for this message
Andrew Wilkins (axwalk) wrote :
Download full text (7.8 KiB)

Reviewers: mp+197673_code.launchpad.net,

Message:
Please take a look.

Description:
Remove secrets-pushing for new bootstraps, API

- environs/BootstrapConfig now no longer removes
   secret attributes from configuration. This is
   on account of configuration not being populated
   into cloud-init config now.
- juju/NewAPIConn now no longer pushes secrets,
   as it is not necessary. This was not present in
   1.16, so it is not a compatibility concern.

If we're okay with disabling new CLI from initialising
an old juju server, then we can also remove secrets
pushing from juju/NewConn. Doing this would allow us
to drop all notion of "secret attributes".

https://code.launchpad.net/~axwalk/juju-core/api-disable-secrets-pushing/+merge/197673

(do not edit description out of merge proposal)

Please review this at https://codereview.appspot.com/37090043/

Affected files (+7, -71 lines):
   A [revision details]
   M environs/cloudinit_test.go
   M environs/config.go
   M environs/config_test.go
   M juju/api.go
   M juju/apiconn_test.go
   M juju/conn_test.go
   M juju/export_test.go

Index: [revision details]
=== added file '[revision details]'
--- [revision details] 2012-01-01 00:00:00 +0000
+++ [revision details] 2012-01-01 00:00:00 +0000
@@ -0,0 +1,2 @@
+Old revision: tarmac-20131203182636-on3s53irtmfaw1di
+New revision: <email address hidden>

Index: environs/cloudinit_test.go
=== modified file 'environs/cloudinit_test.go'
--- environs/cloudinit_test.go 2013-12-03 06:04:43 +0000
+++ environs/cloudinit_test.go 2013-12-04 10:18:57 +0000
@@ -124,7 +124,6 @@

   oldAttrs["ca-private-key"] = ""
   oldAttrs["admin-secret"] = ""
- delete(oldAttrs, "secret")
   c.Check(mcfg.Config.AllAttrs(), gc.DeepEquals, oldAttrs)
   srvCertPEM := mcfg.StateServerCert
   srvKeyPEM := mcfg.StateServerKey

Index: environs/config.go
=== modified file 'environs/config.go'
--- environs/config.go 2013-11-13 08:15:10 +0000
+++ environs/config.go 2013-12-04 10:18:57 +0000
@@ -202,23 +202,12 @@
  // secret attributes removed. If the resulting config is not suitable
  // for bootstrapping an environment, an error is returned.
  func BootstrapConfig(cfg *config.Config) (*config.Config, error) {
- p, err := Provider(cfg.Type())
- if err != nil {
- return nil, err
- }
- secrets, err := p.SecretAttrs(cfg)
- if err != nil {
- return nil, err
- }
   m := cfg.AllAttrs()
- for k := range secrets {
- delete(m, k)
- }
-
   // We never want to push admin-secret or the root CA private key to the
cloud.
   delete(m, "admin-secret")
   delete(m, "ca-private-key")
- if cfg, err = config.New(config.NoDefaults, m); err != nil {
+ cfg, err := config.New(config.NoDefaults, m)
+ if err != nil {
    return nil, err
   }
   if _, ok := cfg.AgentVersion(); !ok {

Index: environs/config_test.go
=== modified file 'environs/config_test.go'
--- environs/config_test.go 2013-11-20 04:28:46 +0000
+++ environs/config_test.go 2013-12-04 10:18:57 +0000
@@ -296,7 +296,6 @@
   c.Assert(err, gc.IsNil)

   expect := cfg.AllAttrs()
- delete(expect, "secret")
   expect["admin-secret"] = ""
   expect["ca-private-key"] = ""
   c.Assert(cfg1.AllAttrs(), gc.DeepEquals,...

Read more...

Revision history for this message
William Reade (fwereade) wrote :

I think we should keep the secret-handling in Conn, until we actually
lose Conn itself -- I'm sure *someone* will make the first connection to
a new env with an old client, and I'd rather not break whoever that
turns out to be.

And I don't think we can drop the notion of secret attrs: (1) we're
still using them in the API server, although that can go any time we
like, but (2) more importantly, we'll need to restrict their display to
non-admin users in the very near future.

On to the review...

https://codereview.appspot.com/37090043/

Revision history for this message
William Reade (fwereade) wrote :

This is great, just a few notes. Rog, can you think of any disadvantage
to just pushing the CA private key now?

...or even generating the whole thing on the server side, and never even
putting the key on the user's machine?

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go
File environs/cloudinit_test.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go#oldcode130
environs/cloudinit_test.go:130: srvKeyPEM := mcfg.StateServerKey
It concerns me a little that this is increasingly poorly-named, because
it's now about initializing juju not driving cloudinit. Can we just
rename environs/cloudinit and this file (and associated types...) now
please?

https://codereview.appspot.com/37090043/diff/1/environs/config.go
File environs/config.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/config.go#oldcode218
environs/config.go:218: // We never want to push admin-secret or the
root CA private key to the cloud.
FWIW, we rather do want to push the CA private key now, because we'll
need to generate new certs for new state servers soon. Maybe not
necessary to change it now.

https://codereview.appspot.com/37090043/diff/1/juju/api.go
File juju/api.go (left):

https://codereview.appspot.com/37090043/diff/1/juju/api.go#oldcode98
juju/api.go:98: }
\o/

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go
File juju/conn_test.go (right):

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go#newcode137
juju/conn_test.go:137: // Verify we have secrets in the environ config
already.
I think we should still test that Conn still does the dance if it's
required.

https://codereview.appspot.com/37090043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

Please take a look.

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go
File environs/cloudinit_test.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go#oldcode130
environs/cloudinit_test.go:130: srvKeyPEM := mcfg.StateServerKey
On 2013/12/04 14:13:09, fwereade wrote:
> It concerns me a little that this is increasingly poorly-named,
because it's now
> about initializing juju not driving cloudinit. Can we just rename
> environs/cloudinit and this file (and associated types...) now please?

Sure. environs/jujuinit?

Can I do this in a followup? There are quite a few files to touch.

https://codereview.appspot.com/37090043/diff/1/environs/config.go
File environs/config.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/config.go#oldcode218
environs/config.go:218: // We never want to push admin-secret or the
root CA private key to the cloud.
On 2013/12/04 14:13:09, fwereade wrote:
> FWIW, we rather do want to push the CA private key now, because we'll
need to
> generate new certs for new state servers soon. Maybe not necessary to
change it
> now.

Okay. Regarding your question about "generating the [ca private key] on
the server side": it wouldn't be *too* hard, but it will mean we'll need
to
  - update jujud to be able to generate certs/keys, so we can initialise
mongo
  - update agent config code to take the cert/key from a file (?)
  - update worker/localstorage to generate a new key server-side also.
This would mean threading the CA cert/key through somehow.

Not overly difficult, but I think it warrants a CL to itself.

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go
File juju/conn_test.go (right):

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go#newcode137
juju/conn_test.go:137: // Verify we have secrets in the environ config
already.
On 2013/12/04 14:13:09, fwereade wrote:
> I think we should still test that Conn still does the dance if it's
required.

Done. Adding the test in is slightly tricky, given that we always have
secrets now. I've gotten around this by modifying provider/dummy to
elide the standard secret if it's set to a special value, and add in
another (unknown attr) secret if it is present. It's a bit ugly - if you
have a better idea of how to do this, please let me know.

https://codereview.appspot.com/37090043/

Revision history for this message
Roger Peppe (rogpeppe) wrote :
Download full text (4.4 KiB)

Looks great. A few remarks below.

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go
File environs/cloudinit_test.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go#oldcode130
environs/cloudinit_test.go:130: srvKeyPEM := mcfg.StateServerKey
On 2013/12/04 14:13:09, fwereade wrote:
> It concerns me a little that this is increasingly poorly-named,
because it's now
> about initializing juju not driving cloudinit. Can we just rename
> environs/cloudinit and this file (and associated types...) now please?

I'm not entirely sure. The principal function of this package is to
transform a MachineConfig structure into a cloudinit structure, which
seems quite cloudinit-specific to me and reasonably well focused.

What's changed about this package that leads to to think that it's
changed enough to warrant a rename?

BTW, I could easily see the MachineConfig type moving out of this
package FWIW.

If we *are* to rename this package, then perhaps environs/init might
work - after all it's all juju around here :-)

https://codereview.appspot.com/37090043/diff/1/environs/config.go
File environs/config.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/config.go#oldcode218
environs/config.go:218: // We never want to push admin-secret or the
root CA private key to the cloud.
On 2013/12/05 07:40:35, axw wrote:
> On 2013/12/04 14:13:09, fwereade wrote:
> > FWIW, we rather do want to push the CA private key now, because
we'll need to
> > generate new certs for new state servers soon. Maybe not necessary
to change
> it
> > now.

> Okay. Regarding your question about "generating the [ca private key]
on the
> server side": it wouldn't be *too* hard, but it will mean we'll need
to
> - update jujud to be able to generate certs/keys, so we can
initialise mongo
> - update agent config code to take the cert/key from a file (?)
> - update worker/localstorage to generate a new key server-side also.
This would
> mean threading the CA cert/key through somehow.

> Not overly difficult, but I think it warrants a CL to itself.

If we generate the root CA private key on the server side, otherwise how
do we verify that we're talking to the right server when we make our
initial connection? If we don't do key verification then ISTM that we're
vulnerable to a MitM attack even if the transport to the provider API is
secure (if it isn't then all bets are off, of course).

BTW even if we don't push the root CA private key, we can still push a
cert/key that can be used to sign new state server certs - we'd just
need to turn on the delegation flag.

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go
File juju/conn_test.go (right):

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go#newcode137
juju/conn_test.go:137: // Verify we have secrets in the environ config
already.
On 2013/12/05 07:40:35, axw wrote:
> On 2013/12/04 14:13:09, fwereade wrote:
> > I think we should still test that Conn still does the dance if it's
required.

> Done. Adding the test in is slightly tricky, given that we always have
secrets
> now. I've gotten around this by modifying provider/dummy to elide the
sta...

Read more...

Revision history for this message
Andrew Wilkins (axwalk) wrote :

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go
File juju/conn_test.go (right):

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go#newcode137
juju/conn_test.go:137: // Verify we have secrets in the environ config
already.
On 2013/12/05 13:20:21, rog wrote:
> On 2013/12/05 07:40:35, axw wrote:
> > On 2013/12/04 14:13:09, fwereade wrote:
> > > I think we should still test that Conn still does the dance if
it's
> required.
> >
> > Done. Adding the test in is slightly tricky, given that we always
have secrets
> > now. I've gotten around this by modifying provider/dummy to elide
the standard
> > secret if it's set to a special value, and add in another (unknown
attr)
> secret
> > if it is present. It's a bit ugly - if you have a better idea of how
to do
> this,
> > please let me know.

> Ah, now I understand the dummy thing. Wouldn't it be easier to make
the test
> specifically delete the secret from the config in state after
bootstrapping?
> Would we still need the ugly dummy logic then?

Sadly, it's not really easier. I would prefer to do that, but
SetEnvironConfig in state never removes any old settings, it only
updates. There's a bug about that somewhere, but it's not clear to me
whether this is required behaviour.

https://codereview.appspot.com/37090043/diff/10001/environs/config_test.go
File environs/config_test.go (left):

https://codereview.appspot.com/37090043/diff/10001/environs/config_test.go#oldcode299
environs/config_test.go:299: delete(expect, "secret")
On 2013/12/05 13:20:21, rog wrote:
> Was this broken before? I thought BootstrapConfig was supposed to
elide secrets.

It used to, but not anymore (that's the primary change).
The assertion here used to be that the config returned by
BootstrapConfig didn't have secrets; the assertion is now that it does.

https://codereview.appspot.com/37090043/

Revision history for this message
Roger Peppe (rogpeppe) wrote :

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go
File juju/conn_test.go (right):

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go#newcode137
juju/conn_test.go:137: // Verify we have secrets in the environ config
already.
On 2013/12/05 15:05:25, axw wrote:
> On 2013/12/05 13:20:21, rog wrote:
> > On 2013/12/05 07:40:35, axw wrote:
> > > On 2013/12/04 14:13:09, fwereade wrote:
> > > > I think we should still test that Conn still does the dance if
it's
> > required.
> > >
> > > Done. Adding the test in is slightly tricky, given that we always
have
> secrets
> > > now. I've gotten around this by modifying provider/dummy to elide
the
> standard
> > > secret if it's set to a special value, and add in another (unknown
attr)
> > secret
> > > if it is present. It's a bit ugly - if you have a better idea of
how to do
> > this,
> > > please let me know.
> >
> > Ah, now I understand the dummy thing. Wouldn't it be easier to make
the test
> > specifically delete the secret from the config in state after
bootstrapping?
> > Would we still need the ugly dummy logic then?

> Sadly, it's not really easier. I would prefer to do that, but
SetEnvironConfig
> in state never removes any old settings, it only updates. There's a
bug about
> that somewhere, but it's not clear to me whether this is required
behaviour.

If that's the problem, rather than the ugly and non-obvious code in
dummy, why not write a little function on State specifically to delete
environment config attributes? We might only use the code in this test,
but at least its purpose would be straightforward and its structure not
predicated on some far removed test.

dummy is already too complex - adding warts like this won't help.

https://codereview.appspot.com/37090043/diff/10001/environs/config.go
File environs/config.go (right):

https://codereview.appspot.com/37090043/diff/10001/environs/config.go#newcode202
environs/config.go:202: // secret attributes removed. If the resulting
config is not suitable
This comment is wrong now because we're not removing all secret
attributes.

https://codereview.appspot.com/37090043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :

On 2013/12/05 15:35:09, rog wrote:
> https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go
> File juju/conn_test.go (right):

https://codereview.appspot.com/37090043/diff/1/juju/conn_test.go#newcode137
> juju/conn_test.go:137: // Verify we have secrets in the environ config
already.
> On 2013/12/05 15:05:25, axw wrote:
> > On 2013/12/05 13:20:21, rog wrote:
> > > On 2013/12/05 07:40:35, axw wrote:
> > > > On 2013/12/04 14:13:09, fwereade wrote:
> > > > > I think we should still test that Conn still does the dance if
it's
> > > required.
> > > >
> > > > Done. Adding the test in is slightly tricky, given that we
always have
> > secrets
> > > > now. I've gotten around this by modifying provider/dummy to
elide the
> > standard
> > > > secret if it's set to a special value, and add in another
(unknown attr)
> > > secret
> > > > if it is present. It's a bit ugly - if you have a better idea of
how to do
> > > this,
> > > > please let me know.
> > >
> > > Ah, now I understand the dummy thing. Wouldn't it be easier to
make the test
> > > specifically delete the secret from the config in state after
bootstrapping?
> > > Would we still need the ugly dummy logic then?
> >
> > Sadly, it's not really easier. I would prefer to do that, but
SetEnvironConfig
> > in state never removes any old settings, it only updates. There's a
bug about
> > that somewhere, but it's not clear to me whether this is required
behaviour.

> If that's the problem, rather than the ugly and non-obvious code in
dummy, why
> not write a little function on State specifically to delete
environment config
> attributes? We might only use the code in this test, but at least its
purpose
> would be straightforward and its structure not predicated on some far
removed
> test.

> dummy is already too complex - adding warts like this won't help.

Yeah, fair enough.
I'm going to look at fixing
https://bugs.launchpad.net/juju-core/+bug/1167616. I'll come back to
this once that's done (or shown to take too much time).

> https://codereview.appspot.com/37090043/diff/10001/environs/config.go
> File environs/config.go (right):

https://codereview.appspot.com/37090043/diff/10001/environs/config.go#newcode202
> environs/config.go:202: // secret attributes removed. If the resulting
config is
> not suitable
> This comment is wrong now because we're not removing all secret
attributes.

Well it doesn't say it takes away *all* the secrets ;)
I'll update the comment and repropose when I've fixed the other thing.

https://codereview.appspot.com/37090043/

Revision history for this message
Andrew Wilkins (axwalk) wrote :
Revision history for this message
William Reade (fwereade) wrote :
Download full text (3.9 KiB)

Essentially LGTM -- you can land this now, but let's come to a decision
re the CA cert private key and whether we push it during bootstrap, or
enable delegation; and land that followup sooner rather than later. Does
anyone feel strongly either way?

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go
File environs/cloudinit_test.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go#oldcode130
environs/cloudinit_test.go:130: srvKeyPEM := mcfg.StateServerKey
On 2013/12/05 13:20:21, rog wrote:
> On 2013/12/04 14:13:09, fwereade wrote:
> > It concerns me a little that this is increasingly poorly-named,
because it's
> now
> > about initializing juju not driving cloudinit. Can we just rename
> > environs/cloudinit and this file (and associated types...) now
please?

> I'm not entirely sure. The principal function of this package is to
transform a
> MachineConfig structure into a cloudinit structure, which seems quite
> cloudinit-specific to me and reasonably well focused.

> What's changed about this package that leads to to think that it's
changed
> enough to warrant a rename?

> BTW, I could easily see the MachineConfig type moving out of this
package FWIW.

> If we *are* to rename this package, then perhaps environs/init might
work -
> after all it's all juju around here :-)

I think we've got our concepts a bit tangled around here. We're treating
cloudinit as the canonical representation and generating different forms
of initialization from one of those, rather than generating an
initialization type and rendering it into a cloudinit form. (That's why
I was grumpy about creating environs/cloudinit in the first place -- I
feared it'd entrench exactly this ill-factoring -- but I guess I didn't
express myself well.)

https://codereview.appspot.com/37090043/diff/1/environs/config.go
File environs/config.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/config.go#oldcode218
environs/config.go:218: // We never want to push admin-secret or the
root CA private key to the cloud.
On 2013/12/05 13:20:21, rog wrote:
> On 2013/12/05 07:40:35, axw wrote:
> > On 2013/12/04 14:13:09, fwereade wrote:
> > > FWIW, we rather do want to push the CA private key now, because
we'll need
> to
> > > generate new certs for new state servers soon. Maybe not necessary
to change
> > it
> > > now.
> >
> > Okay. Regarding your question about "generating the [ca private key]
on the
> > server side": it wouldn't be *too* hard, but it will mean we'll need
to
> > - update jujud to be able to generate certs/keys, so we can
initialise mongo
> > - update agent config code to take the cert/key from a file (?)
> > - update worker/localstorage to generate a new key server-side
also. This
> would
> > mean threading the CA cert/key through somehow.
> >
> > Not overly difficult, but I think it warrants a CL to itself.

> If we generate the root CA private key on the server side, otherwise
how do we
> verify that we're talking to the right server when we make our initial
> connection? If we don't do key verification then ISTM that we're
vulnerable to a
> MitM attack even if the transport to the provider API is secur...

Read more...

Revision history for this message
Andrew Wilkins (axwalk) wrote :
Download full text (4.9 KiB)

On 2013/12/09 10:33:10, fwereade wrote:
> Essentially LGTM -- you can land this now, but let's come to a
decision re the
> CA cert private key and whether we push it during bootstrap, or enable
> delegation; and land that followup sooner rather than later. Does
anyone feel
> strongly either way?

Just throwing an alternative out there (based on the "push during
bootstrap" option). It has come up on the mailing list that it would be
useful to operate over SSH, to better deal with restricted access
environments (i.e. so you don't need to use sshuttle.)

So, we could generate the cert/keys entirely server side, and never use
it for the CLI. The CLI could SSH to the machine with a forwarded port
(or multiplex over the stdio), and the API server could allow plaintext
communication to localhost. This way we get SSH proxying, with only SSH
keys stored outside the environment.

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go
> File environs/cloudinit_test.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/cloudinit_test.go#oldcode130
> environs/cloudinit_test.go:130: srvKeyPEM := mcfg.StateServerKey
> On 2013/12/05 13:20:21, rog wrote:
> > On 2013/12/04 14:13:09, fwereade wrote:
> > > It concerns me a little that this is increasingly poorly-named,
because it's
> > now
> > > about initializing juju not driving cloudinit. Can we just rename
> > > environs/cloudinit and this file (and associated types...) now
please?
> >
> > I'm not entirely sure. The principal function of this package is to
transform
> a
> > MachineConfig structure into a cloudinit structure, which seems
quite
> > cloudinit-specific to me and reasonably well focused.
> >
> > What's changed about this package that leads to to think that it's
changed
> > enough to warrant a rename?
> >
> > BTW, I could easily see the MachineConfig type moving out of this
package
> FWIW.
> >
> > If we *are* to rename this package, then perhaps environs/init might
work -
> > after all it's all juju around here :-)

> I think we've got our concepts a bit tangled around here. We're
treating
> cloudinit as the canonical representation and generating different
forms of
> initialization from one of those, rather than generating an
initialization type
> and rendering it into a cloudinit form. (That's why I was grumpy about
creating
> environs/cloudinit in the first place -- I feared it'd entrench
exactly this
> ill-factoring -- but I guess I didn't express myself well.)

Fair call. When I did the synchronous bootstrap work, I did start down
the road of creating a new canonical representation. It would've
essentially ended up as a clone of a subset of cloudinit.Config, though,
so it didn't seem worthwhile at the time. It may be worthwhile
revisiting.

> https://codereview.appspot.com/37090043/diff/1/environs/config.go
> File environs/config.go (left):

https://codereview.appspot.com/37090043/diff/1/environs/config.go#oldcode218
> environs/config.go:218: // We never want to push admin-secret or the
root CA
> private key to the cloud.
> On 2013/12/05 13:20:21, rog wrote:
> > On 2013/12/05 07:40:35, axw wrote:
> > > On 2013/12/04 14:13:09, fwereade wrote:
> > > > FWIW, w...

Read more...

Revision history for this message
John A Meinel (jameinel) wrote :

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

On 2013-12-10 6:54, Andrew Wilkins wrote:
> On 2013/12/09 10:33:10, fwereade wrote:
>> Essentially LGTM -- you can land this now, but let's come to a
> decision re the
>> CA cert private key and whether we push it during bootstrap, or
>> enable delegation; and land that followup sooner rather than
>> later. Does
> anyone feel
>> strongly either way?
>
> Just throwing an alternative out there (based on the "push during
> bootstrap" option). It has come up on the mailing list that it
> would be useful to operate over SSH, to better deal with restricted
> access environments (i.e. so you don't need to use sshuttle.)
>
> So, we could generate the cert/keys entirely server side, and never
> use it for the CLI. The CLI could SSH to the machine with a
> forwarded port (or multiplex over the stdio), and the API server
> could allow plaintext communication to localhost. This way we get
> SSH proxying, with only SSH keys stored outside the environment.
>

Pyjuju did that, but it was *not* a good user experience.
'time ssh host' is much longer than TLS.Connect.

"openssl s_time $EC2INSTANCE:17070"

says that I can connect to my EC2 instance 45 times in 31s. (682ms per
connect)

time for i in `seq 10`; do ssh ubuntu@$EC2INSTANCE /bin/false; done
is 39.2s, or 3.92s per connect.

Roughly 5-6 times slower.

So yes, it would be possible, and it might be a mode that we want to
allow you to enable "ssh-tunneling-mode: true" or something like that.
But I don't think we want it to be the default mode because the
experience is pretty terrible.

John
=:->
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.13 (Cygwin)
Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/

iEYEARECAAYFAlKonYcACgkQJdeBCYSNAAOPdgCeJtM/Scc4ZzMx1zkG5+gYEBzt
DcAAn1lt8YHLMbK0+UhKQymlHhF8Q/kl
=eVxp
-----END PGP SIGNATURE-----

Revision history for this message
Andrew Wilkins (axwalk) wrote :

On Thu, Dec 12, 2013 at 1:14 AM, John Arbash Meinel
<email address hidden>wrote:

> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> On 2013-12-10 6:54, Andrew Wilkins wrote:
> > On 2013/12/09 10:33:10, fwereade wrote:
> >> Essentially LGTM -- you can land this now, but let's come to a
> > decision re the
> >> CA cert private key and whether we push it during bootstrap, or
> >> enable delegation; and land that followup sooner rather than
> >> later. Does
> > anyone feel
> >> strongly either way?
> >
> > Just throwing an alternative out there (based on the "push during
> > bootstrap" option). It has come up on the mailing list that it
> > would be useful to operate over SSH, to better deal with restricted
> > access environments (i.e. so you don't need to use sshuttle.)
> >
> > So, we could generate the cert/keys entirely server side, and never
> > use it for the CLI. The CLI could SSH to the machine with a
> > forwarded port (or multiplex over the stdio), and the API server
> > could allow plaintext communication to localhost. This way we get
> > SSH proxying, with only SSH keys stored outside the environment.
> >
>
> Pyjuju did that, but it was *not* a good user experience.
> 'time ssh host' is much longer than TLS.Connect.
>
> "openssl s_time $EC2INSTANCE:17070"
>
> says that I can connect to my EC2 instance 45 times in 31s. (682ms per
> connect)
>
> time for i in `seq 10`; do ssh ubuntu@$EC2INSTANCE /bin/false; done
> is 39.2s, or 3.92s per connect.
>
> Roughly 5-6 times slower.
>
> So yes, it would be possible, and it might be a mode that we want to
> allow you to enable "ssh-tunneling-mode: true" or something like that.
> But I don't think we want it to be the default mode because the
> experience is pretty terrible.
>

Yeah, I expected the time to connect would be an issue. I agree that it
probably should be off by default, if we do it at all. The problem can be
mitigated somewhat by having a long-running background process on the CLI
machine that holds an SSH "ControlMaster" socket open; the first connection
will still be slow of course.

John
> =:->
> -----BEGIN PGP SIGNATURE-----
> Version: GnuPG v1.4.13 (Cygwin)
> Comment: Using GnuPG with Thunderbird - http://www.enigmail.net/
>
> iEYEARECAAYFAlKonYcACgkQJdeBCYSNAAOPdgCeJtM/Scc4ZzMx1zkG5+gYEBzt
> DcAAn1lt8YHLMbK0+UhKQymlHhF8Q/kl
> =eVxp
> -----END PGP SIGNATURE-----
>

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'environs/cloudinit_test.go'
2--- environs/cloudinit_test.go 2013-12-03 06:04:43 +0000
3+++ environs/cloudinit_test.go 2013-12-06 09:49:29 +0000
4@@ -124,7 +124,6 @@
5
6 oldAttrs["ca-private-key"] = ""
7 oldAttrs["admin-secret"] = ""
8- delete(oldAttrs, "secret")
9 c.Check(mcfg.Config.AllAttrs(), gc.DeepEquals, oldAttrs)
10 srvCertPEM := mcfg.StateServerCert
11 srvKeyPEM := mcfg.StateServerKey
12
13=== modified file 'environs/config.go'
14--- environs/config.go 2013-11-13 08:15:10 +0000
15+++ environs/config.go 2013-12-06 09:49:29 +0000
16@@ -198,27 +198,17 @@
17 return environsFilepath, nil
18 }
19
20-// BootstrapConfig returns a copy of the supplied configuration with
21-// secret attributes removed. If the resulting config is not suitable
22-// for bootstrapping an environment, an error is returned.
23+// BootstrapConfig returns a copy of the supplied configuration with the
24+// admin-secret and ca-private-key attributes removed. If the resulting
25+// config is not suitable for bootstrapping an environment, an error is
26+// returned.
27 func BootstrapConfig(cfg *config.Config) (*config.Config, error) {
28- p, err := Provider(cfg.Type())
29- if err != nil {
30- return nil, err
31- }
32- secrets, err := p.SecretAttrs(cfg)
33- if err != nil {
34- return nil, err
35- }
36 m := cfg.AllAttrs()
37- for k := range secrets {
38- delete(m, k)
39- }
40-
41 // We never want to push admin-secret or the root CA private key to the cloud.
42 delete(m, "admin-secret")
43 delete(m, "ca-private-key")
44- if cfg, err = config.New(config.NoDefaults, m); err != nil {
45+ cfg, err := config.New(config.NoDefaults, m)
46+ if err != nil {
47 return nil, err
48 }
49 if _, ok := cfg.AgentVersion(); !ok {
50
51=== modified file 'environs/config_test.go'
52--- environs/config_test.go 2013-11-20 04:28:46 +0000
53+++ environs/config_test.go 2013-12-06 09:49:29 +0000
54@@ -296,7 +296,6 @@
55 c.Assert(err, gc.IsNil)
56
57 expect := cfg.AllAttrs()
58- delete(expect, "secret")
59 expect["admin-secret"] = ""
60 expect["ca-private-key"] = ""
61 c.Assert(cfg1.AllAttrs(), gc.DeepEquals, expect)
62
63=== modified file 'juju/api.go'
64--- juju/api.go 2013-11-21 15:22:31 +0000
65+++ juju/api.go 2013-12-06 09:49:29 +0000
66@@ -13,7 +13,6 @@
67 "launchpad.net/juju-core/environs/config"
68 "launchpad.net/juju-core/environs/configstore"
69 "launchpad.net/juju-core/errors"
70- "launchpad.net/juju-core/rpc"
71 "launchpad.net/juju-core/state/api"
72 )
73
74@@ -56,47 +55,12 @@
75 if err != nil {
76 return nil, err
77 }
78- // TODO(axw) remove this once we have synchronous bootstrap.
79- if err := updateSecrets(environ, st); err != nil {
80- apiClose(st)
81- return nil, err
82- }
83 return &APIConn{
84 Environ: environ,
85 State: st,
86 }, nil
87 }
88
89-// updateSecrets pushes environment secrets to the API server.
90-// NOTE: this is a temporary hack, and will disappear when we
91-// have synchronous bootstrap.
92-var updateSecrets = func(environ environs.Environ, st *api.State) error {
93- secrets, err := environ.Provider().SecretAttrs(environ.Config())
94- if err != nil {
95- return err
96- }
97- client := st.Client()
98- cfg, err := client.EnvironmentGet()
99- if rpc.IsNoSuchRequest(err) {
100- // Ignore checking for secrets when using an older (1.16) API
101- // server. This should be removed in 1.18.
102- logger.Warningf("running in 1.16 compatibility mode; connection may fail if environment is just bootstrapped")
103- return nil
104- }
105- if err != nil {
106- return err
107- }
108- for k, v := range secrets {
109- if _, exists := cfg[k]; exists {
110- // Environment already has secrets. Won't send again.
111- return nil
112- } else {
113- cfg[k] = v
114- }
115- }
116- return client.EnvironmentSet(cfg)
117-}
118-
119 // Close terminates the connection to the environment and releases
120 // any associated resources.
121 func (c *APIConn) Close() error {
122
123=== modified file 'juju/apiconn_test.go'
124--- juju/apiconn_test.go 2013-11-07 06:48:00 +0000
125+++ juju/apiconn_test.go 2013-12-06 09:49:29 +0000
126@@ -65,8 +65,9 @@
127 c.Assert(conn.Environ, gc.Equals, env)
128 c.Assert(conn.State, gc.NotNil)
129
130+ // the secrets will not be updated, as they already exist
131 attrs, err := conn.State.Client().EnvironmentGet()
132- c.Assert(attrs["secret"], gc.Equals, "fnord")
133+ c.Assert(attrs["secret"], gc.Equals, "pork")
134
135 c.Assert(conn.Close(), gc.IsNil)
136 }
137@@ -137,7 +138,6 @@
138 return expectState, nil
139 }
140 defer testbase.PatchValue(juju.APIOpen, apiOpen).Restore()
141- defer testbase.PatchValue(juju.UpdateSecrets, updateSecretsNoop).Restore()
142 st, err := juju.NewAPIFromName("noconfig", store)
143 c.Assert(err, gc.IsNil)
144 c.Assert(st, gc.Equals, expectState)
145@@ -186,7 +186,6 @@
146 return nil, expectErr
147 }
148 defer testbase.PatchValue(juju.APIOpen, apiOpen).Restore()
149- defer testbase.PatchValue(juju.UpdateSecrets, updateSecretsNoop).Restore()
150 st, err := juju.NewAPIFromName("noconfig", store)
151 c.Assert(err, gc.Equals, expectErr)
152 c.Assert(st, gc.IsNil)
153@@ -213,7 +212,6 @@
154 return cfgOpenedState, nil
155 }
156 defer testbase.PatchValue(juju.APIOpen, apiOpen).Restore()
157- defer testbase.PatchValue(juju.UpdateSecrets, updateSecretsNoop).Restore()
158
159 stateClosed, restoreAPIClose := setAPIClosed()
160 defer restoreAPIClose.Restore()
161@@ -278,7 +276,6 @@
162 return cfgOpenedState, nil
163 }
164 defer testbase.PatchValue(juju.APIOpen, apiOpen).Restore()
165- defer testbase.PatchValue(juju.UpdateSecrets, updateSecretsNoop).Restore()
166
167 stateClosed, restoreAPIClose := setAPIClosed()
168 defer restoreAPIClose.Restore()
169
170=== modified file 'juju/conn_test.go'
171--- juju/conn_test.go 2013-11-19 17:25:24 +0000
172+++ juju/conn_test.go 2013-12-06 09:49:29 +0000
173@@ -134,19 +134,31 @@
174 st, err := state.Open(info, state.DefaultDialOpts())
175 c.Assert(err, gc.IsNil)
176
177- // Verify we have no secret in the environ config
178- cfg, err = st.EnvironConfig()
179- c.Assert(err, gc.IsNil)
180- c.Assert(cfg.UnknownAttrs()["secret"], gc.IsNil)
181+ // Verify we have secrets in the environ config already.
182+ statecfg, err := st.EnvironConfig()
183+ c.Assert(err, gc.IsNil)
184+ c.Assert(statecfg.UnknownAttrs()["secret"], gc.Equals, "pork")
185+
186+ // Remove the secret from state, and then make sure it gets
187+ // pushed back again.
188+ attrs = statecfg.AllAttrs()
189+ delete(attrs, "secret")
190+ newcfg, err := config.New(config.NoDefaults, attrs)
191+ c.Assert(err, gc.IsNil)
192+ err = st.SetEnvironConfig(newcfg, statecfg)
193+ c.Assert(err, gc.IsNil)
194+ statecfg, err = st.EnvironConfig()
195+ c.Assert(err, gc.IsNil)
196+ c.Assert(statecfg.UnknownAttrs()["secret"], gc.IsNil)
197
198 // Make a new Conn, which will push the secrets.
199 conn, err := juju.NewConn(env)
200 c.Assert(err, gc.IsNil)
201 defer conn.Close()
202
203- cfg, err = conn.State.EnvironConfig()
204+ statecfg, err = conn.State.EnvironConfig()
205 c.Assert(err, gc.IsNil)
206- c.Assert(cfg.UnknownAttrs()["secret"], gc.Equals, "pork")
207+ c.Assert(statecfg.UnknownAttrs()["secret"], gc.Equals, "pork")
208
209 // Reset the admin password so the state db can be reused.
210 err = conn.State.SetAdminMongoPassword("")
211
212=== modified file 'juju/export_test.go'
213--- juju/export_test.go 2013-11-07 06:48:00 +0000
214+++ juju/export_test.go 2013-12-06 09:49:29 +0000
215@@ -5,5 +5,4 @@
216 APIClose = &apiClose
217 ProviderConnectDelay = &providerConnectDelay
218 NewAPIFromName = newAPIFromName
219- UpdateSecrets = &updateSecrets
220 )

Subscribers

People subscribed via source and target branches

to status/vote changes: