github.com/rogpeppe/juju@v0.0.0-20140613142852-6337964b789e/state/api/state.go (about)

     1  // Copyright 2013 Canonical Ltd.
     2  // Licensed under the AGPLv3, see LICENCE file for details.
     3  
     4  package api
     5  
     6  import (
     7  	"net"
     8  	"strconv"
     9  
    10  	"github.com/juju/juju/network"
    11  	"github.com/juju/juju/state/api/agent"
    12  	"github.com/juju/juju/state/api/charmrevisionupdater"
    13  	"github.com/juju/juju/state/api/deployer"
    14  	"github.com/juju/juju/state/api/environment"
    15  	"github.com/juju/juju/state/api/firewaller"
    16  	"github.com/juju/juju/state/api/keyupdater"
    17  	apilogger "github.com/juju/juju/state/api/logger"
    18  	"github.com/juju/juju/state/api/machiner"
    19  	"github.com/juju/juju/state/api/networker"
    20  	"github.com/juju/juju/state/api/params"
    21  	"github.com/juju/juju/state/api/provisioner"
    22  	"github.com/juju/juju/state/api/rsyslog"
    23  	"github.com/juju/juju/state/api/uniter"
    24  	"github.com/juju/juju/state/api/upgrader"
    25  )
    26  
    27  // Login authenticates as the entity with the given name and password.
    28  // Subsequent requests on the state will act as that entity.  This
    29  // method is usually called automatically by Open. The machine nonce
    30  // should be empty unless logging in as a machine agent.
    31  func (st *State) Login(tag, password, nonce string) error {
    32  	var result params.LoginResult
    33  	err := st.Call("Admin", "", "Login", &params.Creds{
    34  		AuthTag:  tag,
    35  		Password: password,
    36  		Nonce:    nonce,
    37  	}, &result)
    38  	if err == nil {
    39  		st.authTag = tag
    40  		hostPorts, err := addAddress(result.Servers, st.addr)
    41  		if err != nil {
    42  			st.Close()
    43  			return err
    44  		}
    45  		st.hostPorts = hostPorts
    46  		st.environTag = result.EnvironTag
    47  	}
    48  	return err
    49  }
    50  
    51  // slideAddressToFront moves the address at the location (serverIndex, addrIndex) to be
    52  // the first address of the first server.
    53  func slideAddressToFront(servers [][]network.HostPort, serverIndex, addrIndex int) {
    54  	server := servers[serverIndex]
    55  	hostPort := server[addrIndex]
    56  	// Move the matching address to be the first in this server
    57  	for ; addrIndex > 0; addrIndex-- {
    58  		server[addrIndex] = server[addrIndex-1]
    59  	}
    60  	server[0] = hostPort
    61  	for ; serverIndex > 0; serverIndex-- {
    62  		servers[serverIndex] = servers[serverIndex-1]
    63  	}
    64  	servers[0] = server
    65  }
    66  
    67  // addAddress appends a new server derived from the given
    68  // address to servers if the address is not already found
    69  // there.
    70  func addAddress(servers [][]network.HostPort, addr string) ([][]network.HostPort, error) {
    71  	for i, server := range servers {
    72  		for j, hostPort := range server {
    73  			if hostPort.NetAddr() == addr {
    74  				slideAddressToFront(servers, i, j)
    75  				return servers, nil
    76  			}
    77  		}
    78  	}
    79  	host, portString, err := net.SplitHostPort(addr)
    80  	if err != nil {
    81  		return nil, err
    82  	}
    83  	port, err := strconv.Atoi(portString)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  	hostPort := network.HostPort{
    88  		Address: network.NewAddress(host, network.ScopeUnknown),
    89  		Port:    port,
    90  	}
    91  	result := make([][]network.HostPort, 0, len(servers)+1)
    92  	result = append(result, []network.HostPort{hostPort})
    93  	result = append(result, servers...)
    94  	return result, nil
    95  }
    96  
    97  // Client returns an object that can be used
    98  // to access client-specific functionality.
    99  func (st *State) Client() *Client {
   100  	return &Client{st}
   101  }
   102  
   103  // Machiner returns a version of the state that provides functionality
   104  // required by the machiner worker.
   105  func (st *State) Machiner() *machiner.State {
   106  	return machiner.NewState(st)
   107  }
   108  
   109  // Networker returns a version of the state that provides functionality
   110  // required by the networker worker.
   111  func (st *State) Networker() *networker.State {
   112  	return networker.NewState(st)
   113  }
   114  
   115  // Provisioner returns a version of the state that provides functionality
   116  // required by the provisioner worker.
   117  func (st *State) Provisioner() *provisioner.State {
   118  	return provisioner.NewState(st)
   119  }
   120  
   121  // Uniter returns a version of the state that provides functionality
   122  // required by the uniter worker.
   123  func (st *State) Uniter() *uniter.State {
   124  	return uniter.NewState(st, st.authTag)
   125  }
   126  
   127  // Firewaller returns a version of the state that provides functionality
   128  // required by the firewaller worker.
   129  func (st *State) Firewaller() *firewaller.State {
   130  	return firewaller.NewState(st)
   131  }
   132  
   133  // Agent returns a version of the state that provides
   134  // functionality required by the agent code.
   135  func (st *State) Agent() *agent.State {
   136  	return agent.NewState(st)
   137  }
   138  
   139  // Upgrader returns access to the Upgrader API
   140  func (st *State) Upgrader() *upgrader.State {
   141  	return upgrader.NewState(st)
   142  }
   143  
   144  // Deployer returns access to the Deployer API
   145  func (st *State) Deployer() *deployer.State {
   146  	return deployer.NewState(st)
   147  }
   148  
   149  // Environment returns access to the Environment API
   150  func (st *State) Environment() *environment.Facade {
   151  	return environment.NewFacade(st)
   152  }
   153  
   154  // Logger returns access to the Logger API
   155  func (st *State) Logger() *apilogger.State {
   156  	return apilogger.NewState(st)
   157  }
   158  
   159  // KeyUpdater returns access to the KeyUpdater API
   160  func (st *State) KeyUpdater() *keyupdater.State {
   161  	return keyupdater.NewState(st)
   162  }
   163  
   164  // CharmRevisionUpdater returns access to the CharmRevisionUpdater API
   165  func (st *State) CharmRevisionUpdater() *charmrevisionupdater.State {
   166  	return charmrevisionupdater.NewState(st)
   167  }
   168  
   169  // Rsyslog returns access to the Rsyslog API
   170  func (st *State) Rsyslog() *rsyslog.State {
   171  	return rsyslog.NewState(st)
   172  }