~nskaggs/+junk/xenial-test

« back to all changes in this revision

Viewing changes to src/github.com/juju/juju/worker/authenticationworker/worker_test.go

  • Committer: Nicholas Skaggs
  • Date: 2016-10-24 20:56:05 UTC
  • Revision ID: nicholas.skaggs@canonical.com-20161024205605-z8lta0uvuhtxwzwl
Initi with beta15

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 authenticationworker_test
 
5
 
 
6
import (
 
7
        "runtime"
 
8
        "strings"
 
9
        "time"
 
10
 
 
11
        jc "github.com/juju/testing/checkers"
 
12
        "github.com/juju/utils/ssh"
 
13
        sshtesting "github.com/juju/utils/ssh/testing"
 
14
        gc "gopkg.in/check.v1"
 
15
        "gopkg.in/juju/names.v2"
 
16
 
 
17
        "github.com/juju/juju/agent"
 
18
        "github.com/juju/juju/api"
 
19
        "github.com/juju/juju/api/keyupdater"
 
20
        jujutesting "github.com/juju/juju/juju/testing"
 
21
        "github.com/juju/juju/state"
 
22
        coretesting "github.com/juju/juju/testing"
 
23
        "github.com/juju/juju/worker"
 
24
        "github.com/juju/juju/worker/authenticationworker"
 
25
)
 
26
 
 
27
type workerSuite struct {
 
28
        jujutesting.JujuConnSuite
 
29
        stateMachine  *state.Machine
 
30
        machine       *state.Machine
 
31
        keyupdaterApi *keyupdater.State
 
32
 
 
33
        existingEnvKey string
 
34
        existingKeys   []string
 
35
}
 
36
 
 
37
var _ = gc.Suite(&workerSuite{})
 
38
 
 
39
func (s *workerSuite) SetUpTest(c *gc.C) {
 
40
        //TODO(bogdanteleaga): Fix this on windows
 
41
        if runtime.GOOS == "windows" {
 
42
                c.Skip("bug 1403084: authentication worker not implemented yet on windows")
 
43
        }
 
44
        s.JujuConnSuite.SetUpTest(c)
 
45
        // Default ssh user is currently "ubuntu".
 
46
        c.Assert(authenticationworker.SSHUser, gc.Equals, "ubuntu")
 
47
        // Set the ssh user to empty (the current user) as required by the test infrastructure.
 
48
        s.PatchValue(&authenticationworker.SSHUser, "")
 
49
 
 
50
        // Replace the default dummy key in the test environment with a valid one.
 
51
        // This will be added to the ssh authorised keys when the agent starts.
 
52
        s.setAuthorisedKeys(c, sshtesting.ValidKeyOne.Key+" firstuser@host")
 
53
        // Record the existing key with its prefix for testing later.
 
54
        s.existingEnvKey = sshtesting.ValidKeyOne.Key + " Juju:firstuser@host"
 
55
 
 
56
        // Set up an existing key (which is not in the environment) in the ssh authorised_keys file.
 
57
        s.existingKeys = []string{sshtesting.ValidKeyTwo.Key + " existinguser@host"}
 
58
        err := ssh.AddKeys(authenticationworker.SSHUser, s.existingKeys...)
 
59
        c.Assert(err, jc.ErrorIsNil)
 
60
 
 
61
        var apiRoot api.Connection
 
62
        apiRoot, s.machine = s.OpenAPIAsNewMachine(c)
 
63
        c.Assert(apiRoot, gc.NotNil)
 
64
        s.keyupdaterApi = keyupdater.NewState(apiRoot)
 
65
        c.Assert(s.keyupdaterApi, gc.NotNil)
 
66
}
 
67
 
 
68
func stop(c *gc.C, w worker.Worker) {
 
69
        c.Assert(worker.Stop(w), gc.IsNil)
 
70
}
 
71
 
 
72
type mockConfig struct {
 
73
        agent.Config
 
74
        c   *gc.C
 
75
        tag names.Tag
 
76
}
 
77
 
 
78
func (mock *mockConfig) Tag() names.Tag {
 
79
        return mock.tag
 
80
}
 
81
 
 
82
func agentConfig(c *gc.C, tag names.MachineTag) *mockConfig {
 
83
        return &mockConfig{c: c, tag: tag}
 
84
}
 
85
 
 
86
func (s *workerSuite) setAuthorisedKeys(c *gc.C, keys ...string) {
 
87
        keyStr := strings.Join(keys, "\n")
 
88
        err := s.BackingState.UpdateModelConfig(map[string]interface{}{"authorized-keys": keyStr}, nil, nil)
 
89
        c.Assert(err, jc.ErrorIsNil)
 
90
        s.BackingState.StartSync()
 
91
}
 
92
 
 
93
func (s *workerSuite) waitSSHKeys(c *gc.C, expected []string) {
 
94
        timeout := time.After(coretesting.LongWait)
 
95
        for {
 
96
                select {
 
97
                case <-timeout:
 
98
                        c.Fatalf("timeout while waiting for authoirsed ssh keys to change")
 
99
                case <-time.After(coretesting.ShortWait):
 
100
                        keys, err := ssh.ListKeys(authenticationworker.SSHUser, ssh.FullKeys)
 
101
                        c.Assert(err, jc.ErrorIsNil)
 
102
                        keysStr := strings.Join(keys, "\n")
 
103
                        expectedStr := strings.Join(expected, "\n")
 
104
                        if expectedStr != keysStr {
 
105
                                continue
 
106
                        }
 
107
                        return
 
108
                }
 
109
        }
 
110
}
 
111
 
 
112
func (s *workerSuite) TestKeyUpdateRetainsExisting(c *gc.C) {
 
113
        authWorker, err := authenticationworker.NewWorker(s.keyupdaterApi, agentConfig(c, s.machine.Tag().(names.MachineTag)))
 
114
        c.Assert(err, jc.ErrorIsNil)
 
115
        defer stop(c, authWorker)
 
116
 
 
117
        newKey := sshtesting.ValidKeyThree.Key + " user@host"
 
118
        s.setAuthorisedKeys(c, newKey)
 
119
        newKeyWithCommentPrefix := sshtesting.ValidKeyThree.Key + " Juju:user@host"
 
120
        s.waitSSHKeys(c, append(s.existingKeys, newKeyWithCommentPrefix))
 
121
}
 
122
 
 
123
func (s *workerSuite) TestNewKeysInJujuAreSavedOnStartup(c *gc.C) {
 
124
        newKey := sshtesting.ValidKeyThree.Key + " user@host"
 
125
        s.setAuthorisedKeys(c, newKey)
 
126
 
 
127
        authWorker, err := authenticationworker.NewWorker(s.keyupdaterApi, agentConfig(c, s.machine.Tag().(names.MachineTag)))
 
128
        c.Assert(err, jc.ErrorIsNil)
 
129
        defer stop(c, authWorker)
 
130
 
 
131
        newKeyWithCommentPrefix := sshtesting.ValidKeyThree.Key + " Juju:user@host"
 
132
        s.waitSSHKeys(c, append(s.existingKeys, newKeyWithCommentPrefix))
 
133
}
 
134
 
 
135
func (s *workerSuite) TestDeleteKey(c *gc.C) {
 
136
        authWorker, err := authenticationworker.NewWorker(s.keyupdaterApi, agentConfig(c, s.machine.Tag().(names.MachineTag)))
 
137
        c.Assert(err, jc.ErrorIsNil)
 
138
        defer stop(c, authWorker)
 
139
 
 
140
        // Add another key
 
141
        anotherKey := sshtesting.ValidKeyThree.Key + " another@host"
 
142
        s.setAuthorisedKeys(c, s.existingEnvKey, anotherKey)
 
143
        anotherKeyWithCommentPrefix := sshtesting.ValidKeyThree.Key + " Juju:another@host"
 
144
        s.waitSSHKeys(c, append(s.existingKeys, s.existingEnvKey, anotherKeyWithCommentPrefix))
 
145
 
 
146
        // Delete the original key and check anotherKey plus the existing keys remain.
 
147
        s.setAuthorisedKeys(c, anotherKey)
 
148
        s.waitSSHKeys(c, append(s.existingKeys, anotherKeyWithCommentPrefix))
 
149
}
 
150
 
 
151
func (s *workerSuite) TestMultipleChanges(c *gc.C) {
 
152
        authWorker, err := authenticationworker.NewWorker(s.keyupdaterApi, agentConfig(c, s.machine.Tag().(names.MachineTag)))
 
153
        c.Assert(err, jc.ErrorIsNil)
 
154
        defer stop(c, authWorker)
 
155
        s.waitSSHKeys(c, append(s.existingKeys, s.existingEnvKey))
 
156
 
 
157
        // Perform a set to add a key and delete a key.
 
158
        // added: key 3
 
159
        // deleted: key 1 (existing env key)
 
160
        s.setAuthorisedKeys(c, sshtesting.ValidKeyThree.Key+" yetanother@host")
 
161
        yetAnotherKeyWithComment := sshtesting.ValidKeyThree.Key + " Juju:yetanother@host"
 
162
        s.waitSSHKeys(c, append(s.existingKeys, yetAnotherKeyWithComment))
 
163
}
 
164
 
 
165
func (s *workerSuite) TestWorkerRestart(c *gc.C) {
 
166
        authWorker, err := authenticationworker.NewWorker(s.keyupdaterApi, agentConfig(c, s.machine.Tag().(names.MachineTag)))
 
167
        c.Assert(err, jc.ErrorIsNil)
 
168
        defer stop(c, authWorker)
 
169
        s.waitSSHKeys(c, append(s.existingKeys, s.existingEnvKey))
 
170
 
 
171
        // Stop the worker and delete and add keys from the environment while it is down.
 
172
        // added: key 3
 
173
        // deleted: key 1 (existing env key)
 
174
        stop(c, authWorker)
 
175
        s.setAuthorisedKeys(c, sshtesting.ValidKeyThree.Key+" yetanother@host")
 
176
 
 
177
        // Restart the worker and check that the ssh auth keys are as expected.
 
178
        authWorker, err = authenticationworker.NewWorker(s.keyupdaterApi, agentConfig(c, s.machine.Tag().(names.MachineTag)))
 
179
        c.Assert(err, jc.ErrorIsNil)
 
180
        defer stop(c, authWorker)
 
181
 
 
182
        yetAnotherKeyWithCommentPrefix := sshtesting.ValidKeyThree.Key + " Juju:yetanother@host"
 
183
        s.waitSSHKeys(c, append(s.existingKeys, yetAnotherKeyWithCommentPrefix))
 
184
}