github.com/mwhudson/juju@v0.0.0-20160512215208-90ff01f3497f/apiserver/sshclient/facade.go (about) 1 // Copyright 2016 Canonical Ltd. 2 // Licensed under the AGPLv3, see LICENCE file for details. 3 4 // Package sshclient implements the API endpoint required for Juju 5 // clients that wish to make SSH connections to Juju managed machines. 6 package sshclient 7 8 import ( 9 "github.com/juju/juju/apiserver/common" 10 "github.com/juju/juju/apiserver/params" 11 "github.com/juju/juju/network" 12 ) 13 14 func init() { 15 common.RegisterStandardFacade("SSHClient", 1, newFacade) 16 } 17 18 // Facade implements the API required by the sshclient worker. 19 type Facade struct { 20 backend Backend 21 } 22 23 // New returns a new API facade for the sshclient worker. 24 func New(backend Backend, _ *common.Resources, authorizer common.Authorizer) (*Facade, error) { 25 if !authorizer.AuthClient() { 26 return nil, common.ErrPerm 27 } 28 return &Facade{backend: backend}, nil 29 } 30 31 // PublicAddress reports the preferred public network address for one 32 // or more entities. Machines and units are suppored. 33 func (facade *Facade) PublicAddress(args params.Entities) (params.SSHAddressResults, error) { 34 getter := func(m SSHMachine) (network.Address, error) { return m.PublicAddress() } 35 return facade.getAddresses(args, getter) 36 } 37 38 // PrivateAddress reports the preferred private network address for one or 39 // more entities. Machines and units are supported. 40 func (facade *Facade) PrivateAddress(args params.Entities) (params.SSHAddressResults, error) { 41 getter := func(m SSHMachine) (network.Address, error) { return m.PrivateAddress() } 42 return facade.getAddresses(args, getter) 43 } 44 45 func (facade *Facade) getAddresses(args params.Entities, getter func(SSHMachine) (network.Address, error)) ( 46 params.SSHAddressResults, error, 47 ) { 48 out := params.SSHAddressResults{ 49 Results: make([]params.SSHAddressResult, len(args.Entities)), 50 } 51 for i, entity := range args.Entities { 52 machine, err := facade.backend.GetMachineForEntity(entity.Tag) 53 if err != nil { 54 out.Results[i].Error = common.ServerError(common.ErrPerm) 55 } else { 56 address, err := getter(machine) 57 if err != nil { 58 out.Results[i].Error = common.ServerError(err) 59 } else { 60 out.Results[i].Address = address.Value 61 } 62 } 63 } 64 return out, nil 65 } 66 67 // PublicKeys returns the public SSH hosts for one or more 68 // entities. Machines and units are supported. 69 func (facade *Facade) PublicKeys(args params.Entities) (params.SSHPublicKeysResults, error) { 70 out := params.SSHPublicKeysResults{ 71 Results: make([]params.SSHPublicKeysResult, len(args.Entities)), 72 } 73 for i, entity := range args.Entities { 74 machine, err := facade.backend.GetMachineForEntity(entity.Tag) 75 if err != nil { 76 out.Results[i].Error = common.ServerError(common.ErrPerm) 77 } else { 78 keys, err := facade.backend.GetSSHHostKeys(machine.MachineTag()) 79 if err != nil { 80 out.Results[i].Error = common.ServerError(err) 81 } else { 82 out.Results[i].PublicKeys = []string(keys) 83 } 84 } 85 } 86 return out, nil 87 } 88 89 // Proxy returns whether SSH connections should be proxied through the 90 // controller hosts for the model associated with the API connection. 91 func (facade *Facade) Proxy() (params.SSHProxyResult, error) { 92 config, err := facade.backend.ModelConfig() 93 if err != nil { 94 return params.SSHProxyResult{}, err 95 } 96 return params.SSHProxyResult{UseProxy: config.ProxySSH()}, nil 97 }