~rogpeppe/juju-core/azure

« back to all changes in this revision

Viewing changes to environs/cert.go

[r=gz] Check correct info attr in cloudinit.apiHostAddrs

Fixes a copy/paste error in cloudinit.MachineConfig to agent.Conf
conversion helper function. No test as the only codepath that uses
this goes through verifyConfig which already asserts both StateInfo
and APIInfo are not nil, so not possible to write a failing test
using exposed functions.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright 2013 Canonical Ltd.
 
2
// Licensed under the AGPLv3, see LICENCE file for details.
 
3
 
 
4
package environs
 
5
 
 
6
import (
 
7
        "fmt"
 
8
        "io/ioutil"
 
9
        "os"
 
10
        "path/filepath"
 
11
        "time"
 
12
 
 
13
        "launchpad.net/juju-core/cert"
 
14
        "launchpad.net/juju-core/environs/config"
 
15
)
 
16
 
 
17
type CreatedCert bool
 
18
 
 
19
const (
 
20
        CertCreated CreatedCert = true
 
21
        CertExists  CreatedCert = false
 
22
)
 
23
 
 
24
// WriteCertAndKey writes the provided certificate and key
 
25
// to the juju home directory, creating it if necessary,
 
26
func WriteCertAndKey(name string, cert, key []byte) error {
 
27
        // If the juju home directory doesn't exist, create it.
 
28
        jujuHome := config.JujuHome()
 
29
        if err := os.MkdirAll(jujuHome, 0775); err != nil {
 
30
                return err
 
31
        }
 
32
        path := filepath.Join(jujuHome, name)
 
33
        if err := ioutil.WriteFile(path+"-cert.pem", cert, 0644); err != nil {
 
34
                return err
 
35
        }
 
36
        return ioutil.WriteFile(path+"-private-key.pem", key, 0600)
 
37
}
 
38
 
 
39
func generateCertificate(environ Environ, writeCertAndKey func(environName string, cert, key []byte) error) error {
 
40
        cfg := environ.Config()
 
41
        caCert, caKey, err := cert.NewCA(environ.Name(), time.Now().UTC().AddDate(10, 0, 0))
 
42
        if err != nil {
 
43
                return err
 
44
        }
 
45
        m := cfg.AllAttrs()
 
46
        m["ca-cert"] = string(caCert)
 
47
        m["ca-private-key"] = string(caKey)
 
48
        cfg, err = config.New(m)
 
49
        if err != nil {
 
50
                return fmt.Errorf("cannot create environment configuration with new CA: %v", err)
 
51
        }
 
52
        if err := environ.SetConfig(cfg); err != nil {
 
53
                return fmt.Errorf("cannot set environment configuration with CA: %v", err)
 
54
        }
 
55
        if err := writeCertAndKey(environ.Name(), caCert, caKey); err != nil {
 
56
                return fmt.Errorf("cannot write CA certificate and key: %v", err)
 
57
        }
 
58
        return nil
 
59
}
 
60
 
 
61
// EnsureCertificate makes sure that there is a certificate and private key
 
62
// for the specified environment.  If one does not exist, then a certificate
 
63
// is generated.
 
64
func EnsureCertificate(environ Environ, writeCertAndKey func(environName string, cert, key []byte) error) (CreatedCert, error) {
 
65
        cfg := environ.Config()
 
66
        _, hasCACert := cfg.CACert()
 
67
        _, hasCAKey := cfg.CAPrivateKey()
 
68
 
 
69
        if hasCACert && hasCAKey {
 
70
                // All is good in the world.
 
71
                return CertExists, nil
 
72
        }
 
73
        // It is not possible to create an environment that has a private key, but no certificate.
 
74
        if hasCACert && !hasCAKey {
 
75
                return CertExists, fmt.Errorf("environment configuration with a certificate but no CA private key")
 
76
        }
 
77
 
 
78
        return CertCreated, generateCertificate(environ, writeCertAndKey)
 
79
}