diff --git a/.gitignore b/.gitignore index a90cbbb..7a0d26f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,21 +1,15 @@ +.vagrant +Berksfile.lock +Gemfile.lock *~ *# .#* \#*# .*.sw[a-z] *.un~ -*.tmp -*.bk -*.bkup +.bundle +.cache +.kitchen +bin .kitchen.local.yml -Berksfile.lock -Gemfile.lock - -.bundle/ -.cache/ -.kitchen/ -.vagrant/ -.vagrant.d/ -bin/ -tmp/ -vendor/ +.coverage \ No newline at end of file diff --git a/.kitchen.cloud.yml b/.kitchen.cloud.yml new file mode 100644 index 0000000..a61e85d --- /dev/null +++ b/.kitchen.cloud.yml @@ -0,0 +1,97 @@ +--- +driver_config: + digitalocean_client_id: <%= ENV['DIGITAL_OCEAN_CLIENT_ID'] %> + digitalocean_api_key: <%= ENV['DIGITAL_OCEAN_API_KEY'] %> + aws_access_key_id: <%= ENV['AWS_ACCESS_KEY_ID'] %> + aws_secret_access_key: <%= ENV['AWS_SECRET_ACCESS_KEY'] %> + aws_ssh_key_id: <%= ENV['AWS_KEYPAIR_NAME'] %> + +provisioner: + name: chef_zero + require_chef_omnibus: latest + +platforms: +- name: centos-5.8 + driver_plugin: digitalocean + driver_config: + image_id: 1601 + flavor_id: 63 + region_id: 4 + ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> + ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> + +- name: centos-6.4 + driver_plugin: digitalocean + driver_config: + image_id: 562354 + flavor_id: 63 + region_id: 4 + ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> + ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> + +- name: amazon-2013.09 + driver_plugin: ec2 + driver_config: + image_id: ami-3be4bc52 + username: ec2-user + ssh_key: <%= ENV['EC2_SSH_KEY_PATH'] %> + +- name: fedora-19 + driver_plugin: digitalocean + driver_config: + image_id: 696598 + flavor_id: 63 + region_id: 4 + ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> + ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> + +- name: debian-70 + driver_plugin: digitalocean + driver_config: + image_id: 308287 + flavor_id: 63 + region_id: 4 + ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> + ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> + run_list: + - recipe[apt] + +- name: ubuntu-1004 + driver_plugin: digitalocean + driver_config: + image_id: 14097 + flavor_id: 63 + region_id: 4 + ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> + ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> + run_list: + - recipe[apt] + +- name: ubuntu-1204 + driver_plugin: digitalocean + driver_config: + image_id: 1505447 + flavor_id: 63 + region_id: 4 + ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> + ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> + run_list: + - recipe[apt] + +- name: ubuntu-1310 + driver_plugin: digitalocean + driver_config: + image_id: 1505699 + flavor_id: 63 + region_id: 4 + ssh_key_ids: <%= ENV['DIGITAL_OCEAN_SSH_KEY_IDS'] %> + ssh_key: <%= ENV['DIGITAL_OCEAN_SSH_KEY_PATH'] %> + run_list: + - recipe[apt] + + +suites: + - name: default + run_list: fake::default + - name: create + run_list: fake::create \ No newline at end of file diff --git a/.kitchen.yml b/.kitchen.yml index 5441ddd..c431f44 100644 --- a/.kitchen.yml +++ b/.kitchen.yml @@ -3,7 +3,7 @@ driver: provisioner: name: chef_zero - require_chef_omnibus: 11.8.0 + require_chef_omnibus: latest platforms: - name: centos-5.10 diff --git a/.rubocop.yml b/.rubocop.yml index 58b7d2e..6846e2c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,3 +1,5 @@ +inherit_from: rubocop-todo.yml + AllCops: Excludes: - vendor/** @@ -13,4 +15,5 @@ HashSyntax: LineLength: Enabled: false MethodLength: - Max: 40 + Enabled: false + diff --git a/.travis.yml b/.travis.yml index 73b4047..fb262d1 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,74 @@ +language: ruby +bundler_args: --without kitchen_vagrant --without development rvm: - - 1.9.3 - - 2.0.0 -script: bundle exec rake travis:ci +- 2.1.0 +before_install: +- echo -n $DO_KEY_CHUNK_{0..30} >> ~/.ssh/id_do.base64 +- cat ~/.ssh/id_do.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_do.pem +- echo -n $EC2_KEY_CHUNK_{0..30} >> ~/.ssh/id_ec2.base64 +- cat ~/.ssh/id_ec2.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_ec2.pem +script: +- bundle exec rake travis +after_script: +- bundle exec kitchen destroy +env: + global: + - secure: CnOrxu3bu+f4xPU5TzSNtIPldGA2lP5Dm2IfZUDRFHuT4bpF4bDnEZBY4pB5uEQAaMLRbnMiuyq2adMgiT5j6zv0RXfDBDllgyQrOieDGbiN6zg7CsuuwrZFkVj7wth8thdgEzj+rCyZtGfUQ4L6EGTaOleIEBDH6+YGZNgyLyo= + - secure: w48w/WVzHZVPpf0wFnKh9WfYj++so3kDlTCUnTny14bXJom53Z9+dA/EFHnSE5n82SazyQz/cdsaoyA7USq2gFrewdIl/V/Yj35y0pB8WhquPkwxao12k4kgfDeMm7gmXkkvrfkdXiNoV80cFZuCh45qdOa6oMWNmqrMqHUSDoQ= + - secure: JKuNiY4Oc10fyiTlXUXTAkeP5HpgPyvhkVoqCi+IbyuwwbIMDpnqNIFsx9yyuveT7WNWGviWoBcpPq9i6j84w0KP7R5NPz6+fJDpfklx7fz1RlGIgPQJ8NhsPvyqYH1AONQivQu+c98Kw1D9tlhlR9ouA19IVAwAVwSz4NcJRE0= + - secure: eNdOtpN6T6BsRhrZEQdkw2LmUJ9UbyJZQRDiEtzBGZ5NzpCzdQ8q0o/dwxm9V/RI1MuggfMJyWm1jWjMnhddM7lYcsStY2EyBCpaSrONQxAQEQSeXrzpvA1YnbjkBxsCcRf1KWFEogsxz16gIVsRByWHfgDpgXJH7n38IN2bK2k= + - secure: tyf4EWa/CBo3rrOuF54omKk4ICXXV7q3obFloKfTQL1lHN9PxvcyGHPTkpqRpiL2LNtEJpLv2FapGtZLktBdMHtNSFYcEj8EpifMPg1+50yvbXEhA5TKTlvu6ULAUy91RoOgR2XPIj+NeKHu9+zqEaRUG/ZAJF9MR/jHrwJRqCs= + - secure: vUM1/ZESuV0dZjmnoFw1L7GKk7tN8YIOYil5R2jaT/tPS/Ho4nosgemCoewxQMbU4c/If6s6ueyIcYuYniwPMTQfuPU5LgQ+9es6UyCTmO+cuHLfLvwGnm2mAX+8U/DzKJL62f8K82ivme+fSVZVA1noYIeGm32380nTRFPEcHw= + - secure: lc9R7rmWnF6hwbbgU8otG3xtFBjS8/+HTXz08fu0Wqow9LG4RD4lDBNSAKajkFKD6ZJTLczUmfo7R5HjWi4ZKIN26u2i+pMonT1OAEdryeScEXM9p1GL35RR5Ehr5gqXU5mGQchPnkOjt3J0aAu/dGI2DEf0Dyrb0eF13eweCS4= + - secure: xrMPSWm2lzA7eMGpxV83wNehwVAohN11L3YVYY2Ttk5ZXW/vRq1CM8/Q4zBRQOmmqfp3mGs70VXOJbmS6KRQIJzOy3kz0qVgOMXDR9iD+kfLmFUvmzjK5bBynHmrtcf+Yd0BOO608GmVgfkXRpe84M7ZJzDfmlqdqe2J3nDFDe4= + - secure: eftxU/SLuKP7ZgA/DHnbwiJ4mDhfaB/XW/ZKhhJ1fWRhithadwKrMHkuQPvewDCX3yiZJYBSQsvfRAmyG0fQ5lNCv24n/op8H15/KcBMhgBH/+/HBQeqiSYdZyJ4TzaUdsAs449DCrTWonhztzS4MRS05KwVTVo7HggnHwoVAlI= + - secure: M4GO+Wm/aoRuSDZ8M27U+tz4QbX8JggqXkYTDdRRTTDrxfCJan1ZqB33PM14k55+jcWJoje6HE42rhu82e9ZBNe4j0BRrI5rBDPXGXFACQkpYkuyWCtSW7sxdQPHxDxlxnjJi+cmhKmk0OPQq0030iI+dZfAsMlAmvVVHts8gzQ= + - secure: PMHV2gGLmevmliLM+asaLNY6r0ngzhb/F+UwP2Kj9PRXi0WUpfiff9J2WaGG3Ycpwm6sPINafT+wQuxEhWavqkiAu8b02UU+ttGE1GW4klLKO6Yy0ZnXcI29o1MDjH4xNpEG8TeEFbkdGBR2Z/n888wP9JfY86yFtUMhSm7tXC8= + - secure: nbcp1ohomDKNFa6RrOX5Zm6Gf5FycLyqmakkcFIKiEoOBJarRwyCgWjU/g0sqtuiVyBnm9W1QkwsTcaQ3D6S+cUi1t3kDdod74oa643QUetrRIBY2XONB4tsOnwdUHGTdkda0wBUrx5SNL5prvDZq7Zq8Zf+8Ahq0SDuXq4dDLw= + - secure: ou87AxIb3ExAsNcBYtPACkeXqYpmac/CV0BRmdBGs1rV5EtLM7Na9TpXPqB3Z7Jip6N02gC8DR66Ft1NjPXce+CZnE1JcrKli5gwjYqyt5qsjqWWhtG+qjroKrASadqtiy/X2ys6r+vB3Jyw7uyjzGWI1xq2FSxOtAo/Qivn8gI= + - secure: bGO7t2dNxXN0u4tnZ75mL4wsZ+/5A2QFoJUitsJliUAYUheNJxkg/g78430s/+4r0VPiEiBJdCPtVYWr1T+cJflZex+NsvfprPerDFRE+Wd5cE0vHoaKkjozOzNAzX6ob5fk/7seA5J7C34LDXKlWADtWoM+UUwzoVJ3L4CbuF4= + - secure: FpycIhVD98Lv8hvIr16qBpmQ36y8xwaHRZdyS2X9H58x9Es7JLdKbf0QN1ECQpVSkFxU02kPCMpvMfiSCO8k5l0+xopeaulmTg3+iA7y6UdW+H0xhXKwcyTazjwdYPWXTcf2zMbwOS1QFyi2mEbaHYgAPo98h9OkX1OlAZMWuG8= + - secure: mUDrRv7jlXKWO+g9w/geun8lP6UtSNpd/uuqMREZwKpiwfig2CtGgqmbMRV33LdArioac5334OkOXarvI/MBEZLMrH/KFqKwV5eB3Qng/xbgzC+LSDjyiet1Iq372t/3LZ3K3Y0uYGGQQm+hRE5BUjEXBT/7Hkm6b9BTD5cYDe8= + - secure: sVetZMID5/ij2KjJGypvGSh4kPm6VTJr/jCizNiQdHKyLbTT7QTRB1eRgI7cLHx2p1IYReSjqF2gwO6NvrbQJupzGs4jX+FM3cG1+gJ6rxr4tyY8PQCA8z+FJHX5JP5ftYP0zX8eDf4siEzFjuJq060/v0qBLyTM8QUUIhICjfg= + - secure: d3odonOb0Gxq1tPI5jzBE5kMoIVt4xhFkqBtUDzPjmGpgvaja2mavb/l65XEDR3BhXSm7TsPMMbg130ItWAftKaPaZZz7NmUdOkCIUZiTPXJaVk9yIZODsf2WLyyNfCUrwZU1RoO/NuEeIE5od5aKsD0Lp0wt2cqIidBE93zHeQ= + - secure: APXrVRwDGOfPOC1XJeFFqQBFkhlBiQ2ZFvLrowTKwcFe0UDm/XRYc4Wm0SQMRx9jICGhCKQkbIvOpxukgOAhbqfAdKUG804wDLGdC0Cnv5Xw28C+T3qP8ojciusx+5sOPIstl4YG8fWyUFI2fdxjK8wuxVd2Nm/WYAsF0+v4gXg= + - secure: P4Lvc4aZ0KA6UcGhfIokFmDLxjSa+utasYfQ6eDUAiziw1EhlntBT+HiiRqrNkRkwAi4daqgx7i8pgZGmtfhO7HEiqMmzZkpXXeZC51iQqA6K9jgowfqj9l4krI/9CWlWxdaaZeC5jy97tmkz4Pph1dye8hq45G/3bviEl3Zw4M= + - secure: ub6uOwcTYkMSCN8D9iP/Y+e3hXKcSD0ocz7EOkQdBZIHlXnjGAFl9VVQsji5KduQcmECZmXqvGSevF3AnNU0IkMSqNU8lyAP0xJO+UXLf0wOFhofvCKQTm3xBeUb/oAFqdk/vfa2wFXaSAaR3dwH50cY/LDtYiPNsx17n6sLOJg= + - secure: wBFJYCqQUkq4N3ISNL9kzx/nNa2U/6TlzhkjkaN22tIz7LPxr1h3oxidjJfYF33kwa3O4v3pZwliWpii/tQPtys0fhtc+2f3Y9tKrnAr4DTyMc6qKAndRcYxw0zyArT/tpmVBBz+EwLl2W/63YfWX1T2mjtNaCWXL5NB9UUQpN0= + - secure: nVOX8rnxEMzlQLn8PKpcLJ7uasYkb2tCRoeMgZCG501xIJkaEyxn1Z6O4oL38G5kNbQAnXSAG0voYAQVIh+pDgOHWMqPjx/YUOtcDPh/XOd1A9hPEX9yQfH1Vfg/sGxPOU9gBc369u/vIdsnWWJ7JRam3LD0MZMzF94CJVyHFxM= + - secure: tQ7l46VTl/vj+1I/MMt1VERhMOOdoumyP9jnuYEi3sP60KcX5RMPNqij/hNUWfyxffvc0P4zNSx4DeEsDzaBxVw78V3gijeGd6GNNBjjmj7KIi69zBUb/GMEcFtEahfrHjGCz+zJtA7lj/qTlP4HvH4Tojz6FYiNuwlFWsYjPJ0= + - secure: rZfl5blsSSR8RNCGMWvBjNZxlBvWRHqw9XIx0wR0vLl13cgf9EIEJMASAMVvFIGhmfUlipqdZjBH1uE42QbL0siauFzPRzulB1lIvCYa3Ae1tML5Me6GN7Z0BtoKmDp5ZdQ8YxvsoK9tUAkcVgjLAURMbFjlIlFR0Qz5VfmMXzQ= + - secure: AFJsxNkNQdJUK7Q0xecDAiMtiXcPZEey+40SQIatAmsGfK2ye+c/elljfUoMsrAZv9oiye5c2FUFQ7Jx2ExWn6TRYEETIpm59C5qQlY4frd/G+Qcg736YXuoKSps43P4KU8jKLm/95uROFQxJa97UXzXC7eaTQY61zuCDmJCrns= + - secure: rOj/ZR8/iCMEs4QdEB0jTG5LAlA0AGQDRraU/hmVYbxjyJeX3Aofd9qqy/+4LJp5voc79lHVvSMugiIW+dnEXJj0V+nQmAkveauLt77nTUOJ2s3y4FJIxMs1Tv6WidgK9H03huKEcC2iqSEKEQj4ENl2gfu6D3rgghLGa3C89o0= + - secure: Aa4QZpA4f9oJ7E435fV5g+E8E2ZugqMxVbSZBtlysFpHCoIZ2RlVS9FBHabtMue5qu8ROlz4Vz2PQgYZPJHKIuFO+/E/mhUM6QDUIaKDF4YzHcLBRdVwrbv/PIaiImlhhp369S6qAdspZPM8BUbpZPorzcggt2SipDxwem+vCow= + - secure: HXCW21YlHyDusEL9sBENdJYqBFiVQsCCFZifow/Zw3RPPg79UmE7dno+bxUFQvxNcgGsk7KV2FlAyz4LamNpBtslbV/ajlOGKj8rEhDNs8b8CFIIeWknkSXQC2na0DBx+oBQQ8w8fnRGigLE2qr4YPUxQv0xvmNQrlpYVeYG0Tc= + - secure: P35omyMrK3/Afkp9wHOExvZekb+7EHrE87TxCMn3kM4DjE0um5lPxeBqA60cDXvsvhLwoWYZhVmIFDC7oIwqpr7xLamr++k+uDa0kAjmaS7eJCDfGvIvJrCzUApRKBgBd2gIWNp/SNbO/z8bnslc0Q6TPb7o7KsSjldPLMmYyfg= + - secure: MtPnqam0ye3Y4CfMC4F1TfFlKnjBtBdw/xOXq+zUY/mqGXsllCDJcOe3Jkty1cZgMBuyvjGXwkbP3ov8FRCViCTBfFIMDMS4hEgf4RV9y1C+TM0rZ/vEku68/CBWYNgM/EVi+luOXXYuw/HFyLxCT9X1R7Ej9dyG/4lH2TUIQ4w= + - secure: DzOtwaeqjkWpjke3X0qTDnfTQFyXowVf8NBi6ze8L5KnR7YwtDWtzZP9OdF3E79n2blMjOTVBNBP2w4dHTZu+Tq8wjF55sCUxl7ukW5caY44ySBb7T+2FmaA+UgERe4KQgSwLn9sDW+PTfmsDMhAhvOH4QOdAH5dzmVUKI0V7n4= + - secure: l9naA8Rf5X4yXIwN71PfrRSrX1GCNM7mwDQ2tJkqVcab03r+diyNTY+byOuQ6WUoAkQHyNbUsntqyPHgQ6spB4I49ubkLsWtQzHQJ9nSCSHSz18gqp3jjpTBlcedZLO54g2CDCe4jkUfTSOpVJtN0m0Mj38alvhLj5WruUPY8To= + - secure: wy/L8ABNt3pBvKpcUJKODF0SezndvgMW8JT4DCpRZPnxeTyCTAaneEx5UDPZqAMHwzWu//IK1t2xI657jy+olvcb6JCGZTDGlGAJikh0xSzSQWqDGNtikYTsAOi5APCY4xcmDld+zap/87rvs3C9EnUMaDkl83l1yk6X8vfQMVc= + - secure: e40d7SEQBxeLaCz0SYNF0Cg05S3UCXuzNyFAd/9IE5VPY7nmL9iejY/MdS++ar4nvh2fsbuIMnrWjeIhxFhkcjz8cO20wsWbhHBWklqGdUiljLHmS1Xsfmqqa126u/FtRkvz8q54Tl7Rcy+KQY81G/6FnPn7UqEQ6Mme4fZrQvY= + - secure: XehZCKRBmdFhh8Jc2gqwbOqEHz8gJ2io3z8M3TcrGAKPBH/BC/4ZUnUoz9qGJaW2++Vq0dFPTPyVz0BZaiu9IyRtRqfH4My1kQcc67FefII49b9zK7plsBaFaRIaELV1V5uHVDe34Ifw/ASn/2GvogZ45IKiJ3K3yXDOmXodLJQ= + - secure: wD9pfIvmJASXWt5zm/gmhaCYRwty+4IjOYISkFG7lRIkNPhzaH+btzn8L1bz7k5zpis+ObuSPF/SZZoAXAIreAxSSQN1VLYGdVaToA+gdaVxQU46UBujckt7gIWW6YQoyC9JGxJIpClWywRi0wc0iyj3hQ7+++HUhu5RsdZz2fg= + - secure: uCsQur7dKTkN7jqcYxKCUf2bOuexQFfAhE8stmnK1JqpvsJUiFmo1Pqoy5EhlxSIaDxI9cJoxeNbe8/ORRkq33FrfKiHIRtR2bmvgsAiic75Stryp4kuvrFFyE9FaASZmPlh/Q0iKa+vlhS0HeW8Zq9W1Dr863rv11WzLxQjYfk= + - secure: dXnWTmpzHfFsggzt0IHUUhwicmnentoVkb+M5no/oJsNMUxA5ex4U1f8qabL04uvrS9K+r75P3JkCzUGKkAbnhQAfzNrIbUDgcDa1WYNJjAoVbVsVsoMFkJXefwntNkIFRrX/gsgWFCzAuis0sSBOpcb5KRvw0lKqhHgTeC/UDg= + - secure: DOLbMXaaeEX2g0XI8n2GpxYbdqwbSHwTkpn9She8EGWqMBGBX6gMV7kdqx9FuDMJxcCHEYHL9LzYZHYcFCKYJAJ3CecAXkvxjLv+nHe170jt7t0rSXojJr4o324fyjgZ8lm24bSDCpb4aLkcV4vF4ZZvOX+2jEeT8wgKnOPda/0= + - secure: HvfgdPKp2RkhHajI9z/WhFaB76wUHjKf5iwnR/qw9jfDQskOrCqpvqEiJCp5RmqsLqYAisw8i8iZr0UZEhRNIT7QRyLd3Wo8cOG3XwK+MWR0FAuH1/oZDbLS+BmlKG7w3+P984sq7OTEmU6MmZA1ro/rj1Aw2GBgkdeR5ZA6VdU= + - secure: e8Z/9F0z2vd+xT1rOMUiDShmeQ7A6mQPVc03fVuq2cOU/FQW9znsYLOddtDXhNeYvevevjkvH94/OnsJC902FhMJbzMvZ1NL47+oAD5ovimDAYxwaZg5H1wpOJai94TVu/vYmm4KgpM/oczIg1kcNyfkqWzJC5UfReP0Xu2Mek4= + - secure: o9jKvV2xzWBQlACn5wKdREjhqLNwX61KgRASURgtnB/xlWfVT6Wo7cQxmUpgRj/iOVHSZuX3qQccnM/t3VlKJcxRN4FLuRP8zg3TTuAasqoYZu3Xxx+E6Qb7BKCvkDN2t3Kon7AWSU+VhaNOvN43y42qA7jmIEXVcqPRPi5LnxE= + - secure: AgtJBBWFq4P/SYeIAmEcPDh5wYaU+T2rN5vC8OPNoIYTjqeiz/OBzY20Z7OyEsHj4qrb4v2ytOfWKOnpCMNWLL0Vbc86M2/wh7UNTfm+u3NZq4wObvHrSD9IKHz/ZP/KT70D7lGKxcb6VE2aF28feO6VK28NBXkfch1Tuja6nD8= + - secure: ocSv+TPEkikF8eZpBRIPOlhHwOVrpEwpV10+JiKygmeOgwLDzyMLtFGnROEqoWJbFbdmoTgou0Lr3R0aJOX9uWMK8sJK+65w0jdV0zAoi8t3cb0soCDn7wjEuKRcWZ67F7weaEGjLakWHuePYn6+PcyADx+f2lp0/87vZzbgPHQ= + - secure: xx6zyNkMFoph56XhvInG5tuJwbWZzyT2xkFVWO3j8iP/ynyUrxSxD/bLxXESjZW2JBUU6FIuGTda2xIG6J7Lwr8s7GXKzSvKU/lM9Q+WOKxiRwS9rdgpaDKThYjFRtDtIeFHpO867HomSxYa8azExwssXcoOy6pbVdK/AOoDjTo= + - secure: sFk4gW8cPJaEGfb2raAOANfafeaKESMA9hYsvvBUzKePQL/W7zbJZrm7mERMZRTMSOA2RYLbBL2G2wJp4ye2Qj1SRJHUxnSx63thsN9JLEHOY7RtMyo7vs03G5ls55gJfEhEkv3ZXeQyrUwilnS2xJD+uO0Q3FmOL+vVqQPDKSE= + - secure: epzYnxlmxyDUNCA7ZIKR/XVmiY9aTDYHH1xk7nMIrb02w6MGTq29UyYr6YtzFCcs2r6ZPwoEyVfgAijAw3NgyIk0aiwQUrxkJgTvOIFHRyYZR36siYx5QVL133/+DYnz9sQrnY8VLIswpDtGUjQiW4TDfDt53P5zvvqeCcxmO0c= + - secure: omE78Qxix37p9AkrJOTUwMZyaOgaIAX9gzfG7PR96wnBbnPB/4FVXK9eVPWlntBPjHcjR2lBB9Iblg8Sep17gEhhVP5jgdttifwZu5Eo5N+BZyqt8tusMKbnig5XXcBKcmeLvxjNJSOlwEXP9sHGF+4+ZxQDT8XuQ8zFSBrAszc= + - secure: CnPRVLWYGTiavJDjHDZg3+WCQuk07r+LWfKSFrQVJwlWsEaJVlSbA9IeTQk6W+APkhQ/XFICHXpxw77vv1SmkroHaMVtFfBV2TUOtDFRnczK+4U+76xSUYX0RSWTddNsySQCk8VMHY8wGf4xl5nG0o0uANjWHW4wXbT7pMoIe6Q= + - secure: uBKVV3CFdrfz/YRoUvblseZ+8DiLlA/nJ3eLzx584DcpObc9/TKhA1h9VBERTodeMqaNDCdb1lQmz8er5J2WqkdO6cCiOLAyB9Iv+glL7bMLVOLxPOxqzCr1x/PVqtS3HZyMA1KZuHwDP5gC3UONA8sa0QYp4x56nfqx9cp0Xns= + - secure: FIcWUmmkFqwhDWnUDQsE4AugX7JTO+mqc5REMQD28Twha3qxMIsEqINvIeL1MmTJ4f6ywemust2UMCibKP+xhu+OLb70E93znuKcWWZv7QwuAfrIwdZ3A+OwoFfseD3VaWkFgzAT+p+eNCCXJ/J3H1a4uTJF38eCD9GXIgKNNRA= + - secure: OblMyUxSNgsbaM9UJ2kISZuEew9hyWYXfc2d5yklv/mYQODmpBMrTebErtcu5Bn4JmtPWU29cPNV2+cDcrtUqXltQo5ENgMSK9Ten7EjM7NuANYuCkOx96ayFM9fru3mxhn6hLgGWJf5Mf6dqTj5zThOKYMldwRl0sPbsDxF5To= + - secure: x1gENY9hXjmH5mLl5brCzl80YWs/SkNr2MGLQ79pX5y6+Wz62x3rmc2HQGegEeGIZqzbfWGGa1TrCgk6c/n7hvPa/j4snAGpBMsIjlHUJ1kCavDjclkuNooq4sIUBO8RICpvuE6rSE7pwQ8F6C9kiM8P8oQkQft9E4xD2JSiPB8= + - secure: sThoXDh92WmlAbdWrJPFL73Rp5a37H/DU8pdGo26UAg1bHhOdlD9VP6cId1VU7l2FtVKqab8DK4msx8Brc2x1NmAs34kCp+CP6xSobciB5QC6fuFXCkw2c8riATWBzy7XtixjcJBMyQbIHD9nNNujop38gOjHyhiVSKETc0lRf8= + - secure: n0aPp2ZpeZ+/4+dwuWeV5KBcnL25ZI/DIuksJL/Q9aGkeMoLN6y/YcuY8L2Ec4cN+u9WVJ0H/aVL+3lNTmG8nh0S0cR3hoY2WubUmAAiSm+aAPDrVgLGZV/8TiB4qXGv/lvvsUco8bcSoRKo5bWYwbpbJS5Uq73G19O9p2w3ztU= + - secure: jyDgwz8hsfveiSGEZ+ebjD/HxGX52hdirpSZhJFHuxnJ3yWw2tLwEm/x2oPuwH/8qVHF2tD8ZuJ6+J6OUH2Tf+ZkD22GAmhexuSO8BpNjKxz7hMC3+woWuBwTvZFwosvt9hOcyMESJ4lX8pl+SezWDz0yzhdIc1y2+a6JvABUGM= + - secure: sm19LGQ8pDNHJlGMjTcRFjRh+wYmfiuH1aa6RVcy+R0YbM8By/Rwwunhr055OL1BNAhkavjDJpBv8r00m8VjOS5UgfCbBWcfSPpRKKPVMh6OsoDGrj7nM5rUlXsIQd+63w3+dN5j8UBMICi50ij93fWJtD5JvPjcnOY6nh7eaY8= + - secure: DJCweA/4YuyX1xXiLdccjy4rFWtNdctcK6A3ZfWTyxxShkYQN8GCZM7pFY77ubEPSOk08AeYVRAW9hgG/6xSA/tGCIuUaxpFh0/n9/+sUcgMhy5629P+Tv3YL8OSfRGTckHzG5Lmq0C6BnT0MGaPb6bp63P38Ye3QsNOhpWv3ds= diff --git a/Gemfile b/Gemfile index 5edaed7..07ee9aa 100644 --- a/Gemfile +++ b/Gemfile @@ -1,11 +1,37 @@ source 'https://rubygems.org' -gem 'berkshelf', '~> 2.0' -gem 'chefspec', '~> 3.1' -gem 'foodcritic', '~> 3.0' -gem 'rubocop', '~> 0.18' - -group :integration do - gem 'test-kitchen', '~> 1.1' - gem 'kitchen-vagrant', '~> 0.14' +group :lint do + gem 'foodcritic', '~> 3.0' + gem 'rubocop', '~> 0.18' + gem 'rainbow', '< 2.0' + gem 'rake' +end + +group :unit do + gem 'berkshelf', '~> 3.0.0.beta6' + gem 'chefspec', '~> 3.2' +end + +group :kitchen_common do + gem 'test-kitchen', '~> 1.2' +end + +group :kitchen_vagrant do + gem 'kitchen-vagrant', '~> 0.11' +end + +group :kitchen_cloud do + gem 'kitchen-digitalocean' + gem 'kitchen-ec2' +end + +group :development do + gem 'ruby_gntp' + gem 'growl' + gem 'rb-fsevent' + gem 'guard', '~> 2.4' + gem 'guard-kitchen' + gem 'guard-foodcritic' + gem 'guard-rspec' + gem 'guard-rubocop' end diff --git a/Guardfile b/Guardfile new file mode 100644 index 0000000..11dc1de --- /dev/null +++ b/Guardfile @@ -0,0 +1,35 @@ +# A sample Guardfile +# More info at https://github.com/guard/guard#readme + +# guard 'kitchen' do +# watch(%r{test/.+}) +# watch(%r{^recipes/(.+)\.rb$}) +# watch(%r{^attributes/(.+)\.rb$}) +# watch(%r{^files/(.+)}) +# watch(%r{^templates/(.+)}) +# watch(%r{^providers/(.+)\.rb}) +# watch(%r{^resources/(.+)\.rb}) +# end + +guard 'foodcritic', cookbook_paths: '.', all_on_start: false do + watch(%r{attributes/.+\.rb$}) + watch(%r{providers/.+\.rb$}) + watch(%r{recipes/.+\.rb$}) + watch(%r{resources/.+\.rb$}) + watch('metadata.rb') +end + +guard 'rubocop', all_on_start: false do + watch(%r{attributes/.+\.rb$}) + watch(%r{providers/.+\.rb$}) + watch(%r{recipes/.+\.rb$}) + watch(%r{resources/.+\.rb$}) + watch('metadata.rb') +end + +guard :rspec, cmd: 'bundle exec rspec', all_on_start: false, notification: false do + watch(%r{^libraries/(.+)\.rb$}) + watch(%r{^spec/(.+)_spec\.rb$}) + watch(%r{^(recipes)/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } + watch('spec/spec_helper.rb') { 'spec' } +end diff --git a/Rakefile b/Rakefile index b38e636..a7cde2b 100644 --- a/Rakefile +++ b/Rakefile @@ -1,37 +1,62 @@ -require 'bundler/setup' +require 'rspec/core/rake_task' +require 'rubocop/rake_task' +require 'foodcritic' +require 'kitchen' +# Style tests. Rubocop and Foodcritic namespace :style do - require 'rubocop/rake_task' desc 'Run Ruby style checks' Rubocop::RakeTask.new(:ruby) - require 'foodcritic' desc 'Run Chef style checks' - FoodCritic::Rake::LintTask.new(:chef) + FoodCritic::Rake::LintTask.new(:chef) do |t| + t.options = { + fail_tags: ['any'], + tags: [ + '~FC005', + '~FC017' + ] + } + end end desc 'Run all style checks' task style: ['style:chef', 'style:ruby'] -require 'kitchen' -desc 'Run Test Kitchen integration tests' -task :integration do - Kitchen.logger = Kitchen.default_file_logger - Kitchen::Config.new.instances.each do |instance| - instance.test(:always) - end -end +# Rspec and ChefSpec +desc "Run ChefSpec examples" +RSpec::Core::RakeTask.new(:spec) -require 'rspec/core/rake_task' -RSpec::Core::RakeTask.new(:unit) do |t| - t.rspec_opts = ['--color --format progress'] +# Integration tests. Kitchen.ci +namespace :integration do + desc 'Run Test Kitchen with Vagrant' + task :vagrant do + Kitchen.logger = Kitchen.default_file_logger + Kitchen::Config.new.instances.each do |instance| + instance.test(:always) + end + end + + desc 'Run Test Kitchen with cloud plugins' + task :cloud do + run_kitchen = true + if ENV['TRAVIS'] == 'true' && ENV['TRAVIS_PULL_REQUEST'] != 'false' + run_kitchen = false + end + + if run_kitchen + Kitchen.logger = Kitchen.default_file_logger + @loader = Kitchen::Loader::YAML.new(project_config: './.kitchen.cloud.yml') + config = Kitchen::Config.new( loader: @loader) + config.instances.each do |instance| + instance.test(:always) + end + end + end end -# We cannot run Test Kitchen on Travis CI yet... -namespace :travis do - desc 'Run tests on Travis' - task ci: ['unit', 'style'] -end +desc 'Run all tests on Travis' +task travis: ['style', 'spec', 'integration:cloud'] -# The default rake task should just run it all -task default: ['travis:ci', 'integration'] +# Default +task default: ['style', 'spec', 'integration:vagrant'] diff --git a/TESTING.md b/TESTING.md index c08c98b..5b20bb8 100644 --- a/TESTING.md +++ b/TESTING.md @@ -1,53 +1,187 @@ -This cookbook uses a variety of testing components: - -- Unit tests: [ChefSpec](https://github.com/acrmp/chefspec) -- Integration tests: [Test Kitchen](https://github.com/opscode/test-kitchen) -- Chef Style lints: [Foodcritic](https://github.com/acrmp/foodcritic) -- Ruby Style lints: [Rubocop](https://github.com/bbatsov/rubocop) - - -Prerequisites +TESTING doc +======================== + +Bundler +------- +A ruby environment with Bundler installed is a prerequisite for using +the testing harness shipped with this cookbook. At the time of this +writing, it works with Ruby 2.0 and Bundler 1.5.3. All programs +involved, with the exception of Vagrant, can be installed by cd'ing +into the parent directory of this cookbook and running "bundle install" + +Rakefile +-------- +The Rakefile ships with a number of tasks, each of which can be ran +individually, or in groups. Typing "rake" by itself will perform style +checks with Rubocop and Foodcritic, ChefSpec with rspec, and +integration with Test Kitchen using the Vagrant driver by +default.Alternatively, integration tests can be ran with Test Kitchen +cloud drivers. + +``` +$ rake -T +rake integration:cloud # Run Test Kitchen with cloud plugins +rake integration:vagrant # Run Test Kitchen with Vagrant +rake spec # Run ChefSpec examples +rake style # Run all style checks +rake style:chef # Lint Chef cookbooks +rake style:ruby # Run Ruby style checks +rake travis # Run all tests on Travis +``` + +Style Testing ------------- -To develop on this cookbook, you must have a sane Ruby 1.9+ environment. Given the nature of this installation process (and it's variance across multiple operating systems), we will leave this installation process to the user. - -You must also have `bundler` installed: - - $ gem install bundler - -You must also have Vagrant and VirtualBox installed: - -- [Vagrant](https://vagrantup.com) -- [VirtualBox](https://virtualbox.org) - -Once installed, you must install the `vagrant-berkshelf` plugin: - - $ vagrant plugin install vagrant-berkshelf - - -Development ------------ -1. Clone the git repository from GitHub: - - $ git clone git@github.com:opscode-cookbooks/COOKBOOK.git - -2. Install the dependencies using bundler: - - $ bundle install - -3. Create a branch for your changes: - - $ git checkout -b my_bug_fix - -4. Make any changes -5. Write tests to support those changes. It is highly recommended you write both unit and integration tests. -6. Run the tests: - - `bundle exec rspec` - - `bundle exec foodcritic .` - - `bundle exec rubocop` - - `bundle exec kitchen test` - -7. Assuming the tests pass, open a Pull Request on GitHub -8. Open a JIRA ticket for this component, linking the JIRA ticket to the Pull Request and visa versa. -9. Mark the JIRA ticket as "Fix Provided" +Ruby style tests can be performed by Rubocop by issuing either +``` +bundle exec rubocop +``` +or +``` +rake style:ruby +``` + +Chef style tests can be performed with Foodcritic by issuing either +``` +bundle exec foodcritic +``` +or +``` +rake style:chef +``` + +Spec Testing +------------- +Unit testing is done by running Rspec examples. Rspec will test any +libraries, then test recipes using ChefSpec. This works by compiling a +recipe (but not converging it), and allowing the user to make +assertions about the resource_collection. + +Integration Testing +------------------- +Integration testing is performed by Test Kitchen. Test Kitchen will +use either the Vagrant driver or various cloud drivers to instantiate +machines and apply cookbooks. After a successful converge, tests are +uploaded and ran out of band of Chef. Tests should be designed to +ensure that a recipe has accomplished its goal. + +Integration Testing using Vagrant +--------------------------------- +Integration tests can be performed on a local workstation using +Virtualbox or VMWare. Detailed instructions for setting this up can be +found at the [Bento](https://github.com/opscode/bento) project web site. + +Integration tests using Vagrant can be performed with either +``` +bundle exec kitchen test +``` +or +``` +rake integration:vagrant +``` + +Integration Testing using Cloud providers +----------------------------------------- +Integration tests can be performed on cloud providers using +Test Kitchen plugins. This cookbook ships a ```.kitchen.cloud.yml``` +that references environmental variables present in the shell that +```kitchen test``` is ran from. These usually contain authentication +tokens for driving IaaS APIs, as well as the paths to ssh private keys +needed for Test Kitchen log into them after they've been created. + +Examples of environment variables being set in ```~/.bash_profile```: +``` +# digital_ocean +export DIGITAL_OCEAN_CLIENT_ID='your_bits_here' +export DIGITAL_OCEAN_API_KEY='your_bits_here' +export DIGITAL_OCEAN_SSH_KEY_IDS='your_bits_here' + +# aws +export AWS_ACCESS_KEY_ID='your_bits_here' +export AWS_SECRET_ACCESS_KEY='your_bits_here' +export AWS_KEYPAIR_NAME='your_bits_here' + +# joyent +export SDC_CLI_ACCOUNT='your_bits_here' +export SDC_CLI_IDENTITY='your_bits_here' +export SDC_CLI_KEY_ID='your_bits_here' +``` + +Integration tests using cloud drivers can be performed with either +``` +export KITCHEN_YAML=.kitchen.cloud.yml +bundle exec kitchen test +``` +or +``` +rake integration:cloud +``` + +Digital Ocean Hint +------------------ +At the time of this writing, you cannot find the numerical values +needed for your SSH_KEY_IDS from the GUI. Instead, you will need to +access the API from the command line. + + curl -L 'https://api.digitalocean.com/ssh_keys/?client_id=your_bits_here&api_key=your_bits_here' + +Words about .travis.yml +----------------------- +In order for Travis to perform integration tests on public cloud +providers, two major things need to happen. First, the environment +variables referenced by ```.kitchen.cloud.yml``` need to be made +available. Second, the private half of the ssh keys needed to log into +machines need to be dropped off on the machine. + +The first part is straight forward. The travis gem can encrypt +environment variables against the public key on the Travis repository +and add them to the .travis.yml. + +``` +gem install travis +travis encrypt AWS_ACCESS_KEY_ID='your_bits_here' --add +travis encrypt AWS_SECRET_ACCESS_'your_bits_here' --add +travis encrypt AWS_KEYPAIR_NAME='your_bits_here' --add +travis encrypt EC2_SSH_KEY_PATH='~/.ssh/id_ec2.pem' --add + +travis encrypt DIGITAL_OCEAN_CLIENT_ID='your_bits_here' --add +travis encrypt DIGITAL_OCEAN_API_KEY='your_bits_here' --add +travis encrypt DIGITAL_OCEAN_SSH_KEY_IDS='your_bits_here' --add +travis encrypt DIGITAL_OCEAN_SSH_KEY_PATH='~/.ssh/id_do.pem' --add +``` + +The second part is a little more complicated. Travis ENV variables are +restricted to 90 bytes, and will not fit an entire SSH key. This can +be worked around by breaking them up into 90 byte chunks, stashing +them into ENV variables, then digging them out in the +```before_install``` section of .travis.yml + +Here is an AWK script to do the encoding. +``` +base64 ~/.ssh/travisci_cook_digitalocean.pem | \ +awk '{ + j=0; + for( i=1; i> ~/.ssh/id_do.base64 +- cat ~/.ssh/id_do.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_do.pem + - echo -n $EC2_KEY_CHUNK_{0..30} >> ~/.ssh/id_ec2.base64 + - cat ~/.ssh/id_ec2.base64 | tr -d ' ' | base64 --decode > ~/.ssh/id_ec2.pem +``` -For more information, see [Opscode's Contribution Guidelines](https://wiki.opscode.com/display/chef/How+to+Contribute). diff --git a/attributes/default.rb b/attributes/default.rb index 7c5a4be..7c1837a 100644 --- a/attributes/default.rb +++ b/attributes/default.rb @@ -17,7 +17,7 @@ # limitations under the License. # -default['authorization']['sudo']['groups'] = [] +default['authorization']['sudo']['groups'] = ['sysadmin'] default['authorization']['sudo']['users'] = [] default['authorization']['sudo']['passwordless'] = false default['authorization']['sudo']['include_sudoers_d'] = false diff --git a/rubocop-todo.yml b/rubocop-todo.yml new file mode 100644 index 0000000..3252da3 --- /dev/null +++ b/rubocop-todo.yml @@ -0,0 +1,16 @@ +# This configuration was generated by `rubocop --auto-gen-config` +# on 2014-02-18 14:05:41 -0500 using RuboCop version 0.18.1. +# The point is for the user to remove these configuration records +# one by one as the offences are removed from the code base. +# Note that changes in the inspected code, or installation of new +# versions of RuboCop, may require this file to be generated again. + +# Offence count: 4 +# Cop supports --auto-correct. +# Configuration parameters: EnforcedHashRocketStyle, EnforcedColonStyle. +AlignHash: + Enabled: false + +# Offence count: 1 +CyclomaticComplexity: + Max: 7 diff --git a/spec/default_spec.rb b/spec/default_spec.rb index 9af750a..279fbeb 100644 --- a/spec/default_spec.rb +++ b/spec/default_spec.rb @@ -1,67 +1,66 @@ require 'spec_helper' describe 'sudo::default' do - before do - stub_command('which sudo').and_return(nil) + before(:each) do + stub_command('sudo -V').and_return(false) end context 'usual business' do - let(:chef_run) do - ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04').converge('sudo::default') - end + let(:chef_run) { ChefSpec::Runner.new.converge(described_recipe) } it 'installs the sudo package' do expect(chef_run).to install_package('sudo') end it 'creates the /etc/sudoers file' do - expect(chef_run).to render_file('/etc/sudoers').with_content('Defaults !lecture,tty_tickets,!fqdn') + expect(chef_run).to render_file('/etc/sudoers').with_content(/Defaults !lecture,tty_tickets,!fqdn/) end end context 'with custom prefix' do let(:chef_run) do - ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') do |node| + ChefSpec::Runner.new do |node| node.set['authorization']['sudo']['prefix'] = '/secret/etc' - end.converge('sudo::default') + end.converge(described_recipe) end it 'creates the sudoers file in the custom location' do - expect(chef_run).to render_file('/secret/etc/sudoers').with_content('Defaults !lecture,tty_tickets,!fqdn') + expect(chef_run).to render_file('/secret/etc/sudoers').with_content(/Defaults !lecture,tty_tickets,!fqdn/) end end context "node['authorization']['sudo']['users']" do let(:chef_run) do - ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') do |node| + ChefSpec::Runner.new do |node| + node.set['authorization']['sudo']['prefix'] = '/secret/etc' node.set['authorization']['sudo']['users'] = %w(bacon) - end.converge('sudo::default') + end.converge(described_recipe) end it 'adds users of the bacon group to the sudoers file' do - expect(chef_run).to render_file('/etc/sudoers').with_content('bacon') + expect(chef_run).to render_file('/secret/etc/sudoers').with_content(/^bacon/) end end context "node['authorization']['sudo']['groups']" do let(:chef_run) do - ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') do |node| + ChefSpec::Runner.new do |node| node.set['authorization']['sudo']['groups'] = %w(bacon) - end.converge('sudo::default') + end.converge(described_recipe) end it 'adds users of the bacon group to the sudoers file' do - expect(chef_run).to render_file('/etc/sudoers').with_content('%bacon ALL=(ALL)') + expect(chef_run).to render_file('/etc/sudoers').with_content('%bacon ALL=(ALL) ALL') end end context "node['authorization']['sudo']['passwordless']" do let(:chef_run) do - ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') do |node| + ChefSpec::Runner.new do |node| node.set['authorization']['sudo']['users'] = %w(bacon) node.set['authorization']['sudo']['groups'] = %w(bacon) node.set['authorization']['sudo']['passwordless'] = true - end.converge('sudo::default') + end.converge(described_recipe) end it 'gives users and groups passwordless sudo' do @@ -72,9 +71,9 @@ context "node['authorization']['sudo']['agent_forwarding']" do let(:chef_run) do - ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') do |node| + ChefSpec::Runner.new do |node| node.set['authorization']['sudo']['agent_forwarding'] = true - end.converge('sudo::default') + end.converge(described_recipe) end it 'includes ssh forwarding in the sudoers file' do @@ -84,9 +83,9 @@ context "node['authorization']['sudo']['sudoers_defaults']" do let(:chef_run) do - ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') do |node| + ChefSpec::Runner.new do |node| node.set['authorization']['sudo']['sudoers_defaults'] = %w(ham bacon) - end.converge('sudo::default') + end.converge(described_recipe) end it 'includes each default' do @@ -97,18 +96,18 @@ context "node['authorization']['sudo']['prefix']" do context 'on SmartOS' do - let(:chef_run) { ChefSpec::Runner.new(platform: 'smartos', version: 'joyent_20130111T180733Z').converge('sudo::default') } + let(:chef_run) { ChefSpec::Runner.new(platform: 'smartos', version: 'joyent_20130111T180733Z').converge(described_recipe) } it 'uses /opt/local/etc' do - expect(chef_run).to render_file('/opt/local/etc/sudoers').with_content('Defaults !lecture,tty_tickets,!fqdn') + expect(chef_run).to create_template('/opt/local/etc/sudoers') end end context 'on Ubuntu' do - let(:chef_run) { ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04').converge('sudo::default') } + let(:chef_run) { ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04').converge(described_recipe) } it 'uses /etc' do - expect(chef_run).to render_file('/etc/sudoers').with_content('Defaults !lecture,tty_tickets,!fqdn') + expect(chef_run).to create_template('/etc/sudoers') end end end @@ -117,14 +116,14 @@ let(:chef_run) do ChefSpec::Runner.new(platform: 'ubuntu', version: '12.04') do |node| node.set['authorization']['sudo']['include_sudoers_d'] = true - end.converge('sudo::default') + end.converge(described_recipe) end it 'creates the sudoers.d directory' do expect(chef_run).to create_directory('/etc/sudoers.d').with( owner: 'root', - mode: '0755' - ) + mode: '0755' + ) end end end diff --git a/templates/default/sudoers.erb b/templates/default/sudoers.erb index 15a20d1..b4a6516 100644 --- a/templates/default/sudoers.erb +++ b/templates/default/sudoers.erb @@ -15,9 +15,6 @@ root ALL=(ALL) ALL <%= user %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL <% end -%> -# Members of the sysadmin group may gain root privileges -%sysadmin ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL - <% @sudoers_groups.each do |group| -%> # Members of the group '<%= group %>' may gain root privileges %<%= group %> ALL=(ALL) <%= "NOPASSWD:" if @passwordless %>ALL