github.com/coreos/mantle@v0.13.0/kola/tests/ignition/passwd.go (about) 1 // Copyright 2017 CoreOS, Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ignition 16 17 import ( 18 "fmt" 19 "strings" 20 21 "github.com/coreos/mantle/kola/cluster" 22 "github.com/coreos/mantle/kola/register" 23 "github.com/coreos/mantle/platform" 24 "github.com/coreos/mantle/platform/conf" 25 ) 26 27 func init() { 28 register.Register(®ister.Test{ 29 Name: "cl.ignition.v1.groups", 30 Run: groups, 31 ClusterSize: 1, 32 UserData: conf.Ignition(`{ 33 "ignitionVersion": 1, 34 "systemd": { 35 "units": [{ 36 "name": "system-cloudinit@usr-share-coreos-developer_data.service", 37 "mask": true 38 }] 39 }, 40 "passwd": { 41 "groups": [ 42 { 43 "name": "group1", 44 "gid": 501 45 }, 46 { 47 "name": "group2", 48 "gid": 502, 49 "passwordHash": "foobar" 50 } 51 ] 52 } 53 }`), 54 Distros: []string{"cl"}, 55 }) 56 register.Register(®ister.Test{ 57 Name: "coreos.ignition.groups", 58 Run: groups, 59 ClusterSize: 1, 60 UserData: conf.Ignition(`{ 61 "ignition": { "version": "2.0.0" }, 62 "systemd": { 63 "units": [{ 64 "name": "system-cloudinit@usr-share-coreos-developer_data.service", 65 "mask": true 66 }] 67 }, 68 "passwd": { 69 "groups": [ 70 { 71 "name": "group1", 72 "gid": 501 73 }, 74 { 75 "name": "group2", 76 "gid": 502, 77 "passwordHash": "foobar" 78 } 79 ] 80 } 81 }`), 82 UserDataV3: conf.Ignition(`{ 83 "ignition": { "version": "3.0.0" }, 84 "systemd": { 85 "units": [{ 86 "name": "system-cloudinit@usr-share-coreos-developer_data.service", 87 "mask": true 88 }] 89 }, 90 "passwd": { 91 "groups": [ 92 { 93 "name": "group1", 94 "gid": 501 95 }, 96 { 97 "name": "group2", 98 "gid": 502, 99 "passwordHash": "foobar" 100 } 101 ] 102 } 103 }`), 104 Distros: []string{"cl", "fcos", "rhcos"}, 105 }) 106 register.Register(®ister.Test{ 107 Name: "cl.ignition.v1.users", 108 Run: users, 109 ClusterSize: 1, 110 UserData: conf.Ignition(`{ 111 "ignitionVersion": 1, 112 "systemd": { 113 "units": [{ 114 "name": "system-cloudinit@usr-share-coreos-developer_data.service", 115 "mask": true 116 }] 117 }, 118 "passwd": { 119 "users": [ 120 { 121 "name": "core", 122 "passwordHash": "foobar" 123 }, 124 { 125 "name": "user1", 126 "create": {} 127 }, 128 { 129 "name": "user2", 130 "create": { 131 "uid": 1010, 132 "groups": [ "docker" ] 133 } 134 } 135 ] 136 } 137 }`), 138 Distros: []string{"cl"}, 139 }) 140 register.Register(®ister.Test{ 141 Name: "cl.ignition.v2.users", 142 Run: users, 143 ClusterSize: 1, 144 UserData: conf.Ignition(`{ 145 "ignition": { "version": "2.0.0" }, 146 "systemd": { 147 "units": [{ 148 "name": "system-cloudinit@usr-share-coreos-developer_data.service", 149 "mask": true 150 }] 151 }, 152 "passwd": { 153 "users": [ 154 { 155 "name": "core", 156 "passwordHash": "foobar" 157 }, 158 { 159 "name": "user1", 160 "create": {} 161 }, 162 { 163 "name": "user2", 164 "create": { 165 "uid": 1010, 166 "groups": [ "docker" ] 167 } 168 } 169 ] 170 } 171 }`), 172 Distros: []string{"cl"}, 173 }) 174 register.Register(®ister.Test{ 175 Name: "coreos.ignition.v2.users", 176 Run: usersRhcos, 177 ClusterSize: 1, 178 UserData: conf.Ignition(`{ 179 "ignition": { "version": "2.0.0" }, 180 "passwd": { 181 "users": [ 182 { 183 "name": "core", 184 "passwordHash": "foobar" 185 }, 186 { 187 "name": "user1", 188 "create": {} 189 }, 190 { 191 "name": "user2", 192 "create": { 193 "uid": 1010, 194 "groups": [ "sudo" ] 195 } 196 } 197 ] 198 } 199 }`), 200 UserDataV3: conf.Ignition(`{ 201 "ignition": { "version": "3.0.0" }, 202 "passwd": { 203 "users": [ 204 { 205 "name": "core", 206 "passwordHash": "foobar" 207 }, 208 { 209 "name": "user1", 210 "create": {} 211 }, 212 { 213 "name": "user2", 214 "create": { 215 "uid": 1010, 216 "groups": [ "sudo" ] 217 } 218 } 219 ] 220 } 221 }`), 222 Distros: []string{"rhcos"}, 223 }) 224 } 225 226 type userTest struct { 227 user string 228 passwdRecord string 229 shadowPassword string 230 } 231 232 type groupTest struct { 233 group string 234 groupRecord string 235 gshadowRecord string 236 } 237 238 func groups(c cluster.TestCluster) { 239 m := c.Machines()[0] 240 241 tests := []groupTest{ 242 { 243 group: "group1", 244 groupRecord: "group1:x:501:", 245 gshadowRecord: "group1:*::", 246 }, 247 { 248 group: "group2", 249 groupRecord: "group2:x:502:", 250 gshadowRecord: "group2:foobar::", 251 }, 252 } 253 testGroup(c, m, tests) 254 } 255 256 func users(c cluster.TestCluster) { 257 m := c.Machines()[0] 258 259 tests := []userTest{ 260 { 261 user: "core", 262 passwdRecord: "core:x:500:500:CoreOS Admin:/home/core:/bin/bash", 263 shadowPassword: "foobar", 264 }, 265 { 266 user: "user1", 267 passwdRecord: "user1:x:1000:1000::/home/user1:/bin/bash", 268 shadowPassword: "*", 269 }, 270 { 271 user: "user2", 272 passwdRecord: "user2:x:1010:1010::/home/user2:/bin/bash", 273 shadowPassword: "*", 274 }, 275 } 276 testUser(c, m, tests) 277 } 278 279 func usersRhcos(c cluster.TestCluster) { 280 m := c.Machines()[0] 281 282 tests := []userTest{ 283 { 284 user: "core", 285 passwdRecord: "core:x:1000:1000::/home/core:/bin/bash", 286 shadowPassword: "foobar", 287 }, 288 { 289 user: "user1", 290 passwdRecord: "user1:x:1001:1001::/var/home/user1:/bin/bash", 291 shadowPassword: "*", 292 }, 293 { 294 user: "user2", 295 passwdRecord: "user2:x:1010:1010::/var/home/user2:/bin/bash", 296 shadowPassword: "*", 297 }, 298 } 299 testUser(c, m, tests) 300 } 301 302 func testUser(c cluster.TestCluster, m platform.Machine, tests []userTest) { 303 for _, t := range tests { 304 if out, err := getent(c, m, "passwd", t.user); err != nil { 305 c.Fatal(err) 306 } else if out != t.passwdRecord { 307 c.Errorf("%q wasn't correctly created: got %q, expected %q", t.user, out, t.passwdRecord) 308 } 309 310 out, err := getent(c, m, "shadow", t.user) 311 if err != nil { 312 c.Fatal(err) 313 } 314 315 fields := strings.Split(out, ":") 316 if len(fields) < 2 { 317 c.Fatalf("could not parse shadow record (%q) for %q", out, t.user) 318 } 319 320 if fields[0] != t.user || fields[1] != t.shadowPassword { 321 c.Errorf("%q wasn't correctly created: got %q:%q, expected %q:%q", t.user, fields[0], fields[1], t.user, t.shadowPassword) 322 } 323 } 324 } 325 326 func testGroup(c cluster.TestCluster, m platform.Machine, tests []groupTest) { 327 for _, t := range tests { 328 if out, err := getent(c, m, "group", t.group); err != nil { 329 c.Fatal(err) 330 } else if out != t.groupRecord { 331 c.Errorf("%q wasn't correctly created: got %q, expected %q", t.group, out, t.groupRecord) 332 } 333 if out, err := getent(c, m, "gshadow", t.group); err != nil { 334 c.Fatal(err) 335 } else if out != t.gshadowRecord { 336 c.Errorf("%q wasn't correctly created: got %q, expected %q", t.group, out, t.gshadowRecord) 337 } 338 } 339 } 340 341 func getent(c cluster.TestCluster, m platform.Machine, database string, entry string) (string, error) { 342 cmd := fmt.Sprintf("sudo getent %s %s", database, entry) 343 if out, err := c.SSH(m, cmd); err == nil { 344 return string(out), nil 345 } else { 346 return "", fmt.Errorf("failed to run `%s`: %s: %v", cmd, out, err) 347 } 348 }