├── spec ├── unit │ ├── README.md │ ├── metadata.rb │ ├── recipes │ │ ├── test_ingredient_config_spec.rb │ │ ├── test_override_platform_spec.rb │ │ ├── test_omnitruck_handler_spec.rb │ │ ├── test_chef_spec.rb │ │ ├── test_chef_server_senstitive.rb │ │ ├── test_chef_server_noaddons.rb │ │ ├── test_omnibus_service_spec.rb │ │ ├── test_local_spec.rb │ │ ├── test_custom_repo_setup_recipe_spec.rb │ │ ├── test_push_spec.rb │ │ ├── test_default_handler_spec.rb │ │ ├── test_config_spec.rb │ │ ├── test_upgrade_spec.rb │ │ └── test_repo_spec.rb │ ├── chef_file_spec.rb │ └── chef_automate_spec.rb └── spec_helper.rb ├── .mdlrc ├── test ├── fixtures │ ├── nodes │ │ ├── .gitkeep │ │ └── sample-node.json │ ├── data_bags │ │ ├── .gitkeep │ │ └── vault │ │ │ └── .gitkeep │ └── cookbooks │ │ ├── test │ │ ├── README.md │ │ ├── recipes │ │ │ ├── install_git.rb │ │ │ ├── omnitruck_handler.rb │ │ │ ├── push.rb │ │ │ ├── default_handler.rb │ │ │ ├── chef.rb │ │ │ ├── unstable_chefdk.rb │ │ │ ├── unstable_chef_server.rb │ │ │ ├── inspec.rb │ │ │ ├── upgrade.rb │ │ │ ├── override_platform.rb │ │ │ ├── ingredient_config.rb │ │ │ ├── chef_workstation.rb │ │ │ ├── rubygems_url.rb │ │ │ ├── chef_server_noaddons.rb │ │ │ ├── custom_repo_setup_recipe.rb │ │ │ ├── automatev2.rb │ │ │ ├── chef_server_sensitive.rb │ │ │ ├── default.rb │ │ │ ├── config.rb │ │ │ ├── file.rb │ │ │ ├── omnibus_service.rb │ │ │ ├── compliance.rb │ │ │ ├── local.rb │ │ │ ├── chef_server.rb │ │ │ ├── repo.rb │ │ │ └── automate.rb │ │ ├── metadata.rb │ │ └── attributes │ │ │ └── default.rb │ │ └── custom_repo │ │ ├── metadata.rb │ │ └── recipes │ │ └── awesome_custom_setup.rb └── integration │ ├── chef-server │ └── test_chef_server_spec.rb │ ├── local-package-install │ └── assert_local_package_installed_spec.rb │ ├── default │ └── default_spec.rb │ ├── inspec │ └── inspec_spec.rb │ ├── chef-workstation │ └── test_chef_workstation_spec.rb │ ├── chef-automatev2 │ └── test_chef_automatev2_spec.rb │ └── rubygems-url │ └── test_rubygems_url.rb ├── .gitattributes ├── .rubocop.yml ├── .github ├── CODEOWNERS └── workflows │ ├── branchcleanup.yml │ └── ci.yml ├── CODE_OF_CONDUCT.md ├── TESTING.md ├── CONTRIBUTING.md ├── .vscode └── extensions.json ├── kitchen.exec.yml ├── .editorconfig ├── metadata.rb ├── templates ├── push-jobs-client.rb.erb └── client.rb.erb ├── .gitignore ├── Guardfile ├── recipes └── default.rb ├── Policyfile.rb ├── attributes └── default.rb ├── resources ├── ingredient_config.rb ├── omnibus_service.rb ├── file.rb ├── supermarket.rb ├── chef_user.rb ├── server.rb ├── chef_org.rb ├── automatev2.rb ├── backend.rb ├── chef_ingredient.rb ├── automate.rb ├── client.rb └── wf_builder.rb ├── chefignore ├── kitchen.dokken.yml ├── kitchen.yml ├── libraries ├── omnitruck_handler.rb ├── default_handler.rb └── helpers.rb ├── LICENSE ├── README.md └── CHANGELOG.md /spec/unit/README.md: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.mdlrc: -------------------------------------------------------------------------------- 1 | rules "~MD013" 2 | -------------------------------------------------------------------------------- /test/fixtures/nodes/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /test/fixtures/data_bags/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | * text=auto eol=lf 2 | -------------------------------------------------------------------------------- /test/fixtures/data_bags/vault/.gitkeep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | --- 2 | AllCops: 3 | TargetChefVersion: 17.0 4 | -------------------------------------------------------------------------------- /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | * @chef-cookbooks/cookbook_engineering_team 2 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/README.md: -------------------------------------------------------------------------------- 1 | This is a test cookbook 2 | -------------------------------------------------------------------------------- /spec/unit/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'FC045-not-a-cookbook' 2 | version '0.0.1' 3 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/install_git.rb: -------------------------------------------------------------------------------- 1 | include_recipe 'git' 2 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/omnitruck_handler.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'chef' 2 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/custom_repo/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'custom_repo' 2 | version '0.0.1' 3 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/custom_repo/recipes/awesome_custom_setup.rb: -------------------------------------------------------------------------------- 1 | log 'configured an awesome custom repo' 2 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | Please refer to the Chef Community Code of Conduct at 2 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/push.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'push-jobs-client' do 2 | action :install 3 | end 4 | -------------------------------------------------------------------------------- /TESTING.md: -------------------------------------------------------------------------------- 1 | Please refer to 2 | 3 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | Please refer to 2 | 3 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/default_handler.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'chef' do 2 | channel :stable 3 | version :latest 4 | end 5 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/chef.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'chef' do 2 | channel :current 3 | version :latest 4 | action :upgrade 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'test' 2 | version '0.0.1' 3 | 4 | depends 'chef-ingredient' 5 | depends 'custom_repo' 6 | depends 'git' 7 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "chef-software.chef", 4 | "rebornix.ruby", 5 | "editorconfig.editorconfig" 6 | ] 7 | } -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/unstable_chefdk.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'chefdk' do 2 | action :upgrade 3 | channel :unstable 4 | version :latest 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/unstable_chef_server.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'chef-server' do 2 | action :install 3 | channel :unstable 4 | version :latest 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/inspec.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'install inspec version' do 2 | product_name 'inspec' 3 | platform_version_compatibility_mode true 4 | end 5 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/upgrade.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'chef-server' 2 | 3 | chef_ingredient 'chef-server' do 4 | action :upgrade 5 | channel :current 6 | end 7 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/override_platform.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'chefdk' do 2 | platform 'el' 3 | platform_version '5' 4 | platform_version_compatibility_mode true 5 | end 6 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/ingredient_config.rb: -------------------------------------------------------------------------------- 1 | ingredient_config 'chef-server' do 2 | action :add 3 | config "topology 'torus'" 4 | end 5 | 6 | ingredient_config 'chef-server' 7 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/chef_workstation.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'install chef-workstation' do 2 | product_name 'chef-workstation' 3 | platform_version_compatibility_mode true 4 | end 5 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/rubygems_url.rb: -------------------------------------------------------------------------------- 1 | chef_ingredient 'cinc' do 2 | channel :stable 3 | version :latest 4 | rubygems_url 'https://packagecloud.io/cinc-project/stable' 5 | action :install 6 | end 7 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/chef_server_noaddons.rb: -------------------------------------------------------------------------------- 1 | node.default['chef_server']['fqdn'] = 'localhost' 2 | 3 | chef_server node['chef_server']['fqdn'] do 4 | config <<-EOS 5 | api_fqdn '#{node['chef_server']['fqdn']}' 6 | EOS 7 | accept_license true 8 | end 9 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/custom_repo_setup_recipe.rb: -------------------------------------------------------------------------------- 1 | # Configure a custom repository setup recipe 2 | node.default['chef-ingredient']['custom-repo-recipe'] = 'custom_repo::awesome_custom_setup' 3 | 4 | chef_ingredient 'chef-server' do 5 | action :install 6 | end 7 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/automatev2.rb: -------------------------------------------------------------------------------- 1 | chef_automatev2 'automatev2.chefstack.local' do 2 | config <<~EOS 3 | [global.v1] 4 | fqdn = "chef-automate.example.com" 5 | EOS 6 | products %w(automate infra-server builder desktop) 7 | accept_license true 8 | end 9 | -------------------------------------------------------------------------------- /kitchen.exec.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: exec 4 | gui: false 5 | customize: 6 | memory: 4096 7 | 8 | transport: 9 | name: exec 10 | 11 | platforms: 12 | - name: windows-2016 13 | - name: windows-2019 14 | - name: windows-2022 15 | - name: macos-latest 16 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/chef_server_sensitive.rb: -------------------------------------------------------------------------------- 1 | chef_server 'chef-server.local' do 2 | sensitive true 3 | config "api_fqdn 'chef-server.local'" 4 | addons manage: { config: 'disable_sign_up false' }, 5 | "push-jobs-server": { config: 'whitelist {}' } 6 | end 7 | -------------------------------------------------------------------------------- /test/integration/chef-server/test_chef_server_spec.rb: -------------------------------------------------------------------------------- 1 | # describe command('chef-server-ctl test') do 2 | # its('exit_status') { should eq 0 } 3 | # end 4 | 5 | describe command('chef-server-ctl status opscode-erchef') do 6 | its('stdout') { should match(/run: opscode-erchef:/) } 7 | end 8 | -------------------------------------------------------------------------------- /test/integration/local-package-install/assert_local_package_installed_spec.rb: -------------------------------------------------------------------------------- 1 | context 'chef-ingredient::default' do 2 | describe package('chef-server-core') do 3 | it { should be_installed } 4 | end 5 | 6 | describe command('sudo chef-server-ctl test') do 7 | its(:exit_status) { should eq 0 } 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/default.rb: -------------------------------------------------------------------------------- 1 | if platform_family?('rhel') 2 | remote_file '/etc/pki/tls/certs/ca-bundle.crt' do 3 | source 'http://opscode-omnibus-cache.s3.amazonaws.com/cacerts-2014.07.15-fd48275847fa10a8007008379ee902f1' 4 | checksum 'a9cce49cec92304d29d05794c9b576899d8a285659b3f987dd7ed784ab3e0621' 5 | sensitive true 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # https://EditorConfig.org 2 | 3 | # top-most EditorConfig file 4 | root=true 5 | 6 | # Unix-style newlines with a newline ending every file 7 | [*] 8 | end_of_line = lf 9 | insert_final_newline = true 10 | 11 | # 2 space indentation 12 | indent_style = space 13 | indent_size = 2 14 | 15 | # Avoid issues parsing cookbook files later 16 | charset = utf-8 17 | 18 | # Avoid cookstyle warnings 19 | trim_trailing_whitespace = true 20 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/config.rb: -------------------------------------------------------------------------------- 1 | # Chef Server Core 2 | chef_ingredient 'chef-server' do 3 | config <<-EOS 4 | api_fqdn "#{node['fqdn']}" 5 | ip_version "ipv6" 6 | notification_email "#{node['chef_admin']}" 7 | nginx["ssl_protocols"] = "TLSv1 TLSv1.1 TLSv1.2" 8 | EOS 9 | action :reconfigure 10 | end 11 | 12 | # Management Console 13 | chef_ingredient 'manage' do 14 | accept_license true 15 | action :reconfigure 16 | end 17 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_ingredient_config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::ingredient_config' do 4 | cached(:chef_run) do 5 | ChefSpec::SoloRunner.new( 6 | platform: 'ubuntu', 7 | step_into: ['ingredient_config'] 8 | ).converge(described_recipe) 9 | end 10 | 11 | it 'it renders ad hoc config' do 12 | expect(chef_run).to create_file('/etc/opscode/chef-server.rb').with(content: "topology 'torus'") 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/file.rb: -------------------------------------------------------------------------------- 1 | chef_file '/tmp/remote_file' do 2 | source 'https://www.example.com/test' 3 | user 'root' 4 | group 'root' 5 | mode '0600' 6 | end 7 | 8 | chef_file '/tmp/cookbook_file' do 9 | source 'cookbook_file://chef_test::testfile' 10 | user 'root' 11 | group 'root' 12 | mode '0600' 13 | end 14 | 15 | chef_file '/tmp/file' do 16 | source 'abcdef' 17 | user 'root' 18 | group 'root' 19 | mode '0600' 20 | end 21 | -------------------------------------------------------------------------------- /.github/workflows/branchcleanup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | name: Branch Cleanup 3 | # This workflow is triggered on all closed pull requests. 4 | # However the script does not do anything if a merge was not performed. 5 | "on": 6 | pull_request: 7 | types: [closed] 8 | 9 | env: 10 | NO_BRANCH_DELETED_EXIT_CODE: 0 11 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 12 | 13 | jobs: 14 | build: 15 | runs-on: ubuntu-latest 16 | steps: 17 | - uses: jessfraz/branch-cleanup-action@master 18 | -------------------------------------------------------------------------------- /test/integration/default/default_spec.rb: -------------------------------------------------------------------------------- 1 | context 'chef-ingredient::default' do 2 | describe package('chef-server-core') do 3 | it { should be_installed } 4 | end 5 | 6 | describe command('sudo chef-server-ctl test') do 7 | its(:exit_status) { should eq 0 } 8 | end 9 | 10 | describe package('chef-manage') do 11 | it { should be_installed } 12 | end 13 | 14 | describe command('sudo chef-manage-ctl test') do 15 | its(:exit_status) { should eq 0 } 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/integration/inspec/inspec_spec.rb: -------------------------------------------------------------------------------- 1 | # The way this spec is written is more of an experiment. Executing Windows programs for the first time 2 | # via inspec require the fully qualified path. Even though the bin has been added to $env:Path the session 3 | # has not been reloaded. This reloads $env:Path before calling the program. I could see this being beneficial to 4 | # inspec's default behavior. 5 | 6 | describe package('inspec') do 7 | it { should be_installed } 8 | end unless os.windows? || os.darwin? 9 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_override_platform_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::override_platform' do 4 | context 'install chefdk on ubuntu' do 5 | cached(:ubuntu) do 6 | ChefSpec::SoloRunner.new( 7 | platform: 'ubuntu', 8 | version: '18.04' 9 | ).converge(described_recipe) 10 | end 11 | 12 | it 'installs chefdk' do 13 | expect(ubuntu).to install_chef_ingredient('chefdk').with(platform: 'el', platform_version: '5') 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /metadata.rb: -------------------------------------------------------------------------------- 1 | name 'chef-ingredient' 2 | maintainer 'Chef Software, Inc.' 3 | maintainer_email 'cookbooks@chef.io' 4 | license 'Apache-2.0' 5 | description 'Primitives for managing Chef products and packages' 6 | version '3.5.0' 7 | 8 | %w(amazon centos redhat scientific oracle fedora debian ubuntu).each do |os| 9 | supports os 10 | end 11 | 12 | source_url 'https://github.com/chef-cookbooks/chef-ingredient' 13 | issues_url 'https://github.com/chef-cookbooks/chef-ingredient/issues' 14 | 15 | chef_version '>= 15.3' 16 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_omnitruck_handler_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::omnitruck_handler' do 4 | context 'install chef on aix' do 5 | let(:aix) do 6 | ChefSpec::SoloRunner.new( 7 | platform: 'aix', 8 | step_into: %w(chef_ingredient) 9 | ).converge(described_recipe) 10 | end 11 | 12 | it 'use the omnitruck handler' do 13 | skip 'currently only works when run alone' 14 | expect(aix).to run_execute('install-chef-latest') 15 | end 16 | end 17 | end 18 | -------------------------------------------------------------------------------- /test/integration/chef-workstation/test_chef_workstation_spec.rb: -------------------------------------------------------------------------------- 1 | # The way this spec is written is more of an experiment. Executing Windows programs for the first time 2 | # via inspec require the fully qualified path. Even though the bin has been added to $env:Path the session 3 | # has not been reloaded. This reloads $env:Path before calling the program. I could see this being beneficial to 4 | # inspec's default behavior. 5 | 6 | describe package('chef-workstation') do 7 | it { should be_installed } 8 | end unless os.windows? || os.darwin? 9 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/attributes/default.rb: -------------------------------------------------------------------------------- 1 | default['test']['source_url'] = case node['platform_family'] 2 | when 'debian' 3 | "https://packages.chef.io/stable/ubuntu/#{node['platform_version']}/chef-server-core_12.8.0-1_amd64.deb" 4 | when 'rhel' 5 | "https://packages.chef.io/stable/el/#{node['platform_version'].to_i}/chef-server-core-12.8.0-1.el#{node['platform_version'].to_i}.x86_64.rpm" 6 | end 7 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/omnibus_service.rb: -------------------------------------------------------------------------------- 1 | # we probably don't need/want to add this to a test kitchen suite. 2 | # This here so we can test with chefspec, really. 3 | omnibus_service 'chef-server/rabbitmq' do 4 | action :restart 5 | end 6 | 7 | omnibus_service 'chef-server/nginx' do 8 | action :nothing 9 | end 10 | 11 | notify_group 'I tell nginx to stop' do 12 | notifies :stop, 'omnibus_service[chef-server/nginx]' 13 | end 14 | 15 | omnibus_service 'never-never/land' do 16 | ctl_command 'never-never-ctl' 17 | action :start 18 | end 19 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/compliance.rb: -------------------------------------------------------------------------------- 1 | # 2 | # This recipe tests the :unstable channel. 3 | # This channel is only accessible from Chef's internal 4 | # network and contains untested builds of Chef products. 5 | # 6 | # Make sure you set below environment variables for 7 | # tests to work correctly. 8 | # 9 | 10 | include_recipe 'test::install_git' 11 | 12 | chef_ingredient 'compliance' do 13 | action :install 14 | channel :stable 15 | version :latest 16 | end 17 | 18 | chef_ingredient 'compliance' do 19 | action :upgrade 20 | channel :unstable 21 | version :latest 22 | end 23 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/local.rb: -------------------------------------------------------------------------------- 1 | # helper methods for recipe clariy 2 | 3 | pkgname = ::File.basename(node['test']['source_url']) 4 | cache_path = Chef::Config[:file_cache_path] 5 | 6 | # recipe 7 | remote_file "#{cache_path}/#{pkgname}" do 8 | source node['test']['source_url'] 9 | mode '0644' 10 | end 11 | 12 | chef_ingredient 'chef-server' do 13 | package_source "#{cache_path}/#{pkgname}" 14 | action :install 15 | end 16 | 17 | file '/tmp/chef-server-core.firstrun' do 18 | content 'ilovechef\n' 19 | notifies :reconfigure, 'chef_ingredient[chef-server]' 20 | action :create 21 | end 22 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/chef_server.rb: -------------------------------------------------------------------------------- 1 | node.default['chef_server']['fqdn'] = 'localhost' 2 | 3 | chef_server node['chef_server']['fqdn'] do 4 | version :latest 5 | config <<-EOS 6 | api_fqdn '#{node['chef_server']['fqdn']}' 7 | oc_id['applications'] = { 8 | "supermarket"=>{"redirect_uri"=>"https://supermarket.services.com/auth/chef_oauth2/callback"} 9 | } 10 | EOS 11 | addons manage: { config: '' }, 12 | "push-jobs-server": { config: '' } 13 | accept_license true 14 | data_collector_url 'https://automate.services.com/data-collector/v0/' if search(:node, 'name:automate-centos-68', filter_result: { 'name' => ['name'] }) 15 | end 16 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_chef_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::chef' do 4 | context 'install chef' do 5 | cached(:chef_run) do 6 | ChefSpec::SoloRunner.new( 7 | platform: 'ubuntu', 8 | version: '18.04', 9 | step_into: %w(chef_ingredient) 10 | ).converge(described_recipe) 11 | end 12 | 13 | it 'installs chef' do 14 | expect(chef_run).to upgrade_package('chef') 15 | end 16 | 17 | it 'stops the run' do 18 | chef_install_resource = chef_run.package('chef') 19 | expect(chef_install_resource).to notify('ruby_block[stop chef run]').to(:run).immediately 20 | end 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /templates/push-jobs-client.rb.erb: -------------------------------------------------------------------------------- 1 | # File managed by Chef. Do not modify. 2 | 3 | chef_server_url "<%= Chef::Config['chef_server_url'] %>" 4 | node_name "<%= Chef::Config['node_name'] %>" 5 | allow_unencrypted true 6 | 7 | # Chef server connect options 8 | trusted_certs_dir "/etc/chef/trusted_certs" 9 | verify_api_cert true 10 | ssl_verify_mode :verify_peer 11 | whitelist({"chef-client"=>"chef-client", 12 | /^delivery-cmd (.+)$/=>"/var/opt/delivery/workspace/bin/delivery-cmd '\\1'"}) 13 | 14 | # NOTE - if we settle on a daemon provider that captures and timestamps logs, 15 | # set this to 'false' to avoid duplicated timestamps in the logs. 16 | Mixlib::Log::Formatter.show_time = false 17 | -------------------------------------------------------------------------------- /test/integration/chef-automatev2/test_chef_automatev2_spec.rb: -------------------------------------------------------------------------------- 1 | # describe command('chef-server-ctl test') do 2 | # its('exit_status') { should eq 0 } 3 | # end 4 | 5 | describe file('/usr/local/bin/chef-automate') do 6 | it { should_not exist } 7 | end 8 | 9 | bin_path = if os.debian? 10 | '/bin/chef-automate' 11 | else 12 | '/usr/bin/chef-automate' 13 | end 14 | 15 | describe file(bin_path) do 16 | it { should exist } 17 | end 18 | 19 | describe command('chef-automate version') do 20 | its('exit_status') { should eq 0 } 21 | end 22 | 23 | %w(80 443).each do |port| 24 | describe port(port) do 25 | it { should be_listening } 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.rbc 2 | .config 3 | InstalledFiles 4 | lib/bundler/man 5 | pkg 6 | test/tmp 7 | test/version_tmp 8 | tmp 9 | _Store 10 | *~ 11 | *# 12 | .#* 13 | \#*# 14 | *.un~ 15 | *.tmp 16 | *.bk 17 | *.bkup 18 | 19 | # editor temp files 20 | .idea 21 | .*.sw[a-z] 22 | 23 | # ruby/bundler files 24 | .ruby-version 25 | .ruby-gemset 26 | .rvmrc 27 | Gemfile.lock 28 | .bundle 29 | *.gem 30 | coverage 31 | spec/reports 32 | 33 | # YARD / rdoc artifacts 34 | .yardoc 35 | _yardoc 36 | doc/ 37 | rdoc 38 | 39 | # chef infra stuff 40 | Berksfile.lock 41 | .kitchen 42 | kitchen.local.yml 43 | vendor/ 44 | .coverage/ 45 | .zero-knife.rb 46 | Policyfile.lock.json 47 | 48 | # vagrant stuff 49 | .vagrant/ 50 | .vagrant.d/ 51 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_chef_server_senstitive.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::chef_server_sensitive' do 4 | context 'install chef server' do 5 | cached(:chef_run) do 6 | ChefSpec::SoloRunner.new( 7 | platform: 'ubuntu', 8 | version: '18.04', 9 | step_into: %w(chef_server) 10 | ).converge(described_recipe) 11 | end 12 | 13 | it 'installs chef server with sensitive true' do 14 | expect(chef_run).to upgrade_chef_ingredient('chef-server').with(sensitive: true) 15 | expect(chef_run).to render_ingredient_config('chef-server').with(sensitive: true) 16 | expect(chef_run).to upgrade_chef_ingredient('manage').with(sensitive: true) 17 | expect(chef_run).to render_ingredient_config('manage').with(sensitive: true) 18 | end 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_chef_server_noaddons.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::chef_server_noaddons' do 4 | context 'install chef server' do 5 | cached(:chef_run) do 6 | stub_search('node', 'name:automate-centos-68').and_return('automate-centos-68') 7 | ChefSpec::SoloRunner.new( 8 | platform: 'ubuntu', 9 | version: '18.04', 10 | step_into: %w(chef_server) 11 | ).converge(described_recipe) 12 | end 13 | 14 | it 'installs chef server without addon manage' do 15 | expect(chef_run).to upgrade_chef_ingredient('chef-server') 16 | expect(chef_run).to render_ingredient_config('chef-server') 17 | expect(chef_run).to_not upgrade_chef_ingredient('manage') 18 | expect(chef_run).to_not render_ingredient_config('manage') 19 | end 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /test/integration/rubygems-url/test_rubygems_url.rb: -------------------------------------------------------------------------------- 1 | # The way this spec is written is more of an experiment. Executing Windows programs for the first time 2 | # via inspec require the fully qualified path. Even though the bin has been added to $env:Path the session 3 | # has not been reloaded. This reloads $env:Path before calling the program. I could see this being beneficial to 4 | # inspec's default behavior. 5 | 6 | resource_command = 'command' 7 | 8 | if os.windows? 9 | resource_command = 'powershell' 10 | 11 | describe powershell('$env:Path = [System.Environment]::GetEnvironmentVariable("Path","Machine") + ";" + [System.Environment]::GetEnvironmentVariable("Path","User")') do 12 | its('exit_status') { should eq 0 } 13 | end 14 | end 15 | 16 | describe send(resource_command, 'cinc-client --version') do 17 | its('stdout') { should match(/Cinc Client:/) } 18 | end 19 | -------------------------------------------------------------------------------- /Guardfile: -------------------------------------------------------------------------------- 1 | # More info at https://github.com/guard/guard#readme 2 | 3 | # guard 'foodcritic', :cookbook_paths => '.', :cli => '-t ~FC023 -t ~FC005', :all_on_start => false do 4 | # watch(/attributes\/.+\.rb$/) 5 | # watch(/providers\/.+\.rb$/) 6 | # watch(/recipes\/.+\.rb$/) 7 | # watch(/resources\/.+\.rb$/) 8 | # watch('metadata.rb') 9 | # end 10 | 11 | guard 'rubocop' do 12 | watch(%r{attributes\/.+\.rb$}) 13 | watch(%r{providers\/.+\.rb$}) 14 | watch(%r{recipes\/.+\.rb$}) 15 | watch(%r{resources\/.+\.rb$}) 16 | watch('metadata.rb') 17 | end 18 | 19 | guard :rspec, cmd: 'chef exec /opt/chef-workstation/embedded/bin/rspec', all_on_start: false, notification: false do 20 | watch(%r{^libraries\/(.+)\.rb$}) 21 | watch(%r{^spec\/(.+)_spec\.rb$}) 22 | watch(%r{^(recipes)\/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" } 23 | watch('spec/spec_helper.rb') { 'spec' } 24 | end 25 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require 'chefspec' 2 | require 'chefspec/berkshelf' 3 | require_relative '../libraries/default_handler' 4 | require_relative '../libraries/omnitruck_handler' 5 | 6 | RSpec.configure do |config| 7 | config.color = true 8 | config.formatter = 'doc' 9 | config.log_level = :error 10 | 11 | config.before do 12 | artifact_info = instance_double('artifact info', 13 | url: 'http://packages.chef.io', 14 | sha256: 'f0e4c2f76c58916ec258f246851bea091d14d4247a2fc3e18694461b1816e13b') 15 | installer = instance_double('installer', 16 | artifact_info: artifact_info, 17 | current_version: nil, 18 | install_command: 'install_command') 19 | allow_any_instance_of(ChefIngredient::DefaultHandler).to receive(:installer).and_return(installer) 20 | allow_any_instance_of(ChefIngredient::OmnitruckHandler).to receive(:installer).and_return(installer) 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /recipes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright:: 2015-2021, Chef Software, Inc. 3 | # 4 | # Licensed under the Apache License, Version 2.0 (the "License"); 5 | # you may not use this file except in compliance with the License. 6 | # You may obtain a copy of the License at 7 | # 8 | # http://www.apache.org/licenses/LICENSE-2.0 9 | # 10 | # Unless required by applicable law or agreed to in writing, software 11 | # distributed under the License is distributed on an "AS IS" BASIS, 12 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | # See the License for the specific language governing permissions and 14 | # limitations under the License. 15 | # 16 | 17 | # This recipe is included to make our tests happy. 18 | # By intention, it does not contain anything. 19 | 20 | Chef::Log.warn('The chef-ingredient::default recipe includes no resources and should not be included directly on nodes') 21 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/repo.rb: -------------------------------------------------------------------------------- 1 | # Chef Server Core 2 | chef_ingredient 'chef-server' do 3 | config <<-EOS 4 | api_fqdn "#{node['fqdn']}" 5 | ip_version "ipv6" 6 | notification_email "#{node['chef_admin']}" 7 | nginx["ssl_protocols"] = "TLSv1 TLSv1.1 TLSv1.2" 8 | EOS 9 | action :install 10 | end 11 | 12 | file '/tmp/chef-server-core.firstrun' do 13 | content 'ilovechef\n' 14 | action :create 15 | end 16 | 17 | ingredient_config 'chef-server' do 18 | notifies :reconfigure, 'chef_ingredient[chef-server]' 19 | end 20 | 21 | chef_ingredient 'manage' do 22 | config <<-EOS 23 | disable_sign_up true 24 | support_email_address "#{node['chef_admin']}" 25 | EOS 26 | action :install 27 | accept_license true 28 | end 29 | 30 | file '/tmp/opscode-manage.firstrun' do 31 | content 'ilovechef\n' 32 | action :create 33 | end 34 | 35 | ingredient_config 'manage' do 36 | notifies :reconfigure, 'chef_ingredient[manage]' 37 | sensitive true 38 | end 39 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_omnibus_service_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::omnibus_service' do 4 | cached(:chef_run) do 5 | ChefSpec::SoloRunner.new( 6 | platform: 'ubuntu', 7 | version: '18.04', 8 | step_into: ['omnibus_service'] 9 | ).converge(described_recipe) 10 | end 11 | 12 | # let(:log_message) { chef_run.log('I tell nginx to stop') } 13 | 14 | it 'allows the chef-server-core/rabbitmq service to restart' do 15 | expect(chef_run).to restart_omnibus_service('chef-server/rabbitmq') 16 | end 17 | 18 | it 'restarts the rabbitmq service' do 19 | expect(chef_run).to run_execute('chef-server-ctl restart rabbitmq') 20 | end 21 | 22 | # it 'has a log service that notifies the chef server nginx' do 23 | # expect(log_message).to notify('omnibus_service[chef-server/nginx]').to(:stop) 24 | # end 25 | # 26 | # it 'starts with a made up service' do 27 | # expect(chef_run).to run_execute('never-never-ctl start land') 28 | # end 29 | end 30 | -------------------------------------------------------------------------------- /templates/client.rb.erb: -------------------------------------------------------------------------------- 1 | # This file managed by Chef. Do not edit. 2 | 3 | chef_server_url "<%= @chef_server_url %>" 4 | client_fork true 5 | 6 | log_level :<%= @log_level %> 7 | log_location <%= @log_location %> 8 | 9 | <%- if @ssl_verify.eql?(true) %> 10 | verify_api_cert true 11 | ssl_verify_mode :verify_peer 12 | <%- else %> 13 | verify_api_cert false 14 | ssl_verify_mode :verify_none 15 | <%- end %> 16 | 17 | <%- if @validation_client_name %> 18 | validation_client_name "<%= @validation_client_name %>" 19 | <%- end %> 20 | 21 | node_name "<%= @node_name %>" 22 | <%- if @client_key %> 23 | client_key "<%= @client_key %>" 24 | <%- end %> 25 | 26 | <%- if @json_attribs %> 27 | json_attribs "<%= @json_attribs %>" 28 | <%- end %> 29 | 30 | <%- if @data_collector_url %> 31 | data_collector.server_url = '<%= @data_collector_url %>' 32 | data_collector.token = '<%= @data_collector_token %>' 33 | <%- end %> 34 | 35 | trusted_certs_dir "<%= @trusted_certs_dir || '/etc/chef/trusted_certs' %>" 36 | 37 | # Do not crash if a handler is missing / not installed yet 38 | begin 39 | rescue NameError => e 40 | Chef::Log.error e 41 | end 42 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_local_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::local' do 4 | context 'on centos' do 5 | cached(:centos_6) do 6 | ChefSpec::SoloRunner.new( 7 | platform: 'centos', 8 | version: '6', 9 | step_into: %w(chef_ingredient chef_server_ingredient) 10 | ) do |node| 11 | node.normal['chef-server-core']['version'] = nil 12 | end.converge(described_recipe) 13 | end 14 | 15 | it 'uses the Yum package provider' do 16 | expect(centos_6).to install_package('chef-server-core').with(provider: Chef::Provider::Package::Yum) 17 | end 18 | end 19 | 20 | context 'on ubuntu' do 21 | cached(:ubuntu) do 22 | ChefSpec::SoloRunner.new( 23 | platform: 'ubuntu', 24 | version: '18.04', 25 | step_into: %w(chef_ingredient chef_server_ingredient) 26 | ) do |node| 27 | node.normal['chef-server-core']['version'] = nil 28 | end.converge(described_recipe) 29 | end 30 | 31 | it 'uses the dpkg package provider' do 32 | expect(ubuntu).to install_package('chef-server-core').with(provider: Chef::Provider::Package::Dpkg) 33 | end 34 | end 35 | end 36 | -------------------------------------------------------------------------------- /Policyfile.rb: -------------------------------------------------------------------------------- 1 | # Policyfile.rb - Describe how you want Chef Infra Client to build your system. 2 | # 3 | # For more information on the Policyfile feature, visit 4 | # https://docs.chef.io/policyfile/ 5 | 6 | # A name that describes what the system you're building with Chef does. 7 | name 'chef-ingredient' 8 | 9 | # Where to find external cookbooks: 10 | default_source :supermarket 11 | 12 | # run_list: chef-client will run these recipes in the order specified. 13 | run_list 'chef-ingredient::default' 14 | named_run_list :test, 'test' 15 | named_run_list :test_install_git, 'test::install_git' 16 | named_run_list :test_repo, %w(test::install_git test test::repo) 17 | named_run_list :test_local, %w(test::install_git test test::local) 18 | named_run_list :test_chef_workstation, 'test::chef_workstation' 19 | named_run_list :test_inspec,'test::inspec' 20 | named_run_list :test_chef_server, 'test::chef_server_noaddons' 21 | named_run_list :test_chef_automatev2, 'test::automatev2' 22 | 23 | # Specify a custom source for a single cookbook: 24 | cookbook 'chef-ingredient', path: '.' 25 | cookbook 'test', path: './test/fixtures/cookbooks/test' 26 | cookbook 'custom_repo', path: './test/fixtures/cookbooks/custom_repo' 27 | -------------------------------------------------------------------------------- /attributes/default.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Salim Afiune 3 | # Copyright:: 2015-2021, Chef Software, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | default['chef-ingredient'] = {} 19 | 20 | # Set `custom-repo-recipe` to a string "cookbook::recipe" to specify 21 | # a custom recipe that sets up your own yum/apt repository where you have 22 | # mirrored the ingredient packages you want to use. 23 | # 24 | # Do this elsewhere in your cookbook where you use chef_ingredient, in a 25 | # policyfile, environment, role, etc. 26 | # 27 | # default['chef-ingredient']['custom-repo-recipe'] = 'custom_repo::awesome_custom_setup' 28 | 29 | # Testing Attributes # 30 | # 31 | # Optionally install the mixlib-install gem from source. This ref can be 32 | # a revision, branch or tag. 33 | # 34 | default['chef-ingredient']['mixlib-install']['git_ref'] = nil 35 | default['chef-ingredient']['mixlib-install']['version'] = nil # nil installs latest 36 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_custom_repo_setup_recipe_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::custom_repo_setup_recipe' do 4 | context 'on centos' do 5 | cached(:centos_6) do 6 | ChefSpec::SoloRunner.new( 7 | platform: 'centos', 8 | version: '6', 9 | step_into: %w(chef_ingredient) 10 | ).converge(described_recipe) 11 | end 12 | 13 | it 'does not creates the yum repository' do 14 | expect(centos_6).to_not create_yum_repository('chef-stable') 15 | end 16 | 17 | it 'installs yum_package[chef-server]' do 18 | pkgres = centos_6.find_resource('package', 'chef-server') 19 | expect(pkgres).to_not be_nil 20 | expect(pkgres).to be_a(Chef::Resource::YumPackage) 21 | expect(centos_6).to install_package('chef-server') 22 | end 23 | 24 | it 'includes the custom_repo_setup_recipe' do 25 | expect(centos_6).to include_recipe 'custom_repo::awesome_custom_setup' 26 | end 27 | end 28 | 29 | context 'on ubuntu' do 30 | cached(:ubuntu) do 31 | ChefSpec::SoloRunner.new( 32 | platform: 'ubuntu', 33 | version: '18.04', 34 | step_into: %w(chef_ingredient) 35 | ).converge(described_recipe) 36 | end 37 | 38 | it 'does not sets up current apt repository' do 39 | expect(ubuntu).to_not add_apt_repository('chef-stable') 40 | end 41 | 42 | it 'installs chef' do 43 | expect(ubuntu).to install_package('chef-server') 44 | end 45 | 46 | it 'includes the custom_repo_setup_recipe' do 47 | expect(ubuntu).to include_recipe 'custom_repo::awesome_custom_setup' 48 | end 49 | end 50 | end 51 | -------------------------------------------------------------------------------- /resources/ingredient_config.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Joshua Timberman 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | provides :ingredient_config 19 | resource_name :ingredient_config 20 | 21 | unified_mode true if respond_to?(:unified_mode) 22 | 23 | property :product_name, String, name_property: true 24 | property :config, [String, NilClass] 25 | 26 | # Install mixlib-install/version gems from rubygems.org or an alternative source 27 | property :rubygems_url, String 28 | 29 | action :render do 30 | target_config = ingredient_config_file(new_resource.product_name) 31 | return if target_config.nil? 32 | 33 | directory ::File.dirname(target_config) do 34 | recursive true 35 | action :create 36 | end 37 | 38 | file target_config do 39 | sensitive new_resource.sensitive if new_resource.sensitive 40 | action :create 41 | content get_config(new_resource.product_name) 42 | end 43 | end 44 | 45 | action :add do 46 | add_config(new_resource.product_name, new_resource.config) 47 | end 48 | 49 | action_class do 50 | include ChefIngredientCookbook::Helpers 51 | end 52 | -------------------------------------------------------------------------------- /chefignore: -------------------------------------------------------------------------------- 1 | # Put files/directories that should be ignored in this file when uploading 2 | # to a Chef Infra Server or Supermarket. 3 | # Lines that start with '# ' are comments. 4 | 5 | # OS generated files # 6 | ###################### 7 | .DS_Store 8 | ehthumbs.db 9 | Icon? 10 | nohup.out 11 | Thumbs.db 12 | .envrc 13 | 14 | # EDITORS # 15 | ########### 16 | .#* 17 | .project 18 | .settings 19 | *_flymake 20 | *_flymake.* 21 | *.bak 22 | *.sw[a-z] 23 | *.tmproj 24 | *~ 25 | \#* 26 | REVISION 27 | TAGS* 28 | tmtags 29 | .vscode 30 | .editorconfig 31 | 32 | ## COMPILED ## 33 | ############## 34 | *.class 35 | *.com 36 | *.dll 37 | *.exe 38 | *.o 39 | *.pyc 40 | *.so 41 | */rdoc/ 42 | a.out 43 | mkmf.log 44 | 45 | # Testing # 46 | ########### 47 | .circleci/* 48 | .codeclimate.yml 49 | .delivery/* 50 | .foodcritic 51 | .kitchen* 52 | .mdlrc 53 | .overcommit.yml 54 | .rspec 55 | .rubocop.yml 56 | .travis.yml 57 | .watchr 58 | .yamllint 59 | azure-pipelines.yml 60 | Dangerfile 61 | examples/* 62 | features/* 63 | Guardfile 64 | kitchen.yml* 65 | mlc_config.json 66 | Procfile 67 | Rakefile 68 | spec/* 69 | test/* 70 | 71 | # SCM # 72 | ####### 73 | .git 74 | .gitattributes 75 | .gitconfig 76 | .github/* 77 | .gitignore 78 | .gitkeep 79 | .gitmodules 80 | .svn 81 | */.bzr/* 82 | */.git 83 | */.hg/* 84 | */.svn/* 85 | 86 | # Berkshelf # 87 | ############# 88 | Berksfile 89 | Berksfile.lock 90 | cookbooks/* 91 | tmp 92 | 93 | # Bundler # 94 | ########### 95 | vendor/* 96 | Gemfile 97 | Gemfile.lock 98 | 99 | # Policyfile # 100 | ############## 101 | Policyfile.rb 102 | Policyfile.lock.json 103 | 104 | # Documentation # 105 | ############# 106 | CODE_OF_CONDUCT* 107 | CONTRIBUTING* 108 | documentation/* 109 | TESTING* 110 | UPGRADING* 111 | 112 | # Vagrant # 113 | ########### 114 | .vagrant 115 | Vagrantfile 116 | -------------------------------------------------------------------------------- /resources/omnibus_service.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Joshua Timberman 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | provides :omnibus_service 19 | resource_name :omnibus_service 20 | 21 | unified_mode true if respond_to?(:unified_mode) 22 | 23 | default_action :nothing 24 | 25 | property :ctl_command, String 26 | property :service_name, String, regex: %r{[\w-]+\/[\w-]+}, name_property: true 27 | 28 | # Install mixlib-install/version gems from rubygems.org or an alternative source 29 | property :rubygems_url, String 30 | 31 | %w(start stop restart hup int kill graceful-kill once).each do |sv_command| 32 | action sv_command.tr('-', '_').to_sym do 33 | execute "#{omnibus_ctl_command} #{sv_command} #{raw_service_name}" 34 | end 35 | end 36 | 37 | action_class do 38 | include ChefIngredientCookbook::Helpers 39 | 40 | # 41 | # Returns the ctl-command to be used when executing commands for the 42 | # service. 43 | # 44 | def omnibus_ctl_command 45 | product_key_for_service = new_resource.service_name.split('/').first 46 | new_resource.ctl_command || ctl_command_for_product(product_key_for_service) 47 | end 48 | 49 | # 50 | # Returns the raw service name 51 | # 52 | def raw_service_name 53 | new_resource.service_name.split('/').last 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /test/fixtures/nodes/sample-node.json: -------------------------------------------------------------------------------- 1 | { 2 | "chef_type": "node", 3 | "name": "sample-node", 4 | "chef_environment": "_default", 5 | "recipe": [ 6 | 7 | ], 8 | "run_list": [ 9 | 10 | ], 11 | "normal": { 12 | 13 | }, 14 | "automatic": { 15 | "kernel": { 16 | "name": "Linux", 17 | "machine": "x86_64", 18 | "os": "GNU/Linux" 19 | }, 20 | "os": "linux", 21 | "os_version": "3.5.0-23-generic", 22 | "root_group": "root", 23 | "etc": { 24 | "passwd": { 25 | "root": { 26 | "dir": "/root", 27 | "gid": 0, 28 | "uid": 0, 29 | "shell": "/bin/bash", 30 | "gecos": "root" 31 | } 32 | }, 33 | "group": { 34 | "root": { 35 | "gid": 0, 36 | "members": [ 37 | 38 | ] 39 | } 40 | } 41 | }, 42 | "current_user": "vagrant", 43 | "hostname": "sample-server-ubuntu-1204", 44 | "fqdn": "sample-server-ubuntu-1204.example.com", 45 | "domain": "example.com", 46 | "ipaddress": "10.0.2.47", 47 | "macaddress": "08:00:27:F9:09:1F", 48 | "ip6address": "fe80::a00:27ff:fef9:91f", 49 | "virtualization": { 50 | "system": "vbox", 51 | "role": "guest" 52 | }, 53 | "ohai_time": 1389202858.7629967, 54 | "lsb": { 55 | "id": "Ubuntu", 56 | "release": "12.04", 57 | "codename": "precise", 58 | "description": "Ubuntu 12.04.2 LTS" 59 | }, 60 | "platform": "ubuntu", 61 | "platform_version": "12.04", 62 | "platform_family": "debian", 63 | "cpu": { 64 | "total": 1, 65 | "real": 0 66 | }, 67 | "memory": { 68 | "total": "244960kB", 69 | "free": "16628kB" 70 | }, 71 | "uptime_seconds": 390, 72 | "uptime": "6 minutes 30 seconds", 73 | "idletime_seconds": 343, 74 | "idletime": "5 minutes 43 seconds", 75 | "recipes": [ 76 | ], 77 | "roles": [ 78 | ] 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_push_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::push' do 4 | [{ platform: 'ubuntu', version: '18.04' }, 5 | { platform: 'centos', version: '6' }].each do |platform| 6 | context "non-platform specific resources on #{platform[:platform]}" do 7 | cached(:chef_run) do 8 | ChefSpec::SoloRunner.new( 9 | platform.merge(step_into: ['chef_ingredient']) 10 | ).converge(described_recipe) 11 | end 12 | 13 | it 'installs the chef_ingredient[push-jobs-client]' do 14 | expect(chef_run).to install_chef_ingredient('push-jobs-client') 15 | end 16 | end 17 | end 18 | 19 | context 'installs packages with yum on centos' do 20 | cached(:centos_6) do 21 | ChefSpec::SoloRunner.new( 22 | platform: 'centos', 23 | version: '6', 24 | step_into: %w(chef_ingredient) 25 | ) do |node| 26 | node.normal['test']['push-client']['version'] = :latest 27 | end.converge(described_recipe) 28 | end 29 | 30 | it 'upgrades package[push-client]' do 31 | pkgres = centos_6.find_resource('package', 'push-jobs-client') 32 | expect(pkgres).to_not be_nil 33 | expect(pkgres).to be_a(Chef::Resource::Package) 34 | expect(centos_6).to install_package('push-jobs-client') 35 | end 36 | end 37 | 38 | context 'install packages on ubuntu' do 39 | cached(:ubuntu) do 40 | ChefSpec::SoloRunner.new( 41 | platform: 'ubuntu', 42 | version: '18.04', 43 | step_into: %w(chef_ingredient) 44 | ) do |node| 45 | node.normal['test']['push-client']['version'] = :latest 46 | end.converge(described_recipe) 47 | end 48 | 49 | it 'upgrades package[push-client]' do 50 | pkgres = ubuntu.find_resource('package', 'push-jobs-client') 51 | expect(pkgres).to_not be_nil 52 | expect(pkgres).to be_a(Chef::Resource::Package) 53 | expect(ubuntu).to install_package('push-jobs-client') 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_default_handler_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::default_handler' do 4 | context 'install chef on ubuntu' do 5 | let(:ubuntu) do 6 | ChefSpec::SoloRunner.new( 7 | platform: 'ubuntu', 8 | version: '18.04', 9 | step_into: %w(chef_ingredient) 10 | ).converge(described_recipe) 11 | end 12 | 13 | it 'use the default handler' do 14 | expect(ubuntu).to install_package('chef').with(provider: Chef::Provider::Package::Dpkg) 15 | end 16 | end 17 | 18 | context 'install chef on suse' do 19 | let(:suse) do 20 | ChefSpec::SoloRunner.new( 21 | platform: 'suse', 22 | version: '12', 23 | step_into: %w(chef_ingredient) 24 | ).converge(described_recipe) 25 | end 26 | 27 | it 'use the default handler' do 28 | expect(suse).to install_package('chef').with(provider: Chef::Provider::Package::Rpm) 29 | end 30 | end 31 | 32 | context 'install chef on rhel 6' do 33 | let(:rhel_6) do 34 | ChefSpec::SoloRunner.new( 35 | platform: 'redhat', 36 | version: '6', 37 | step_into: %w(chef_ingredient) 38 | ).converge(described_recipe) 39 | end 40 | 41 | it 'use the Yum package provider' do 42 | expect(rhel_6).to install_package('chef').with(provider: Chef::Provider::Package::Yum) 43 | end 44 | end 45 | context 'install chef on rhel 7' do 46 | let(:rhel_7) do 47 | ChefSpec::SoloRunner.new( 48 | platform: 'redhat', 49 | version: '7', 50 | step_into: %w(chef_ingredient) 51 | ).converge(described_recipe) 52 | end 53 | 54 | it 'use the Yum package provider' do 55 | expect(rhel_7).to install_package('chef').with(provider: Chef::Provider::Package::Yum) 56 | end 57 | end 58 | context 'install chef on rhel 8' do 59 | let(:rhel_8) do 60 | ChefSpec::SoloRunner.new( 61 | platform: 'redhat', 62 | version: '8', 63 | step_into: %w(chef_ingredient) 64 | ).converge(described_recipe) 65 | end 66 | 67 | it 'use the Dnf package provider' do 68 | expect(rhel_8).to install_package('chef').with(provider: Chef::Provider::Package::Dnf) 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /test/fixtures/cookbooks/test/recipes/automate.rb: -------------------------------------------------------------------------------- 1 | insecure_key = <<-EOS 2 | -----BEGIN RSA PRIVATE KEY----- 3 | MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI 4 | w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP 5 | kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2 6 | hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO 7 | Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW 8 | yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd 9 | ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1 10 | Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf 11 | TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK 12 | iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A 13 | sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf 14 | 4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP 15 | cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk 16 | EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN 17 | CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX 18 | 3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG 19 | YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj 20 | 3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+ 21 | dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz 22 | 6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC 23 | P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF 24 | llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ 25 | kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH 26 | +vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ 27 | NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s= 28 | -----END RSA PRIVATE KEY----- 29 | EOS 30 | 31 | user 'delivery' 32 | 33 | group 'delivery' do 34 | members 'delivery' 35 | end 36 | 37 | chef_automate 'automate.chefstack.local' do 38 | config <<-EOS 39 | nginx['ssl_protocols'] = 'TLSv1.2' 40 | EOS 41 | accept_license true 42 | enterprise 'test' 43 | license 'license' 44 | chef_user 'chef_user' 45 | chef_user_pem insecure_key 46 | chef_server 'https://localhost/organizations/foo' 47 | validation_pem insecure_key 48 | builder_pem insecure_key 49 | end 50 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_config_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::config' do 4 | [ 5 | { platform: 'ubuntu', version: '18.04' }, 6 | { platform: 'centos', version: '6' }, 7 | ].each do |platform| 8 | context "non-platform specific resources on #{platform[:platform]}" do 9 | cached(:chef_run) do 10 | ChefSpec::SoloRunner.new( 11 | platform.merge(step_into: %w(chef_ingredient ingredient_config)) 12 | ) do |node| 13 | node.normal['chef_admin'] = 'admin@chef.io' 14 | end.converge(described_recipe) 15 | end 16 | 17 | it 'reconfigure chef_ingredient[chef-server]' do 18 | expect(chef_run).to reconfigure_chef_ingredient('chef-server') 19 | end 20 | 21 | it 'renders config file using ingredient_config' do 22 | expect(chef_run).to render_ingredient_config('chef-server') 23 | end 24 | 25 | it 'creates config directory for chef-server' do 26 | expect(chef_run).to create_directory('/etc/opscode') 27 | end 28 | 29 | it 'creates config file for chef-server with default of false for sensitive' do 30 | expect(chef_run).to create_file('/etc/opscode/chef-server.rb').with sensitive: false, content: <<-EOS 31 | api_fqdn "fauxhai.local" 32 | ip_version "ipv6" 33 | notification_email "admin@chef.io" 34 | nginx["ssl_protocols"] = "TLSv1 TLSv1.1 TLSv1.2" 35 | EOS 36 | end 37 | 38 | it 'reconfigure chef_ingredient[manage]' do 39 | expect(chef_run).to reconfigure_chef_ingredient('manage') 40 | end 41 | 42 | it 'creates the directory for the license acceptance file' do 43 | expect(chef_run).to create_directory('/var/opt/chef-manage').with(recursive: true) 44 | end 45 | 46 | it 'creates the license acceptance file' do 47 | expect(chef_run).to touch_file('/var/opt/chef-manage/.license.accepted') 48 | end 49 | 50 | it 'does not render config file using ingredient_config' do 51 | expect(chef_run).to_not render_ingredient_config('manage') 52 | end 53 | 54 | it 'does not create config directory for manage' do 55 | expect(chef_run).to_not create_directory('/etc/opscode-manage') 56 | end 57 | 58 | it 'does not create config file for manage' do 59 | expect(chef_run).to_not create_file('/etc/opscode-manage/manage.rb') 60 | end 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /spec/unit/chef_file_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-ingredient 3 | # Spec:: chef_file 4 | # 5 | # Copyright:: 2016-2021, Chef Software Inc 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | require 'spec_helper' 20 | 21 | describe 'test::file' do 22 | cached(:centos_7) do 23 | ChefSpec::ServerRunner.new( 24 | step_into: 'chef_file', 25 | platform: 'centos', 26 | version: '7' 27 | ).converge(described_recipe) 28 | end 29 | 30 | context 'compiling the recipe' do 31 | it 'creates chef_file[/tmp/uri.test]' do 32 | expect(centos_7).to create_chef_file('/tmp/remote_file') 33 | end 34 | it 'creates chef_file[/tmp/cookbook.test]' do 35 | expect(centos_7).to create_chef_file('/tmp/cookbook_file') 36 | end 37 | it 'creates chef_file[/tmp/content.test]' do 38 | expect(centos_7).to create_chef_file('/tmp/file') 39 | end 40 | end 41 | 42 | context 'stepping into chef_file' do 43 | it 'correctly creates cookbook_files' do 44 | expect(centos_7).to create_cookbook_file('/tmp/cookbook_file') 45 | .with( 46 | source: 'testfile', 47 | cookbook: 'chef_test', 48 | user: 'root', 49 | group: 'root', 50 | mode: '0600' 51 | ) 52 | end 53 | it 'correctly creates remote_files' do 54 | expect(centos_7).to create_remote_file('/tmp/remote_file') 55 | .with( 56 | source: 'https://www.example.com/test', 57 | user: 'root', 58 | group: 'root', 59 | mode: '0600' 60 | ) 61 | end 62 | it 'correctly creates files' do 63 | expect(centos_7).to create_file('/tmp/file') 64 | .with( 65 | content: 'abcdef', 66 | user: 'root', 67 | group: 'root', 68 | mode: '0600' 69 | ) 70 | expect(centos_7).to render_file('/tmp/file').with_content('abcdef') 71 | end 72 | end 73 | end 74 | -------------------------------------------------------------------------------- /kitchen.dokken.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: dokken 4 | privileged: true # because Docker and SystemD/Upstart 5 | chef_version: <%= ENV['CHEF_VERSION'] || 'current' %> 6 | chef_license: accept-no-persist 7 | 8 | transport: 9 | name: dokken 10 | 11 | provisioner: 12 | name: dokken 13 | data_bags_path: test/fixtures/data_bags 14 | deprecations_as_errors: true 15 | always_update_cookbooks: true 16 | clean_dokken_sandbox: false 17 | client_rb: 18 | silence_deprecation_warnings: 19 | - chef-25 20 | 21 | verifier: 22 | name: inspec 23 | 24 | platforms: 25 | - name: almalinux-8 26 | driver: 27 | image: dokken/almalinux-8 28 | pid_one_command: /usr/lib/systemd/systemd 29 | 30 | - name: almalinux-9 31 | driver: 32 | image: dokken/almalinux-9 33 | pid_one_command: /usr/lib/systemd/systemd 34 | 35 | - name: amazonlinux-2 36 | driver: 37 | image: dokken/amazonlinux-2 38 | pid_one_command: /usr/lib/systemd/systemd 39 | 40 | - name: debian-10 41 | driver: 42 | image: dokken/debian-10 43 | pid_one_command: /bin/systemd 44 | intermediate_instructions: 45 | - RUN /usr/bin/apt-get update 46 | 47 | - name: debian-11 48 | driver: 49 | image: dokken/debian-11 50 | pid_one_command: /bin/systemd 51 | intermediate_instructions: 52 | - RUN /usr/bin/apt-get update 53 | 54 | - name: centos-7 55 | driver: 56 | image: dokken/centos-7 57 | pid_one_command: /usr/lib/systemd/systemd 58 | 59 | - name: centos-8 60 | driver: 61 | image: dokken/centos-8 62 | pid_one_command: /usr/lib/systemd/systemd 63 | 64 | - name: fedora-latest 65 | driver: 66 | image: dokken/fedora-latest 67 | pid_one_command: /usr/lib/systemd/systemd 68 | 69 | - name: ubuntu-18.04 70 | driver: 71 | image: dokken/ubuntu-18.04 72 | pid_one_command: /bin/systemd 73 | intermediate_instructions: 74 | - RUN /usr/bin/apt-get update 75 | 76 | - name: ubuntu-20.04 77 | driver: 78 | image: dokken/ubuntu-20.04 79 | pid_one_command: /bin/systemd 80 | intermediate_instructions: 81 | - RUN /usr/bin/apt-get update 82 | 83 | - name: ubuntu-22.04 84 | driver: 85 | image: dokken/ubuntu-22.04 86 | pid_one_command: /bin/systemd 87 | intermediate_instructions: 88 | - RUN /usr/bin/apt-get update 89 | 90 | - name: opensuse-leap-15 91 | driver: 92 | image: dokken/opensuse-leap-15 93 | pid_one_command: /bin/systemd 94 | -------------------------------------------------------------------------------- /resources/file.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: file 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # rubocop:disable Lint/ParenthesesAsGroupedExpression 21 | 22 | provides :chef_file 23 | resource_name :chef_file 24 | 25 | unified_mode true if respond_to?(:unified_mode) 26 | 27 | property :filename, String, name_property: true 28 | property :source, String 29 | property :user, String, default: 'root' 30 | property :group, String, default: 'root' 31 | property :mode, String, default: '0600' 32 | 33 | load_current_value do 34 | current_value_does_not_exist! unless ::File.exist?(filename) 35 | end 36 | 37 | action :create do 38 | new_resource.source = (property_is_set?(:source) ? new_resource.source : "cookbook_file://#{new_resource.filename}") 39 | if new_resource.source.start_with?('cookbook_file://') 40 | src = new_resource.source.split('://')[1].split('::') 41 | 42 | cookbook_file new_resource.filename do 43 | sensitive new_resource.sensitive if new_resource.sensitive 44 | source src[-1] 45 | cookbook (src.length == 2 ? src[0] : cookbook_name) 46 | user new_resource.user 47 | group new_resource.group 48 | mode new_resource.mode 49 | end 50 | elsif new_resource.source =~ %r{^[a-zA-Z]*://.*} 51 | remote_file new_resource.filename do 52 | sensitive new_resource.sensitive if new_resource.sensitive 53 | source new_resource.source 54 | user new_resource.user 55 | group new_resource.group 56 | mode new_resource.mode 57 | end 58 | else 59 | file new_resource.filename do 60 | sensitive new_resource.sensitive if new_resource.sensitive 61 | content new_resource.source 62 | user new_resource.user 63 | group new_resource.group 64 | mode new_resource.mode 65 | end 66 | end 67 | end 68 | 69 | action_class do 70 | include ChefIngredientCookbook::Helpers 71 | end 72 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_upgrade_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::upgrade' do 4 | [{ platform: 'ubuntu', version: '18.04' }, 5 | { platform: 'centos', version: '6' }].each do |platform| 6 | context "non-platform specific resources on #{platform[:platform]}" do 7 | cached(:chef_run) do 8 | ChefSpec::SoloRunner.new( 9 | platform.merge(step_into: ['chef_ingredient']) 10 | ).converge(described_recipe) 11 | end 12 | 13 | it 'upgrades the chef_ingredient[chef-server]' do 14 | expect(chef_run).to upgrade_chef_ingredient('chef-server') 15 | end 16 | end 17 | end 18 | 19 | context 'upgrade packages with yum on centos' do 20 | cached(:centos_6) do 21 | ChefSpec::SoloRunner.new( 22 | platform: 'centos', 23 | version: '6', 24 | step_into: %w(chef_ingredient) 25 | ) do |node| 26 | node.normal['chef-server-core']['version'] = :latest 27 | end.converge(described_recipe) 28 | end 29 | 30 | it 'upgrades yum_package[chef-server]' do 31 | # Since we have two resources with same name and identity we can't use 32 | # the upgrade_package & install_package matchers directly. 33 | chef_server_resources = centos_6.find_resources(:package) 34 | expect(chef_server_resources.length).to eq(2) 35 | expect(chef_server_resources[0].action.first).to eq(:install) 36 | expect(chef_server_resources[0].package_name).to eq('chef-server-core') 37 | expect(chef_server_resources[1].action.first).to eq(:upgrade) 38 | expect(chef_server_resources[1].package_name).to eq('chef-server-core') 39 | end 40 | end 41 | 42 | context 'upgrade packages on ubuntu' do 43 | cached(:ubuntu) do 44 | ChefSpec::SoloRunner.new( 45 | platform: 'ubuntu', 46 | version: '18.04', 47 | architecture: 'x86_64', 48 | step_into: %w(chef_ingredient) 49 | ) do |node| 50 | node.normal['chef-server-core']['version'] = :latest 51 | end.converge(described_recipe) 52 | end 53 | 54 | it 'upgrades package[chef-server]' do 55 | chef_server_resources = ubuntu.find_resources(:package) 56 | expect(chef_server_resources.length).to eq(2) 57 | expect(chef_server_resources[0].action.first).to eq(:install) 58 | expect(chef_server_resources[0].package_name).to eq('chef-server-core') 59 | expect(chef_server_resources[1].action.first).to eq(:upgrade) 60 | expect(chef_server_resources[1].package_name).to eq('chef-server-core') 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /kitchen.yml: -------------------------------------------------------------------------------- 1 | --- 2 | driver: 3 | name: vagrant 4 | customize: 5 | memory: 2048 6 | cpus: 2 7 | 8 | provisioner: 9 | require_chef_omnibus: <%= ENV['CHEF_VERSION'] || true %> 10 | name: chef_infra 11 | data_bags_path: test/fixtures/data_bags 12 | deprecations_as_errors: true 13 | always_update_cookbooks: true 14 | retry_on_exit_code: 15 | - 213 16 | max_retries: 1 17 | wait_for_retry: 1 18 | chef_license: accept-no-persist 19 | client_rb: 20 | exit_status: :enabled 21 | client_fork: false 22 | silence_deprecation_warnings: 23 | - chef-25 24 | 25 | verifier: 26 | name: inspec 27 | 28 | platforms: 29 | - name: almalinux-8 30 | - name: almalinux-9 31 | - name: amazonlinux-2 32 | - name: centos-7 33 | - name: centos-8 34 | - name: debian-10 35 | - name: debian-11 36 | - name: fedora-latest 37 | - name: freebsd-12 38 | - name: freebsd-13 39 | - name: opensuse-leap-15 40 | - name: rockylinux-8 41 | - name: rockylinux-9 42 | - name: ubuntu-18.04 43 | - name: ubuntu-20.04 44 | - name: ubuntu-22.04 45 | - name: macos-10.12 46 | driver: 47 | box: chef/macos-10.12 # private 48 | - name: macos-latest # Used for CI pipeline 49 | - name: windows-2016 50 | driver: 51 | box: stromweld/windows-2016 52 | customize: 53 | cpus: 4 54 | - name: windows-2019 55 | driver_config: 56 | box: stromweld/windows-2019 57 | customize: 58 | cpus: 4 59 | - name: windows-2022 60 | driver_config: 61 | box: stromweld/windows-2022 62 | customize: 63 | cpus: 4 64 | 65 | suites: 66 | - name: default 67 | excludes: ['macos-10.12', 'macos-latest', 'windows-2016', 'windows-2019', 'windows-2022'] 68 | named_run_list: test_repo 69 | 70 | - name: local-package-install 71 | excludes: ['macos-10.12', 'macos-latest', 'windows-2016', 'windows-2019', 'windows-2022'] 72 | named_run_list: test_local 73 | 74 | - name: rubygems-url 75 | excludes: ['macos-10.12', 'macos-latest', 'windows-2016', 'windows-2019', 'windows-2022'] 76 | named_run_list: test_rubygems_url 77 | 78 | - name: chef-workstation 79 | named_run_list: test_chef_workstation 80 | 81 | - name: inspec 82 | named_run_list: test_inspec 83 | 84 | - name: chef-server 85 | includes: ['almalinux-8', 'almalinux-9', 'rockylinux-8', 'rockylinux-9', 'ubuntu-18.04', 'ubuntu-20.04', 'ubuntu-22.04', 'centos-7', 'centos-8'] 86 | named_run_list: test_chef_server 87 | 88 | - name: chef-automatev2 89 | driver: 90 | customize: 91 | memory: 2560 92 | includes: ['almalinux-8', 'almalinux-9', 'rockylinux-8', 'rockylinux-9', 'ubuntu-18.04', 'ubuntu-20.04', 'ubuntu-22.04', 'centos-7', 'centos-8'] 93 | named_run_list: test_chef_automatev2 94 | -------------------------------------------------------------------------------- /resources/supermarket.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: supermarket 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | provides :chef_supermarket 22 | resource_name :chef_supermarket 23 | 24 | unified_mode true if respond_to?(:unified_mode) 25 | 26 | property :channel, Symbol, default: :stable 27 | property :version, [String, Symbol], default: :latest 28 | property :config, Hash, default: {} 29 | property :chef_server_url, String, default: Chef::Config['chef_server_url'] 30 | property :chef_oauth2_app_id, String, required: true 31 | property :chef_oauth2_secret, String, required: true 32 | property :chef_oauth2_verify_ssl, [true, false], default: true 33 | property :accept_license, [true, false], default: false 34 | property :platform, String 35 | property :platform_version, String 36 | 37 | load_current_value do 38 | # node.run_state['chef-users'] ||= Mixlib::ShellOut.new('chef-server-ctl user-list').run_command.stdout 39 | # current_value_does_not_exist! unless node.run_state['chef-users'].index(/^#{username}$/) 40 | end 41 | 42 | action :create do 43 | chef_ingredient 'supermarket' do 44 | action :upgrade 45 | channel new_resource.channel 46 | version new_resource.version 47 | config JSON.pretty_generate( 48 | new_resource.config.merge( 49 | chef_server_url: new_resource.chef_server_url, 50 | chef_oauth2_app_id: new_resource.chef_oauth2_app_id, 51 | chef_oauth2_secret: new_resource.chef_oauth2_secret, 52 | chef_oauth2_verify_ssl: new_resource.chef_oauth2_verify_ssl 53 | ) 54 | ) 55 | accept_license new_resource.accept_license 56 | platform new_resource.platform if new_resource.platform 57 | platform_version new_resource.platform_version if new_resource.platform_version 58 | sensitive new_resource.sensitive if new_resource.sensitive 59 | end 60 | 61 | ingredient_config 'supermarket' do 62 | sensitive new_resource.sensitive if new_resource.sensitive 63 | notifies :reconfigure, 'chef_ingredient[supermarket]', :immediately 64 | end 65 | end 66 | 67 | action_class do 68 | include ChefIngredientCookbook::Helpers 69 | end 70 | -------------------------------------------------------------------------------- /libraries/omnitruck_handler.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Serdar Sutay 3 | # Copyright:: 2015-2021, Chef Software, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | module ChefIngredient 19 | module OmnitruckHandler 20 | def handle_install 21 | current_version = installer.current_version 22 | 23 | if new_resource.version == :latest 24 | # When we are installing :latest, we install only if there is no version right now 25 | if current_version.nil? 26 | configure_version(installer) 27 | else 28 | Chef::Log.debug("Found version #{current_version}, skipping installing :latest.") 29 | end 30 | elsif new_resource.version != current_version 31 | configure_version(installer) 32 | end 33 | end 34 | 35 | def handle_upgrade 36 | configure_version(installer) if installer.upgrade_available? 37 | end 38 | 39 | def handle_uninstall 40 | raise 'Uninstalling a product is currently not supported.' 41 | end 42 | 43 | def configure_version(installer) 44 | install_command_resource = "install-#{new_resource.product_name}-#{new_resource.version}" 45 | file installer_script_path do 46 | content installer.install_command 47 | end 48 | 49 | if windows? 50 | powershell_script install_command_resource do 51 | code installer.install_command 52 | 53 | if new_resource.product_name == 'chef' 54 | # We define this resource in ChefIngredientProvider 55 | notifies :run, 'ruby_block[stop chef run]', :immediately 56 | end 57 | end 58 | else 59 | execute install_command_resource do 60 | command "sudo /bin/sh #{installer_script_path}" 61 | 62 | if new_resource.product_name == 'chef' 63 | # We define this resource in ChefIngredientProvider 64 | notifies :run, 'ruby_block[stop chef run]', :immediately 65 | end 66 | end 67 | end 68 | end 69 | 70 | def installer_script_path 71 | @installer_script_path ||= begin 72 | installer_file = windows? ? 'installer.ps1' : 'installer.sh' 73 | File.join(Chef::Config[:file_cache_path], installer_file) 74 | end 75 | end 76 | end 77 | end 78 | -------------------------------------------------------------------------------- /resources/chef_user.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: chef_user 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | provides :chef_user 22 | resource_name :chef_user 23 | 24 | unified_mode true if respond_to?(:unified_mode) 25 | 26 | property :username, String, name_property: true 27 | property :first_name, String, required: true 28 | property :last_name, String, required: true 29 | property :email, String, required: true 30 | property :password, String 31 | property :key_path, String 32 | property :serveradmin, [true, false], default: false 33 | 34 | load_current_value do 35 | node.run_state['chef-users'] ||= shell_out('chef-server-ctl user-list').stdout 36 | current_value_does_not_exist! unless node.run_state['chef-users'].index(/^#{username}$/) 37 | end 38 | 39 | action :create do 40 | directory '/etc/opscode/users' do 41 | owner 'root' 42 | group 'root' 43 | mode '0700' 44 | recursive true 45 | end 46 | 47 | key = (property_is_set?(:key_path) ? new_resource.key_path : "/etc/opscode/users/#{new_resource.username}.pem") 48 | password = (property_is_set?(:password) ? new_resource.password : SecureRandom.base64(36)) 49 | 50 | execute "create-user-#{new_resource.username}" do 51 | sensitive true 52 | retries 3 53 | command "chef-server-ctl user-create #{new_resource.username} #{new_resource.first_name} #{new_resource.last_name} #{new_resource.email} #{password} -f #{key}" 54 | not_if { node.run_state['chef-users'].index(/^#{new_resource.username}$/) } 55 | end 56 | 57 | ruby_block 'append-user-to-users' do 58 | block do 59 | node.run_state['chef-users'] << "#{new_resource.username}\n" 60 | end 61 | not_if { node.run_state['chef-users'].index(/^#{new_resource.username}$/) } 62 | end 63 | 64 | execute "grant-server-admin-#{new_resource.username}" do 65 | command "chef-server-ctl grant-server-admin-permissions #{new_resource.username}" 66 | only_if { new_resource.serveradmin } 67 | not_if { shell_out('chef-server-ctl list-server-admins').stdout.include?(new_resource.username) } 68 | end 69 | end 70 | 71 | action :delete do 72 | execute "delete-user-#{new_resource.username}" do 73 | retries 3 74 | command "chef-server-ctl user-delete #{new_resource.username} --yes --remove-from-admin-groups" 75 | only_if { node.run_state['chef-users'].index(/^#{new_resource.username}$/) } 76 | end 77 | 78 | ruby_block 'delete-user-to-users' do 79 | block do 80 | node.run_state['chef-users'] = node.run_state['chef-users'].gsub(/#{new_resource.username}\n/, '') 81 | end 82 | end 83 | end 84 | 85 | action_class do 86 | include ChefIngredientCookbook::Helpers 87 | end 88 | -------------------------------------------------------------------------------- /resources/server.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: server 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | provides :chef_server 22 | resource_name :chef_server 23 | 24 | unified_mode true if respond_to?(:unified_mode) 25 | 26 | property :channel, Symbol, default: :stable 27 | property :version, [String, Symbol], default: :latest 28 | property :config, String, required: true 29 | property :accept_license, [true, false], default: false 30 | property :addons, Hash, default: {} 31 | property :data_collector_token, String, default: '93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506' 32 | property :data_collector_url, String 33 | property :platform, String 34 | property :platform_version, String 35 | 36 | load_current_value do 37 | # node.run_state['chef-users'] ||= Mixlib::ShellOut.new('chef-server-ctl user-list').run_command.stdout 38 | # current_value_does_not_exist! unless node.run_state['chef-users'].index(/^#{username}$/) 39 | end 40 | 41 | action :create do 42 | if new_resource.data_collector_url 43 | new_resource.config << "\ndata_collector['root_url'] = '#{new_resource.data_collector_url}'" 44 | new_resource.config << "\ndata_collector['token'] = '#{new_resource.data_collector_token}'" 45 | end 46 | chef_ingredient 'chef-server' do 47 | action :upgrade 48 | channel new_resource.channel 49 | version new_resource.version 50 | config new_resource.config 51 | accept_license new_resource.accept_license 52 | platform new_resource.platform if new_resource.platform 53 | platform_version new_resource.platform_version if new_resource.platform_version 54 | sensitive new_resource.sensitive if new_resource.sensitive 55 | end 56 | 57 | ingredient_config 'chef-server' do 58 | sensitive new_resource.sensitive if new_resource.sensitive 59 | notifies :reconfigure, 'chef_ingredient[chef-server]', :immediately 60 | end 61 | 62 | new_resource.addons.each do |addon, options| 63 | chef_ingredient addon do 64 | action :upgrade 65 | channel options['channel'] || :stable 66 | version options['version'] || :latest 67 | config options['config'] || '' 68 | accept_license new_resource.accept_license 69 | platform new_resource.platform if new_resource.platform 70 | platform_version new_resource.platform_version if new_resource.platform_version 71 | sensitive new_resource.sensitive if new_resource.sensitive 72 | end 73 | 74 | ingredient_config addon do 75 | sensitive new_resource.sensitive if new_resource.sensitive 76 | notifies :reconfigure, "chef_ingredient[#{addon}]", :immediately 77 | end 78 | end 79 | end 80 | 81 | action_class do 82 | include ChefIngredientCookbook::Helpers 83 | end 84 | -------------------------------------------------------------------------------- /resources/chef_org.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: chef_org 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | provides :chef_org 22 | resource_name :chef_org 23 | 24 | unified_mode true if respond_to?(:unified_mode) 25 | 26 | property :org, String, name_property: true 27 | property :org_full_name, String 28 | property :admins, Array, required: true 29 | property :users, Array, default: [] 30 | property :remove_users, Array, default: [] 31 | property :key_path, String 32 | 33 | load_current_value do 34 | node.run_state['chef-users'] ||= shell_out('chef-server-ctl user-list').stdout 35 | node.run_state['chef-orgs'] ||= shell_out('chef-server-ctl org-list').stdout 36 | current_value_does_not_exist! unless node.run_state['chef-orgs'].index(/^#{org}$/) 37 | end 38 | 39 | action :create do 40 | directory '/etc/opscode/orgs' do 41 | owner 'root' 42 | group 'root' 43 | mode '0700' 44 | recursive true 45 | end 46 | 47 | org_full_name = (property_is_set?(:org_full_name) ? new_resource.org_full_name : new_resource.org) 48 | key = (property_is_set?(:key_path) ? new_resource.key_path : "/etc/opscode/orgs/#{new_resource.org}-validation.pem") 49 | execute "create-org-#{new_resource.org}" do 50 | retries 10 51 | command "chef-server-ctl org-create #{new_resource.org} '#{org_full_name}' -f #{key}" 52 | not_if { node.run_state['chef-orgs'].index(/^#{new_resource.org}$/) } 53 | end 54 | 55 | new_resource.users.each do |user| 56 | org_user_exist = JSON.parse(shell_out("chef-server-ctl user-show #{user} -l -F json").stdout)['organizations'].include?(new_resource.org) 57 | execute "add-user-#{user}-org-#{new_resource.org}" do 58 | command "chef-server-ctl org-user-add #{new_resource.org} #{user}" 59 | only_if { node.run_state['chef-users'].index(/^#{user}$/) } 60 | not_if { org_user_exist } 61 | end 62 | end 63 | 64 | # TODO: fix idempotency for org admins 65 | new_resource.admins.each do |user| 66 | execute "add-admin-#{user}-org-#{new_resource.org}" do 67 | command "chef-server-ctl org-user-add --admin #{new_resource.org} #{user}" 68 | only_if { node.run_state['chef-users'].index(/^#{user}$/) } 69 | end 70 | end 71 | 72 | new_resource.remove_users.each do |user| 73 | org_user_exist = JSON.parse(shell_out("chef-server-ctl user-show #{user} -l -F json").stdout)['organizations'].include?(new_resource.org) 74 | execute "remove-user-#{user}-org-#{new_resource.org}" do 75 | command "chef-server-ctl org-user-remove #{new_resource.org} #{user}" 76 | only_if { node.run_state['chef-users'].index(/^#{user}$/) } 77 | only_if { org_user_exist } 78 | end 79 | end 80 | end 81 | 82 | action_class do 83 | include ChefIngredientCookbook::Helpers 84 | end 85 | -------------------------------------------------------------------------------- /resources/automatev2.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-ingredient 3 | # Resource:: automatev2 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | 17 | provides :chef_automatev2 18 | resource_name :chef_automatev2 19 | 20 | unified_mode true if respond_to?(:unified_mode) 21 | 22 | property :channel, Symbol, default: :current 23 | property :version, [String, Symbol], default: :latest 24 | property :config, String, required: true 25 | property :accept_license, [true, false], default: false 26 | property :products, Array, default: ['automate'] 27 | 28 | action :create do 29 | bin_path = value_for_platform_family( 30 | debian: '/bin/chef-automate', 31 | default: '/usr/bin/chef-automate' 32 | ) 33 | 34 | execute "curl https://packages.chef.io/files/#{new_resource.channel}/#{new_resource.version}/chef-automate-cli/chef-automate_linux_amd64.zip | gunzip - > chef-automate && chmod +x chef-automate" do 35 | cwd '/usr/local/bin' 36 | creates '/usr/local/bin/chef-automate' 37 | not_if { FileTest.file?(bin_path) } 38 | end 39 | 40 | ## TODO: add dependancy on sysctl cookbook unless chef-client v14.0+ 41 | sysctl 'vm.max_map_count' do 42 | value 262144 43 | end 44 | 45 | sysctl 'vm.dirty_expire_centisecs' do 46 | value 20000 47 | end 48 | 49 | execute '/usr/local/bin/chef-automate init-config' do 50 | cwd Chef::Config[:file_cache_path] 51 | creates "#{Chef::Config[:file_cache_path]}/config.toml" 52 | only_if { FileTest.file?('/usr/local/bin/chef-automate') } 53 | end 54 | 55 | execute "/usr/local/bin/chef-automate deploy #{Chef::Config[:file_cache_path]}/config.toml --product #{new_resource.products.join(' --product ')}#{' --accept-terms-and-mlsa' if new_resource.accept_license}" do 56 | cwd Chef::Config[:file_cache_path] 57 | live_stream true 58 | only_if { FileTest.file?("#{Chef::Config[:file_cache_path]}/config.toml") } 59 | not_if { FileTest.file?(bin_path) && shell_out("#{bin_path} service-versions").exitstatus.eql?(0) } 60 | end 61 | 62 | file "#{Chef::Config[:file_cache_path]}/custom_config.toml" do 63 | content new_resource.config 64 | notifies :run, "execute[chef-automate config patch #{Chef::Config[:file_cache_path]}/custom_config.toml]", :immediately 65 | end 66 | 67 | execute "chef-automate config patch #{Chef::Config[:file_cache_path]}/custom_config.toml" do 68 | cwd Chef::Config[:file_cache_path] 69 | live_stream true 70 | action :nothing 71 | only_if { FileTest.file?(bin_path) } 72 | end 73 | 74 | file '/usr/local/bin/chef-automate' do 75 | action :delete 76 | end 77 | end 78 | 79 | action :uninstall do 80 | execute 'chef-automate uninstall --yes' 81 | end 82 | 83 | action :reconfigure do 84 | bin_path = value_for_platform_family( 85 | debian: '/bin/chef-automate', 86 | default: '/usr/bin/chef-automate' 87 | ) 88 | 89 | file "#{Chef::Config[:file_cache_path]}/custom_config.toml" do 90 | content new_resource.config 91 | notifies :run, "execute[chef-automate config patch #{Chef::Config[:file_cache_path]}/custom_config.toml]", :immediately 92 | end 93 | 94 | execute "chef-automate config patch #{Chef::Config[:file_cache_path]}/custom_config.toml" do 95 | cwd Chef::Config[:file_cache_path] 96 | live_stream true 97 | action :nothing 98 | only_if { FileTest.file?(bin_path) } 99 | end 100 | end 101 | -------------------------------------------------------------------------------- /resources/backend.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: backend 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | provides :chef_backend 22 | resource_name :chef_backend 23 | 24 | unified_mode true if respond_to?(:unified_mode) 25 | 26 | property :channel, Symbol, default: :stable 27 | property :version, [String, Symbol], default: :latest 28 | property :config, String, default: '' 29 | property :accept_license, [true, false], default: false 30 | property :peers, [String, Array], required: true 31 | property :publish_address, String, default: lazy { node['ipaddress'] } 32 | property :chef_backend_secrets, String, default: '' 33 | property :chef_backend_secrets_user, String, default: 'root' 34 | property :chef_backend_secrets_group, String, default: 'chef_pgsql' 35 | property :platform, String 36 | property :platform_version, String 37 | 38 | alias :bootstrap_node :peers 39 | 40 | load_current_value do 41 | # node.run_state['chef-users'] ||= Mixlib::ShellOut.new('chef-server-ctl user-list').run_command.stdout 42 | # current_value_does_not_exist! unless node.run_state['chef-users'].index(/^#{username}$/) 43 | end 44 | 45 | action :create do 46 | raise 'Must accept the Chef License agreement before continuing.' unless new_resource.accept_license 47 | 48 | new_resource.config = ensurekv(new_resource.config, publish_address: new_resource.publish_address) 49 | chef_ingredient 'chef-backend' do 50 | action :upgrade 51 | channel new_resource.channel 52 | version new_resource.version 53 | config new_resource.config # TODO: Figure out why this isn't working in chef-ingredient 54 | accept_license new_resource.accept_license 55 | platform new_resource.platform if new_resource.platform 56 | platform_version new_resource.platform_version if new_resource.platform_version 57 | sensitive new_resource.sensitive if new_resource.sensitive 58 | end 59 | 60 | file '/etc/chef-backend/chef-backend.rb' do 61 | sensitive new_resource.sensitive if new_resource.sensitive 62 | content new_resource.config 63 | end 64 | 65 | chef_file '/etc/chef-backend/chef-backend-secrets.json' do 66 | sensitive new_resource.sensitive if new_resource.sensitive 67 | source new_resource.chef_backend_secrets 68 | user new_resource.chef_backend_secrets_user 69 | group new_resource.chef_backend_secrets_group 70 | mode '0640' 71 | not_if { new_resource.chef_backend_secrets.empty? } 72 | end 73 | 74 | http_retry_count = Chef::Config['http_retry_count'] 75 | Chef::Config['http_retry_count'] = 0 76 | existing_peer = false 77 | peers = (new_resource.peers.is_a?(Array) ? new_resource.peers : [new_resource.peers]) 78 | 79 | peers.each do |peer| 80 | begin 81 | Chef::HTTP.new("http://#{peer}:2379").get('/version') 82 | existing_peer = peer 83 | break 84 | rescue 85 | next 86 | end 87 | end 88 | Chef::Config['http_retry_count'] = http_retry_count 89 | 90 | execute 'chef-backend-ctl create-cluster --accept-license --yes' do 91 | not_if 'chef-backend-ctl cluster-status &> /dev/null' 92 | not_if { existing_peer } 93 | end 94 | 95 | execute "chef-backend-ctl join-cluster #{existing_peer} --accept-license --yes" do 96 | not_if 'chef-backend-ctl cluster-status &> /dev/null' 97 | only_if { existing_peer } 98 | end 99 | end 100 | 101 | action_class do 102 | include ChefIngredientCookbook::Helpers 103 | end 104 | -------------------------------------------------------------------------------- /libraries/default_handler.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Serdar Sutay 3 | # Author:: Patrick Wright 4 | # 5 | # Copyright:: 2016-2021, Chef Software, Inc. 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | # 19 | 20 | module ChefIngredient 21 | module DefaultHandler 22 | def handle_install 23 | configure_package(:install) 24 | end 25 | 26 | def handle_upgrade 27 | configure_package(:upgrade) 28 | end 29 | 30 | def handle_uninstall 31 | package ingredient_package_name do 32 | action :remove 33 | end 34 | end 35 | 36 | private 37 | 38 | def configure_package(action_name) 39 | # Set action name to :install when Windows :upgrade 40 | action_name = :install if action_name == :upgrade && windows? 41 | 42 | if new_resource.package_source 43 | configure_from_source_package(action_name) 44 | elsif use_custom_repo_recipe? 45 | # Use the custom repository recipe. 46 | include_recipe custom_repo_recipe 47 | configure_from_repo(action_name) 48 | else 49 | configure_from_channel(action_name) 50 | end 51 | end 52 | 53 | def configure_from_source_package(action_name, local_path = nil) 54 | # Foodcritic doesn't like timeout attribute in package resource 55 | package new_resource.product_name do 56 | action action_name 57 | package_name ingredient_package_name 58 | options new_resource.options 59 | source local_path || new_resource.package_source 60 | timeout new_resource.timeout if new_resource.timeout 61 | provider value_for_platform_family( 62 | 'debian' => Chef::Provider::Package::Dpkg, 63 | 'rhel' => value_for_platform( 64 | %w(centos redhat) => { 65 | '~> 5.0' => Chef::Provider::Package::Rpm, 66 | '~> 6.0' => Chef::Provider::Package::Yum, 67 | '~> 7.0' => Chef::Provider::Package::Yum, 68 | '>= 8.0' => Chef::Provider::Package::Dnf, 69 | } 70 | ), 71 | 'suse' => Chef::Provider::Package::Rpm, 72 | 'amazon' => Chef::Provider::Package::Rpm, 73 | 'windows' => Chef::Provider::Package::Windows 74 | ) 75 | if new_resource.product_name == 'chef' 76 | # We define this resource in ChefIngredientProvider 77 | notifies :run, 'ruby_block[stop chef run]', :immediately 78 | end 79 | end 80 | end 81 | 82 | def configure_from_repo(action_name) 83 | # Foodcritic doesn't like timeout attribute in package resource 84 | package new_resource.product_name do 85 | action action_name 86 | package_name ingredient_package_name 87 | options new_resource.options 88 | timeout new_resource.timeout if new_resource.timeout 89 | 90 | # If the latest version is specified, we should not give any version 91 | # to the package resource. 92 | unless version_latest?(new_resource.version) 93 | version version_for_package_resource 94 | end 95 | 96 | if new_resource.product_name == 'chef' 97 | # We define this resource in ChefIngredientProvider 98 | notifies :run, 'ruby_block[stop chef run]', :immediately 99 | end 100 | end 101 | end 102 | 103 | def configure_from_channel(action_name) 104 | cache_path = Chef::Config[:file_cache_path] 105 | 106 | # raises Mixlib::Install::Backend::ArtifactsNotFound exception 107 | artifact_info = installer.artifact_info 108 | 109 | remote_artifact_path = artifact_info.url 110 | local_artifact_path = File.join(cache_path, ::File.basename(remote_artifact_path)) 111 | 112 | remote_file local_artifact_path do 113 | source remote_artifact_path 114 | mode '0644' 115 | checksum artifact_info.sha256 116 | backup 1 117 | end 118 | 119 | configure_from_source_package(action_name, local_artifact_path) 120 | end 121 | end 122 | end 123 | -------------------------------------------------------------------------------- /resources/chef_ingredient.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Joshua Timberman 3 | # Author:: Patrick Wright 4 | # Copyright:: 2015-2021, Chef Software, Inc. 5 | # 6 | # Licensed under the Apache License, Version 2.0 (the "License"); 7 | # you may not use this file except in compliance with the License. 8 | # You may obtain a copy of the License at 9 | # 10 | # http://www.apache.org/licenses/LICENSE-2.0 11 | # 12 | # Unless required by applicable law or agreed to in writing, software 13 | # distributed under the License is distributed on an "AS IS" BASIS, 14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | # See the License for the specific language governing permissions and 16 | # limitations under the License. 17 | # 18 | 19 | provides :chef_ingredient 20 | resource_name :chef_ingredient 21 | 22 | unified_mode true if respond_to?(:unified_mode) 23 | 24 | property :product_name, String, name_property: true 25 | property :config, String 26 | 27 | # Determine what version to install from which channel 28 | property :version, [String, Symbol], default: :latest 29 | property :channel, Symbol, default: :stable, equal_to: [:stable, :current, :unstable] 30 | 31 | # Install package from local file 32 | property :package_source, String 33 | 34 | # Install mixlib-install/version gems from rubygems.org or an alternative source 35 | property :rubygems_url, [String] 36 | 37 | # Set the *-ctl command to use when doing reconfigure 38 | property :ctl_command, String 39 | 40 | # Package resources used on rhel and debian platforms 41 | property :options, String 42 | 43 | property :timeout, [Integer, String] 44 | 45 | # Accept the license when applicable 46 | property :accept_license, [true, false], default: false 47 | 48 | # Enable selecting packages built for earlier versions in 49 | # platforms that are not yet officially added to Chef support matrix 50 | property :platform_version_compatibility_mode, [true, false] 51 | 52 | # Configure specific platform package 53 | property :platform, String 54 | property :platform_version, String 55 | property :architecture, String 56 | 57 | platform_family = node['platform_family'] 58 | 59 | action :install do 60 | add_config(new_resource.product_name, new_resource.config) 61 | declare_chef_run_stop_resource 62 | 63 | handle_install 64 | end 65 | 66 | action :upgrade do 67 | add_config(new_resource.product_name, new_resource.config) 68 | declare_chef_run_stop_resource 69 | 70 | handle_upgrade 71 | end 72 | 73 | action :uninstall do 74 | handle_uninstall 75 | end 76 | 77 | action :reconfigure do 78 | add_config(new_resource.product_name, new_resource.config) 79 | 80 | if ingredient_ctl_command.nil? 81 | Chef::Log.warn "Product '#{new_resource.product_name}' does not support reconfigure." 82 | Chef::Log.warn 'chef_ingredient is skipping :reconfigure.' 83 | else 84 | # Render the config in case it is not rendered yet 85 | ingredient_config new_resource.product_name do 86 | sensitive new_resource.sensitive if new_resource.sensitive 87 | action :render 88 | not_if { get_config(new_resource.product_name).empty? } 89 | end 90 | 91 | # If accept_license is set, drop .license.accepted file so that 92 | # reconfigure does not prompt for license acceptance. This is 93 | # the backwards compatible way of accepting a Chef license. 94 | if new_resource.accept_license && %w(analytics manage reporting compliance).include?(new_resource.product_name) 95 | # The way we construct the data directory for a product, that looks 96 | # like /var/opt/ is to get the config file path that 97 | # looks like /etc//.rb and do path 98 | # manipulation. 99 | product_data_dir_name = ::File.basename(::File.dirname(ingredient_config_file(new_resource.product_name))) 100 | product_data_dir = ::File.join('/var/opt', product_data_dir_name) 101 | 102 | directory product_data_dir do 103 | recursive true 104 | action :create 105 | end 106 | 107 | file ::File.join(product_data_dir, '.license.accepted') do 108 | action :touch 109 | end 110 | end 111 | 112 | execute "#{ingredient_package_name}-reconfigure" do 113 | command "#{ingredient_ctl_command} #{reconfigure_command}" 114 | live_stream true 115 | end 116 | end 117 | end 118 | 119 | action_class do 120 | include ChefIngredientCookbook::Helpers 121 | 122 | case platform_family 123 | when 'debian', 'rhel', 'suse', 'windows', 'amazon' 124 | include ::ChefIngredient::DefaultHandler 125 | else 126 | # OmnitruckHandler is used for Solaris, AIX, FreeBSD, etc. 127 | # Eventually, we would like to support all platforms with the DefaultHandler 128 | include ::ChefIngredient::OmnitruckHandler 129 | end 130 | 131 | def reconfigure_command 132 | if new_resource.accept_license && new_resource.product_name == 'chef-server' 133 | 'reconfigure --chef-license=accept' 134 | else 135 | 'reconfigure' 136 | end 137 | end 138 | end 139 | -------------------------------------------------------------------------------- /resources/automate.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: automate 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | provides :chef_automate 22 | resource_name :chef_automate 23 | 24 | unified_mode true if respond_to?(:unified_mode) 25 | 26 | property :fqdn, String, name_property: true 27 | property :channel, Symbol, default: :stable 28 | property :version, [String, Symbol], default: :latest 29 | property :config, String, required: true 30 | property :accept_license, [true, false], default: false 31 | property :enterprise, [String, Array], default: 'chef' 32 | property :license, String 33 | property :chef_user, String, default: 'workflow' 34 | property :chef_user_pem, String, required: true 35 | property :chef_server, String, required: true 36 | property :validation_pem, String, required: true 37 | property :builder_pem, String, required: true 38 | property :platform, String 39 | property :platform_version, String 40 | 41 | load_current_value do 42 | # node.run_state['chef-users'] ||= Mixlib::ShellOut.new('chef-server-ctl user-list').run_command.stdout 43 | # node.run_state['chef-orgs'] ||= Mixlib::ShellOut.new('chef-server-ctl org-list').run_command.stdout 44 | # current_value_does_not_exist! unless node.run_state['chef-orgs'].index(/^#{org}$/) 45 | end 46 | 47 | action :create do 48 | Chef::Log.warn('The chef_automate resource is deprecated as Chef Automate V1 is EOL.') 49 | 50 | required_config = <<-EOF 51 | delivery['chef_username'] = '#{new_resource.chef_user}' 52 | delivery['chef_private_key'] = '/etc/delivery/#{new_resource.chef_user}.pem' 53 | delivery['chef_server'] = '#{new_resource.chef_server}' 54 | delivery['default_search'] = 'tags:delivery-build-node' 55 | EOF 56 | 57 | chef_ingredient 'automate' do 58 | action :upgrade 59 | channel new_resource.channel 60 | version new_resource.version 61 | config ensurekv(new_resource.config.dup.concat(required_config), delivery_fqdn: new_resource.fqdn) 62 | accept_license new_resource.accept_license 63 | platform new_resource.platform if new_resource.platform 64 | platform_version new_resource.platform_version if new_resource.platform_version 65 | sensitive new_resource.sensitive if new_resource.sensitive 66 | end 67 | 68 | # Extract custom username and group from the automate config, if it is set. 69 | # We will use these values to set permissions on files appropriately. 70 | os_user = new_resource.config[/user\['username'\] ?= ?['"](?.*)['"]/, 'username'] || 'delivery' 71 | os_group = new_resource.config[/user\['group'\] ?= ?['"](?.*)['"]/, 'group'] || 'delivery' 72 | 73 | %w(/etc/delivery /etc/chef /var/opt/delivery/license).each do |dir| 74 | directory dir do 75 | recursive true 76 | end 77 | end 78 | 79 | chef_file '/var/opt/delivery/license/delivery.license' do 80 | sensitive new_resource.sensitive if new_resource.sensitive 81 | source new_resource.license 82 | user os_user 83 | group os_group 84 | mode '0644' 85 | end 86 | 87 | { 88 | "/etc/delivery/#{new_resource.chef_user}.pem" => new_resource.chef_user_pem, 89 | '/etc/chef/validation.pem' => new_resource.validation_pem, 90 | }.each do |file, src| 91 | chef_file file do 92 | sensitive new_resource.sensitive if new_resource.sensitive 93 | source src 94 | user 'root' 95 | group 'root' 96 | mode '0644' 97 | end 98 | end 99 | 100 | chef_file '/etc/delivery/builder_key' do 101 | sensitive new_resource.sensitive if new_resource.sensitive 102 | source new_resource.builder_pem 103 | user 'root' 104 | group 'root' 105 | mode '0600' 106 | end 107 | 108 | file '/etc/delivery/builder_key.pub' do 109 | sensitive new_resource.sensitive if new_resource.sensitive 110 | content lazy { "ssh-rsa #{[OpenSSL::PKey::RSA.new(::File.read('/etc/delivery/builder_key')).to_blob].pack('m0')}" } 111 | user 'root' 112 | group 'root' 113 | mode '0644' 114 | end 115 | 116 | directory '/var/opt/delivery/nginx/etc/addon.d' do 117 | recursive true 118 | end 119 | 120 | file '/var/opt/delivery/nginx/etc/addon.d/99-installer_internal.conf' do 121 | content <<-EOF 122 | location /installer { 123 | alias /opt/delivery/embedded/service/omnibus-ctl/installer; 124 | } 125 | EOF 126 | end 127 | 128 | ingredient_config 'automate' do 129 | sensitive new_resource.sensitive if new_resource.sensitive 130 | notifies :reconfigure, 'chef_ingredient[automate]', :immediately 131 | end 132 | 133 | Array(new_resource.enterprise).each do |ent| 134 | execute "create enterprise #{ent}" do 135 | command "automate-ctl create-enterprise #{ent} --ssh-pub-key-file=/etc/delivery/builder_key.pub >> /etc/delivery/#{ent}.creds" 136 | not_if "automate-ctl list-enterprises --ssh-pub-key-file=/etc/delivery/builder_key.pub | grep -w #{ent}" 137 | only_if 'automate-ctl status' 138 | end 139 | end 140 | end 141 | 142 | action_class do 143 | include ChefIngredientCookbook::Helpers 144 | end 145 | -------------------------------------------------------------------------------- /spec/unit/chef_automate_spec.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Cookbook:: chef-ingredient 3 | # Spec:: chef_automate 4 | # 5 | # Copyright:: 2016-2021, Chef Software Inc 6 | # 7 | # Licensed under the Apache License, Version 2.0 (the "License"); 8 | # you may not use this file except in compliance with the License. 9 | # You may obtain a copy of the License at 10 | # 11 | # http://www.apache.org/licenses/LICENSE-2.0 12 | # 13 | # Unless required by applicable law or agreed to in writing, software 14 | # distributed under the License is distributed on an "AS IS" BASIS, 15 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 16 | # See the License for the specific language governing permissions and 17 | # limitations under the License. 18 | 19 | insecure_key = <<-EOS 20 | -----BEGIN RSA PRIVATE KEY----- 21 | MIIEogIBAAKCAQEA6NF8iallvQVp22WDkTkyrtvp9eWW6A8YVr+kz4TjGYe7gHzI 22 | w+niNltGEFHzD8+v1I2YJ6oXevct1YeS0o9HZyN1Q9qgCgzUFtdOKLv6IedplqoP 23 | kcmF0aYet2PkEDo3MlTBckFXPITAMzF8dJSIFo9D8HfdOV0IAdx4O7PtixWKn5y2 24 | hMNG0zQPyUecp4pzC6kivAIhyfHilFR61RGL+GPXQ2MWZWFYbAGjyiYJnAmCP3NO 25 | Td0jMZEnDkbUvxhMmBYSdETk1rRgm+R4LOzFUGaHqHDLKLX+FIPKcF96hrucXzcW 26 | yLbIbEgE98OHlnVYCzRdK8jlqm8tehUc9c9WhQIBIwKCAQEA4iqWPJXtzZA68mKd 27 | ELs4jJsdyky+ewdZeNds5tjcnHU5zUYE25K+ffJED9qUWICcLZDc81TGWjHyAqD1 28 | Bw7XpgUwFgeUJwUlzQurAv+/ySnxiwuaGJfhFM1CaQHzfXphgVml+fZUvnJUTvzf 29 | TK2Lg6EdbUE9TarUlBf/xPfuEhMSlIE5keb/Zz3/LUlRg8yDqz5w+QWVJ4utnKnK 30 | iqwZN0mwpwU7YSyJhlT4YV1F3n4YjLswM5wJs2oqm0jssQu/BT0tyEXNDYBLEF4A 31 | sClaWuSJ2kjq7KhrrYXzagqhnSei9ODYFShJu8UWVec3Ihb5ZXlzO6vdNQ1J9Xsf 32 | 4m+2ywKBgQD6qFxx/Rv9CNN96l/4rb14HKirC2o/orApiHmHDsURs5rUKDx0f9iP 33 | cXN7S1uePXuJRK/5hsubaOCx3Owd2u9gD6Oq0CsMkE4CUSiJcYrMANtx54cGH7Rk 34 | EjFZxK8xAv1ldELEyxrFqkbE4BKd8QOt414qjvTGyAK+OLD3M2QdCQKBgQDtx8pN 35 | CAxR7yhHbIWT1AH66+XWN8bXq7l3RO/ukeaci98JfkbkxURZhtxV/HHuvUhnPLdX 36 | 3TwygPBYZFNo4pzVEhzWoTtnEtrFueKxyc3+LjZpuo+mBlQ6ORtfgkr9gBVphXZG 37 | YEzkCD3lVdl8L4cw9BVpKrJCs1c5taGjDgdInQKBgHm/fVvv96bJxc9x1tffXAcj 38 | 3OVdUN0UgXNCSaf/3A/phbeBQe9xS+3mpc4r6qvx+iy69mNBeNZ0xOitIjpjBo2+ 39 | dBEjSBwLk5q5tJqHmy/jKMJL4n9ROlx93XS+njxgibTvU6Fp9w+NOFD/HvxB3Tcz 40 | 6+jJF85D5BNAG3DBMKBjAoGBAOAxZvgsKN+JuENXsST7F89Tck2iTcQIT8g5rwWC 41 | P9Vt74yboe2kDT531w8+egz7nAmRBKNM751U/95P9t88EDacDI/Z2OwnuFQHCPDF 42 | llYOUI+SpLJ6/vURRbHSnnn8a/XG+nzedGH5JGqEJNQsz+xT2axM0/W/CRknmGaJ 43 | kda/AoGANWrLCz708y7VYgAtW2Uf1DPOIYMdvo6fxIB5i9ZfISgcJ/bbCUkFrhoH 44 | +vq/5CIWxCPp0f85R4qxxQ5ihxJ0YDQT9Jpx4TMss4PSavPaBH3RXow5Ohe+bYoQ 45 | NE5OgEXk2wVfZczCZpigBKbKZHNYcelXtTt/nP3rsCuGcM4h53s= 46 | -----END RSA PRIVATE KEY----- 47 | EOS 48 | 49 | require 'spec_helper' 50 | 51 | describe 'test::automate' do 52 | cached(:centos_7) do 53 | stub_command('automate-ctl list-enterprises --ssh-pub-key-file=/etc/delivery/builder_key.pub | grep -w test').and_return(false) 54 | stub_command('automate-ctl status').and_return(true) 55 | ChefSpec::ServerRunner.new( 56 | step_into: 'chef_automate', 57 | platform: 'centos', 58 | version: '7' 59 | ).converge(described_recipe) 60 | end 61 | 62 | context 'compiling the recipe' do 63 | it 'creates chef_automate[automate.chefstack.local]' do 64 | expect(centos_7).to create_chef_automate('automate.chefstack.local') 65 | end 66 | end 67 | 68 | context 'stepping into chef_automate' do 69 | it 'upgrades chef_ingredient[automate]' do 70 | skip 'test failure introduced by chefspec 7.2.1, works with <= 7.2.0' 71 | expect(centos_7).to upgrade_chef_ingredient('automate') 72 | .with( 73 | accept_license: true, 74 | enterprise: 'test', 75 | license: 'license', 76 | chef_user: 'chef_user', 77 | chef_user_pem: insecure_key, 78 | chef_server: 'https://localhost/organizations/foo', 79 | validation_pem: insecure_key, 80 | builder_pem: insecure_key 81 | ) 82 | end 83 | 84 | it 'creates required directories' do 85 | [ 86 | '/var/opt/delivery/license', 87 | '/etc/delivery', 88 | '/etc/chef', 89 | ].each do |dir| 90 | expect(centos_7).to create_directory(dir) 91 | end 92 | end 93 | 94 | it 'creates automate keys' do 95 | expect(centos_7).to create_chef_file('/var/opt/delivery/license/delivery.license') 96 | .with( 97 | source: 'license', 98 | user: 'delivery', 99 | group: 'delivery', 100 | mode: '0644' 101 | ) 102 | { 103 | '/etc/delivery/chef_user.pem' => insecure_key, 104 | '/etc/chef/validation.pem' => insecure_key, 105 | }.each do |file, src| 106 | expect(centos_7).to create_chef_file(file) 107 | .with( 108 | source: src, 109 | user: 'root', 110 | group: 'root', 111 | mode: '0644' 112 | ) 113 | end 114 | expect(centos_7).to create_chef_file('/etc/delivery/builder_key') 115 | .with( 116 | source: insecure_key, 117 | user: 'root', 118 | group: 'root', 119 | mode: '0600' 120 | ) 121 | end 122 | 123 | it 'creates the builder public key' do 124 | expect(centos_7).to create_file('/etc/delivery/builder_key.pub') 125 | .with( 126 | user: 'root', 127 | group: 'root', 128 | mode: '0644' 129 | ) 130 | end 131 | 132 | it 'configures nginx to host installation files' do 133 | expect(centos_7).to create_directory('/var/opt/delivery/nginx/etc/addon.d') 134 | expect(centos_7).to create_file('/var/opt/delivery/nginx/etc/addon.d/99-installer_internal.conf') 135 | .with( 136 | content: <<-EOF 137 | location /installer { 138 | alias /opt/delivery/embedded/service/omnibus-ctl/installer; 139 | } 140 | EOF 141 | ) 142 | end 143 | 144 | it 'reconfigures automate' do 145 | expect(centos_7).to render_ingredient_config('automate') 146 | expect(centos_7.ingredient_config('automate')).to notify('chef_ingredient[automate]').to(:reconfigure).immediately 147 | end 148 | 149 | it 'configures automate enterprises' do 150 | expect(centos_7).to run_execute('create enterprise test') 151 | end 152 | end 153 | end 154 | -------------------------------------------------------------------------------- /resources/client.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: client 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | # rubocop:disable Lint/ParenthesesAsGroupedExpression 21 | 22 | provides :chef_client 23 | resource_name :chef_client 24 | 25 | unified_mode true if respond_to?(:unified_mode) 26 | 27 | property :node_name, String, name_property: true 28 | property :version, [String, Symbol], default: :latest 29 | property :chefdk, [true, false], default: false 30 | property :chef_server_url, [String, Symbol], default: :local 31 | property :ssl_verify, [true, false], default: true 32 | property :log_location, String, default: 'STDOUT' 33 | property :log_level, Symbol, default: :auto 34 | property :config, String 35 | property :run_list, Array 36 | property :environment, String 37 | property :validation_pem, String 38 | property :validation_client_name, String 39 | property :tags, [String, Array], default: '' 40 | property :interval, Integer, default: 1800 41 | property :splay, Integer, default: 1800 42 | property :data_collector_token, String, default: '93a49a4f2482c64126f7b6015e6b0f30284287ee4054ff8807fb63d9cbd1c506' 43 | property :data_collector_url, String 44 | property :platform, String 45 | property :platform_version, String 46 | 47 | load_current_value do 48 | version Chef::VERSION 49 | chef_server_url Chef::Config['chef_server_url'] 50 | ssl_verify (Chef::Config['ssl_verify_mode'].eql?(:verify_peer) ? true : false) 51 | if Chef::Config['log_location'].is_a?(IO) 52 | log_location Chef::Config['log_location'].inspect[/#.*)>>/, 'stream'] 53 | else 54 | log_location Chef::Config['log_location'] 55 | end 56 | log_level Chef::Config['log_level'] 57 | if ::File.exist?(::File.join(Chef::Config[:config_d_dir], 'custom.rb')) 58 | config ::File.read(::File.join(Chef::Config[:config_d_dir], 'custom.rb')) 59 | end 60 | run_list node['recipes'] 61 | end 62 | 63 | action :install do 64 | Chef::Log.warn('The chef_client resource is deprecated. Please use the chef_client_config resource in Chef Infra Client 16.6 or later: https://docs.chef.io/resources/chef_client_config/') 65 | 66 | chef_ingredient 'chef' do 67 | action :upgrade 68 | version new_resource.version 69 | not_if { new_resource.chefdk } 70 | platform new_resource.platform if new_resource.platform 71 | platform_version new_resource.platform_version if new_resource.platform_version 72 | end 73 | 74 | chef_ingredient 'chefdk' do 75 | action :upgrade 76 | version new_resource.version 77 | only_if { new_resource.chefdk } 78 | platform new_resource.platform if new_resource.platform 79 | platform_version new_resource.platform_version if new_resource.platform_version 80 | end 81 | 82 | %w( config.d client.d ).each do |d_folder| 83 | directory ::File.join(prefix, d_folder) do 84 | mode '0755' 85 | recursive true 86 | end 87 | end 88 | 89 | template 'client.rb' do 90 | source 'client.rb.erb' 91 | path ::File.join(prefix, 'client.rb') 92 | cookbook 'chef-ingredient' 93 | mode '0640' 94 | variables node_name: new_resource.node_name, 95 | chef_server_url: new_resource.chef_server_url, 96 | ssl_verify: new_resource.ssl_verify, 97 | log_location: new_resource.log_location, 98 | log_level: new_resource.log_level, 99 | validation_client_name: new_resource.validation_client_name, 100 | json_attribs: ::File.join(prefix, 'dna.json'), 101 | data_collector_url: new_resource.data_collector_url, 102 | data_collector_token: new_resource.data_collector_token 103 | end 104 | 105 | rl = {} 106 | rl = rl.merge(run_list: new_resource.run_list) if new_resource.run_list 107 | rl = rl.merge(environment: new_resource.environment) if new_resource.environment 108 | file 'dna.json' do 109 | path ::File.join(prefix, 'dna.json') 110 | content rl.to_json 111 | end 112 | 113 | file 'custom.rb' do 114 | sensitive new_resource.sensitive if new_resource.sensitive 115 | path ::File.join(prefix, 'config.d', 'custom.rb') 116 | content new_resource.config 117 | mode '0640' 118 | only_if { new_resource.config } 119 | end 120 | 121 | chef_file ::File.join(prefix, 'validation.pem') do 122 | sensitive new_resource.sensitive if new_resource.sensitive 123 | source new_resource.validation_pem 124 | user 'root' 125 | group 'root' 126 | mode '0600' 127 | not_if { ::File.exist?(::File.join(prefix, 'client.pem')) } 128 | only_if { new_resource.property_is_set?(:validation_pem) } 129 | end 130 | end 131 | 132 | action :register do 133 | execute 'fetch ssl certificates' do 134 | command "knife ssl fetch -c #{::File.join(prefix, 'client.rb')}" 135 | not_if "knife ssl check -c #{::File.join(prefix, 'client.rb')}" 136 | end 137 | 138 | execute 'register with chef-server' do 139 | sensitive new_resource.sensitive if new_resource.sensitive 140 | command "chef-client -j #{::File.join(prefix, 'dna.json')}" 141 | live_stream true 142 | not_if { ::File.exist?(::File.join(prefix, 'client.pem')) } 143 | end 144 | 145 | # ruby_block 'update run_list' do 146 | # block do 147 | # rest = Chef::REST.new(Chef::Config[:chef_server_url]) 148 | # org = Chef::Config[:chef_server_url].split('/')[-1] 149 | # rest.post("/organizations/#{org}/nodes/#{node['fqdn']}", '{"run_list": [new_resource.run_list]}') 150 | # end 151 | # not_if { new_resource.run_list.eql?(current_resource.run_list) } 152 | # end 153 | 154 | file 'delete validation.pem' do 155 | action :delete 156 | path ::File.join(prefix, 'validation.pem') 157 | end 158 | 159 | execute 'add tags to node' do 160 | command "knife tag create #{node['fqdn']} #{tags.is_a?(Array) ? tags.join(' ') : tags} -c /etc/chef/client.rb -u #{node['fqdn']}" 161 | not_if { tags.eql?('') } 162 | end 163 | end 164 | 165 | action :run do 166 | execute 'chef-client' do 167 | live_stream true 168 | end 169 | end 170 | 171 | action_class do 172 | include ChefIngredientCookbook::Helpers 173 | end 174 | -------------------------------------------------------------------------------- /spec/unit/recipes/test_repo_spec.rb: -------------------------------------------------------------------------------- 1 | require 'spec_helper' 2 | 3 | describe 'test::repo' do 4 | [{ platform: 'ubuntu', version: '18.04' }, 5 | { platform: 'centos', version: '6' }].each do |platform| 6 | context "non-platform specific resources on #{platform[:platform]}" do 7 | cached(:chef_run) do 8 | ChefSpec::SoloRunner.new( 9 | platform.merge(step_into: %w(chef_ingredient ingredient_config)) 10 | ) do |node| 11 | node.normal['chef_admin'] = 'admin@chef.io' 12 | end.converge(described_recipe) 13 | end 14 | 15 | it 'installs chef_ingredient[chef-server]' do 16 | expect(chef_run).to install_chef_ingredient('chef-server') 17 | end 18 | 19 | it 'creates file[/tmp/chef-server-core.firstrun]' do 20 | expect(chef_run).to create_file('/tmp/chef-server-core.firstrun') 21 | end 22 | 23 | it 'creates config directory for chef-server' do 24 | expect(chef_run).to create_directory('/etc/opscode') 25 | end 26 | 27 | it 'creates config file for chef-server with default of false for sensitive' do 28 | expect(chef_run).to create_file('/etc/opscode/chef-server.rb').with sensitive: false, content: <<-EOS 29 | api_fqdn "fauxhai.local" 30 | ip_version "ipv6" 31 | notification_email "admin@chef.io" 32 | nginx["ssl_protocols"] = "TLSv1 TLSv1.1 TLSv1.2" 33 | EOS 34 | end 35 | 36 | it 'uses ingredient_config to notify a reconfigure for chef-server' do 37 | resource = chef_run.find_resource('ingredient_config', 'chef-server') 38 | expect(resource).to notify('chef_ingredient[chef-server]') 39 | end 40 | 41 | it 'installs chef_ingredient[manage]' do 42 | expect(chef_run).to install_chef_ingredient('manage') 43 | end 44 | 45 | it 'creates file[/tmp/opscode-manage.firstrun]' do 46 | expect(chef_run).to create_file('/tmp/opscode-manage.firstrun') 47 | end 48 | 49 | it 'creates config directory for manage' do 50 | expect(chef_run).to create_directory('/etc/chef-manage') 51 | end 52 | 53 | it 'creates config file for manage with sensitive set' do 54 | expect(chef_run).to create_file('/etc/chef-manage/manage.rb').with sensitive: true, content: <<-EOS 55 | disable_sign_up true 56 | support_email_address "admin@chef.io" 57 | EOS 58 | end 59 | 60 | it 'uses ingredient_config to notify a reconfigure for manage' do 61 | resource = chef_run.find_resource('ingredient_config', 'manage') 62 | expect(resource).to notify('chef_ingredient[manage]') 63 | end 64 | end 65 | end 66 | 67 | context 'install packages with yum on centos' do 68 | cached(:centos_6) do 69 | ChefSpec::SoloRunner.new( 70 | platform: 'centos', 71 | version: '6', 72 | step_into: %w(chef_ingredient chef_ingredient) 73 | ) do |node| 74 | node.normal['chef-server-core']['version'] = nil 75 | end.converge(described_recipe) 76 | end 77 | 78 | it 'installs package[chef-server]' do 79 | pkgres = centos_6.find_resource('package', 'chef-server') 80 | expect(pkgres).to_not be_nil 81 | expect(pkgres).to be_a(Chef::Resource::Package) 82 | expect(centos_6).to install_package('chef-server') 83 | end 84 | 85 | it 'installs package[opscode-manage]' do 86 | pkgres = centos_6.find_resource('package', 'manage') 87 | expect(pkgres).to_not be_nil 88 | expect(pkgres).to be_a(Chef::Resource::Package) 89 | expect(centos_6).to install_package('manage') 90 | end 91 | end 92 | 93 | context ':latest is specified for the version as a symbol' do 94 | cached(:centos_6) do 95 | ChefSpec::SoloRunner.new( 96 | platform: 'centos', 97 | version: '6', 98 | step_into: ['chef_ingredient'] 99 | ) do |node| 100 | node.normal['test']['chef-server-core']['version'] = :latest 101 | end.converge(described_recipe) 102 | end 103 | 104 | it 'installs yum_package[chef-server]' do 105 | expect(centos_6).to install_package('chef-server-core') 106 | end 107 | end 108 | 109 | context 'latest is specified for the version as a string' do 110 | cached(:centos_6) do 111 | ChefSpec::SoloRunner.new( 112 | platform: 'centos', 113 | version: '6', 114 | step_into: ['chef_ingredient'] 115 | ) do |node| 116 | node.normal['test']['chef-server-core']['version'] = 'latest' 117 | end.converge(described_recipe) 118 | end 119 | 120 | it 'installs yum_package[chef-server]' do 121 | expect(centos_6).to install_package('chef-server-core') 122 | end 123 | end 124 | 125 | context 'installs packages with apt on ubuntu' do 126 | cached(:ubuntu) do 127 | ChefSpec::SoloRunner.new( 128 | platform: 'ubuntu', 129 | version: '18.04', 130 | step_into: %w(chef_ingredient chef_ingredient) 131 | ) do |node| 132 | node.normal['chef-server-core']['version'] = nil 133 | end.converge(described_recipe) 134 | end 135 | 136 | it 'installs apt_package[chef-server-core]' do 137 | pkgres = ubuntu.find_resource('package', 'chef-server') 138 | expect(pkgres).to_not be_nil 139 | expect(pkgres).to be_a(Chef::Resource::AptPackage) 140 | expect(ubuntu).to install_package('chef-server') 141 | end 142 | 143 | it 'installs apt_package[opscode-manage]' do 144 | pkgres = ubuntu.find_resource('package', 'manage') 145 | expect(pkgres).to_not be_nil 146 | expect(pkgres).to be_a(Chef::Resource::AptPackage) 147 | expect(ubuntu).to install_package('manage') 148 | end 149 | end 150 | 151 | context ':latest is specified for the version as a symbol' do 152 | cached(:ubuntu) do 153 | ChefSpec::SoloRunner.new( 154 | platform: 'ubuntu', 155 | version: '18.04', 156 | step_into: ['chef_ingredient'] 157 | ) do |node| 158 | node.normal['test']['chef-server-core']['version'] = :latest 159 | end.converge(described_recipe) 160 | end 161 | 162 | it 'installs yum_package[chef-server]' do 163 | expect(ubuntu).to install_package('chef-server-core') 164 | end 165 | end 166 | 167 | context 'latest is specified for the version as a string' do 168 | cached(:ubuntu) do 169 | ChefSpec::SoloRunner.new( 170 | platform: 'ubuntu', 171 | version: '18.04', 172 | step_into: ['chef_ingredient'] 173 | ) do |node| 174 | node.normal['test']['chef-server-core']['version'] = 'latest' 175 | end.converge(described_recipe) 176 | end 177 | 178 | it 'installs apt_package[chef-server]' do 179 | expect(ubuntu).to install_package('chef-server-core') 180 | end 181 | end 182 | end 183 | -------------------------------------------------------------------------------- /.github/workflows/ci.yml: -------------------------------------------------------------------------------- 1 | on: 2 | pull_request: 3 | 4 | jobs: 5 | markdownlint: 6 | uses: Stromweld/github-workflows/.github/workflows/markdownlint.yml@main 7 | 8 | yamllint: 9 | uses: Stromweld/github-workflows/.github/workflows/yamllint.yml@main 10 | 11 | jsonlint: 12 | uses: Stromweld/github-workflows/.github/workflows/jsonlint.yml@main 13 | 14 | cookstylelint: 15 | uses: Stromweld/github-workflows/.github/workflows/cookstylelint.yml@main 16 | 17 | integration-dokken: 18 | runs-on: ubuntu-latest 19 | strategy: 20 | matrix: 21 | os: 22 | - centos-7 23 | - centos-8 24 | - almalinux-8 25 | # - almalinux-9 # TODO: uncomment this when almalinux-9 dokken image is fixed 26 | - ubuntu-1804 27 | - ubuntu-2004 28 | - ubuntu-2204 29 | suite: 30 | - chef-workstation 31 | - inspec 32 | - chef-server 33 | - chef-automatev2 34 | exclude: 35 | - os: centos-7 36 | suite: chef-server 37 | - os: ubuntu-2204 38 | suite: chef-server 39 | fail-fast: false 40 | steps: 41 | - name: Check out code 42 | uses: actions/checkout@main 43 | - name: Install Chef 44 | uses: actionshub/chef-install@main 45 | - name: Test-Kitchen Converge 46 | uses: actionshub/test-kitchen@main 47 | with: 48 | suite: ${{ matrix.suite }} 49 | os: ${{ matrix.os }} 50 | action: converge 51 | env: 52 | CHEF_LICENSE: accept-no-persist 53 | KITCHEN_LOCAL_YAML: kitchen.dokken.yml 54 | continue-on-error: false 55 | - name: Test-Kitchen Verify 56 | uses: actionshub/test-kitchen@main 57 | with: 58 | suite: ${{ matrix.suite }} 59 | os: ${{ matrix.os }} 60 | action: verify 61 | env: 62 | CHEF_LICENSE: accept-no-persist 63 | KITCHEN_LOCAL_YAML: kitchen.dokken.yml 64 | 65 | 66 | integration-windows-2016: 67 | runs-on: windows-2016 68 | strategy: 69 | matrix: 70 | os: 71 | - windows-2016 72 | suite: 73 | - chef-workstation 74 | - inspec 75 | fail-fast: false 76 | steps: 77 | - name: Check windows Version 78 | run: systeminfo 79 | - name: Check out code 80 | uses: actions/checkout@main 81 | - name: Install Chef 82 | uses: actionshub/chef-install@main 83 | - name: Test-Kitchen Converge 84 | uses: actionshub/test-kitchen@main 85 | with: 86 | suite: ${{ matrix.suite }} 87 | os: ${{ matrix.os }} 88 | action: converge 89 | env: 90 | CHEF_LICENSE: accept-no-persist 91 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 92 | continue-on-error: false 93 | - name: Test-Kitchen Verify 94 | uses: actionshub/test-kitchen@main 95 | with: 96 | suite: ${{ matrix.suite }} 97 | os: ${{ matrix.os }} 98 | action: verify 99 | env: 100 | CHEF_LICENSE: accept-no-persist 101 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 102 | 103 | integration-windows-2019: 104 | runs-on: windows-2019 105 | strategy: 106 | matrix: 107 | os: 108 | - windows-2019 109 | suite: 110 | - chef-workstation 111 | - inspec 112 | fail-fast: false 113 | steps: 114 | - name: Check windows Version 115 | run: systeminfo 116 | - name: Check out code 117 | uses: actions/checkout@main 118 | - name: Install Chef 119 | uses: actionshub/chef-install@main 120 | - name: Test-Kitchen Converge 121 | uses: actionshub/test-kitchen@main 122 | with: 123 | suite: ${{ matrix.suite }} 124 | os: ${{ matrix.os }} 125 | action: converge 126 | env: 127 | CHEF_LICENSE: accept-no-persist 128 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 129 | continue-on-error: false 130 | - name: Test-Kitchen Verify 131 | uses: actionshub/test-kitchen@main 132 | with: 133 | suite: ${{ matrix.suite }} 134 | os: ${{ matrix.os }} 135 | action: verify 136 | env: 137 | CHEF_LICENSE: accept-no-persist 138 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 139 | 140 | integration-windows-2022: 141 | runs-on: windows-2022 142 | strategy: 143 | matrix: 144 | os: 145 | - windows-2022 146 | suite: 147 | - chef-workstation 148 | - inspec 149 | fail-fast: false 150 | steps: 151 | - name: Check windows Version 152 | run: systeminfo 153 | - name: Check out code 154 | uses: actions/checkout@main 155 | - name: Install Chef 156 | uses: actionshub/chef-install@main 157 | - name: Test-Kitchen Converge 158 | uses: actionshub/test-kitchen@main 159 | with: 160 | suite: ${{ matrix.suite }} 161 | os: ${{ matrix.os }} 162 | action: converge 163 | env: 164 | CHEF_LICENSE: accept-no-persist 165 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 166 | continue-on-error: false 167 | - name: Test-Kitchen Verify 168 | uses: actionshub/test-kitchen@main 169 | with: 170 | suite: ${{ matrix.suite }} 171 | os: ${{ matrix.os }} 172 | action: verify 173 | env: 174 | CHEF_LICENSE: accept-no-persist 175 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 176 | 177 | integration-macos-latest: 178 | runs-on: macos-latest 179 | strategy: 180 | matrix: 181 | os: 182 | - macos-latest 183 | suite: 184 | - chef-workstation 185 | - inspec 186 | fail-fast: false 187 | steps: 188 | - name: Check macOS Version 189 | run: sw_vers 190 | - name: Check out code 191 | uses: actions/checkout@main 192 | - name: Install Chef 193 | uses: actionshub/chef-install@main 194 | - name: Test-Kitchen Converge 195 | uses: actionshub/test-kitchen@main 196 | with: 197 | suite: ${{ matrix.suite }} 198 | os: ${{ matrix.os }} 199 | action: converge 200 | env: 201 | CHEF_LICENSE: accept-no-persist 202 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 203 | continue-on-error: false 204 | - name: Test-Kitchen Verify 205 | uses: actionshub/test-kitchen@main 206 | with: 207 | suite: ${{ matrix.suite }} 208 | os: ${{ matrix.os }} 209 | action: verify 210 | env: 211 | CHEF_LICENSE: accept-no-persist 212 | KITCHEN_LOCAL_YAML: kitchen.exec.yml 213 | 214 | check: 215 | if: always() 216 | needs: 217 | - markdownlint 218 | - yamllint 219 | - jsonlint 220 | - cookstylelint 221 | - integration-dokken 222 | - integration-windows-2016 223 | - integration-windows-2019 224 | - integration-windows-2022 225 | - integration-macos-latest 226 | runs-on: Ubuntu-latest 227 | steps: 228 | - name: Decide whether the needed jobs succeeded or failed 229 | uses: re-actors/alls-green@main 230 | with: 231 | allowed-failures: 232 | allowed-skips: 233 | jobs: ${{ toJSON(needs) }} 234 | -------------------------------------------------------------------------------- /resources/wf_builder.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Nathan Cerny 3 | # 4 | # Cookbook:: chef-ingredient 5 | # Resource:: wf_runner 6 | # 7 | # Copyright:: 2017-2021, Chef Software, Inc. 8 | # 9 | # Licensed under the Apache License, Version 2.0 (the "License"); 10 | # you may not use this file except in compliance with the License. 11 | # You may obtain a copy of the License at 12 | # 13 | # http://www.apache.org/licenses/LICENSE-2.0 14 | # 15 | # Unless required by applicable law or agreed to in writing, software 16 | # distributed under the License is distributed on an "AS IS" BASIS, 17 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 18 | # See the License for the specific language governing permissions and 19 | # limitations under the License. 20 | 21 | provides :workflow_builder 22 | resource_name :workflow_builder 23 | 24 | unified_mode true if respond_to?(:unified_mode) 25 | 26 | property :channel, Symbol, default: :stable 27 | property :version, [String, Symbol], default: :latest 28 | property :pj_version, [String, Symbol], default: :latest 29 | property :accept_license, [true, false], default: false 30 | property :chef_user, String, default: 'workflow' 31 | property :chef_user_pem, String, required: true 32 | property :builder_pem, String, required: true 33 | property :chef_fqdn, String, default: URI.parse(Chef::Config['chef_server_url']).host 34 | property :automate_fqdn, String, required: true 35 | property :supermarket_fqdn, String 36 | property :job_dispatch_version, String, default: 'v2' 37 | property :automate_user, String, default: 'admin' 38 | property :automate_password, String 39 | property :automate_enterprise, String, default: 'chef' 40 | property :chef_config_path, String, default: '/etc/chef/client.rb' 41 | property :platform, String 42 | property :platform_version, String 43 | 44 | load_current_value do 45 | # node.run_state['chef-users'] ||= Mixlib::ShellOut.new('chef-server-ctl user-list').run_command.stdout 46 | # current_value_does_not_exist! unless node.run_state['chef-users'].index(/^#{username}$/) 47 | end 48 | 49 | action :create do 50 | Chef::Log.warn('The workflow_builder resource is deprecated as Chef Workflow (Delivery) is EOL') 51 | 52 | chef_ingredient 'chefdk' do 53 | action :upgrade 54 | channel new_resource.channel 55 | version new_resource.version 56 | accept_license new_resource.accept_license 57 | platform new_resource.platform if new_resource.platform 58 | platform_version new_resource.platform_version if new_resource.platform_version 59 | end 60 | 61 | directory '/etc/chef/trusted_certs' do 62 | recursive true 63 | mode '0755' 64 | end 65 | 66 | [ 67 | new_resource.chef_fqdn, 68 | new_resource.automate_fqdn, 69 | new_resource.supermarket_fqdn, 70 | ].each do |server| 71 | execute "fetch ssl cert for #{server}" do 72 | command "knife ssl fetch -s https://#{server} -c #{Chef::Config['config_file']}" 73 | not_if "knife ssl check -s https://#{server} -c #{Chef::Config['config_file']}" 74 | ignore_failure true 75 | end unless server.nil? || server.empty? 76 | end 77 | 78 | ruby_block 'configure SSL certificates' do 79 | block do 80 | @cacert_pem = ::File.read('/opt/chefdk/embedded/ssl/certs/cacert.pem') 81 | ::Dir.glob('/etc/chef/trusted_certs/*.crt').each do |crt| 82 | c = ::File.read(crt) 83 | @cacert_pem << "\n" << c unless @cacert_pem.include?(c) 84 | end 85 | end 86 | end 87 | 88 | file '/opt/chefdk/embedded/ssl/certs/cacert.pem' do 89 | sensitive new_resource.sensitive if new_resource.sensitive 90 | content @cacert_pem 91 | end 92 | 93 | ohai 'reload_passwd' do 94 | action :nothing 95 | plugin 'etc' 96 | ignore_failure true 97 | end 98 | 99 | workspace = '/var/opt/delivery/workspace' 100 | 101 | group 'dbuild' 102 | 103 | user 'dbuild' do 104 | home workspace 105 | group 'dbuild' 106 | notifies :reload, 'ohai[reload_passwd]', :immediately 107 | end 108 | 109 | %w(.chef bin lib etc).each do |dir| 110 | directory "#{workspace}/#{dir}" do 111 | mode '0755' 112 | owner 'dbuild' 113 | group 'dbuild' 114 | recursive true 115 | end 116 | end 117 | 118 | %w(etc .chef).each do |dir| 119 | chef_file "#{workspace}/#{dir}/builder_key" do 120 | sensitive new_resource.sensitive if new_resource.sensitive 121 | source new_resource.builder_pem 122 | mode '0600' 123 | user 'root' 124 | group 'root' 125 | end 126 | 127 | chef_file "#{workspace}/#{dir}/#{new_resource.chef_user}.pem" do 128 | sensitive new_resource.sensitive if new_resource.sensitive 129 | source new_resource.chef_user_pem 130 | mode '0600' 131 | user 'dbuild' 132 | group 'dbuild' 133 | end 134 | end 135 | 136 | file "#{workspace}/etc/delivery.rb" do 137 | content ensurekv(::File.read(new_resource.chef_config_path), 138 | node_name: new_resource.chef_user, 139 | log_location: :STDOUT, 140 | client_key: "#{workspace}/etc/#{new_resource.chef_user}.pem", 141 | trusted_certs_dir: '/etc/chef/trusted_certs') 142 | mode '0644' 143 | owner 'dbuild' 144 | group 'dbuild' 145 | end 146 | 147 | file "#{workspace}/.chef/knife.rb" do 148 | content ensurekv(::File.read(new_resource.chef_config_path), 149 | node_name: new_resource.chef_user, 150 | log_location: :STDOUT, 151 | client_key: "#{workspace}/.chef/#{new_resource.chef_user}.pem", 152 | trusted_certs_dir: '/etc/chef/trusted_certs') 153 | mode '0644' 154 | owner 'dbuild' 155 | group 'dbuild' 156 | end 157 | 158 | remote_file "#{workspace}/bin/git_ssh" do 159 | source "https://#{new_resource.automate_fqdn}/installer/git-ssh-wrapper" 160 | owner 'dbuild' 161 | group 'dbuild' 162 | mode '0755' 163 | end 164 | 165 | remote_file "#{workspace}/bin/delivery-cmd" do 166 | source "https://#{new_resource.automate_fqdn}/installer/delivery-cmd" 167 | owner 'root' 168 | group 'root' 169 | mode '0750' 170 | end 171 | 172 | file '/etc/chef/client.pem' do 173 | sensitive new_resource.sensitive if new_resource.sensitive 174 | owner 'root' 175 | group 'dbuild' 176 | mode '0640' 177 | end 178 | 179 | file new_resource.chef_config_path do 180 | mode '0644' 181 | end 182 | 183 | Dir.glob('/etc/chef/trusted_certs/*').each do |fn| 184 | file fn do 185 | mode '0644' 186 | end 187 | end 188 | 189 | case new_resource.job_dispatch_version 190 | when 'v1' 191 | execute 'tag node as legacy build-node' do 192 | command "knife tag create #{Chef::Config['node_name']} delivery-build-node -c new_resource.chef_config_path" 193 | not_if { node['tags'].include?('delivery-build-node') } 194 | end 195 | 196 | directory '/var/log/push-jobs-client' do 197 | recursive true 198 | end 199 | 200 | chef_ingredient 'push-jobs-client' do 201 | version new_resource.pj_version 202 | end 203 | 204 | template '/etc/chef/push-jobs-client.rb' do 205 | source 'push-jobs-client.rb.erb' 206 | notifies :restart, 'service[push-jobs-client]', :delayed 207 | end 208 | 209 | if node['init_package'].eql?('systemd') 210 | init_template = 'push-jobs-client-systemd' 211 | init_file = '/etc/systemd/system/push-jobs-client.service' 212 | elsif platform_family?('debian') 213 | init_template = 'push-jobs-client-ubuntu-upstart' 214 | init_file = '/etc/init/push-jobs-client.conf' 215 | elsif platform_family?('rhel') 216 | init_template = 'push-jobs-client-rhel-6' 217 | init_file = '/etc/rc.d/init.d/push-jobs-client' 218 | else 219 | raise 'Unsupported platform for build node' 220 | end 221 | 222 | remote_file init_file do 223 | source "https://#{new_resource.automate_fqdn}/installer/#{init_template}" 224 | mode '0755' 225 | notifies :restart, 'service[push-jobs-client]', :delayed 226 | end 227 | 228 | service 'push-jobs-client' do 229 | action [:enable, :start] 230 | end 231 | when 'v2' 232 | build_user = 'job_runner' 233 | home_dir = '/home/job_runner' 234 | 235 | execute 'tag node as job-runner' do 236 | command "knife tag create #{Chef::Config['node_name']} delivery-job-runner -c #{new_resource.chef_config_path}" 237 | not_if { node['tags'].include?('delivery-job-runner') } 238 | end 239 | 240 | user build_user do 241 | action [:create, :lock] 242 | home home_dir 243 | end 244 | 245 | directory home_dir do 246 | owner build_user 247 | group build_user 248 | end 249 | 250 | directory "#{home_dir}/.ssh" do 251 | owner build_user 252 | group build_user 253 | notifies :touch, "file[#{home_dir}/.ssh/authorized_keys]", :immediately 254 | end 255 | 256 | file "#{home_dir}/.ssh/authorized_keys" do 257 | action :nothing 258 | end 259 | 260 | # TODO: Figure out how to auto-detect enterprise 261 | ruby_block 'install job runner' do 262 | block do 263 | ENV['AUTOMATE_PASSWORD'] = new_resource.automate_password 264 | 265 | shell_out("delivery token \ 266 | -s #{new_resource.automate_fqdn} \ 267 | -e #{new_resource.automate_enterprise} \ 268 | -u #{new_resource.automate_user}") 269 | 270 | data = { 271 | hostname: new_resource.name, 272 | os: node['os'], 273 | platform_family: node['platform_family'], 274 | platform: node['platform'], 275 | platform_version: node['platform_version'], 276 | } 277 | 278 | # TODO: Rework this to call the API directly, so we don't have delivery-cli formatting things. 279 | runner = shell_out("delivery api post runners \ 280 | --non-interactive --no-color \ 281 | -d '#{data.to_json}' \ 282 | -s #{new_resource.automate_fqdn} \ 283 | -e #{new_resource.automate_enterprise} \ 284 | -u #{new_resource.automate_user}") 285 | ::File.write(::File.join(home_dir, '.ssh/authorized_keys'), JSON.parse(runner.stdout)['openssh_public_key']) 286 | end 287 | not_if { ::File.read(::File.join(home_dir, '.ssh/authorized_keys')).include?("#{build_user}@#{node['fqdn']}") } 288 | end 289 | 290 | file ::File.join('/etc/sudoers.d', build_user) do 291 | content <<-EOF 292 | #{build_user} ALL=(root) NOPASSWD:/usr/local/bin/delivery-cmd, /bin/ls 293 | Defaults:#{build_user} !requiretty 294 | Defaults:#{build_user} secure_path = /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin 295 | EOF 296 | mode '0440' 297 | end 298 | 299 | directory ::File.join(home_dir, '.ssh') do 300 | owner build_user 301 | group build_user 302 | mode '0700' 303 | end 304 | 305 | file ::File.join(home_dir, '.ssh/authorized_keys') do 306 | owner build_user 307 | group build_user 308 | mode '0600' 309 | end 310 | 311 | file '/usr/local/bin/delivery-cmd' do 312 | content lazy { ::File.read('/var/opt/delivery/workspace/bin/delivery-cmd') } 313 | owner 'dbuild' 314 | group 'dbuild' 315 | mode '0755' 316 | end 317 | else 318 | raise 'Invalid Runner Version' 319 | end 320 | end 321 | 322 | action_class do 323 | include ChefIngredientCookbook::Helpers 324 | end 325 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /libraries/helpers.rb: -------------------------------------------------------------------------------- 1 | # 2 | # Author:: Joshua Timberman 3 | # Copyright:: 2014-2021, Chef Software, Inc. 4 | # 5 | # Licensed under the Apache License, Version 2.0 (the "License"); 6 | # you may not use this file except in compliance with the License. 7 | # You may obtain a copy of the License at 8 | # 9 | # http://www.apache.org/licenses/LICENSE-2.0 10 | # 11 | # Unless required by applicable law or agreed to in writing, software 12 | # distributed under the License is distributed on an "AS IS" BASIS, 13 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 | # See the License for the specific language governing permissions and 15 | # limitations under the License. 16 | # 17 | 18 | module ChefIngredientCookbook 19 | module Helpers 20 | ######################################################################## 21 | # Product details lookup helpers 22 | ######################################################################## 23 | 24 | # 25 | # Returns the ctl-command to be used for omnibus_service resource. 26 | # Notice that we do not include version in our lookup since omnibus_service 27 | # is not aware of it. 28 | # 29 | def ctl_command_for_product(product) 30 | ensure_mixlib_install_gem_installed! 31 | 32 | PRODUCT_MATRIX.lookup(product).ctl_command 33 | end 34 | 35 | # 36 | # Returns the package name for a given product and version. 37 | # 38 | def ingredient_package_name 39 | ensure_mixlib_install_gem_installed! 40 | 41 | PRODUCT_MATRIX.lookup(new_resource.product_name, new_resource.version).package_name 42 | end 43 | 44 | # 45 | # Returns the ctl-command for a chef_ingredient resource 46 | # 47 | def ingredient_ctl_command 48 | ensure_mixlib_install_gem_installed! 49 | 50 | new_resource.ctl_command || PRODUCT_MATRIX.lookup(new_resource.product_name, new_resource.version).ctl_command 51 | end 52 | 53 | # 54 | # Returns the ctl-command for a chef_ingredient resource 55 | # 56 | def ingredient_config_file(product_name) 57 | ensure_mixlib_install_gem_installed! 58 | 59 | PRODUCT_MATRIX.lookup(product_name).config_file 60 | end 61 | 62 | ######################################################################## 63 | # Helpers installing gem prerequisites. 64 | ######################################################################## 65 | 66 | # 67 | # Ensures mixlib-versioning gem is installed and loaded. 68 | # 69 | def ensure_mixlib_versioning_gem_installed! 70 | node.run_state[:mixlib_versioning_gem_installed] ||= begin 71 | install_gem_from_rubygems('mixlib-versioning') 72 | 73 | require 'mixlib/versioning' 74 | true 75 | end 76 | end 77 | 78 | # 79 | # Ensures mixlib-install gem is installed and loaded. 80 | # 81 | def ensure_mixlib_install_gem_installed! 82 | node.run_state[:mixlib_install_gem_installed] ||= begin 83 | if node['chef-ingredient']['mixlib-install']['git_ref'] 84 | install_gem_from_source( 85 | 'https://github.com/chef/mixlib-install.git', 86 | node['chef-ingredient']['mixlib-install']['git_ref'], 87 | 'mixlib-install' 88 | ) 89 | else 90 | install_gem_from_rubygems('mixlib-install', node['chef-ingredient']['mixlib-install']['version']) 91 | end 92 | 93 | require 'mixlib/install' 94 | require 'mixlib/install/product' 95 | true 96 | end 97 | end 98 | 99 | # 100 | # Helper method to install a gem from rubygems at compile time. 101 | # 102 | def install_gem_from_rubygems(gem_name, gem_version = nil) 103 | Chef::Log.debug("Installing #{gem_name}#{" v#{gem_version}" if gem_version} from #{new_resource.rubygems_url}") 104 | chefgem = Chef::Resource::ChefGem.new(gem_name, run_context) 105 | chefgem.source(new_resource.rubygems_url) if new_resource.rubygems_url 106 | chefgem.version(gem_version) if gem_version 107 | chefgem.run_action(:install) 108 | end 109 | 110 | # 111 | # Helper method to install a gem from source at compile time. 112 | # 113 | def install_gem_from_source(repo_url, git_ref, gem_name = nil) 114 | uri = URI.parse(repo_url) 115 | repo_basename = ::File.basename(uri.path) 116 | repo_name = repo_basename.match(/(?.*)\.git/)[:name] 117 | gem_name ||= repo_name 118 | 119 | Chef::Log.debug("Building #{gem_name} gem from source") 120 | 121 | gem_clone_path = ::File.join(Chef::Config[:file_cache_path], repo_name) 122 | gem_file_path = ::File.join(gem_clone_path, "#{gem_name}-*.gem") 123 | 124 | checkout_gem = Chef::Resource::Git.new(gem_clone_path, run_context) 125 | checkout_gem.repository(repo_url) 126 | checkout_gem.revision(git_ref) 127 | checkout_gem.run_action(:sync) 128 | 129 | ::FileUtils.rm_rf gem_file_path 130 | 131 | build_gem = Chef::Resource::Execute.new("build-#{gem_name}-gem", run_context) 132 | build_gem.cwd(gem_clone_path) 133 | build_gem.command( 134 | <<-EOH 135 | #{::File.join(RbConfig::CONFIG['bindir'], 'gem')} build #{gem_name}.gemspec 136 | EOH 137 | ) 138 | build_gem.run_action(:run) if checkout_gem.updated? 139 | 140 | install_gem = Chef::Resource::ChefGem.new(gem_name, run_context) 141 | install_gem_file_path = if windows? 142 | Dir.glob(gem_file_path.tr('\\', '/')).first 143 | else 144 | Dir.glob(gem_file_path).first 145 | end 146 | install_gem.source(install_gem_file_path) 147 | install_gem.run_action(:install) if build_gem.updated? 148 | end 149 | 150 | ######################################################################## 151 | # Version helpers 152 | ######################################################################## 153 | 154 | # 155 | # Returns if a given version is equivalent to :latest 156 | # 157 | def version_latest?(vers) 158 | vers == :latest || vers == '0.0.0' || vers == 'latest' 159 | end 160 | 161 | # 162 | # Returns true if the custom repo recipe was specified 163 | # 164 | def use_custom_repo_recipe? 165 | node['chef-ingredient'].attribute?('custom-repo-recipe') 166 | end 167 | 168 | # 169 | # Returns the custom setup recipe name 170 | # 171 | # When the user specifies this attribute chef-ingredient will not configure 172 | # our default packagecloud Chef repositories and instead it will include the 173 | # custom recipe. This will eliminate the hard dependency to the internet. 174 | # 175 | def custom_repo_recipe 176 | node['chef-ingredient']['custom-repo-recipe'] 177 | end 178 | 179 | # 180 | # Returns the version string to use in package resource for all platforms. 181 | # 182 | def version_for_package_resource 183 | ensure_mixlib_versioning_gem_installed! 184 | 185 | version_string = if version_latest?(new_resource.version) 186 | '0.0.0' 187 | else 188 | new_resource.version 189 | end 190 | 191 | v = Mixlib::Versioning.parse(version_string) 192 | version = "#{v.major}.#{v.minor}.#{v.patch}" 193 | version << "~#{v.prerelease}" if v.prerelease? && !v.prerelease.match(/^\d$/) 194 | version << "+#{v.build}" if v.build? 195 | version << '-1' unless version =~ /-1$/ 196 | version << rhel_append_version if platform_family?('rhel') && 197 | !version.match(/#{rhel_append_version}$/) 198 | version 199 | end 200 | 201 | def rhel_major_version 202 | return node['platform_version'].to_i if platform_family?('rhel') 203 | node['platform_version'] 204 | end 205 | 206 | def rhel_append_version 207 | ".el#{rhel_major_version}" 208 | end 209 | 210 | ######################################################################## 211 | # ingredient_config helpers 212 | ######################################################################## 213 | 214 | # 215 | # Adds given config information for the given product to the run_state so 216 | # that it can be retrieved later. 217 | # 218 | def add_config(product, content) 219 | return if content.nil? 220 | 221 | # FC001: Use strings in preference to symbols to access node attributes 222 | # foodcritic thinks we are accessing a node attribute 223 | node.run_state[:ingredient_config_data] ||= {} 224 | node.run_state[:ingredient_config_data][product] ||= '' 225 | node.run_state[:ingredient_config_data][product] += content unless node.run_state[:ingredient_config_data][product].include?(content) 226 | end 227 | 228 | # 229 | # Returns the collected config information for the given product. 230 | # 231 | def get_config(product) 232 | # FC001: Use strings in preference to symbols to access node attributes 233 | # foodcritic thinks we are accessing a node attribute 234 | node.run_state[:ingredient_config_data] ||= {} 235 | node.run_state[:ingredient_config_data][product] ||= '' 236 | end 237 | 238 | ######################################################################## 239 | # misc helpers 240 | ######################################################################## 241 | 242 | # 243 | # Declares a resource that will fail the chef run when signalled. 244 | # 245 | def declare_chef_run_stop_resource 246 | # We do not supply an option to turn off stopping the chef client run 247 | # after a version change. As the gems shipped with omnitruck artifacts 248 | # change, chef-client runs *WILL* occasionally break on minor version 249 | # updates of chef, so we *MUST* stop the chef-client run when its version 250 | # changes. The gems versions that chef-client started with will not 251 | # necessarily exist after an upgrade. 252 | ruby_block 'stop chef run' do 253 | action :nothing 254 | block do 255 | raise('Chef version has changed during the run. Stopping the current Chef run. Please run chef again.') 256 | end 257 | end 258 | end 259 | 260 | def fqdn_resolves?(fqdn) 261 | require 'resolv' 262 | Resolv.getaddress(fqdn) 263 | true 264 | rescue Resolv::ResolvError, Resolv::ResolvTimeout 265 | false 266 | end 267 | 268 | module_function :fqdn_resolves? 269 | 270 | def windows? 271 | platform_family?('windows') 272 | end 273 | 274 | # 275 | # Creates a Mixlib::Install instance using the common attributes of 276 | # chef_ingredient resource that can be used for querying builds or 277 | # generating install scripts. 278 | # 279 | # 280 | def installer 281 | @installer ||= begin 282 | ensure_mixlib_install_gem_installed! 283 | 284 | resolve_platform_properties! 285 | 286 | options = { 287 | product_name: new_resource.product_name, 288 | channel: new_resource.channel, 289 | product_version: new_resource.version, 290 | platform: new_resource.platform, 291 | platform_version: new_resource.platform_version, 292 | architecture: Mixlib::Install::Util.normalize_architecture(new_resource.architecture), 293 | }.tap do |opt| 294 | if new_resource.platform_version_compatibility_mode 295 | opt[:platform_version_compatibility_mode] = new_resource.platform_version_compatibility_mode 296 | end 297 | opt[:shell_type] = :ps1 if windows? 298 | end 299 | 300 | Mixlib::Install.new(options) 301 | end 302 | end 303 | 304 | # 305 | # Defaults platform, platform_version, and architecture 306 | # properties when not set by recipe 307 | # 308 | def resolve_platform_properties! 309 | # Auto detect platform 310 | detected_platform = Mixlib::Install.detect_platform 311 | 312 | if new_resource.platform.nil? 313 | new_resource.platform(detected_platform[:platform]) 314 | end 315 | 316 | if new_resource.platform_version.nil? 317 | new_resource.platform_version(detected_platform[:platform_version]) 318 | end 319 | 320 | if new_resource.architecture.nil? 321 | new_resource.architecture(detected_platform[:architecture]) 322 | end 323 | 324 | true 325 | end 326 | 327 | def prefix 328 | (platform_family?('windows') ? 'C:/Chef/' : '/etc/chef/') 329 | end 330 | 331 | def ensurekv(config, hash) 332 | hash.each do |k, v| 333 | if v.is_a?(Symbol) 334 | v = v.to_s 335 | str = v 336 | else 337 | str = "'#{v}'" 338 | end 339 | if config =~ /^ *#{v}.*$/ 340 | config.sub(/^ *#{v}.*$/, "#{k} #{str}") 341 | else 342 | config << "\n#{k} #{str}" 343 | end 344 | end 345 | config 346 | end 347 | end 348 | end 349 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # chef-ingredient Cookbook 2 | 3 | [![Build Status](https://travis-ci.org/chef-cookbooks/chef-ingredient.svg?branch=master)](https://travis-ci.org/chef-cookbooks/chef-ingredient) [![Cookbook Version](https://img.shields.io/cookbook/v/chef-ingredient.svg)](https://supermarket.chef.io/cookbooks/chef-ingredient) 4 | 5 | This cookbook provides primitives - helpers and resources - to manage Chef Software, Inc.'s products and add-ons including, but not limited to: 6 | 7 | - Chef Infra Server 8 | - Chef Automate 9 | - Supermarket 10 | 11 | This cookbook also provides primitives for building and managing your Chef infrastructure. 12 | 13 | It will perform component installation and configuration. It provides no recipes. Instead, wrapper cookbooks should be created using the resources that this cookbook provides. 14 | 15 | ## Requirements 16 | 17 | ### Platforms 18 | 19 | - Ubuntu 20 | - Debian 21 | - CentOS/RHEL/Almalinux/Rockylinux 22 | - openSUSE 23 | - Amazon Linux 24 | 25 | ### Chef Infra 26 | 27 | - Chef Infra Client 15.3 28 | 29 | ### Cookbooks 30 | 31 | - none 32 | 33 | ## Chef Product Resources 34 | 35 | ### chef_ingredient 36 | 37 | A "chef ingredient" is the core package itself, or products or add-on components published by Chef Software, Inc. This resource manages the installation, configuration, and running the `ctl reconfigure` of individual packages. 38 | 39 | By default, `chef_ingredient` will install using the `packages.chef.io` stable repository depending on the platform. However, it can be configured to use a custom repository by setting the `node['chef-ingredient']['custom-repo-recipe']` attribute (nil by default). 40 | 41 | #### chef_ingredient Actions 42 | 43 | - `install` - (default) Configures the package repository and installs the specified package. 44 | - `upgrade` - Upgrades the specified package. 45 | - `uninstall` - Uninstalls the specified package. 46 | - `remove` - Alias for uninstall 47 | - `reconfigure` - Performs the `ctl reconfigure` command for the package. 48 | 49 | #### chef_ingredient Properties 50 | 51 | - `product_name` - The product name. See the [PRODUCT_MATRIX.md](https://github.com/chef/mixlib-install/blob/master/PRODUCT_MATRIX.md). For example, `chef-server`, `analytics`, `delivery`, `manage`, etc. 52 | - `config` - content that will be added to the configuration file of the given product. 53 | - `ctl_command` - The "ctl" command, e.g., `chef-server-ctl`. This should be automatically detected by the library helper method `chef_ctl_command`, but may need to be specified if something changes, like a new add-on is made available. 54 | - `options` - Options passed to the `package` resource used for installation. 55 | - `version` - Package version to install. Can be specified in various semver-alike ways: `12.0.4`, `12.0.3-rc.3`, and also `:latest`/`'latest'`. Do not use this property when specifying `package_source`. 56 | - `channel` - Channel to install the products from. It can be `:stable`, `:current` or `:unstable`. 57 | - `package_source` - Full path to a location where the package is located. If present, this file is used for installing the package. 58 | - `rubygems_url` - Install mixlib-install/version gems from rubygems.org or an alternative source. Useful for community distributions. Defaults to `Chef::Config[:rubygems_url]`. 59 | - `timeout` - The amount of time (in seconds) to wait to fetch the installer before timing out. Default timeout of the Chef package resource is `900` seconds. 60 | - `accept_license` - A boolean value that specifies if license should be accepted if it is asked for during `reconfigure`action. This option is applicable to only these products: manage, analytics, reporting and compliance. 61 | - `platform` - Override the auto-detected platform for which package to install. 62 | - `platform_version` - Override the auto-detected platform version for which package to install. 63 | - `architecture` - Override the auto-detected architecture for which package to install. 64 | - `platform_version_compatibility_mode` - Find closest matching package when platform auto-detection does not find an exact package match in the repository. 65 | 66 | ### omnibus_service 67 | 68 | Manages a sub-service within the context of a Chef product package. For example the `rabbitmq` service that is run for the Chef Server. 69 | 70 | #### omnibus_service Actions 71 | 72 | This delegates to the ctl command the service management command specified in the action. Not all the service management commands are supported, however, as not all of them would make sense when used in a recipe. This resource is primarily used for sending or receiving notifications. See the example section. 73 | 74 | #### omnibus_service Properties 75 | 76 | - `service_name` - The name of the service to manage. Specify this like `product_name/service`, for example, `chef-server/rabbitmq`. 77 | - `ctl_command` - The "ctl" command, e.g. `chef-server-ctl`. This should be automatically detected by the library helper method `chef_ctl_command`, but may need to be specified if something changes, like a new add-on is made available. 78 | 79 | ### ingredient_config 80 | 81 | Makes it easy to create update configuration files of each Chef product. It uses the default locations for each product. 82 | 83 | #### ingredient_config Actions 84 | 85 | - `render` - (default) Creates the configuration file using the options passed in via `add` action or `config` attribute of `chef_ingredient` resource. 86 | - `add` - Adds the `config` attribute contents to the data collection. Must run `:render` action to generate the file. 87 | 88 | #### ingredient_config Properties 89 | 90 | - `product_name` - The product name. See the [PRODUCT_MATRIX.md](https://github.com/chef/mixlib-install/blob/master/PRODUCT_MATRIX.md). For example, `chef-server`, `analytics`, `delivery`, `manage`, etc. 91 | - `config` - Content that will be added to the configuration file of the given product. 92 | - `sensitive` - Set to mask the config contents in logs. Use when you config contains information like passwords or secrets. 93 | 94 | #### ingredient_config Examples 95 | 96 | We may need to restart the RabbitMQ service on the Chef Server, for example when adding configuration for Chef Analytics. 97 | 98 | ```ruby 99 | template '/etc/opscode/chef-server.rb' do 100 | notifies :restart, 'omnibus_service[chef-server/rabbitmq]' 101 | end 102 | 103 | omnibus_service 'chef-server/rabbitmq' do 104 | action :nothing 105 | end 106 | ``` 107 | 108 | To install Chef Server using some custom configuration options: 109 | 110 | ```ruby 111 | chef_ingredient "chef-server" do 112 | config <<~EOS 113 | api_fqdn "#{node["fqdn"]}" 114 | ip_version "ipv6" 115 | notification_email "#{node["chef_admin"]}" 116 | nginx["ssl_protocols"] = "TLSv1 TLSv1.1 TLSv1.2" 117 | EOS 118 | action :install 119 | end 120 | 121 | ingredient_config "chef-server" do 122 | notifies :reconfigure, "chef_ingredient[chef-server]" 123 | end 124 | ``` 125 | 126 | To install or upgrade latest version of Chef Client on your nodes: 127 | 128 | ```ruby 129 | chef_ingredient "chef" do 130 | action :upgrade 131 | version :latest 132 | end 133 | ``` 134 | 135 | To install an add-on of Chef Server from `:current` channel: 136 | 137 | ```ruby 138 | chef_ingredient 'chef-server' do 139 | channel :stable 140 | action :install 141 | end 142 | 143 | chef_ingredient 'analytics' do 144 | channel :current 145 | action :install 146 | end 147 | ``` 148 | 149 | ## Chef Infrastructure Resources 150 | 151 | ### General Properties 152 | 153 | These properties exist for all infrastructure resources 154 | 155 | - `name` - A name for the resource. 156 | - `channel` - The channel from our package repository to install. Most of the time you want stable. 157 | - `version` - The version of Automate you want to install. 158 | - `config` - The configuration that will be written to the appropriate configuration file for the product. 159 | - `accept_license` - Do you accept Chef's license agreements. 160 | - `platform` - Use only if you need to over-ride the default platform. 161 | - `platform_version` - Use only if you need to over-ride the default platform. 162 | 163 | ### chef_automate 164 | 165 | Installs Chef Automate. 166 | 167 | #### chef_automate Properties 168 | 169 | - `enterprise` - The Enterprise to create in Automate 170 | - `license` - we recommend using the chef_file resource 171 | - `chef_user` - The user you will connect to the Chef server as 172 | - `chef_user_pem` - The private key of the above Chef user 173 | - `validation_pem` - The validator key of the Chef org we're connecting to 174 | - `builder_pem` - The private key of the build nodes 175 | 176 | ### chef_automatev2 177 | 178 | Installs Chef Automate version 2 179 | 180 | #### chef_automatev2 Requirements 181 | 182 | - Requires chef-client 14+ due to use of sysctl resource 183 | - General Properties used 184 | 185 | ### chef_backend 186 | 187 | #### chef_backend Properties 188 | 189 | - `bootstrap_node` - The node we'll bootstrap secrets with. 190 | - `publish_address` - node['ipaddress'] | The address you want Chef-Backend to listen on. 191 | - `chef_backend_secrets` - A location where your secrets are | we recommend using the chef_file resource. 192 | - `chef_backend_secrets_user` - The user that owns the file created by the `chef_backend_secrets` attribute 193 | - `chef_backend_secrets_group` - The group that owns the file created by the `chef_backend_secrets` attribute 194 | 195 | ### chef_org 196 | 197 | #### chef_org Properties 198 | 199 | - `org` - The short name of the org. 200 | - `org_full_name` - The full name of the org you want to create. 201 | - `admins` - An array of admins for the org. 202 | - `users` - An array of users for the org. 203 | - `remove_users` - An array of users to remove from the org. 204 | - `key_path` - Where to store the validator key that is created with the org. 205 | 206 | ### chef_user 207 | 208 | - `username` - The username of the user. 209 | - `first_name` - The first name of the user. 210 | - `last_name` - The last name of the user. 211 | - `email` - The users e-mail. 212 | - `password` - The users password. 213 | - `key_path` - Where to store the users private key that is created with the user. 214 | - `serveradmin` - Is the user a serveradmin? 215 | 216 | ### chef_client 217 | 218 | - `node_name` - The name of the node. 219 | - `version` - The version of chef-client to install. 220 | - `chefdk` - Do you want to install chefdk? 221 | - `chef_server_url` - What is the Chef server URL to connect to. 222 | - `ssl_verify` - Validate ssl certificates? 223 | - `log_location` - Where to log. 224 | - `log_level` - Log level. 225 | - `config` - Any configuration for client.rb. 226 | - `run_list` - The clients runlist. 227 | - `environment` - Which Chef Environment the client belongs to. 228 | - `validation_pem` - The validation pem to validate with. 229 | - `validation_client_name` - The validation client name. 230 | - `tags` - Any tags for the node. 231 | - `interval` - The interval to run chef-client on. 232 | - `splay` - The randomization to add to the interval. 233 | - `data_collector_token` - The data collector token to talk to Visibility. 234 | - `data_collector_url` - The Visibility URL to send data. 235 | 236 | ### chef_file 237 | 238 | - `filename` - The name of the resource. 239 | - `source` - The source of the file. 240 | - `user` - The owner of the file. 241 | - `group` - The group owner of the file. 242 | - `mode` - The mode for the file. 243 | 244 | ### chef_server 245 | 246 | - `addons` - A set of add-ons to install with the Chef Server. 247 | - `data_collector_token` - The data collector token to authenticate with Chef Visiblity. 248 | - `data_collector_url` - The URL to connect to Visibility. 249 | 250 | ### chef_supermarket 251 | 252 | - `chef_server_url` - The Chef server's URL. 253 | - `chef_oauth2_app_id` - The oauth2 app id from the Chef server. 254 | - `chef_oauth2_secret` - The oauth2 secret from the Chef server. 255 | - `chef_oauth2_verify_ssl` - Whether to validate SSL certificates. 256 | 257 | ### workflow_builder 258 | 259 | - `pj_version` - The version of Push-Jobs to install. 260 | - `chef_user` - The Chef user to authenticate with the Chef Server. 261 | - `chef_user_pem` - The private key of the Chef user to authenticate with the Chef Server. 262 | - `builder_pem` - The builder users private key to communicate with Chef Automate. 263 | - `chef_fqdn` - The FQDN of the Chef server. 264 | - `automate_fqdn` - The FQDN of the automate server. 265 | - `supermarket_fqdn` - The FQDN of the Supermarket server. 266 | - `job_dispatch_version` - Which job dispatch version to use. V1 is push-jobs, V2 is SSH runners. 267 | - `automate_user` - What is the Automate user we're connecting to Automate as. 268 | - `automate_password` - The password for the user above. 269 | - `automate_enterprise` - The Enterprise to connect to. 270 | - `chef_config_path` - The config path for chef-client. 271 | 272 | ## License & Authors 273 | 274 | - Author: Joshua Timberman [joshua@chef.io](mailto:joshua@chef.io) 275 | - Author: Serdar Sutay [serdar@chef.io](mailto:serdar@chef.io) 276 | - Author: Patrick Wright [patrick@chef.io](mailto:patrick@chef.io) 277 | - Author: Nathan Cerny [ncerny@chef.io](mailto:ncerny@chef.io) 278 | - Author: Andy Dufour [adufour@chef.io](mailto:adufour@chef.io) 279 | - Author: Brandon Raabe [brandon.raabe@newcontext.com](mailto:brandon.raabe@newcontext.com) 280 | - Author: Jeremy J. Miller [jm@chef.io](mailto:jm@chef.io) 281 | - Author: Josh Hudson [jhudson@chef.io](mailto:jhudson@chef.io) 282 | - Author: Stephen Lauck [lauck@chef.io](mailto:lauck@chef.io) 283 | - Copyright (C) 2014-2017, Chef Software Inc. [legal@chef.io](mailto:legal@chef.io) 284 | 285 | ```text 286 | Licensed under the Apache License, Version 2.0 (the "License"); 287 | you may not use this file except in compliance with the License. 288 | You may obtain a copy of the License at 289 | 290 | http://www.apache.org/licenses/LICENSE-2.0 291 | 292 | Unless required by applicable law or agreed to in writing, software 293 | distributed under the License is distributed on an "AS IS" BASIS, 294 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 295 | See the License for the specific language governing permissions and 296 | limitations under the License. 297 | ``` 298 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # chef-ingredient Cookbook CHANGELOG 2 | 3 | This file is used to list changes made in each version of the chef-ingredient cookbook. 4 | 5 | ## 3.5.0 (2022-07-28) 6 | 7 | - Added attribute to specify mixlib-install version, defaults to nil to install latest version - [@stromweld](https://github.com/stromweld) 8 | - Fixed automatev2 resource guard and made it idempotent - [@stromweld](https://github.com/stromweld) 9 | - Fixed automatev2 resource to work with debian and rhel family bin locations - [@stromweld](https://github.com/stromweld) 10 | - Updated testing and switched to Github actions for CI pipeline - [@stromweld](https://github.com/stromweld) 11 | 12 | ## 3.4.0 (2021-08-05) 13 | 14 | - Enable `unified_mode` for Chef 17 compatibility - [@detjensrobert](https://github.com/detjensrobert) 15 | - Add deprecations to the automate, chef_client and wf_builder resources - [@tas50](https://github.com/tas50) 16 | 17 | ## 3.3.0 (2021-01-29) 18 | 19 | - Add rubygems_url property to chef_ingredient - [@ramereth](https://github.com/ramereth) 20 | - Add rubygems_url property to ingredient_config - [@ramereth](https://github.com/ramereth) 21 | - Add rubygems_url property to omnibus_service - [@ramereth](https://github.com/ramereth) 22 | - Cookstyle Bot Auto Corrections with Cookstyle 6.15.9 - [@cookstyle](https://github.com/cookstyle) 23 | - Cookstyle 7.0.0 Fixes - [@xorimabot](https://github.com/xorimabot) 24 | - Change from testing ChefDK to Chef Workstation in dokken - [@ramereth](https://github.com/ramereth) 25 | 26 | ## Unreleased 27 | 28 | - resolved cookstyle error: resources/client.rb:156:49 convention: `Style/RedundantParentheses` 29 | 30 | ## 3.2.0 (2020-08-12) 31 | 32 | - adding a products property to the automatev2 resource - [@srb3](https://github.com/srb3) 33 | - Ensure we have resource_name in addition to provides in resources - [@tas50](https://github.com/tas50) 34 | - Added provides to resources to add Chef Infra Client 16 compatability - [@Stromweld](https://github.com/Stromweld) 35 | 36 | ## 3.1.3 (2020-06-02) 37 | 38 | - Remove unnecessary Foodcritic comments - [@tas50](https://github.com/tas50) 39 | - Resolve ChefSpec deprecation warnings - [@tas50](https://github.com/tas50) 40 | - Make Chef Infra Server honor license acceptance. Pulled this in from chef-cookbooks/chef-ingredient#241 - [@bkonick](https://github.com/bkonick) 41 | - correct automate path - [@dheerajd-msys](https://github.com/dheerajd-msys) 42 | - move reconfigure_command to a method in action_class - [@bkonick](https://github.com/bkonick) 43 | - Cookstyle 6.2.9 Fixes - [@xorimabot](https://github.com/xorimabot) 44 | - Update platforms we test on - [@tas50](https://github.com/tas50) 45 | - Cookstyle Fixes including Chef Infra Client 16 compatibility - [@xorimabot](https://github.com/xorimabot) 46 | - resolved cookstyle error: resources/chef_ingredient.rb:19:1 warning: `ChefDeprecations/ResourceUsesOnlyResourceName` 47 | - resolved cookstyle error: resources/ingredient_config.rb:18:1 warning: `ChefDeprecations/ResourceUsesOnlyResourceName` 48 | - resolved cookstyle error: resources/omnibus_service.rb:18:1 warning: `ChefDeprecations/ResourceUsesOnlyResourceName` 49 | - resolved cookstyle error: resources/backend.rb:28:45 refactor: `ChefCorrectness/LazyEvalNodeAttributeDefaults` 50 | - resolved cookstyle error: resources/chef_org.rb:31:36 refactor: `ChefModernize/ShellOutHelper` 51 | - resolved cookstyle error: resources/chef_org.rb:32:35 refactor: `ChefModernize/ShellOutHelper` 52 | - resolved cookstyle error: resources/chef_user.rb:32:36 refactor: `ChefModernize/ShellOutHelper` 53 | - resolved cookstyle error: resources/wf_builder.rb:260:9 refactor: `ChefModernize/ShellOutHelper` 54 | - resolved cookstyle error: resources/wf_builder.rb:274:18 refactor: `ChefModernize/ShellOutHelper` 55 | - resolved cookstyle error: spec/unit/recipes/test_default_handler_spec.rb:20:7 warning: `ChefDeprecations/DeprecatedChefSpecPlatform` 56 | - resolved cookstyle error: libraries/helpers.rb:254:11 refactor: `ChefCorrectness/ChefApplicationFatal` 57 | - resolved cookstyle error: resources/automatev2.rb:48:5 refactor: `ChefCorrectness/ConditionalRubyShellout` 58 | - resolved cookstyle error: resources/wf_builder.rb:207:11 refactor: `ChefStyle/UsePlatformHelpers` 59 | - resolved cookstyle error: resources/wf_builder.rb:210:11 refactor: `ChefStyle/UsePlatformHelpers` 60 | 61 | ## 3.1.2 (2019-10-02) 62 | 63 | - Minor lint and testing updates - [@tas50](https://github.com/tas50) 64 | - Fix support for RHEL/CentOS 8 - [@ramereth](https://github.com/ramereth) 65 | 66 | ## 3.1.1 (2019-01-15) 67 | 68 | - Fix user idempotency (#238) - [@Stromweld](https://github.com/Stromweld) 69 | 70 | ## 3.1.0 (2019-01-14) 71 | 72 | - Add a new automatev2 resource (requires Chef 14+) (#237) - [@Stromweld](https://github.com/Stromweld) 73 | 74 | ## 3.0.0 (2019-01-11) 75 | 76 | - Require Chef 13+ and remove Ubuntu 14.04 testing 77 | 78 | ## 2.3.3 (2018-11-28) 79 | 80 | - Rrevert chef_org user/admin guards (PR#223) (#233) 81 | - Remove default action, which isn't necessary in Chef 12.5+ (#232) 82 | - Pass sensitive & add guard to chef_user ruby_block (#231) 83 | 84 | ## 2.3.2 (2018-07-16) 85 | 86 | - Create client.d directory for `chef_client` resource 87 | - Fix `chef_org` guards for adding users and admins 88 | 89 | ## 2.3.1 (2018-06-27) 90 | 91 | - Resolve multiple incompatibilities with Chef 14 92 | 93 | ## 2.3.0 (2018-02-15) 94 | 95 | - Multiple fixes for Automate and Workflow Builder resources. 96 | - Fix permissions on chef-backend-secrets.json and provide new properties for modifying the permissions 97 | - Remove Chefspec matchers that are no longer necessary 98 | 99 | ## 2.2.1 (2018-01-12) 100 | 101 | - Resolve chef_org full name truncation issue (#215) 102 | 103 | ## 2.2.0 (2017-11-30) 104 | 105 | - Resolve multiple issues with the custom resources in various Chef 12 releases by requiring Chef 12.7 or later and removing the usage of class_eval on the action_classes 106 | - Restored compatibility with Amazon Linux on Chef 13 and added testing 107 | - Removed unnecessary default_actions in the custom custom resources 108 | - Resolved FC108 warnings by removing redundant :name name_properties from the custom resources 109 | 110 | ## 2.1.11 (2017-11-13) 111 | 112 | - Fixed pathing for etc and .chef directories for dbuild in wf_builder 113 | 114 | ## 2.1.10 (2017-10-23) 115 | 116 | - Required for chef_server cookbook (#202) 117 | 118 | ## 2.1.9 (2017-10-11) 119 | 120 | - Multiple fixes for Automate and Workflow Builder resources 121 | - Honor sensitive property when set on high level resources 122 | - Fix chef_server resource to run without configured addons 123 | 124 | ## 2.1.8 (2017-08-23) 125 | 126 | - Fix permissions on automate keys and license. 127 | 128 | ## 2.1.7 (2017-08-11) 129 | 130 | - Fix remove_users to use new_resource instead of current_resource. 131 | 132 | ## 2.1.6 (2017-08-10) 133 | 134 | - fix chef_org resource deprecation warnings 135 | - RHEL 5 and 6 package manager support (RHEL 5 is not officially supported) 136 | 137 | ## 2.1.5 (2017-07-31) 138 | 139 | - Update the client resource to properly source the client.rb template 140 | - Add a log warning if the default recipe is included on a run_list 141 | - Added supported platforms to the metadata for Supermarket 142 | 143 | ## 2.1.4 (2017-07-27) 144 | 145 | - Use default package provider on RHEL instead of RPM; fixes #181 146 | - Resolve CHEF-19 deprecation warnings (#184) 147 | 148 | ## 2.1.3 (2017-06-29) 149 | 150 | - Pin mixlib-install `~> 3.3` 151 | 152 | ## 2.1.2 (2017-06-03) 153 | 154 | - Fix normalization of auto-detected and set architectures 155 | 156 | ## 2.1.1 (2017-05-22) 157 | 158 | - Revert platform remapping and platform version truncation changes. 159 | - `chef_ingredient` properties `platform`, `platform_version`, `architecture` default to auto-detected value when not set. 160 | 161 | ## 2.1.0 (2017-05-18) 162 | 163 | - Add initial chef infrastructure resources and contributors from chef_stack project 164 | - Add Ohai attributes as defaults to `chef_ingredient` resource properties `platform`, `platform_version`, and `architecture` 165 | - Add platform remapping and platform version truncation fixes to align with Chef Software Inc's software distribution systems 166 | 167 | ## 2.0.5 (2017-04-24) 168 | 169 | - [#155](https://github.com/chef-cookbooks/chef-ingredient/issues/155) Workaround chef_ingredient timeout property on Windows (windows_package timeout property currently broken in Chef) 170 | - [#158](https://github.com/chef-cookbooks/chef-ingredient/issues/158) Remove #check_deprecated_properties logic (handled by mixlib-install) 171 | - Allow chef_ingredient action :upgrade on Windows 172 | 173 | ## 2.0.4 (2017-04-13) 174 | 175 | - Ensure mixlib-install `~> 3.2` is installed 176 | 177 | ## 2.0.3 (2017-04-13) 178 | 179 | - Normalize architectures detected by ohai before mixlib-install validation 180 | 181 | ## 2.0.2 (2017-04-11) 182 | 183 | - Update resources to support Chef 12.5 and 12.6 184 | 185 | ## 2.0.1 (2017-03-28) 186 | 187 | - Update DefaultHandler and OmnitruckHandler to use a global constant lookup. In some environments, not doing so caused a naming conflict with the dynamically generated ChefIngredient DSL resource class. 188 | 189 | ## 2.0.0 (2017-03-24) 190 | 191 | - Remove `chef_server_ingredient` resource shim 192 | - Update mixlib-install to major version 3 193 | - `platform_version_compatibility_mode` property no longer has a default value 194 | - If no matching artifacts are found a `Mixlib::Install::Backend::ArtifactsNotFound` exception is raised instead a `RuntimeError` 195 | - All resources have been converted to custom resources 196 | 197 | ## 1.1.0 (2017-03-01) 198 | 199 | - Test with local delivery and not Rake 200 | - Remove sensitive property for Chef 13 compatibility as this properly is provided by chef-client now for us by any resource and doesn't need to be defined 201 | - Test in Travis CI with kitchen-dokken and convert tests to InSpec 202 | 203 | ## 1.0.1 (2017-02-22) 204 | 205 | - Testing cleanup for Chef 13 compatibility and testing on the latest platforms 206 | 207 | ## 1.0.0 (2017-02-15) 208 | 209 | - Require Chef 12.5+ and remove compat_resource dependency 210 | - Use mixlib-install >= 2.1.12 - this brings in an important fix for the `delivery` -> `automate` package rename. See the [Discourse announcement](https://discourse.chef.io/t/chef-automate-install-package-renaming-in-0-7-14-available/10429/1) for details on the rename 211 | 212 | ## 0.21.4 (2017-02-13) 213 | 214 | - Add properties to override the platform details of a `chef_ingredient` product to install 215 | 216 | ## 0.21.3 (2017-02-02) 217 | 218 | - Add timeout to package resource created by configure_from_source_package 219 | 220 | ## 0.21.2 (2016-10-26) 221 | 222 | - Fix issue when failed package installs using OmnitruckHandler would not raise a converge error on subsequent runs 223 | 224 | ## 0.21.1 (2016-10-25) 225 | 226 | - Update SUSE platform to use DefaultHandler 227 | 228 | ## 0.21.0 (2016-09-26) 229 | 230 | - Update mixlib-install to version 2.0 (PackageRouter support) 231 | 232 | ## 0.20.0 (2016-09-08) 233 | 234 | - Remove extraneous converge_by that caused downloads to show as converged on every run 235 | - Use compat_resource cookbook to add support for Chef 12.1-12.4 236 | - Use apt_update resource vs. the apt cookbook in the test cookbook 237 | - Update Travis CI testing to use our standard Rakefile and cookstyle for ruby linting. 238 | - Fix chefspec / foodcritic / test kitchen failures 239 | - Swap the Policyfile for a Berksfile 240 | - Remove unnecessary action and default_action properties from the custom resources 241 | 242 | ## v0.19.0 243 | 244 | - Remove delivery-cli examples and tests (we now shipit with ChefDK) 245 | - Set version constraint to ~> 1.1 for installing mixlib-install from Rubygems 246 | 247 | ## v0.18.5 248 | 249 | - [#106](https://github.com/chef-cookbooks/chef-ingredient/pull/106) Limit `remote_file` backups to 1 250 | - [#110](https://github.com/chef-cookbooks/chef-ingredient/pull/110) Get rid of default: nil warnings 251 | 252 | ## v0.18.4 253 | 254 | - Add `platform_version_compatibility_mode` property to `chef_ingredient` which makes chef-ingredient select packages built for earlier version of a platform during install when a package does not exist for the current platform version. 255 | 256 | ## v0.18.3 257 | 258 | - Add `accept_license` property to `chef_ingredient` which can accept license for Chef products when applicable. 259 | 260 | ## v0.18.2 261 | 262 | - Set version constraint to ~> 1.0 for installing mixlib-install from Rubygems 263 | 264 | ## v0.18.1 265 | 266 | - Bump mixlib-install version to 1.0.6 so unstable channel artifacts won't include metadata.json files. 267 | 268 | ## v0.18.0 269 | 270 | - [#85](https://github.com/chef-cookbooks/chef-ingredient/pull/85) Ability to support unstable channel for all products / platforms. 271 | - [#90](https://github.com/chef-cookbooks/chef-ingredient/pull/90) Use packages from packages.chef.io instead of package cloud & remove packagecloud repository setup. 272 | - [#91](https://github.com/chef-cookbooks/chef-ingredient/pull/91) Deprecate chef-ha, chef-marketplace, chef-sync, push-client, push-server in favor of ha, marketplace, sync, push-jobs-client, push-jobs-server. 273 | 274 | ## v0.17.0 275 | 276 | - [#77](https://github.com/chef-cookbooks/chef-ingredient/pull/77) Enable installation of chef and chefdk from unstable 277 | - [#82](https://github.com/chef-cookbooks/chef-ingredient/pull/82) Set `--force-yes` for older Debian/Ubuntu 278 | 279 | ## v0.16.0 280 | 281 | - [#62](https://github.com/chef-cookbooks/chef-ingredient/issues/62) Do not assume connection to the internet, allow custom recipe for a local repository 282 | - [#75](https://github.com/chef-cookbooks/chef-ingredient/pull/75) omnitruck handler windows implementation 283 | 284 | ## v0.15.0 285 | 286 | - [#66](https://github.com/chef-cookbooks/chef-ingredient/pull/66) Fix push job client and server naming 287 | - [#68](https://github.com/chef-cookbooks/chef-ingredient/pull/68) Use mixlib-install while installing / upgrading packages from omnitruck 288 | - [#71](https://github.com/chef-cookbooks/chef-ingredient/pull/71) Convert `omnibus_service` and `ingredient_config` to "12.5 [custom resources](https://docs.chef.io/custom_resources.html)" 289 | - [#73](https://github.com/chef-cookbooks/chef-ingredient/pull/73) Use PRODUCT_MATRIX from mixlib-install 290 | 291 | ## v0.14.0 292 | 293 | - [#58](https://github.com/chef-cookbooks/chef-ingredient/pull/58) Add Chef Compliance product 294 | 295 | ## v0.13.1 296 | 297 | - [#57](https://github.com/chef-cookbooks/chef-ingredient/pull/57) Content accumulator guard 298 | 299 | ## v0.13.0 300 | 301 | - [#56](https://github.com/chef-cookbooks/chef-ingredient/pull/56) Uncomment `use_inline_resources`, this is required for the providers to work properly 302 | - [#55](https://github.com/chef-cookbooks/chef-ingredient/pull/55) Remove unit tests for specifically the custom resources 303 | - [#54](https://github.com/chef-cookbooks/chef-ingredient/pull/54) Clarify maintainer/support in the README 304 | 305 | ## v0.12.1 306 | 307 | - [#53](https://github.com/chef-cookbooks/chef-ingredient/pull/53) Relax version constraints 308 | 309 | ## v0.12.0 310 | 311 | - Refactor `chef_ingredient` and prepare to handle install/upgrade from omnitruck 312 | - Add channel property to `chef_ingredient` 313 | - Removed installed state property 314 | - Use `product_name` instead of `package_name` 315 | - Add not if to skip `ingredient_config` render if `config` property isn't used 316 | 317 | ## v0.11.3 318 | 319 | - Remove `resource_name` from Provider because `:facepalm:` 320 | 321 | ## v0.11.2 322 | 323 | - Add `repository` and `master_token` properties to `chef_server_ingredient` shim for compatibility 324 | 325 | ## v0.11.1 326 | 327 | - [#37](https://github.com/chef-cookbooks/chef-ingredient/issues/37) use `define_matchers` for ChefSpec 328 | 329 | ## v0.11.0 330 | 331 | - [#35](https://github.com/chef-cookbooks/chef-ingredient/issues/35) Add `fqdn_resolves?` method for `chef-server` cookbook. 332 | 333 | ## v0.10.2 334 | 335 | - Add `:add` action to `ingredient_config` 336 | 337 | ## v0.10.1 338 | 339 | - [#30](https://github.com/chef-cookbooks/chef-ingredient/issues/30) Supermarket doesn't use supermarket.rb for configuration, it's supermarket.json 340 | 341 | ## v0.10.0 342 | 343 | - [#23](https://github.com/chef-cookbooks/chef-ingredient/pull/23) Add Chef Marketplace 344 | - [#29](https://github.com/chef-cookbooks/chef-ingredient/pull/29) Fix RSpec and noisy warnings 345 | 346 | ## v0.9.1 347 | 348 | - [#26](https://github.com/chef-cookbooks/chef-ingredient/issues/26) Remove mode, owner, and group properties from `ingredient_config`'s resources to prevent resource updates after running ctl commands that manage those file permissions. 349 | 350 | ## v0.9.0 351 | 352 | - Add sensitive property to `ingredient_config` 353 | - Use recipe DSL to set resource name 354 | 355 | ## v0.8.1 356 | 357 | - Update PRODUCT_MATRIX.md with correct updated Chef Push product names (push-server, push-client). The code was updated but not the document. 358 | 359 | ## v0.8.0 360 | 361 | - [#7](https://github.com/chef-cookbooks/chef-ingredient/issues/7) Add `ingredient_config` resource 362 | - [#10](https://github.com/chef-cookbooks/chef-ingredient/pull/10) Add upgrade action for `chef_ingredient` 363 | - Test cleanup, various rubocop fixes 364 | 365 | ## v0.7.0 366 | 367 | - [#3](https://github.com/chef-cookbooks/chef-ingredient/issues/3) Allow :latest as a version 368 | - Removes the `package_name` property from the `chef_ingredient` resource, long live `product_name` 369 | 370 | ## v0.6.0 371 | 372 | **Breaking changes** This version is backwards-incompatible with previous versions. We're still sub-1.0, but those who wish to use the `chef_server_ingredient` resource really should pin to version 0.5.0. 373 | 374 | - [#1](https://github.com/chef-cookbooks/chef-ingredient/issues/1) Use product names instead of package names. 375 | 376 | ## v0.5.0 377 | 378 | - Major refactor and rename. It's fine, this is a new cookbook! 379 | 380 | ## v0.4.0 (2015-06-11) 381 | 382 | - Add timeout attribute to `chef_server_ingredient` 383 | - Use `declare_resource` DSL method to select local package resource 384 | - Allow specifying the repository name for the packagecloud repo 385 | 386 | ## v0.3.2 (2015-04-15) 387 | 388 | - adding proxy support for packagecloud 389 | 390 | ## v0.3.1 (2015-04-09) 391 | 392 | - Various refactoring and cleanup 393 | 394 | ## v0.3.0 395 | 396 | - Add ctl command for supermarket 397 | 398 | ## v0.2.0 399 | 400 | - Add reconfigure property to ingredient resource 401 | 402 | ## v0.1.0 403 | 404 | - Release this cookbook to Supermarket 405 | 406 | ## v0.0.2 407 | 408 | - #4: define the installed attribute 409 | - #1, #2, use packagecloud cookbook 410 | 411 | ## v0.0.1 412 | 413 | - Initial release 414 | --------------------------------------------------------------------------------