├── LICENSE ├── README.md └── src ├── chef-repo ├── cookbooks │ └── custom-ssh-banner │ │ ├── CHANGELOG.md │ │ ├── README.md │ │ ├── metadata.rb │ │ └── recipes │ │ └── default.rb └── roles │ └── base-role.json └── chef-server └── oracle-ccs-deploy-chef.py /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015 Oracle and/or its affiliates. 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Compute Cloud Service Demos 2 | ===== 3 | This project contains automation samples for [Oracle Compute Cloud Service](https://cloud.oracle.com/compute) using [Chef](https://www.chef.io). It is used by tutorial [Deploying Chef Server on Oracle Compute Cloud Service Instances](https://apexapps.oracle.com/pls/apex/f?p=44785:24:::NO::P24_CONTENT_ID,P24_PREV_PAGE:11587,2). This tutorial will show you how to install a Chef server on an Oracle Compute Cloud Service instance or virtual machine. You will use the Chef server to automate deployment and configuration of different products on Oracle Compute Cloud Service instances. 4 | 5 | For other tutorials on Compute Cloud Service, visit the [Oracle Learning Library](https://apexapps.oracle.com/pls/apex/f?p=44785:141:::::P141_PAGE_ID,P141_SECTION_ID:379,2909). 6 | 7 | ## License 8 | Licensed under the Apache License, Version 2.0 (the "License"); 9 | you may not use this file except in compliance with the License. 10 | You may obtain a copy of the License at 11 | 12 | http://www.apache.org/licenses/LICENSE-2.0 13 | 14 | Unless required by applicable law or agreed to in writing, software 15 | distributed under the License is distributed on an "AS IS" BASIS, 16 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | See the License for the specific language governing permissions and 18 | limitations under the License. 19 | 20 | ## Copyright 21 | Copyright (c) 2015-2016 Oracle and/or its affiliates. All rights reserved. 22 | -------------------------------------------------------------------------------- /src/chef-repo/cookbooks/custom-ssh-banner/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | custom-ssh-banner CHANGELOG 2 | =========================== 3 | 4 | This file is used to list changes made in each version of the custom-ssh-banner cookbook. 5 | 6 | 0.1.0 7 | ----- 8 | - Eder Zechim - Initial release of custom-ssh-banner 9 | 10 | -------------------------------------------------------------------------------- /src/chef-repo/cookbooks/custom-ssh-banner/README.md: -------------------------------------------------------------------------------- 1 | custom-ssh-banner Cookbook 2 | ========================== 3 | This cookbook creates a /etc/custom-ssh-banner file with the following message: 4 | ``` 5 | This banner was brought to you by Chef using custom-ssh-banner. 6 | ``` 7 | It also creates a /etc/profile.d/custom-ssh-banner.sh to print the above message on login. 8 | 9 | Testing 10 | ------- 11 | After applying your role to your node, ssh to it and verify the login message. 12 | 13 | Before applying this cookbook: 14 | ```bash 15 | ssh opc@your.ccs.node 16 | Authorized uses only. All activity may be monitored and reported. 17 | -bash-4.1$ 18 | ``` 19 | 20 | After applying this cookbook: 21 | ```bash 22 | ssh opc@your.ccs.node 23 | Authorized uses only. All activity may be monitored and reported. 24 | This banner was brought to you by Chef using custom-ssh-banner. 25 | -bash-4.1$ 26 | ``` 27 | 28 | License and Authors 29 | ------------------- 30 | Copyright 2015 Oracle and/or its affiliates. 31 | 32 | Licensed under the Apache License, Version 2.0 (the "License"); 33 | you may not use this file except in compliance with the License. 34 | You may obtain a copy of the License at 35 | 36 | http://www.apache.org/licenses/LICENSE-2.0 37 | 38 | Unless required by applicable law or agreed to in writing, software 39 | distributed under the License is distributed on an "AS IS" BASIS, 40 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 41 | See the License for the specific language governing permissions and 42 | limitations under the License. 43 | 44 | -------------------------------------------------------------------------------- /src/chef-repo/cookbooks/custom-ssh-banner/metadata.rb: -------------------------------------------------------------------------------- 1 | name 'custom-ssh-banner' 2 | maintainer 'Oracle' 3 | maintainer_email 'no-reply@oracle.com' 4 | license 'Apache 2.0' 5 | description 'Installs/Configures custom-ssh-banner via /etc/issue.net' 6 | long_description IO.read(File.join(File.dirname(__FILE__), 'README.md')) 7 | version '0.1.0' 8 | -------------------------------------------------------------------------------- /src/chef-repo/cookbooks/custom-ssh-banner/recipes/default.rb: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | # 3 | # Cookbook Name:: custom-ssh-banner 4 | # Recipe:: default 5 | # 6 | # Copyright 2015 Oracle and/or its affiliates. 7 | # 8 | # Licensed under the Apache License, Version 2.0 (the "License"); 9 | # you may not use this file except in compliance with the License. 10 | # You may obtain a copy of the License at 11 | # 12 | # http://www.apache.org/licenses/LICENSE-2.0 13 | # 14 | # Unless required by applicable law or agreed to in writing, software 15 | # distributed under the License is distributed on an "AS IS" BASIS, 16 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17 | # See the License for the specific language governing permissions and 18 | # limitations under the License. 19 | # 20 | log "Starting custom-ssh-banner recipe..." 21 | 22 | software_repo = "https://#{URI(Chef::Config[:chef_server_url]).host}:#{URI(Chef::Config[:chef_server_url]).port}/files" 23 | 24 | remote_file '/etc/custom-ssh-banner' do 25 | source "#{software_repo}/custom-ssh-banner.txt" 26 | end 27 | 28 | remote_file '/etc/profile.d/custom-ssh-banner.sh' do 29 | mode '0755' 30 | source "#{software_repo}/custom-ssh-banner.sh" 31 | end 32 | -------------------------------------------------------------------------------- /src/chef-repo/roles/base-role.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "base-role", 3 | "chef_type": "role", 4 | "json_class": "Chef::Role", 5 | "description": "A role with test cookbooks for CCS Demo", 6 | "run_list": [ 7 | "recipe[custom-ssh-banner]" 8 | ] 9 | } 10 | -------------------------------------------------------------------------------- /src/chef-server/oracle-ccs-deploy-chef.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | ################################################################################ 3 | ## Copyright 2015 Oracle and/or its affiliates. 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 | import sys 18 | import logging 19 | import os 20 | import shlex 21 | import subprocess 22 | import hashlib 23 | import getopt 24 | import getpass 25 | 26 | SCRIPT_NAME = 'oracle-ccs-deploy-chef.py' 27 | VERSION = '1.0.0.1 ' 28 | RELEASE_DATE = '04-Jun-2015 ' 29 | # Configure logger 30 | log = logging.getLogger('') 31 | log.setLevel(logging.DEBUG) 32 | logFormatter = logging.Formatter('[%(asctime)s] %(levelname)s: %(message)s') 33 | 34 | flog = logging.FileHandler("." + SCRIPT_NAME[:-3] + ".log") 35 | flog.setLevel(logging.DEBUG) 36 | flog.setFormatter(logFormatter) 37 | log.addHandler(flog) 38 | 39 | clog = logging.StreamHandler() 40 | clog.setLevel(logging.INFO) 41 | clog.setFormatter(logFormatter) 42 | log.addHandler(clog) 43 | 44 | # 45 | # Package list 46 | PACKAGE_LIST = ["chef-server-core-12.0.8-1.el6.x86_64.rpm,https://packages.chef.io/stable/el/6/chef-server-core-12.0.8-1.el6.x86_64.rpm,828b4f87763b93063028c41f88c72d20f22bb2c1", 47 | "chef-12.3.0-1.el6.x86_64.rpm,https://packages.chef.io/stable/el/6/chef-12.3.0-1.el6.x86_64.rpm,b92e7b8a61ad17909b554cc120680f73d186e96f", 48 | ] 49 | # 50 | # Chef Server defaults 51 | USERNAME="admin" 52 | EMAIL="no-replies@oracle.com" 53 | ORG="ccs-demo" 54 | ORGNAME="Oracle Compute Cloud Services Demo" 55 | 56 | # 57 | # Usage 58 | def usage(): 59 | print ('Usage: ') 60 | print ('./' + SCRIPT_NAME) 61 | print ('') 62 | print ('Optional Parameters') 63 | print (' --username : Defines the Chef Server administrator user. Defaults to '+ USERNAME +'.') 64 | print (' --email : Defines the Chef Server administrator user e-mail. Defaults to '+ EMAIL +'.') 65 | print (' --org : Defines the Chef Server default organization. Defaults to '+ ORG +'.') 66 | print (' --orgname : Defines the Chef Server default organization description. Defaults to '+ ORGNAME +'.') 67 | print (' --debug : Prints debug output during execution.') 68 | print (' --version : Prints script version information.') 69 | 70 | # 71 | # Run command 72 | def runCommand(command): 73 | # log.debug('runCommand() called with arguments: cmd: '+ command) 74 | cmd = shlex.split(command) 75 | p = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True) 76 | stdout, stderr = p.communicate() 77 | out = stdout.splitlines() 78 | err = stderr.splitlines() 79 | log.debug('STDOUT: '+ '\n'.join(out)) 80 | log.debug('STDERR: '+ '\n'.join(err)) 81 | return p.returncode, out, err 82 | 83 | # 84 | # Download files 85 | def downloadFile(filename, url, sha1): 86 | log.debug('downloadFile() called with arguments: filename: ' + filename +', url: ' + url) 87 | rc, out, err = runCommand('curl -L --silent --connect-timeout 2 --output /tmp/'+ filename +' --write-out "%{http_code}" '+ url) 88 | if rc != 0 or out[0] != '200': 89 | log.error('Failed to download '+ url) 90 | log.error('HTTP code: '+ out[0] +', Return code: '+ str(rc)) 91 | sys.exit(0) 92 | # 93 | # Install RPM 94 | def installRPM(rpm_string): 95 | rpm, url, sha1 = rpm_string.split(',') 96 | log.debug('Checking if '+ rpm[:-4] +' is installed.') 97 | rc, out, err = runCommand('yum list --disablerepo=* '+ rpm[:-4]) 98 | if rc == 0: 99 | log.error(' '+ rpm[:-3] +' already installed. Aborting...') 100 | sys.exit(1) 101 | else: 102 | log.info(' Installing '+ rpm +'...') 103 | if not os.path.isfile('/tmp/'+ rpm +''): 104 | log.info(' local RPM not found on /tmp. Downloading it (be patient)...') 105 | downloadFile(rpm, url, sha1) 106 | hasher = hashlib.sha1() 107 | bin_file = open('/tmp/'+ rpm, 'r') 108 | while True: 109 | data = bin_file.read(4096) 110 | if not data: 111 | break 112 | hasher.update(data) 113 | filesha1 = hasher.hexdigest() 114 | if sha1 != filesha1: 115 | log.debug('Expected '+ sha1 +', calculated '+ filesha1) 116 | log.error('Failed to check SHA1. Please remove the /tmp/'+ rpm +' and try again') 117 | sys.exit(0) 118 | rc, out, err = runCommand('sudo yum localinstall -y --disablerepo=* /tmp/'+ rpm) 119 | if rc != 0: 120 | log.error('Chef Server installation FAILED!') 121 | log.error("\n".join(out)) 122 | sys.exit(1) 123 | log.info(' '+ rpm +' done.') 124 | 125 | # 126 | # Main 127 | def main(argv): 128 | log.info('Running '+ SCRIPT_NAME +' version '+ VERSION) 129 | global USERNAME 130 | global PASSWORD 131 | global EMAIL 132 | global ORG 133 | global ORGNAME 134 | # Handle arguments from command line 135 | options = 'u:p:e:o:n:dv' 136 | longOptions = ['username=','password=','email=','org=','orgname=','debug', 'version'] 137 | try: 138 | opts, args = getopt.getopt(argv, options, longOptions) 139 | except getopt.GetoptError: 140 | usage() 141 | sys.exit(2) 142 | for opt, arg in opts: 143 | if opt == '--username' or opt == '-u': 144 | USERNAME = arg 145 | elif opt == '--email' or opt == '-e': 146 | EMAIL = arg 147 | elif opt == '--org' or opt == '-o': 148 | ORG = arg 149 | elif opt == '--orgname' or opt == '-n': 150 | ORGNAME = arg 151 | elif opt == '--version' or opt == '-v': 152 | print(VERSION) 153 | sys.exit() 154 | elif opt == '--debug' or opt == '-d': 155 | clog.setLevel(logging.DEBUG) 156 | if sys.stdin.isatty(): 157 | PASSWORD = getpass.getpass("Chef administrator user (" + USERNAME + ") password: ") 158 | if len(PASSWORD) < 6 : 159 | log.error('Password must have at least 6 characters! Aborting...') 160 | sys.exit(1) 161 | REPASSWORD = getpass.getpass("Re-enter password: ") 162 | if PASSWORD != REPASSWORD: 163 | log.error("Password does not match! Aborting...") 164 | sys.exit(1) 165 | else: 166 | PASSWORD = sys.stdin.readline().rstrip() 167 | log.debug('Options: '+ USERNAME +', '+ EMAIL +', '+ ORG +', '+ ORGNAME) 168 | # Installs RPMs from PACKAGE_LIST 169 | for rpm_string in PACKAGE_LIST: 170 | installRPM(rpm_string) 171 | # Configures Chef Server 172 | # TODO: allow changes to these values via args 173 | hostname = os.popen('hostname -f').read()[:-1] 174 | linux_user = os.popen('whoami').read()[:-1] 175 | log.info(' Configuring Chef Server. This will take a few minutes, please be patient...') 176 | rc, out, err = runCommand("sudo chef-server-ctl reconfigure") 177 | if rc != 0: 178 | log.error('chef-server reconfigure failed: '+ '\n'.join(err)) 179 | log.error('Aborting...') 180 | sys.exit(1) 181 | rc, out, err = runCommand("mkdir -p /home/"+ linux_user +"/.chef/trusted_certs") 182 | if rc != 0: 183 | log.error('Unable to create /home/'+ linux_user +'/.chef/trusted_certs: '+ '\n'.join(err)) 184 | log.error('Aborting...') 185 | sys.exit(1) 186 | log.info(' Chef Server configured!') 187 | log.info(' Setup Chef Server...') 188 | rc, out, err = runCommand("sudo chef-server-ctl user-create "+ USERNAME +" Organization Administrator "+ EMAIL +" "+ PASSWORD +" --filename /home/"+ linux_user +"/.chef/"+ USERNAME +".pem") 189 | if rc != 0: 190 | log.error('chef user-create failed: '+ '\n'.join(err)) 191 | log.error('Aborting...') 192 | sys.exit(1) 193 | rc, out, err = runCommand("sudo chef-server-ctl org-create "+ ORG +" "+ ORGNAME +" --association_user "+ USERNAME +" --filename /home/"+ linux_user +"/.chef/"+ ORG +"-validator.pem") 194 | if rc != 0: 195 | log.error('chef org-create failed: '+ '\n'.join(err)) 196 | log.error('Aborting...') 197 | sys.exit(1) 198 | rc, out, err = runCommand("sudo cp /var/opt/opscode/nginx/ca/"+ hostname +".crt /home/"+ linux_user +"/.chef/trusted_certs") 199 | if rc != 0: 200 | log.error('Unable to copy '+ hostname +'.crt: '+ '\n'.join(err)) 201 | log.error('Aborting...') 202 | sys.exit(1) 203 | rc, out, err = runCommand("sudo chown -R "+ linux_user +" /home/"+ linux_user + "/.chef") 204 | if rc != 0: 205 | log.error('Unable to chown -R '+ linux_user +' /home/'+ linux_user + '/.chef: '+ '\n'.join(err)) 206 | log.error('Aborting...') 207 | sys.exit(1) 208 | # Configure knife 209 | config_file = "/home/"+ linux_user +"/.chef/knife.rb" 210 | config = open(config_file, 'w') 211 | config.write('current_dir = File.dirname(__FILE__)\n') 212 | config.write('log_level :info\n') 213 | config.write('log_location STDOUT\n') 214 | config.write('node_name "'+ USERNAME +'"\n') 215 | config.write('client_key "/home/'+ linux_user +'/.chef/'+ USERNAME +'.pem"\n') 216 | config.write('validation_client_name "'+ ORG +'-validator"\n') 217 | config.write('validation_key "/home/'+ linux_user +'/.chef/'+ ORG +'-validator.pem"\n') 218 | config.write('chef_server_url "https://'+ hostname +'/organizations/' + ORG +'"\n') 219 | config.write('cookbook_path "/home/'+ linux_user +'/chef-repo/cookbooks"\n') 220 | config.close() 221 | # Configure sofware repository 222 | config_file = "/tmp/nginx.conf" 223 | config = open(config_file, 'w') 224 | config.write('#\n') 225 | config.write('# Oracle Compute Cloud Demo Software Repository\n') 226 | config.write('#\n') 227 | config.write('') 228 | config.write('location /files {\n') 229 | config.write(' root /var/www;\n') 230 | config.write(' autoindex on;\n') 231 | config.write('}\n') 232 | config.close() 233 | rc, out, err = runCommand("sudo mv /tmp/nginx.conf /var/opt/opscode/nginx/etc/addon.d/50-software-repo_external.conf") 234 | rc, out, err = runCommand("sudo mkdir -p /var/www/files") 235 | rc, out, err = runCommand("sudo chmod 755 /var/www") 236 | rc, out, err = runCommand("sudo chmod 755 /var/www/files") 237 | # Create assets for sample cookbook 238 | config_file = "/tmp/custom-ssh-banner.txt" 239 | config = open(config_file, 'w') 240 | config.write('This banner was brought to you by Chef using custom-ssh-banner.\n') 241 | config.close() 242 | config_file = "/tmp/custom-ssh-banner.sh" 243 | config = open(config_file, 'w') 244 | config.write('cat /etc/custom-ssh-banner\n') 245 | config.close() 246 | runCommand("sudo mv /tmp/custom-ssh-banner.txt /var/www/files/custom-ssh-banner.txt") 247 | runCommand("sudo mv /tmp/custom-ssh-banner.sh /var/www/files/custom-ssh-banner.sh") 248 | rc, out, err = runCommand("sudo chown -R "+ linux_user +" /var/www/files") 249 | rc, out, err = runCommand("sudo chmod 644 /var/www/files/custom-ssh-banner.txt /var/www/files/custom-ssh-banner.sh") 250 | rc, out, err = runCommand("sudo chef-server-ctl restart nginx") 251 | if rc != 0: 252 | log.error('Unable to restart nginx after setting up our software repository.') 253 | log.error('Aborting...') 254 | sys.exit(1) 255 | log.info(' Chef Server setup done!') 256 | log.info('Chef Server configuration finshed successfully!') 257 | # 258 | # Main function to kick off processing 259 | if __name__ == '__main__': 260 | main(sys.argv[1:]) 261 | --------------------------------------------------------------------------------