├── .gitignore ├── CHANGELOG.md ├── LICENSE ├── README.md ├── examples └── install-installation-manager.yml └── library ├── ibmim.py ├── ibmim_installer.py ├── liberty_server.py ├── profile_dmgr.py ├── profile_liberty.py ├── profile_nodeagent.py ├── was_server.py └── wsadmin.py /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_store 2 | *.swp 3 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 1.0.2 2 | * Added some additional options 3 | * `acceptLicense` is now present on the cmd when updating packages 4 | * Improved some module outputting 5 | 6 | # 1.0.1 7 | * Merged ibmim and ibmwas modules to one module, ibmim. This new updated module can be used to install, uninstall and update all IBM products that can be used with Installation Manager. Not just WebSphere. Installing Installation Manager itself can be done using the ibmim_installer module 8 | 9 | # 1.0.0 10 | * Initial Version -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 amimof 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # README 2 | A set of Ansible modules that lets you manage IBM packages and WebSphere resources 3 | 4 | ## Getting started 5 | 6 | Copy the folder `library` in this repo to your playbook directory or to [`ANSIBLE_LIBRARY`](http://docs.ansible.com/ansible/latest/intro_configuration.html#library) 7 | ``` 8 | $ git clone https://github.com/amimof/ansible-websphere && cp -r ansible-websphere/library 9 | ``` 10 | 11 | ## Module Summary 12 | | Module | Description | 13 | |:-------|:------------| 14 | | ibmim_installer.py | Installs and uninstalls IBM Installation Manager. | 15 | | ibmim.py | Manage IBM Installation Manager packages. Currently supports Install/Uninstall and Update packages. | 16 | | profile_dmgr.py | Creates or removes a WebSphere Application Server Deployment Manager or Base profile. Requires a Network Deployment or Base installation. | 17 | | profile_nodeagent.py |Creates or removes a WebSphere Application Server Node Agent profile. Requires a Network Deployment installation. | 18 | | profile_liberty.py | Creates or removes a Liberty Profile server runtime | 19 | | server.py | Start or stops a WebSphere Application Server | 20 | | liberty_server.py | Start or stops a Liberty Profile server | 21 | 22 | ## Modules 23 | 24 | ### ibmim_installer.py 25 | This module installs or uninstalls IBM Installation Manager. 26 | 27 | #### Options 28 | | Parameter | Required | Default | Choices | Comments | 29 | |:---------|:--------|:---------|:---------|:---------| 30 | | state | false | present | present, absent | present=install, absent=uninstall | 31 | | src | false | N/A | N/A | Path to installation files for Installation Manager | 32 | | dest | false | /opt/IBM/InstallationManager | N/A | Path to desired installation directory of Installation Manager | 33 | | logdir | false | N/A | /tmp | Directory to save installation log file | 34 | | accessRights | false | admin | admin, nonAdmin | Using a root or a user installation | 35 | 36 | #### Example 37 | ```yaml 38 | - name: Install 39 | ibmim_installer: 40 | state: present 41 | src: /some/dir/install/ 42 | logdir: /tmp/im_install.log 43 | 44 | - name: Uninstall 45 | ibmim_installer: 46 | state: absent 47 | dest: /opt/IBM/InstallationManager 48 | ## 49 | ## Install IIM 50 | - name: IBM Installation Manager installed 51 | ibmim_installer: 52 | state: present 53 | src: /tmp/iimSrc/unpack 54 | dest: ~/IBM/InstallationManager 55 | accessRights: nonAdmin 56 | logdir: /tmp 57 | become_user: '{{ was_user }}' 58 | ## 59 | ## Un-Install IIM 60 | - name: IBM Installation Manager un-installed 61 | ibmim_installer: 62 | state: absent 63 | dest: ~/IBM/InstallationManager 64 | accessRights: nonAdmin 65 | logdir: /tmp 66 | become_user: '{{ was_user }}' 67 | ``` 68 | 69 | ### ibmim.py 70 | This module installs, uninstalls or updates IBM packages from local or remote repositories 71 | 72 | #### Options 73 | | Parameter | Required | Default | Choices | Comments | 74 | |:---------|:--------|:---------|:---------|:---------| 75 | | state | false | present | present, absent, latest | present=install,absent=uninstall or latest=update | 76 | | ibmim | false | /opt/IBM/InstallationManager | N/A | Path to installation directory of Installation Manager | 77 | | dest | false | N/A | N/A | Path to destination installation directory | 78 | | im_shared | false | N/A | N/A | Path to Installation Manager shared resources folder | 79 | | id | true | N/A | N/A | ID of the package which you want to install | 80 | | repositories | false | N/A | N/A | Comma separated list of repositories to use. May be a path, URL or both | 81 | | properties | false | N/A | N/A | Comma separated list of properties needed for package installation. In the format key1=value,key2=value | 82 | | install_fixes | false | none | N/A | Install fixes if available in the repositories | 83 | | connect_passport_advantage | false | N/A | N/A | Append the PassportAdvantage repository to the repository list | 84 | | log | false | N/A | N/A | Specify a log file that records the result of Installation Manager operations. | 85 | 86 | #### Example 87 | ```yaml 88 | - name: Install WebSphere Application Server Liberty v8 89 | ibmim: 90 | name: com.ibm.websphere.liberty.v85 91 | repositories: 92 | - http://was-repos/ 93 | 94 | - name: Uninstall WebSphere Application Server Liberty v8 95 | ibmim: 96 | name: com.ibm.websphere.liberty.v85 97 | state: absent 98 | 99 | - name: Update all packages 100 | ibmim: 101 | state: latest 102 | repositories: 103 | - http://was-repos/ 104 | ``` 105 | 106 | ### profile_dmgr.py 107 | This module creates or removes a WebSphere Application Server Deployment Manager profile. Requires a Network Deployment installation. 108 | 109 | #### Options 110 | | Parameter | Required | Default | Choices | Comments | 111 | |:---------|:--------|:---------|:---------|:---------| 112 | | state | true | present | present,absent | present=create,absent=remove | 113 | | wasdir | true | N/A | N/A | Path to installation location of WAS | 114 | | name | true | N/A | N/A | Name of the profile | 115 | | cell_name | true | N/A | N/A | Name of the cell | 116 | | host_name | true | N/A | N/A | Host Name | 117 | | node_name | true | N/A | N/A | Node name of this profile | 118 | | username | true | N/A | N/A | Administrative user name | 119 | | password | true | N/A | N/A | Administrative user password | 120 | | template | true | management | management,default | management=dmgr,default=base | 121 | 122 | #### Example 123 | ```yaml 124 | - name: Create 125 | profile_dmgr: 126 | state: present 127 | wasdir: /usr/local/WebSphere/AppServer/ 128 | name: dmgr 129 | cell_name: devCell 130 | host_name: localhost 131 | node_name: devcell-dmgr 132 | username: admin 133 | password: allyourbasearebelongtous 134 | 135 | - name: Remove 136 | profile_dmgr: 137 | state: absent 138 | wasdir: /usr/local/WebSphere/AppServer/ 139 | name: dmgr 140 | ``` 141 | 142 | ### profile_nodeagent.py 143 | This module creates or removes a WebSphere Application Server Node Agent profile. Requires a Network Deployment installation. 144 | 145 | #### Options 146 | | Parameter | Required | Default | Choices | Comments | 147 | |:---------|:--------|:---------|:---------|:---------| 148 | | state | true | present | present,absent | present=create,absent=remove | 149 | | wasdir | true | N/A | N/A | Path to installation location of WAS | 150 | | name | true | N/A | N/A | Name of the profile | 151 | | cell_name | true | N/A | N/A | Name of the cell | 152 | | host_name | true | N/A | N/A | Host Name | 153 | | node_name | true | N/A | N/A | Node name of this profile | 154 | | username | true | N/A | N/A | Administrative user name of the deployment manager | 155 | | password | true | N/A | N/A | Administrative user password of the deployment manager | 156 | | dmgr_host | true | N/A | N/A | Host name of the Deployment Manager | 157 | | dmgr_port | true | N/A | N/A | SOAP port number of the Deployment Manager | 158 | | federate | false | N/A | N/A | Wether the node should be federated to a cell. If true, cell name cannot be the same as the cell name of the deployment manager. | 159 | 160 | #### Example 161 | ```yaml 162 | - name: Create 163 | profile_nodeagent: 164 | state: present 165 | wasdir: /usr/local/WebSphere/AppServer/ 166 | name: nodeagent 167 | cell_name: devCellTmp 168 | host_name: localhost 169 | node_name: devcell-node1 170 | username: admin 171 | password: allyourbasearebelongtous 172 | dmgr_host: localhost 173 | dmgr_port: 8879 174 | federate: true 175 | 176 | - name: Remove 177 | profile_dmgr: 178 | state: absent 179 | wasdir: /usr/local/WebSphere/AppServer/ 180 | name: nodeagent 181 | ``` 182 | 183 | ### was_server.py 184 | This module start or stops a WebSphere Application Server 185 | 186 | #### Options 187 | | Parameter | Required | Default | Choices | Comments | 188 | |:---------|:--------|:---------|:---------|:---------| 189 | | state | true | started | started, stopped | N/A | 190 | | name | true | N/A | N/A | Name of the app server | 191 | | wasdir | true | N/A | N/A | Path to binary files of the application server | 192 | | username | true | N/A | N/A | Administrative user name | 193 | | password | true | N/A | N/A | Administrative user password | 194 | 195 | #### Example 196 | ```yaml 197 | - name: Start 198 | was_server: 199 | state: started 200 | wasdir: /usr/local/WebSphere/AppServer/ 201 | name: my-server-01 202 | 203 | - name: Stop 204 | was_server: 205 | state: stopped 206 | wasdir: /usr/local/WebSphere/AppServer/ 207 | name: my-server-01 208 | ``` 209 | 210 | ### liberty_server.py 211 | This module start or stops a Liberty Profile server 212 | 213 | #### Options 214 | | Parameter | Required | Default | Choices | Comments | 215 | |:---------|:--------|:---------|:---------|:---------| 216 | | state | true | started | started, stopped | N/A | 217 | | name | true | N/A | N/A | Name of the app server | 218 | | libertydir | true | N/A | N/A | Path to binary files of the application server | 219 | 220 | #### Example 221 | ```yaml 222 | - name: Start 223 | liberty_server: 224 | state: started 225 | libertydir: /usr/local/WebSphere/Liberty/ 226 | name: my-server-01 227 | 228 | - name: Stop 229 | liberty_server: 230 | state: stopped 231 | libertydir: /usr/local/WebSphere/Liberty/ 232 | name: my-server-01 233 | ``` 234 | 235 | ### profile_liberty.py 236 | This module creates or removes a Liberty Profile server runtime 237 | 238 | #### Options 239 | | Parameter | Required | Default | Choices | Comments | 240 | |:---------|:--------|:---------|:---------|:---------| 241 | | state | true | present | present,absent | present=create,absent=remove | 242 | | libertydir | true | N/A | N/A | Path to install location of Liberty Profile binaries | 243 | | name | true | N/A | N/A | Name of the server which is to be created/removed | 244 | 245 | #### Example 246 | ```yaml 247 | - name: Create 248 | profile_liberty: 249 | state: present 250 | libertydir: /usr/local/WebSphere/Liberty/ 251 | name: server01 252 | 253 | - name: Remove 254 | profile_liberty: 255 | state: absent 256 | libertydir: /usr/local/WebSphere/Liberty/ 257 | name: server01 258 | ``` 259 | -------------------------------------------------------------------------------- /examples/install-installation-manager.yml: -------------------------------------------------------------------------------- 1 | # 2 | # Downloads Installation Manager from an URL and installs it at a default location. 3 | # 4 | 5 | - hosts: localhost 6 | connection: local 7 | tasks: 8 | - name: Download installer zip 9 | get_url: 10 | url: http://myserver.domain.com/~ibmrepo/im/linux/agent.installer.linux.x86_64-latest.zip 11 | dest: /tmp/ 12 | 13 | - name: Create IM directory 14 | file: 15 | state: directory 16 | path: /tmp/im 17 | 18 | - name: Unarchive installer zip 19 | unarchive: 20 | src: /tmp/agent.installer.linux.x86_64-latest.zip 21 | dest: /tmp/im/ 22 | 23 | - name: Install Installation Manager 24 | ibmim_installer: 25 | src: /tmp/im/ -------------------------------------------------------------------------------- /library/ibmim.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) 2015 Amir Mofasser (@amimof) 4 | 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | ANSIBLE_METADATA = {'status': ['preview'], 8 | 'supported_by': 'community', 9 | 'metadata_version': '1.1'} 10 | 11 | DOCUMENTATION = ''' 12 | --- 13 | module: ibmim 14 | short_description: Manage IBM Installation Manager packages 15 | description: 16 | - This module can Install, Uninstall and Update IBM Installation Manager packages on a supported Linux distribution. 17 | - This module relies on 'imcl', the binary command line installed by the IM installer. You may use this module to install Installation Manager itself. 18 | version_added: "1.9.4" 19 | author: Amir Mofasser (@github) 20 | requirements: 21 | - IBM Installation Manager 22 | - Installation files on remote server or local directory 23 | options: 24 | id: 25 | description: The ID of the package which is to be installed 26 | aliases: 27 | - name 28 | ibmim: 29 | default: /opt/IBM/InstallationManager 30 | description: Path to installation directory of Installation Manager 31 | dest: 32 | description: Path to destination installation directory 33 | im_shared: 34 | description: Path to Installation Manager shared resources folder 35 | repositories: 36 | description: A list of repositories to use. May be a path, URL or both. 37 | type: list 38 | aliases: 39 | - repos 40 | preferences: 41 | type: list 42 | description: Specify a preference value or a comma-delimited list of preference values to be used 43 | properties: 44 | type: list 45 | description: Specify a preference value or a comma-delimited list of properties values to be used 46 | state: 47 | choices: 48 | - present 49 | - absent 50 | - latest 51 | default: present 52 | description: Install a package with 'present'. Uninstall a package with 'absent'. Update all packages with 'latest'. 53 | install_fixes: 54 | choices: 55 | - none 56 | - recommended 57 | - all 58 | default: none 59 | description: Install fixes if available in the repositories. 60 | connect_passport_advantage: 61 | default: false 62 | type: bool 63 | description: Append the PassportAdvantage repository to the repository list 64 | log: 65 | description: Specify a log file that records the result of Installation Manager operations. 66 | ''' 67 | 68 | EXAMPLES = ''' 69 | --- 70 | - name: Install WebSphere Application Server Liberty v8.5 71 | ibmim: 72 | name: com.ibm.websphere.liberty.v85 73 | repositories: 74 | - http://was-repos/ 75 | 76 | - name: Uninstall WebSphere Application Server Liberty v8.5 77 | ibmim: 78 | name: com.ibm.websphere.liberty.v85 79 | state: absent 80 | 81 | - name: Update all packages 82 | ibmim: 83 | state: latest 84 | repositories: 85 | - http://was-repos/ 86 | ''' 87 | 88 | import os 89 | import subprocess 90 | import platform 91 | import datetime 92 | import shutil 93 | import re 94 | 95 | from ansible.module_utils.basic import AnsibleModule 96 | 97 | class InstallationManager(): 98 | 99 | module = None 100 | module_facts = dict( 101 | installed = False, 102 | version = None, 103 | id = None, 104 | path = None, 105 | name = None, 106 | stdout = None, 107 | stderr = None 108 | ) 109 | 110 | def __init__(self): 111 | # Read arguments 112 | self.module = AnsibleModule( 113 | argument_spec = dict( 114 | 115 | # install/uninstall/updateAll 116 | state = dict(default='present', choices=['present', 'absent', 'latest']), 117 | 118 | # /opt/IBM/InstallationManager 119 | ibmim = dict(default='/opt/IBM/InstallationManager'), 120 | 121 | # Package ID 122 | id = dict(required=False, aliases=['name']), 123 | 124 | # -installationDirectory 125 | dest = dict(required=False), 126 | 127 | # -sharedResourcesDirectory 128 | im_shared = dict(required=False), 129 | 130 | # -repositories 131 | repositories = dict(required=False, type='list', aliases=['repos']), 132 | 133 | # -properties 134 | preferences = dict(required=False, type='list'), 135 | 136 | # -properties 137 | properties = dict(required=False, type='list'), 138 | 139 | # -connectPassportAdvantage 140 | connect_passport_advantage = dict(default=False, type='bool'), 141 | 142 | # -installFixes 143 | install_fixes = dict(default='none', choices=['none', 'recommended', 'all']), 144 | 145 | # -log 146 | log = dict(required=False) 147 | 148 | ), 149 | supports_check_mode = True 150 | ) 151 | 152 | def getItem(self, key): 153 | """ 154 | Returns an item at key from the global dict module_facts 155 | """ 156 | return self.module_facts[key] 157 | 158 | 159 | def isProvisioned(self, dest, packageId): 160 | """ 161 | Checks if package is already installed at dest 162 | :param dest: Destination installation directory of the product 163 | :return: True if already provisioned. False if not provisioned 164 | """ 165 | # If destination dir does not exists then its safe to assume that IM is not installed 166 | if dest: 167 | if not os.path.exists(dest): 168 | return False 169 | return self.getVersion(packageId)["installed"] 170 | 171 | 172 | def getVersion(self, packageId): 173 | 174 | child = subprocess.Popen( 175 | ["{0}/eclipse/tools/imcl " 176 | " listInstalledPackages " 177 | " -long".format(self.module.params['ibmim'])], 178 | shell=True, 179 | stdout=subprocess.PIPE, 180 | stderr=subprocess.PIPE 181 | ) 182 | 183 | stdout_value, stderr_value = child.communicate() 184 | 185 | # Store stdout and stderr 186 | self.module_facts["stdout"] = stdout_value 187 | self.module_facts["stderr"] = stderr_value 188 | 189 | if child.returncode != 0: 190 | self.module.fail_json( 191 | msg="Error getting installed version of package '{0}'".format(packageId), 192 | stdout=stdout_value 193 | ) 194 | 195 | for line in stdout_value.split(os.linesep): 196 | if packageId in line: 197 | linesplit = line.split(" : ") 198 | self.module_facts["installed"] = True 199 | self.module_facts["path"] = linesplit[0] 200 | self.module_facts["id"] = linesplit[1] 201 | self.module_facts["name"] = linesplit[2] 202 | self.module_facts["version"] = linesplit[3] 203 | break 204 | 205 | return self.module_facts 206 | 207 | def install(self, module_params): 208 | 209 | # Check mode on 210 | if self.module.check_mode: 211 | self.module.exit_json(msg="Package '{0}' is to be installed".format(module_params['id'])) 212 | 213 | # Check wether package is already installed 214 | if self.isProvisioned(module_params['dest'], module_params['id']): 215 | self.module.exit_json(changed=False, msg="Package '{0}' is already installed".format(module_params['id']), ansible_facts=self.module_facts) 216 | 217 | # Check if one of repositories and connectPassportAdvantage is provided 218 | if not module_params['repositories'] and not module_params['connect_passport_advantage']: 219 | self.module.fail_json(msg="One or more repositories are required when installing packages") 220 | 221 | cmd = ("{0}/eclipse/tools/imcl install {1} " 222 | "-repositories {2} " 223 | "-acceptLicense " 224 | "-stopBlockingProcesses ").format(module_params['ibmim'], module_params['id'], ",".join(module_params['repositories'])) 225 | 226 | if module_params['dest']: 227 | cmd = "{0} -installationDirectory {1} ".format(cmd, module_params['dest']) 228 | if module_params['im_shared']: 229 | cmd = "{0} -sharedResourcesDirectory {1} ".format(cmd, module_params['im_shared']) 230 | if module_params['properties']: 231 | cmd = "{0} -properties {1} ".format(cmd, ",".join(module_params['properties'])) 232 | if module_params['preferences']: 233 | cmd = "{0} -preferences {1} ".format(cmd, ",".join(module_params['preferences'])) 234 | if module_params['install_fixes']: 235 | cmd = "{0} -installFixes {1} ".format(cmd, module_params['install_fixes']) 236 | if module_params['connect_passport_advantage']: 237 | cmd = "{0} -connectPassportAdvantage ".format(cmd) 238 | if module_params['log']: 239 | cmd = "{0} -log {1} ".format(cmd, module_params['log']) 240 | 241 | child = subprocess.Popen( 242 | [cmd], 243 | shell=True, 244 | stdout=subprocess.PIPE, 245 | stderr=subprocess.PIPE 246 | ) 247 | 248 | stdout_value, stderr_value = child.communicate() 249 | if child.returncode != 0: 250 | self.module.fail_json( 251 | msg="Failed installing package '{0}'".format(module_params['id']), 252 | stdout=stdout_value, 253 | stderr=stderr_value 254 | ) 255 | 256 | # After install, get versionInfo so that we can show it to the user 257 | self.getVersion(module_params['id']) 258 | self.module.exit_json(changed=True, msg="Package '{0}' installed".format(module_params['id']), ansible_facts=self.module_facts) 259 | 260 | def uninstall(self, module_params): 261 | 262 | # CHeck mode on 263 | if self.module.check_mode: 264 | self.module.exit_json(changed=False, msg="Package '{0}' is to be uninstalled".format(module_params['id']), ansible_facts=self.module_facts) 265 | 266 | # Check wether package is installed 267 | if not self.isProvisioned(module_params['dest'], module_params['id']): 268 | self.module.exit_json(changed=False, msg="Package '{0}' is not installed".format(module_params['id']), ansible_facts=self.module_facts) 269 | 270 | cmd = "{0}/eclipse/tools/imcl uninstall {1} ".format(module_params['ibmim'], module_params['id']) 271 | 272 | if module_params['dest']: 273 | cmd = "{0} -installationDirectory {1} ".format(cmd, module_params['dest']) 274 | if module_params['preferences']: 275 | cmd = "{0} -preferences {1} ".format(cmd, ",".join(module_params['preferences'])) 276 | if module_params['properties']: 277 | cmd = "{0} -properties {1} ".format(cmd, ",".join(module_params['properties'])) 278 | if module_params['log']: 279 | cmd = "{0} -log {1} ".format(cmd, module_params['log']) 280 | 281 | child = subprocess.Popen( 282 | [cmd], 283 | shell=True, 284 | stdout=subprocess.PIPE, 285 | stderr=subprocess.PIPE 286 | ) 287 | stdout_value, stderr_value = child.communicate() 288 | if child.returncode != 0: 289 | self.module.fail_json(msg="Failed uninstalling package '{0}'".format(module_params['id'])) 290 | 291 | # Remove AppServer dir forcefully so that it doesn't prevents us from reinstalling. 292 | shutil.rmtree(module_params['dest'], ignore_errors=False, onerror=None) 293 | self.module.exit_json(changed=True, msg="Package '{0}' uninstalled".format(module_params['id']), ansible_facts=self.module_facts) 294 | 295 | def updateAll(self, module_params): 296 | 297 | # Check mode on 298 | if self.module.check_mode: 299 | self.module.exit_json(changed=False, msg="All installed packages are to be updated".format(module_params['id']), ansible_facts=self.module_facts) 300 | 301 | # Check if one of repositories and connectPassportAdvantage is provided 302 | if not module_params['repositories'] and not module_params['connect_passport_advantage']: 303 | self.module.fail_json(msg="One or more repositories are required when installing packages") 304 | 305 | cmd = ("{0}/eclipse/tools/imcl updateAll " 306 | "-acceptLicense -repositories {1}").format(module_params['ibmim'], ",".join(module_params['repositories'])) 307 | 308 | if module_params['preferences']: 309 | cmd = "{0} -preferences {1} ".format(cmd, ",".join(module_params['preferences'])) 310 | if module_params['properties']: 311 | cmd = "{0} -properties {1} ".format(cmd, ",".join(module_params['properties'])) 312 | if module_params['connect_passport_advantage']: 313 | cmd = "{0} -connectPassportAdvantage ".format(cmd) 314 | if module_params['install_fixes']: 315 | cmd = "{0} -installFixes {1} ".format(cmd, module_params['install_fixes']) 316 | if module_params['log']: 317 | cmd = "{0} -log {1} ".format(cmd, module_params['log']) 318 | 319 | child = subprocess.Popen( 320 | [cmd], 321 | shell=True, 322 | stdout=subprocess.PIPE, 323 | stderr=subprocess.PIPE 324 | ) 325 | stdout_value, stderr_value = child.communicate() 326 | 327 | if child.returncode != 0: 328 | self.module.fail_json(msg="Failed updating packages", stdout=stdout_value, stderr=stderr_value) 329 | 330 | self.module.exit_json(changed=True, msg="All packages updated", ansible_facts=self.module_facts) 331 | 332 | def main(self): 333 | 334 | # Check if paths are valid 335 | if not os.path.exists("{0}/eclipse".format(self.module.params['ibmim'])): 336 | self.module.fail_json( 337 | msg="IBM Installation Manager is not installed. Install it and try again.") 338 | 339 | # Install 340 | if self.module.params['state'] == 'present': 341 | self.install(self.module.params) 342 | 343 | # Uninstall 344 | if self.module.params['state'] == 'absent': 345 | self.uninstall(self.module.params) 346 | 347 | # Update everything 348 | if self.module.params['state'] == 'latest': 349 | self.updateAll(self.module.params) 350 | 351 | # import module snippets 352 | if __name__ == '__main__': 353 | im = InstallationManager() 354 | im.main() -------------------------------------------------------------------------------- /library/ibmim_installer.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) 2015 Amir Mofasser (@amimof) 4 | 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | DOCUMENTATION = """ 8 | module: ibmim_installer 9 | version_added: "1.9.4" 10 | short_description: Install/Uninstall IBM Installation Manager 11 | description: 12 | - Install/Uninstall IBM Installation Manager 13 | options: 14 | src: 15 | required: false 16 | description: Path to installation files for Installation Manager 17 | dest: 18 | required: false 19 | default: "/opt/IBM/InstallationManager" 20 | description: Path to desired installation directory of Installation Manager 21 | accessRights: 22 | required: false 23 | default: "admin" 24 | description: admin (root) or nonAdmin installation? 25 | logdir: 26 | required: false 27 | default: "/tmp/" 28 | description: Path and file name of installation log file 29 | state: 30 | required: false 31 | choices: [ present, absent ] 32 | default: "present" 33 | description: Whether Installation Manager should be installed or removed 34 | author: "Amir Mofasser (@amofasser)" 35 | """ 36 | 37 | EXAMPLES = """ 38 | - name: Install 39 | ibmim: 40 | state: present 41 | src: /some/dir/install/ 42 | logdir: /tmp/im_install.log 43 | 44 | - name: Uninstall 45 | ibmim: 46 | state: absent 47 | dest: /opt/IBM/InstallationManager 48 | """ 49 | 50 | import os 51 | import subprocess 52 | import platform 53 | import datetime 54 | import socket 55 | 56 | class InstallationManagerInstaller(): 57 | 58 | module = None 59 | module_facts = dict( 60 | im_version = None, 61 | im_internal_version = None, 62 | im_arch = None, 63 | im_header = None 64 | ) 65 | 66 | def __init__(self): 67 | # Read arguments 68 | self.module = AnsibleModule( 69 | argument_spec = dict( 70 | state = dict(default='present', choices=['present', 'absent']), 71 | src = dict(required=False), 72 | dest = dict(default="/opt/IBM/InstallationManager/"), 73 | accessRights = dict(default="admin", choices=['admin', 'nonAdmin']), 74 | logdir = dict(default="/tmp/") 75 | ), 76 | supports_check_mode=True 77 | ) 78 | 79 | 80 | def getItem(self, str): 81 | return self.module_facts[str] 82 | 83 | 84 | def isProvisioned(self, dest): 85 | """ 86 | Checks if Installation Manager is already installed at dest 87 | :param dest: Installation directory of Installation Manager 88 | :return: True if already provisioned. False if not provisioned 89 | """ 90 | # If destination dir does not exists then its safe to assume that IM is not installed 91 | if not os.path.exists(dest): 92 | print ("Path does not exist: '%s'" % (dest)) 93 | return False 94 | else: 95 | resultDict = self.getVersion(dest) 96 | print ("ResultDict is: '%s'" % (resultDict)) 97 | if "installed" in resultDict["im_header"]: 98 | return True 99 | print ("installed not found in ReturnDict") 100 | return False 101 | 102 | 103 | def getVersion(self, dest): 104 | """ 105 | Runs imcl with the version parameter and stores the output in a dict 106 | :param dest: Installation directory of Installation Manager 107 | :return: dict 108 | """ 109 | imclCmd = "{0}/eclipse/tools/imcl version".format(dest) 110 | print ("imclCmd is: '%s'" % (imclCmd)) 111 | child = subprocess.Popen( 112 | [ imclCmd ], 113 | shell=True, 114 | stdout=subprocess.PIPE, 115 | stderr=subprocess.PIPE 116 | ) 117 | stdout_value, stderr_value = child.communicate() 118 | stdout_value = repr(stdout_value) 119 | stderr_value = repr(stderr_value) 120 | 121 | try: 122 | self.module_facts["im_version"] = re.search("Version: ([0-9].*)", stdout_value).group(1) 123 | self.module_facts["im_internal_version"] = re.search("Internal Version: ([0-9].*)", stdout_value).group(1) 124 | self.module_facts["im_arch"] = re.search("Architecture: ([0-9].*-bit)", stdout_value).group(1) 125 | self.module_facts["im_header"] = re.search("Installation Manager.*", stdout_value).group(0) 126 | except AttributeError: 127 | self.module_facts["im_header"] = "**AttributeError**" 128 | ##### pass 129 | 130 | return self.module_facts 131 | 132 | 133 | def main(self): 134 | 135 | state = self.module.params['state'] 136 | src = self.module.params['src'] 137 | dest = self.module.params['dest'] 138 | logdir = self.module.params['logdir'] 139 | accessRights = self.module.params['accessRights'] 140 | ## 141 | ## If we have a nonAdmin Installation we might need to expand "~" for the 142 | ## users home directory 143 | dest = os.path.expanduser(dest) 144 | 145 | if state == 'present': 146 | 147 | if self.module.check_mode: 148 | self.module.exit_json(changed=False, msg="IBM IM where to be installed at {0}".format(dest)) 149 | 150 | # Check if IM is already installed 151 | if not self.isProvisioned(dest): 152 | 153 | # Check if paths are valid 154 | if not os.path.exists(src+"/install"): 155 | self.module.fail_json(msg=src+"/install not found") 156 | 157 | if not os.path.exists(logdir): 158 | if not os.listdir(logdir): 159 | os.makedirs(logdir) 160 | 161 | logfile = "{0}_ibmim_{1}.xml".format(platform.node(), datetime.datetime.now().strftime("%Y%m%d-%H%M%S")) 162 | installCmd = "{0}/tools/imcl install com.ibm.cic.agent -repositories {0}/repository.config -accessRights {1} -acceptLicense -log {2}/{3} -installationDirectory {4} -properties com.ibm.cic.common.core.preferences.preserveDownloadedArtifacts=true".format(src, accessRights, logdir, logfile, dest) 163 | print ("installCmd is: '%s'" % (installCmd)) 164 | child = subprocess.Popen( 165 | [ installCmd ], 166 | shell=True, 167 | stdout=subprocess.PIPE, 168 | stderr=subprocess.PIPE 169 | ) 170 | stdout_value, stderr_value = child.communicate() 171 | stdout_value = repr(stdout_value) 172 | stderr_value = repr(stderr_value) 173 | if child.returncode != 0: 174 | self.module.fail_json( 175 | msg="IBM IM installation failed", 176 | stderr=stderr_value, 177 | stdout=stdout_value, 178 | module_facts=self.module_facts 179 | ) 180 | 181 | # Module finished. Get version of IM after installation so that we can print it to the user 182 | self.getVersion(dest) 183 | self.module.exit_json( 184 | msg="IBM IM installed successfully", 185 | changed=True, 186 | stdout=stdout_value, 187 | stderr=stderr_value, 188 | module_facts=self.module_facts 189 | ) 190 | else: 191 | self.module.exit_json( 192 | changed=False, 193 | msg="IBM IM is already installed", 194 | module_facts=self.module_facts 195 | ) 196 | 197 | if state == 'absent': 198 | 199 | if self.module.check_mode: 200 | self.module.exit_json( 201 | changed=False, 202 | msg="IBM IM where to be uninstalled from {0}".format(dest), 203 | module_facts=self.module_facts 204 | ) 205 | 206 | # Check if IM is already installed 207 | if self.isProvisioned(dest): 208 | if (accessRights == 'admin'): 209 | uninstall_dir = "/var/ibm/InstallationManager/uninstall/uninstallc" 210 | else: 211 | uninstall_dir = os.path.expanduser("~/var/ibm/InstallationManager/uninstall/uninstallc") 212 | if not os.path.exists(uninstall_dir): 213 | self.module.fail_json(msg=uninstall_dir + " does not exist") 214 | child = subprocess.Popen( 215 | [uninstall_dir], 216 | shell=True, 217 | stdout=subprocess.PIPE, 218 | stderr=subprocess.PIPE 219 | ) 220 | stdout_value, stderr_value = child.communicate() 221 | stdout_value = repr(stdout_value) 222 | stderr_value = repr(stderr_value) 223 | if child.returncode != 0: 224 | self.module.fail_json( 225 | msg="IBM IM uninstall failed", 226 | stderr=stderr_value, 227 | stdout=stdout_value, 228 | module_facts=self.module_facts 229 | ) 230 | 231 | # Module finished 232 | self.module.exit_json( 233 | changed=True, 234 | msg="IBM IM uninstalled successfully", 235 | stdout=stdout_value, 236 | module_facts=self.module_facts 237 | ) 238 | else: 239 | self.module.exit_json( 240 | changed=False, 241 | msg="IBM IM is not installed", 242 | module_facts=self.module_facts 243 | ) 244 | 245 | # import module snippets 246 | from ansible.module_utils.basic import * 247 | if __name__ == '__main__': 248 | imi = InstallationManagerInstaller() 249 | imi.main() 250 | -------------------------------------------------------------------------------- /library/liberty_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) 2015 Amir Mofasser (@amimof) 4 | 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | import os 8 | import subprocess 9 | import platform 10 | import datetime 11 | 12 | def main(): 13 | 14 | # Read arguments 15 | module = AnsibleModule( 16 | argument_spec = dict( 17 | state = dict(default='started', choices=['started', 'stopped']), 18 | name = dict(required=True), 19 | libertydir = dict(required=True) 20 | ) 21 | ) 22 | 23 | state = module.params['state'] 24 | name = module.params['name'] 25 | libertydir = module.params['libertydir'] 26 | 27 | # Check if paths are valid 28 | if not os.path.exists(libertydir): 29 | module.fail_json(msg=libertydir+" does not exists") 30 | 31 | if state == 'stopped': 32 | child = subprocess.Popen([libertydir+"/bin/server stop " + name], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 33 | stdout_value, stderr_value = child.communicate() 34 | if child.returncode != 0: 35 | if not stderr_value.find("is not running") < 0: 36 | module.fail_json(msg=name + " stop failed", stdout=stdout_value, stderr=stderr_value) 37 | 38 | module.exit_json(changed=True, msg=name + " stopped successfully", stdout=stdout_value) 39 | 40 | if state == 'started': 41 | child = subprocess.Popen([libertydir+"/bin/server start " + name], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 42 | stdout_value, stderr_value = child.communicate() 43 | if child.returncode != 0: 44 | if not stderr_value.find("is running with process") < 0: 45 | module.fail_json(msg=name + " start failed", stdout=stdout_value, stderr=stderr_value) 46 | 47 | module.exit_json(changed=True, msg=name + " started successfully", stdout=stdout_value) 48 | 49 | 50 | # import module snippets 51 | from ansible.module_utils.basic import * 52 | if __name__ == '__main__': 53 | main() 54 | -------------------------------------------------------------------------------- /library/profile_dmgr.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) 2015 Amir Mofasser (@amimof) 4 | 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | DOCUMENTATION = """ 8 | module: profile_dmgr 9 | version_added: "1.9.4" 10 | short_description: Manage a WebSphere Application Server profile 11 | description: 12 | - Manage a WebSphere Application Server profile 13 | options: 14 | state: 15 | required: false 16 | choices: [ present, absent ] 17 | default: "present" 18 | description: 19 | - The profile should be created or removed 20 | name: 21 | required: true 22 | description: 23 | - Name of the profile 24 | wasdir: 25 | required: true 26 | description: 27 | - Path to installation folder of WAS 28 | cell_name: 29 | required: false 30 | description: 31 | - Cell Name 32 | host_name: 33 | required: false 34 | description: 35 | - Deployment manager host name 36 | node_name: 37 | required: false 38 | description: 39 | - Deployment manager node name 40 | password: 41 | required: false 42 | description: 43 | - Deployment manager password 44 | username: 45 | required: false 46 | description: 47 | - Deployment manager username 48 | state: 49 | required: false 50 | choices: [ present, absent ] 51 | default: "present" 52 | description: 53 | - The profile should be created or removed 54 | template: 55 | required: false 56 | choices: [ management, default ] 57 | default: "management" 58 | description: 59 | - The profile name which should be used (management = dmgr, default = base) 60 | author: "Amir Mofasser (@amofasser)" 61 | """ 62 | 63 | EXAMPLES = """ 64 | # Install: 65 | profile_dmgr: state=present wasdir=/usr/local/WebSphere name=dmgr cell_name=mycell host_name=dmgr.domain.com node_name=mycell-dmgr username=wasadmin password=waspass 66 | # Install (Base version): 67 | profile_dmgr: state=present wasdir=/usr/local/WebSphere name=dmgr cell_name=mycell host_name=dmgr.domain.com node_name=mycell-dmgr username=wasadmin password=waspass port=12000 profile=default 68 | # Uninstall 69 | profile_dmgr: state=absent wasdir=/usr/local/WebSphere name=dmgr 70 | """ 71 | 72 | import os 73 | import subprocess 74 | import platform 75 | import datetime 76 | import shutil 77 | 78 | def isProvisioned(dest, profileName): 79 | """ 80 | Runs manageprofiles.sh -listProfiles command and stores the output in a dict 81 | :param dest: WAS installation dir 82 | :param profilesName: Profile Name 83 | :return: boolean 84 | """ 85 | if not os.path.exists(dest): 86 | return False 87 | else: 88 | child = subprocess.Popen( 89 | ["{0}/bin/manageprofiles.sh -listProfiles".format(dest)], 90 | shell=True, 91 | stdout=subprocess.PIPE, 92 | stderr=subprocess.PIPE 93 | ) 94 | stdout_value, stderr_value = child.communicate() 95 | 96 | if profileName in stdout_value: 97 | return True 98 | return False 99 | 100 | 101 | def main(): 102 | 103 | # Read arguments 104 | module = AnsibleModule( 105 | argument_spec = dict( 106 | state = dict(default='present', choices=['present', 'absent']), 107 | wasdir = dict(required=True), 108 | name = dict(required=True), 109 | cell_name = dict(required=False), 110 | host_name = dict(required=False), 111 | node_name = dict(required=False), 112 | username = dict(required=False), 113 | password = dict(required=False), 114 | template = dict(default='management', choices=['management', 'default']) 115 | ) 116 | ) 117 | 118 | state = module.params['state'] 119 | wasdir = module.params['wasdir'] 120 | name = module.params['name'] 121 | cell_name = module.params['cell_name'] 122 | host_name = module.params['host_name'] 123 | node_name = module.params['node_name'] 124 | username = module.params['username'] 125 | password = module.params['password'] 126 | template = module.params['template'] 127 | 128 | # Check if paths are valid 129 | if not os.path.exists(wasdir): 130 | module.fail_json(msg=wasdir+" does not exists") 131 | 132 | # Create a profile 133 | if state == 'present': 134 | 135 | if module.check_mode: 136 | module.exit_json( 137 | changed=False, 138 | msg="Profile {0} is to be created".format(name) 139 | ) 140 | 141 | if not isProvisioned(wasdir, name): 142 | child = subprocess.Popen( 143 | ["{0}/bin/manageprofiles.sh -create " 144 | "-profileName {1} " 145 | "-profilePath {0}/profiles/{1} " 146 | "-templatePath {0}/profileTemplates/{8} " 147 | "-cellName {2} " 148 | "-hostName {3} " 149 | "-nodeName {4} " 150 | "-enableAdminSecurity true " 151 | "-adminUserName {5} " 152 | "-adminPassword {6} ".format(wasdir, name, cell_name, host_name, node_name, username, password, template)], 153 | shell=True, 154 | stdout=subprocess.PIPE, 155 | stderr=subprocess.PIPE 156 | ) 157 | stdout_value, stderr_value = child.communicate() 158 | if child.returncode != 0: 159 | module.fail_json( 160 | msg="Dmgr profile creation failed", 161 | stdout=stdout_value, 162 | stderr=stderr_value 163 | ) 164 | 165 | module.exit_json( 166 | changed=True, 167 | msg="profile {0} created successfully".format(name), 168 | stdout=stdout_value, 169 | stderr=stderr_value 170 | ) 171 | else: 172 | module.exit_json( 173 | changed=False, 174 | msg="profile {0} already exists".format(name) 175 | ) 176 | 177 | # Remove a profile 178 | if state == 'absent': 179 | 180 | if module.check_mode: 181 | module.exit_json( 182 | changed=False, 183 | msg="Profile {0} is to be removed".format(name) 184 | ) 185 | 186 | if isProvisioned(wasdir, name): 187 | 188 | child = subprocess.Popen( 189 | ["{0}/bin/manageprofiles.sh -delete " 190 | "-profileName {1}".format(wasdir, name)], 191 | shell=True, 192 | stdout=subprocess.PIPE, 193 | stderr=subprocess.PIPE 194 | ) 195 | stdout_value, stderr_value = child.communicate() 196 | if child.returncode != 0: 197 | # manageprofiles.sh -delete will fail if the profile does not exist. 198 | # But creation of a profile with the same name will also fail if 199 | # the directory is not empty. So we better remove the dir forcefully. 200 | if not stdout_value.find("INSTCONFFAILED") < 0: 201 | shutil.rmtree("{0}/profiles/{1}".format(wasdir, name), ignore_errors=False, onerror=None) 202 | else: 203 | module.fail_json( 204 | msg="Profile {0} removal failed".format(name), 205 | stdout=stdout_value, 206 | stderr=stderr_value 207 | ) 208 | 209 | module.exit_json( 210 | changed=True, 211 | msg="Profile {0} removed successfully".format(name), 212 | stdout=stdout_value, 213 | stderr=stderr_value 214 | ) 215 | else: 216 | module.exit_json( 217 | changed=False, 218 | msg="Profile {0} does not exist".format(name) 219 | ) 220 | 221 | 222 | # import module snippets 223 | from ansible.module_utils.basic import * 224 | if __name__ == '__main__': 225 | main() 226 | -------------------------------------------------------------------------------- /library/profile_liberty.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) 2015 Amir Mofasser (@amimof) 4 | 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | import os 8 | import subprocess 9 | 10 | def main(): 11 | 12 | # Read arguments 13 | module = AnsibleModule( 14 | argument_spec = dict( 15 | state = dict(default='present', choices=['present', 'absent']), 16 | libertydir = dict(required=True), 17 | name = dict(required=True), 18 | ) 19 | ) 20 | 21 | state = module.params['state'] 22 | libertydir = module.params['libertydir'] 23 | name = module.params['name'] 24 | 25 | # Check if paths are valid 26 | if not os.path.exists(libertydir): 27 | module.fail_json(msg=libertydir+" does not exists") 28 | 29 | # Create a profile 30 | if state == 'present': 31 | child = subprocess.Popen([libertydir+"/bin/server create " + name], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 32 | stdout_value, stderr_value = child.communicate() 33 | if child.returncode != 0: 34 | module.fail_json(msg="Failed to create liberty server " + name, stdout=stdout_value, stderr=stderr_value) 35 | 36 | module.exit_json(changed=True, msg=name + " server created successfully", stdout=stdout_value) 37 | 38 | # Remove a profile 39 | if state == 'absent': 40 | child = subprocess.Popen(["rm -rf " + libertydir+"/usr/servers/" + name], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 41 | stdout_value, stderr_value = child.communicate() 42 | if child.returncode != 0: 43 | module.fail_json(msg="Dmgr profile removal failed", stdout=stdout_value, stderr=stderr_value) 44 | 45 | module.exit_json(changed=True, msg=name + " server removed successfully", stdout=stdout_value, stderr=stderr_value) 46 | 47 | 48 | # import module snippets 49 | from ansible.module_utils.basic import * 50 | if __name__ == '__main__': 51 | main() 52 | -------------------------------------------------------------------------------- /library/profile_nodeagent.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) 2015 Amir Mofasser (@amimof) 4 | 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | DOCUMENTATION = """ 8 | module: profile_dmgr 9 | version_added: "1.9.4" 10 | short_description: Manage a WebSphere Application Server profile 11 | description: 12 | - Manage a WebSphere Application Server profile 13 | options: 14 | state: 15 | required: false 16 | choices: [ present, absent ] 17 | default: "present" 18 | description: 19 | - The profile should be created or removed 20 | name: 21 | required: true 22 | description: 23 | - Name of the profile 24 | wasdir: 25 | required: true 26 | description: 27 | - Path to installation folder of WAS 28 | cell_name: 29 | required: false 30 | description: 31 | - Cell Name 32 | host_name: 33 | required: false 34 | description: 35 | - Nodeagent host name 36 | password: 37 | required: false 38 | description: 39 | - Deployment manager password 40 | username: 41 | required: false 42 | description: 43 | - Deployment manager username 44 | dmgr_host: 45 | required: false 46 | description: 47 | - Deployment manager host name 48 | dmgr_port: 49 | required: false 50 | default: 8879 51 | description: 52 | - Deployment manager port 53 | federate: 54 | required: false 55 | choices: true, false 56 | description: 57 | - Wether to federate this node agent profile to a cell 58 | state: 59 | required: false 60 | choices: [ present, absent ] 61 | default: "present" 62 | description: 63 | - The profile should be created or removed 64 | author: "Amir Mofasser (@amofasser)" 65 | """ 66 | 67 | EXAMPLES = """ 68 | # Install: 69 | profile_nodeagent: state=present wasdir=/usr/local/WebSphere name=nodeagent cell_name=myNodeCell host_name=node.domain.com node_name=mycell-node1 username=wasadmin password=waspass dmgr_host=dmgr.domain.com dmgr_port=8879 federate=true 70 | # Uninstall 71 | profile_nodeagent: state=absent wasdir=/usr/local/WebSphere name=nodeagent 72 | """ 73 | 74 | import os 75 | import subprocess 76 | import platform 77 | import datetime 78 | import shutil 79 | 80 | def isProvisioned(dest, profileName): 81 | """ 82 | Runs manageprofiles.sh -listProfiles command nd stores the output in a dict 83 | :param dest: WAS installation dir 84 | :param profilesName: Profile Name 85 | :return: boolean 86 | """ 87 | if not os.path.exists(dest): 88 | return False 89 | else: 90 | child = subprocess.Popen( 91 | ["{0}/bin/manageprofiles.sh -listProfiles".format(dest)], 92 | shell=True, 93 | stdout=subprocess.PIPE, 94 | stderr=subprocess.PIPE 95 | ) 96 | stdout_value, stderr_value = child.communicate() 97 | 98 | if profileName in stdout_value: 99 | return True 100 | return False 101 | 102 | def main(): 103 | 104 | # Read arguments 105 | module = AnsibleModule( 106 | argument_spec = dict( 107 | state = dict(default='present', choices=['present', 'absent']), 108 | wasdir = dict(required=True), 109 | name = dict(required=True), 110 | cell_name = dict(required=False), 111 | host_name = dict(required=False), 112 | node_name = dict(required=False), 113 | username = dict(required=False), 114 | password = dict(required=False), 115 | dmgr_host = dict(required=False), 116 | dmgr_port = dict(required=False, default='8879'), 117 | federate = dict(required=False, type='bool') 118 | ) 119 | ) 120 | 121 | state = module.params['state'] 122 | wasdir = module.params['wasdir'] 123 | name = module.params['name'] 124 | cell_name = module.params['cell_name'] 125 | host_name = module.params['host_name'] 126 | node_name = module.params['node_name'] 127 | username = module.params['username'] 128 | password = module.params['password'] 129 | dmgr_host = module.params['dmgr_host'] 130 | dmgr_port = module.params['dmgr_port'] 131 | federate = module.params['federate'] 132 | 133 | # Check if paths are valid 134 | if not os.path.exists(wasdir): 135 | module.fail_json(msg=wasdir+" does not exists") 136 | 137 | # Create a profile 138 | if state == 'present': 139 | if module.check_mode: 140 | module.exit_json( 141 | changed=False, 142 | msg="Profile {0} is to be created".format(name) 143 | ) 144 | 145 | if not isProvisioned(wasdir, name): 146 | child = subprocess.Popen([ 147 | "{0}/bin/manageprofiles.sh -create " 148 | "-profileName {1} " 149 | "-profilePath {0}/profiles/{1} " 150 | "-templatePath {0}/profileTemplates/managed " 151 | "-cellName {2} " 152 | "-hostName {3} " 153 | "-nodeName {4} " 154 | "-enableAdminSecurity true " 155 | "-adminUserName {5} " 156 | "-adminPassword {6} ".format(wasdir, name, cell_name, host_name, node_name, username, password)], 157 | shell=True, 158 | stdout=subprocess.PIPE, 159 | stderr=subprocess.PIPE 160 | ) 161 | stdout_value, stderr_value = child.communicate() 162 | if child.returncode != 0: 163 | # Remove profile dir if creation fails so that it doesnt prevents us from retrying 164 | shutil.rmtree("{0}/profiles/{1}".format(wasdir, name), ignore_errors=False, onerror=None) 165 | 166 | module.fail_json( 167 | msg="Profile {0} creation failed".format(name), 168 | stdout=stdout_value, 169 | stderr=stderr_value 170 | ) 171 | 172 | if federate: 173 | # Federate the node 174 | child = subprocess.Popen([ 175 | "{0}/bin/addNode.sh {1} {2} " 176 | "-conntype SOAP " 177 | "-username {3} " 178 | "-password {4} " 179 | "-profileName {5} ".format(wasdir, dmgr_host, dmgr_port, username, password, name)], 180 | shell=True, 181 | stdout=subprocess.PIPE, 182 | stderr=subprocess.PIPE 183 | ) 184 | stdout_value, stderr_value = child.communicate() 185 | if child.returncode != 0: 186 | module.fail_json( 187 | msg="Profile {0} federation failed".format(name), 188 | stdout=stdout_value, 189 | stderr=stderr_value 190 | ) 191 | 192 | module.exit_json( 193 | changed=True, 194 | msg="Profile {0} created successfully", 195 | stdout=stdout_value 196 | ) 197 | 198 | else: 199 | module.exit_json( 200 | changed=False, 201 | msg="Profile {0} already exists".format(name) 202 | ) 203 | 204 | # Remove a profile 205 | if state == 'absent': 206 | if module.check_mode: 207 | module.exit_json( 208 | changed=False, 209 | msg="Profile {0} is to be removed".format(name) 210 | ) 211 | 212 | if isProvisioned(wasdir, name): 213 | 214 | child = subprocess.Popen([ 215 | "{0}/bin/manageprofiles.sh -delete " 216 | "-profileName {1} ".format(wasdir, name)], 217 | shell=True, 218 | stdout=subprocess.PIPE, 219 | stderr=subprocess.PIPE 220 | ) 221 | 222 | stdout_value, stderr_value = child.communicate() 223 | if child.returncode != 0: 224 | # manageprofiles.sh -delete will fail if the profile does not exist. 225 | # But creation of a profile with the same name will also fail if 226 | # the directory is not empty. So we better remove the dir forcefully. 227 | if not stdout_value.find("INSTCONFFAILED") < 0: 228 | shutil.rmtree(wasdir+"/profiles/"+name, ignore_errors=False, onerror=None) 229 | else: 230 | module.fail_json( 231 | msg="Profile {0} removal failed".format(name), 232 | stdout=stdout_value, 233 | stderr=stderr_value 234 | ) 235 | 236 | module.exit_json( 237 | changed=True, 238 | msg="Profile {0} removed successfully".format(name), 239 | stdout=stdout_value, 240 | stderr=stderr_value 241 | ) 242 | 243 | else: 244 | module.exit_json( 245 | changed=False, 246 | msg="Profile {0} does not exist".format(name) 247 | ) 248 | 249 | 250 | # import module snippets 251 | from ansible.module_utils.basic import * 252 | if __name__ == '__main__': 253 | main() 254 | -------------------------------------------------------------------------------- /library/was_server.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) 2015 Amir Mofasser (@amimof) 4 | 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | DOCUMENTATION = """ 8 | module: was_server 9 | version_added: "1.9.4" 10 | short_description: Stop/Start a WebSphere Application Server on a node 11 | description: 12 | - Stop/Start a WebSphere Application Server on a node 13 | options: 14 | state: 15 | required: false 16 | default: started 17 | description: 18 | - Whether WAS should be stopped or started 19 | name: 20 | required: true 21 | description: 22 | - Name of the application server 23 | node: 24 | required: true 25 | description: 26 | - Name of the node on which the application server is running on 27 | username: 28 | required: false 29 | description: 30 | - Administrative user username 31 | password: 32 | required: false 33 | description: 34 | - Administrative user password 35 | wasdir: 36 | required: true 37 | description: 38 | - Path to root of WAS installation directory 39 | wsadmin: 40 | required: false 41 | default: True 42 | description: 43 | - Use wsadmin to start/stop processes on a node (True) or the native startServer.sh/stopServer.sh on the node machine (False) 44 | author: "Amir Mofasser (@amofasser)" 45 | """ 46 | 47 | EXAMPLES = """ 48 | # Stop: 49 | - was_server: state=stopped name=AppSrv01 node=devnode wasdir=/usr/local/WebSphere/AppServer/ 50 | # Start: 51 | - was_server: state=started name=AppSrv01 node=devnode wasdir=/usr/local/WebSphere/AppServer/ 52 | """ 53 | 54 | import os 55 | import subprocess 56 | import platform 57 | import datetime 58 | 59 | was_dict = dict( 60 | was_name = None, 61 | was_state = 0, 62 | check_stdout = None 63 | ) 64 | 65 | def getItem(str): 66 | return was_dict[str] 67 | 68 | def getState(stdout_value, name, wsadmin): 69 | """ 70 | Does regexp on str to see if wsadmin is returning that the server is running 71 | :param str: stdout from AdminControl.startServer() 72 | :param name: name of the application server 73 | :return: dict 74 | """ 75 | 76 | was_dict["check_stdout"] = stdout_value 77 | was_dict["was_name"] = name 78 | 79 | try: 80 | if wsadmin: 81 | match = re.search("(Server \"{0}\" is already running)".format(name), stdout_value) 82 | if match: 83 | if match.group(0): 84 | was_dict["was_state"] = 1 85 | else: 86 | match = re.search("(An instance of the server may already be running: {0})".format(name), stdout_value) 87 | if match: 88 | if match.group(0): 89 | was_dict["was_state"] = 1 90 | 91 | except AttributeError: 92 | raise 93 | 94 | return was_dict 95 | 96 | 97 | def main(): 98 | 99 | # Read arguments 100 | module = AnsibleModule( 101 | argument_spec = dict( 102 | state = dict(default='started', choices=['started', 'stopped']), 103 | name = dict(required=True), 104 | node = dict(required=True), 105 | username = dict(required=False), 106 | password = dict(required=False), 107 | wasdir = dict(required=True), 108 | wsadmin = dict(default=True, type='bool') 109 | ), 110 | supports_check_mode = True 111 | ) 112 | 113 | state = module.params['state'] 114 | name = module.params['name'] 115 | node = module.params['node'] 116 | username = module.params['username'] 117 | password = module.params['password'] 118 | wasdir = module.params['wasdir'] 119 | wsadmin = module.params['wsadmin'] 120 | 121 | # Check if paths are valid 122 | if not os.path.exists(wasdir): 123 | module.fail_json(msg="{0} does not exists".format(wasdir)) 124 | 125 | cmd = "" 126 | credentials = "" 127 | if username is not None: 128 | credentials += " {0} -username {1} ".format(credentials, username) 129 | if password is not None: 130 | credentials += " {0} -password {1} ".format(credentials, password) 131 | 132 | # Start server 133 | if state == 'started': 134 | if wsadmin: 135 | cmd = "{0}/bin/wsadmin.sh -lang jython {1} -c \"AdminControl.startServer('{2}', '{3}')\"".format(wasdir, credentials, name, node) 136 | else: 137 | cmd = "{0}/bin/startServer.sh {1} {2}".format(wasdir, name, credentials) 138 | child = subprocess.Popen( 139 | [cmd], 140 | shell=True, 141 | stdout=subprocess.PIPE, 142 | stderr=subprocess.PIPE 143 | ) 144 | stdout_value, stderr_value = child.communicate() 145 | if child.returncode != 0: 146 | module.fail_json( 147 | changed=False, 148 | msg="Failed to start server {0} on node {1}".format(name, node), 149 | stdout=stdout_value, 150 | stderr=stderr_value 151 | ) 152 | 153 | if getState(stdout_value, name, wsadmin)["was_state"] == 1: 154 | module.exit_json( 155 | changed=False, 156 | msg="Server {0} is already started".format(name), 157 | stdout=stdout_value, 158 | stderr=stderr_value, 159 | was_name=getItem("was_name"), 160 | was_state=getItem("was_state"), 161 | check_stdout=getItem("check_stdout") 162 | ) 163 | else: 164 | module.exit_json( 165 | changed=False, 166 | msg="Server {0} successfully started".format(name), 167 | stdout=stdout_value, 168 | stderr=stderr_value, 169 | was_name=getItem("was_name"), 170 | was_state=getItem("was_state"), 171 | check_stdout=getItem("check_stdout") 172 | ) 173 | 174 | # Stop server 175 | if state == 'stopped': 176 | if wsadmin: 177 | cmd = "{0}/bin/wsadmin.sh -lang jython {1} -c \"AdminControl.stopServer('{2}', '{3}')\"".format(wasdir, credentials, name, node) 178 | else: 179 | cmd = "{0}/bin/stopServer.sh {1} {2}".format(wasdir, name, credentials) 180 | child = subprocess.Popen( 181 | [cmd], 182 | shell=True, 183 | stdout=subprocess.PIPE, 184 | stderr=subprocess.PIPE 185 | ) 186 | stdout_value, stderr_value = child.communicate() 187 | if child.returncode != 0: 188 | module.fail_json( 189 | changed=False, 190 | msg="Failed to stop server {0} on node {1}".format(name, node), 191 | stdout=stdout_value, 192 | stderr=stderr_value 193 | ) 194 | if getState(stdout_value, name, wsadmin)["was_state"] == 0: 195 | module.exit_json( 196 | changed=False, 197 | msg="Server {0} is already stopped".format(name), 198 | stdout=stdout_value, 199 | stderr=stderr_value, 200 | was_name=getItem("was_name"), 201 | was_state=getItem("was_state"), 202 | check_stdout=getItem("check_stdout") 203 | ) 204 | else: 205 | module.exit_json( 206 | changed=False, 207 | msg="Server {0} successfully stopped".format(name), 208 | stdout=stdout_value, 209 | stderr=stderr_value, 210 | was_name=getItem("was_name"), 211 | was_state=getItem("was_state"), 212 | check_stdout=getItem("check_stdout") 213 | ) 214 | 215 | # import module snippets 216 | from ansible.module_utils.basic import * 217 | if __name__ == '__main__': 218 | main() 219 | -------------------------------------------------------------------------------- /library/wsadmin.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | # Copyright (c) 2015 Amir Mofasser (@amimof) 4 | 5 | # GNU General Public License v3.0+ (see COPYING or https://www.gnu.org/licenses/gpl-3.0.txt) 6 | 7 | import os 8 | import subprocess 9 | import platform 10 | import datetime 11 | 12 | def main(): 13 | 14 | # Read arguments 15 | module = AnsibleModule( 16 | argument_spec = dict( 17 | params = dict(required=True), 18 | host = dict(default='localhost', required=False), 19 | port = dict(default='8879', required=False), 20 | username = dict(required=False), 21 | password = dict(required=False), 22 | script = dict(required=True) 23 | ) 24 | ) 25 | 26 | params = module.params['params'] 27 | host = module.params['host'] 28 | port = module.params['port'] 29 | username = module.params['username'] 30 | password = module.params['password'] 31 | script = module.params['script'] 32 | 33 | # Run wsadmin command server 34 | if state == 'stopped': 35 | child = subprocess.Popen([wasdir+"/bin/wsadmin.sh -lang jython -conntype SOAP -host "+host+" -port "+port+" -username " + username + " -password " + password " -f "+script+" "+params], shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 36 | stdout_value, stderr_value = child.communicate() 37 | if child.returncode != 0: 38 | module.fail_json(msg="Failed executing wsadmin script: " + ¨script, stdout=stdout_value, stderr=stderr_value) 39 | 40 | module.exit_json(changed=True, msg="Script executed successfully: " + script, stdout=stdout_value) 41 | 42 | 43 | # import module snippets 44 | from ansible.module_utils.basic import * 45 | if __name__ == '__main__': 46 | main() 47 | --------------------------------------------------------------------------------