diff --git a/.rubocop.yml b/.rubocop.yml index f8ab3e1..342a28c 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,149 +1,160 @@ +require: + - rubocop-performance + # # Disabled rules # -Encoding: +## Layout +# Seems buggy - https://github.com/bbatsov/rubocop/issues/2690 +Layout/MultilineOperationIndentation: Enabled: false -NumericLiterals: +## Lint +# it wants File.exist? instead of File.exists? +Lint/DeprecatedClassMethods: Enabled: false -MultilineTernaryOperator: +## Metrics +Metrics/AbcSize: Enabled: false -ModuleLength: +# Unrealistic +Metrics/BlockNesting: Enabled: false -MethodLength: +Metrics/ClassLength: Enabled: false -ClassLength: +Metrics/CyclomaticComplexity: Enabled: false -CyclomaticComplexity: +Metrics/MethodLength: Enabled: false -# So just keep iterating instead of breaking? wtf. -Next: +Metrics/ModuleLength: Enabled: false -# While this can be nice, it also can promote errors. Let people -# use what's comfortable for them -GuardClause: +# I don't know what it's metric for "human complexity" is, but it's wrong. +Metrics/PerceivedComplexity: Enabled: false -AbcSize: +## Naming + +# this trips on *any* method called 'get_*' wtf. +Naming/AccessorMethodName: Enabled: false -# less readable, not more -IfUnlessModifier: +# This blows up on things like base_packages-redhat +Naming/FileName: Enabled: false -# Really? -PerlBackrefs: +## Performance +# Performance rules have moved to the rubocop-performance gem. + +# buggy: https://github.com/bbatsov/rubocop/issues/2639 +Performance/RedundantMatch: Enabled: false -# Unrealistic -BlockNesting: +# https://github.com/bbatsov/rubocop/issues/2676 +Performance/RedundantMerge: Enabled: false -# Disabled because of the way 'variables' works. -BracesAroundHashParameters: +# We'll .times.map all we want. +Performance/TimesMap: Enabled: false -WordArray: +## Style + +Style/CommentAnnotation: Enabled: false -RedundantReturn: +# Bug with constants? https://phabricator.fb.com/P56108678 +Style/ConditionalAssignment: Enabled: false -RedundantSelf: +Style/Documentation: Enabled: false -CommentAnnotation: +Style/Encoding: Enabled: false -# this trips on *any* method called 'get_*' wtf. -AccessorMethodName: +# No more 'Missing frozen string literal comment.' linting violations +Style/FrozenStringLiteralComment: Enabled: false -# backslash is extra dumb in ruby, we want the OPPOSITE of this rule -LineEndConcatenation: +# While this can be nice, it also can promote errors. Let people +# use what's comfortable for them +Style/GuardClause: Enabled: false -# this isn't testing for consistency it always wants %w() which is dumb -PercentLiteralDelimiters: +# less readable, not more +Style/IfUnlessModifier: Enabled: false -# it wants File.exist? instead of File.exists? -DeprecatedClassMethods: +# backslash is extra dumb in ruby, we want the OPPOSITE of this rule +Style/LineEndConcatenation: Enabled: false -# This blows up on things like base_packages-redhat -FileName: +Style/MultilineTernaryOperator: Enabled: false -# I don't know what it's metric for "human complexity" is, but it's wrong. -PerceivedComplexity: +# We don't use CAPS just for constants. +Style/MutableConstant: Enabled: false -# Seems buggy - https://github.com/bbatsov/rubocop/issues/2690 -MultilineOperationIndentation: +# So just keep iterating instead of breaking? wtf. +Style/Next: Enabled: false -# buggy: https://github.com/bbatsov/rubocop/issues/2639 -Performance/RedundantMatch: +Style/NumericLiterals: Enabled: false -# We don't use CAPS just for constants. -Style/MutableConstant: +# this isn't testing for consistency it always wants %w() which is dumb +Style/PercentLiteralDelimiters: Enabled: false -# We'll .times.map all we want. -Performance/TimesMap: +# Really? +Style/PerlBackrefs: Enabled: false -# https://github.com/bbatsov/rubocop/issues/2676 -Performance/RedundantMerge: +Style/RedundantReturn: Enabled: false -# Bug with constants? https://phabricator.fb.com/P56108678 -Style/ConditionalAssignment: +Style/RedundantSelf: Enabled: false -# No more 'Missing frozen string literal comment.' linting violations -Style/FrozenStringLiteralComment: +Style/WordArray: Enabled: false + # # Modified rules # -LineLength: - Max: 120 -DotPosition: +Layout/DotPosition: EnforcedStyle: trailing -HashSyntax: +Layout/FirstArrayElementIndentation: + EnforcedStyle: consistent + +Layout/LineLength: + Max: 120 + +Metrics/BlockLength: + Max: 80 + +Style/HashSyntax: EnforcedStyle: hash_rockets -Style/Documentation: - Enabled: false +Style/SignalException: + EnforcedStyle: semantic -TrailingCommaInArrayLiteral: +Style/TrailingCommaInArguments: EnforcedStyleForMultiline: comma -TrailingCommaInHashLiteral: +Style/TrailingCommaInArrayLiteral: EnforcedStyleForMultiline: comma -TrailingCommaInArguments: +Style/TrailingCommaInHashLiteral: EnforcedStyleForMultiline: comma - -Layout/IndentArray: - EnforcedStyle: consistent - -Style/SignalException: - EnforcedStyle: semantic - -Metrics/BlockLength: - Max: 80 diff --git a/chef/cookbooks/cpe_zoom/README.md b/chef/cookbooks/cpe_zoom/README.md index 0a3689a..1ed086a 100644 --- a/chef/cookbooks/cpe_zoom/README.md +++ b/chef/cookbooks/cpe_zoom/README.md @@ -1,6 +1,6 @@ cpe_zoom Cookbook ======================== -Install a profile to manage diagnostic information submission settings. +Manages Zoom Desktop Client configuration on macOS and Windows. Attributes @@ -9,18 +9,23 @@ Attributes Usage ----- -The profile will manage the `us.zoom.config` preference domain. +On macOS, a profile will manage the `us.zoom.config` preference domain. -The profile's organization key defaults to `Uber` unless `node['organization']` is +The profile's organization key defaults to `Uber`, unless `node['organization']` is configured in your company's custom init recipe. The profile will also use whichever prefix is set in node['cpe_profiles']['prefix'], which defaults to `com.facebook.chef` -The profile delivers a payload for the above keys in `node['cpe_zoom']`. The three provided have a sane default, which can be overridden in another recipe if desired. +The profile delivers a payload for the above keys in `node['cpe_zoom']`. The three provided have a sensible default, which can be overridden in another recipe if desired. -This cookbook provides zero keys within the default attributes as there are many undocumented keys. +This cookbook doesn't provide any keys within the default attributes as there are many undocumented keys. -For a list of supported keys, please see this [Zoom knowledge base article](https://support.zoom.us/hc/en-us/articles/115001799006-Mass-Deployment-with-Preconfigured-Settings-for-Mac) +On Windows, take care not to deploy Zoom with MSI install arguments which conflict with the registry keys you set via this cookbook. -For example, you could tweak the above values - # Disable the ability for Zoom to turn on your webcam when joining a meeting. +For a list of supported configuration keys, please see the Zoom knowledge base articles for [macOS](https://support.zoom.us/hc/en-us/articles/115001799006-Mass-Deployment-with-Preconfigured-Settings-for-Mac) and [Windows](https://support.zoom.us/hc/en-us/articles/201362163). + +Example +----- +```ruby + # Disable activating your webcam when joining meetings. node.default['cpe_zoom']['ZDisableVideo'] = true +``` diff --git a/chef/cookbooks/cpe_zoom/metadata.rb b/chef/cookbooks/cpe_zoom/metadata.rb index 79cccd9..8a751a0 100644 --- a/chef/cookbooks/cpe_zoom/metadata.rb +++ b/chef/cookbooks/cpe_zoom/metadata.rb @@ -7,5 +7,3 @@ chef_version '>= 14.14' depends 'cpe_profiles' -depends 'cpe_utils' -depends 'uber_helpers' diff --git a/chef/cookbooks/cpe_zoom/resources/cpe_zoom.rb b/chef/cookbooks/cpe_zoom/resources/cpe_zoom.rb index a1b9085..ec4c187 100644 --- a/chef/cookbooks/cpe_zoom/resources/cpe_zoom.rb +++ b/chef/cookbooks/cpe_zoom/resources/cpe_zoom.rb @@ -2,8 +2,6 @@ # Cookbook:: cpe_zoom # Resources:: cpe_zoom # -# vim: syntax=ruby:expandtab:shiftwidth=2:softtabstop=2:tabstop=2 -# # Copyright:: (c) 2019-present, Uber Technologies, Inc. # All rights reserved. # @@ -17,15 +15,96 @@ default_action :run -# Enforce Zoom Settings -action :run do - zoom_prefs = node['cpe_zoom'].compact - unless zoom_prefs.empty? - zoom_prefs.each_key do |key| - next if zoom_prefs[key].nil? +action_class do + WINDOWS_GENERAL_SETTINGS_MAP = { + 'ZAutoSSOLogin' => 'ForceLoginWithSSO', + 'ZSSOHost' => 'ForceSSOURL', + 'ZAutoUpdate' => 'EnableClientAutoUpdate', + 'disableloginwithemail' => 'DisableLoginWithEmail', + 'nofacebook' => 'DisableFacebookLogin', + 'nogoogle' => 'DisableGoogleLogin', + }.freeze + + WINDOWS_CHAT_SETTINGS_MAP = { + 'DisableLinkPreviewInChat' => 'DisableLinkPreviewInChat', + }.freeze + + WINDOWS_IGNORABLE_SETTINGS_MAP = [ + 'LastLoginType', + 'forcessourl', # ZSSOHost is already mapped to ForceSSOURL + ].freeze + + def zoom_prefs + node['cpe_zoom'].compact + end + + def convert_to_registry_key(value) + if value == true + return { :data => 1, :type => :dword } + elsif value == false + return { :data => 0, :type => :dword } + else + return { :data => value.to_s, :type => :string } + end + end + + def configure_windows + zoom_settings = {} + zoom_prefs.each do |key, value| + next if WINDOWS_IGNORABLE_SETTINGS_MAP.include?(key) # Skippable preferences on Windows + + preference = WINDOWS_CHAT_SETTINGS_MAP[key] + if preference.nil? # If the preference isn't in WINDOWS_CHAT_SETTINGS_MAP, set General path. + zoom_settings[WINDOWS_GENERAL_SETTINGS_MAP.fetch(key, key)] = { + :path => 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Zoom\Zoom Meetings\General', + :name => WINDOWS_GENERAL_SETTINGS_MAP.fetch(key, key), + }.merge(convert_to_registry_key(value)) + else + zoom_settings[preference] = { + :path => 'HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Zoom\Zoom Meetings\chat', + :name => key, + }.merge(convert_to_registry_key(value)) + end + end - # Zoom doesn't use profiles atm. Chef 14+ - if node.at_least_chef14? + unless zoom_settings.empty? + zoom_settings.each do |_name, reg_key| + registry_key reg_key[:path] do + values [{ :name => reg_key[:name], :type => reg_key[:type], :data => reg_key[:data] }] + recursive true + action :create + end + end + end + end + + def configure_macos + prefix = node['cpe_profiles']['prefix'] + organization = node['organization'] || 'Uber' + zoom_profile = { + 'PayloadIdentifier' => "#{prefix}.zoom", + 'PayloadRemovalDisallowed' => true, + 'PayloadScope' => 'System', + 'PayloadType' => 'Configuration', + 'PayloadUUID' => 'B1B0DEED-DC7C-4122-912F-A22F660DF53D', + 'PayloadOrganization' => organization, + 'PayloadVersion' => 1, + 'PayloadDisplayName' => 'Zoom', + 'PayloadContent' => [], + } + unless zoom_prefs.empty? + zoom_profile['PayloadContent'].push( + 'PayloadType' => 'us.zoom.config', + 'PayloadVersion' => 1, + 'PayloadIdentifier' => "#{prefix}.zoom", + 'PayloadUUID' => 'B976C3E1-B59D-4060-80DA-13A42270D1E7', + 'PayloadEnabled' => true, + 'PayloadDisplayName' => 'Zoom', + ) + zoom_prefs.each_key do |key| + next if zoom_prefs[key].nil? + zoom_profile['PayloadContent'][0][key] = zoom_prefs[key] + # Double tap the preferences since Zoom didn't use profiles at one point. Requires Chef 14 or newer macos_userdefaults "Configure us.zoom.config - #{key}" do domain '/Library/Preferences/us.zoom.config' key key @@ -33,5 +112,18 @@ end end end + + node.default['cpe_profiles']["#{prefix}.zoom"] = zoom_profile + end +end + +# Enforce Zoom Settings +action :run do + return if zoom_prefs.empty? + + if macos? + configure_macos + elsif windows? + configure_windows end end diff --git a/opensource_links.md b/opensource_links.md index 1d4824e..fe453c8 100644 --- a/opensource_links.md +++ b/opensource_links.md @@ -1,11 +1,12 @@ Chef API Cookbook Repos -- -* [Facebook](https://github.com/facebook/IT-CPE/tree/master/chef/cookbooks) +* [Facebook](https://github.com/facebook/IT-CPE/tree/main/itchef/cookbooks) +* [Gusto](https://github.com/Gusto/it-cpe-opensource/tree/main/chef) * [Pinterest](https://github.com/pinterest/it-cpe-cookbooks) -* [Uber](https://github.com/uber/cpe-chef-cookbooks) +* [Uber](https://github.com/uber/client-platform-engineering) -Opensource Projects +Open source Projects -- * [Crypt](https://github.com/grahamgilbert/crypt) * [Crypt-Server](https://github.com/grahamgilbert/Crypt-Server)