mirror of
https://github.com/ansible/awx.git
synced 2026-02-04 19:18:13 -03:30
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
8a763d6cf8 | ||
|
|
1165dcfa07 | ||
|
|
f9928eef70 | ||
|
|
ee1d5e43b9 | ||
|
|
e94e79d57a | ||
|
|
f87a09c46a | ||
|
|
535e16c6cf | ||
|
|
5ae19fd9c2 | ||
|
|
7d5f6aa49d | ||
|
|
c0fc3a74ee | ||
|
|
22c831ff31 | ||
|
|
17dc6bf5a1 | ||
|
|
e7fb82ffe7 | ||
|
|
70ae546dee | ||
|
|
5d22fc2bd7 | ||
|
|
9033b3f2a5 | ||
|
|
de60165a49 | ||
|
|
b8c1724880 | ||
|
|
6baa2a109d | ||
|
|
7a5cfd05a3 | ||
|
|
b9279ebd5e | ||
|
|
49396178ca | ||
|
|
a4dfd96a8d | ||
|
|
40602875e0 | ||
|
|
d0572cf170 | ||
|
|
1edede213e | ||
|
|
e0c7a7bece | ||
|
|
640f9474fc | ||
|
|
29b90b700e | ||
|
|
f7c5289195 | ||
|
|
ee11341430 | ||
|
|
56263a5fea | ||
|
|
89e41f7524 | ||
|
|
3a8bacb8ef | ||
|
|
f328f8cad4 | ||
|
|
7752446067 | ||
|
|
96bc0f1578 | ||
|
|
9f25fdd079 | ||
|
|
7249b21214 | ||
|
|
2d642b95ae | ||
|
|
b94d5c7f20 | ||
|
|
02c23fc1c6 |
@@ -86,8 +86,8 @@ If you're not using Docker for Mac, or Docker for Windows, you may need, or choo
|
||||
|
||||
The AWX UI requires the following:
|
||||
|
||||
- Node 6.x LTS version
|
||||
- NPM 3.x LTS
|
||||
- Node 8.x LTS
|
||||
- NPM 6.x LTS
|
||||
|
||||
### Build the environment
|
||||
|
||||
@@ -329,7 +329,7 @@ We like to keep our commit history clean, and will require resubmission of pull
|
||||
|
||||
Sometimes it might take us a while to fully review your PR. We try to keep the `devel` branch in good working order, and so we review requests carefully. Please be patient.
|
||||
|
||||
All submitted PRs will have the linter and unit tests run against them, and the status reported in the PR.
|
||||
All submitted PRs will have the linter and unit tests run against them via Zuul, and the status reported in the PR.
|
||||
|
||||
## Reporting Issues
|
||||
|
||||
|
||||
@@ -38,7 +38,7 @@ Export all objects
|
||||
|
||||
Clean up remnants of the old AWX install:
|
||||
|
||||
```docker rm -f $(ps -aq)``` # remove all old awx containers
|
||||
```docker rm -f $(docker ps -aq)``` # remove all old awx containers
|
||||
|
||||
```make clean-ui``` # clean up ui artifacts
|
||||
|
||||
|
||||
18
Makefile
18
Makefile
@@ -355,7 +355,7 @@ check: flake8 pep8 # pyflakes pylint
|
||||
awx-link:
|
||||
cp -R /tmp/awx.egg-info /awx_devel/ || true
|
||||
sed -i "s/placeholder/$(shell git describe --long | sed 's/\./\\./g')/" /awx_devel/awx.egg-info/PKG-INFO
|
||||
cp /tmp/awx.egg-link /venv/awx/lib/python2.7/site-packages/awx.egg-link
|
||||
cp -f /tmp/awx.egg-link /venv/awx/lib/python2.7/site-packages/awx.egg-link
|
||||
|
||||
TEST_DIRS ?= awx/main/tests/unit awx/main/tests/functional awx/conf/tests awx/sso/tests
|
||||
|
||||
@@ -364,7 +364,7 @@ test:
|
||||
@if [ "$(VENV_BASE)" ]; then \
|
||||
. $(VENV_BASE)/awx/bin/activate; \
|
||||
fi; \
|
||||
py.test -n auto $(TEST_DIRS)
|
||||
PYTHONDONTWRITEBYTECODE=1 py.test -p no:cacheprovider -n auto $(TEST_DIRS)
|
||||
awx-manage check_migrations --dry-run --check -n 'vNNN_missing_migration_file'
|
||||
|
||||
test_combined: test_ansible test
|
||||
@@ -466,7 +466,7 @@ $(I18N_FLAG_FILE): $(UI_DEPS_FLAG_FILE)
|
||||
ui-deps: $(UI_DEPS_FLAG_FILE)
|
||||
|
||||
$(UI_DEPS_FLAG_FILE):
|
||||
$(NPM_BIN) --unsafe-perm --prefix awx/ui install awx/ui
|
||||
$(NPM_BIN) --unsafe-perm --prefix awx/ui install --no-save awx/ui
|
||||
touch $(UI_DEPS_FLAG_FILE)
|
||||
|
||||
ui-docker-machine: $(UI_DEPS_FLAG_FILE)
|
||||
@@ -564,11 +564,21 @@ docker-compose-cluster: docker-auth
|
||||
docker-compose-test: docker-auth
|
||||
cd tools && TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose run --rm --service-ports awx /bin/bash
|
||||
|
||||
docker-compose-runtest:
|
||||
cd tools && TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose run --user=$(shell id -u) --rm --service-ports awx /start_tests.sh
|
||||
|
||||
docker-compose-build-swagger:
|
||||
cd tools && TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose run --user=$(shell id -u) --rm --service-ports awx /start_tests.sh swagger
|
||||
|
||||
docker-compose-clean:
|
||||
cd tools && TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose run --rm -w /awx_devel --service-ports awx make clean
|
||||
cd tools && TAG=$(COMPOSE_TAG) DEV_DOCKER_TAG_BASE=$(DEV_DOCKER_TAG_BASE) docker-compose rm -sf
|
||||
|
||||
docker-compose-build: awx-devel-build
|
||||
|
||||
# Base development image build
|
||||
awx-devel-build:
|
||||
docker build -t ansible/awx_devel -f tools/docker-compose/Dockerfile .
|
||||
docker build -t ansible/awx_devel --build-arg UID=$(shell id -u) -f tools/docker-compose/Dockerfile .
|
||||
docker tag ansible/awx_devel $(DEV_DOCKER_TAG_BASE)/awx_devel:$(COMPOSE_TAG)
|
||||
#docker push $(DEV_DOCKER_TAG_BASE)/awx_devel:$(COMPOSE_TAG)
|
||||
|
||||
|
||||
@@ -19,7 +19,7 @@ import six
|
||||
from django.conf import settings
|
||||
from django.core.exceptions import FieldError, ObjectDoesNotExist
|
||||
from django.db.models import Q, Count
|
||||
from django.db import IntegrityError, transaction
|
||||
from django.db import IntegrityError, transaction, connection
|
||||
from django.shortcuts import get_object_or_404
|
||||
from django.utils.encoding import smart_text
|
||||
from django.utils.safestring import mark_safe
|
||||
|
||||
@@ -29,3 +29,11 @@ STANDARD_INVENTORY_UPDATE_ENV = {
|
||||
CAN_CANCEL = ('new', 'pending', 'waiting', 'running')
|
||||
ACTIVE_STATES = CAN_CANCEL
|
||||
CENSOR_VALUE = '************'
|
||||
ENV_BLACKLIST = frozenset((
|
||||
'VIRTUAL_ENV', 'PATH', 'PYTHONPATH', 'PROOT_TMP_DIR', 'JOB_ID',
|
||||
'INVENTORY_ID', 'INVENTORY_SOURCE_ID', 'INVENTORY_UPDATE_ID',
|
||||
'AD_HOC_COMMAND_ID', 'REST_API_URL', 'REST_API_TOKEN', 'MAX_EVENT_RES',
|
||||
'CALLBACK_QUEUE', 'CALLBACK_CONNECTION', 'CACHE',
|
||||
'JOB_CALLBACK_DEBUG', 'INVENTORY_HOSTVARS', 'FACT_QUEUE',
|
||||
'AWX_HOST', 'PROJECT_REVISION'
|
||||
))
|
||||
|
||||
@@ -46,7 +46,7 @@ from awx.main.utils.filters import SmartFilter
|
||||
from awx.main.utils.encryption import encrypt_value, decrypt_value, get_encryption_key
|
||||
from awx.main.validators import validate_ssh_private_key
|
||||
from awx.main.models.rbac import batch_role_ancestor_rebuilding, Role
|
||||
from awx.main.constants import CHOICES_PRIVILEGE_ESCALATION_METHODS
|
||||
from awx.main.constants import CHOICES_PRIVILEGE_ESCALATION_METHODS, ENV_BLACKLIST
|
||||
from awx.main import utils
|
||||
|
||||
|
||||
@@ -767,7 +767,12 @@ class CredentialTypeInjectorField(JSONSchemaField):
|
||||
# of underscores, digits, and alphabetics from the portable
|
||||
# character set. The first character of a name is not
|
||||
# a digit.
|
||||
'^[a-zA-Z_]+[a-zA-Z0-9_]*$': {'type': 'string'},
|
||||
'^[a-zA-Z_]+[a-zA-Z0-9_]*$': {
|
||||
'type': 'string',
|
||||
# The environment variable _value_ can be any ascii,
|
||||
# but pexpect will choke on any unicode
|
||||
'pattern': '^[\x00-\x7F]*$'
|
||||
},
|
||||
},
|
||||
'additionalProperties': False,
|
||||
},
|
||||
@@ -783,6 +788,19 @@ class CredentialTypeInjectorField(JSONSchemaField):
|
||||
'additionalProperties': False
|
||||
}
|
||||
|
||||
def validate_env_var_allowed(self, env_var):
|
||||
if env_var.startswith('ANSIBLE_'):
|
||||
raise django_exceptions.ValidationError(
|
||||
_('Environment variable {} may affect Ansible configuration so its '
|
||||
'use is not allowed in credentials.').format(env_var),
|
||||
code='invalid', params={'value': env_var},
|
||||
)
|
||||
if env_var in ENV_BLACKLIST:
|
||||
raise django_exceptions.ValidationError(
|
||||
_('Environment variable {} is blacklisted from use in credentials.').format(env_var),
|
||||
code='invalid', params={'value': env_var},
|
||||
)
|
||||
|
||||
def validate(self, value, model_instance):
|
||||
super(CredentialTypeInjectorField, self).validate(
|
||||
value, model_instance
|
||||
@@ -834,6 +852,9 @@ class CredentialTypeInjectorField(JSONSchemaField):
|
||||
setattr(valid_namespace['tower'].filename, template_name, 'EXAMPLE_FILENAME')
|
||||
|
||||
for type_, injector in value.items():
|
||||
if type_ == 'env':
|
||||
for key in injector.keys():
|
||||
self.validate_env_var_allowed(key)
|
||||
for key, tmpl in injector.items():
|
||||
try:
|
||||
Environment(
|
||||
|
||||
@@ -439,15 +439,6 @@ class CredentialType(CommonModelNameNotUnique):
|
||||
|
||||
defaults = OrderedDict()
|
||||
|
||||
ENV_BLACKLIST = set((
|
||||
'VIRTUAL_ENV', 'PATH', 'PYTHONPATH', 'PROOT_TMP_DIR', 'JOB_ID',
|
||||
'INVENTORY_ID', 'INVENTORY_SOURCE_ID', 'INVENTORY_UPDATE_ID',
|
||||
'AD_HOC_COMMAND_ID', 'REST_API_URL', 'REST_API_TOKEN', 'MAX_EVENT_RES',
|
||||
'CALLBACK_QUEUE', 'CALLBACK_CONNECTION', 'CACHE',
|
||||
'JOB_CALLBACK_DEBUG', 'INVENTORY_HOSTVARS', 'FACT_QUEUE',
|
||||
'AWX_HOST', 'PROJECT_REVISION'
|
||||
))
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
ordering = ('kind', 'name')
|
||||
@@ -648,8 +639,14 @@ class CredentialType(CommonModelNameNotUnique):
|
||||
file_label = file_label.split('.')[1]
|
||||
setattr(tower_namespace.filename, file_label, path)
|
||||
|
||||
injector_field = self._meta.get_field('injectors')
|
||||
for env_var, tmpl in self.injectors.get('env', {}).items():
|
||||
if env_var.startswith('ANSIBLE_') or env_var in self.ENV_BLACKLIST:
|
||||
try:
|
||||
injector_field.validate_env_var_allowed(env_var)
|
||||
except ValidationError as e:
|
||||
logger.error(six.text_type(
|
||||
'Ignoring prohibited env var {}, reason: {}'
|
||||
).format(env_var, e))
|
||||
continue
|
||||
env[env_var] = Template(tmpl).render(**namespace)
|
||||
safe_env[env_var] = Template(tmpl).render(**safe_namespace)
|
||||
|
||||
@@ -359,18 +359,17 @@ def test_create_with_valid_injectors(get, post, admin):
|
||||
},
|
||||
'injectors': {
|
||||
'env': {
|
||||
'ANSIBLE_MY_CLOUD_TOKEN': '{{api_token}}'
|
||||
'AWX_MY_CLOUD_TOKEN': '{{api_token}}'
|
||||
}
|
||||
}
|
||||
}, admin)
|
||||
assert response.status_code == 201
|
||||
}, admin, expect=201)
|
||||
|
||||
response = get(reverse('api:credential_type_list'), admin)
|
||||
assert response.data['count'] == 1
|
||||
injectors = response.data['results'][0]['injectors']
|
||||
assert len(injectors) == 1
|
||||
assert injectors['env'] == {
|
||||
'ANSIBLE_MY_CLOUD_TOKEN': '{{api_token}}'
|
||||
'AWX_MY_CLOUD_TOKEN': '{{api_token}}'
|
||||
}
|
||||
|
||||
|
||||
@@ -388,7 +387,7 @@ def test_create_with_undefined_template_variable_xfail(post, admin):
|
||||
}]
|
||||
},
|
||||
'injectors': {
|
||||
'env': {'ANSIBLE_MY_CLOUD_TOKEN': '{{api_tolkien}}'}
|
||||
'env': {'AWX_MY_CLOUD_TOKEN': '{{api_tolkien}}'}
|
||||
}
|
||||
}, admin)
|
||||
assert response.status_code == 400
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
import pytest
|
||||
import six
|
||||
|
||||
from django.core.exceptions import ValidationError
|
||||
from rest_framework.serializers import ValidationError as DRFValidationError
|
||||
@@ -123,6 +125,9 @@ def test_cred_type_input_schema_validity(input_, valid):
|
||||
({'env': {'AWX_SECRET_99': '{{awx_secret}}'}}, True),
|
||||
({'env': {'99': '{{awx_secret}}'}}, False),
|
||||
({'env': {'AWX_SECRET=': '{{awx_secret}}'}}, False),
|
||||
({'env': {'ANSIBLE_SETTING': '{{awx_secret}}'}}, False),
|
||||
({'env': {'DRAGON': u'🐉'}}, False),
|
||||
({'env': {u'🐉': 'DRAGON'}}, False),
|
||||
({'extra_vars': 123}, False),
|
||||
({'extra_vars': {}}, True),
|
||||
({'extra_vars': {'hostname': '{{host}}'}}, True),
|
||||
@@ -147,7 +152,8 @@ def test_cred_type_injectors_schema(injectors, valid):
|
||||
)
|
||||
field = CredentialType._meta.get_field('injectors')
|
||||
if valid is False:
|
||||
with pytest.raises(ValidationError):
|
||||
with pytest.raises(ValidationError, message=six.text_type(
|
||||
"Injector was supposed to throw a validation error, data: {}").format(injectors)):
|
||||
field.clean(injectors, type_)
|
||||
else:
|
||||
field.clean(injectors, type_)
|
||||
|
||||
177
awx/ui/README.md
177
awx/ui/README.md
@@ -1,46 +1,26 @@
|
||||
# AWX UI
|
||||
|
||||
## Requirements
|
||||
- node.js 8.x LTS
|
||||
- npm 5.x LTS
|
||||
- bzip2, gcc-c++, git, make
|
||||
|
||||
### Node / NPM
|
||||
## Development
|
||||
The API development server will need to be running. See [CONTRIBUTING.md](../../CONTRIBUTING.md).
|
||||
|
||||
AWX currently requires the 6.x LTS version of Node and NPM.
|
||||
```shell
|
||||
# Build ui for the devel environment - reachable at https://localhost:8043
|
||||
make ui-devel
|
||||
|
||||
macOS installer: [https://nodejs.org/dist/latest-v6.x/](https://nodejs.org/dist/latest-v6.x/)
|
||||
# Alternatively, start the ui development server. While running, the ui will be reachable
|
||||
# at https://localhost:3000 and updated automatically when code changes.
|
||||
make ui-docker
|
||||
|
||||
RHEL / CentOS / Fedora:
|
||||
|
||||
```
|
||||
$ curl --silent --location https://rpm.nodesource.com/setup_6.x | bash -
|
||||
$ yum install nodejs
|
||||
```
|
||||
|
||||
### Other Dependencies
|
||||
|
||||
On macOS, install the Command Line Tools:
|
||||
|
||||
```
|
||||
$ xcode-select --install
|
||||
```
|
||||
|
||||
RHEL / CentOS / Fedora:
|
||||
|
||||
```
|
||||
$ yum install bzip2 gcc-c++ git make
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
### Starting the UI
|
||||
|
||||
First, the AWX API will need to be running. See [CONTRIBUTING.md](../../CONTRIBUTING.md).
|
||||
|
||||
When using Docker for Mac or native Docker on Linux:
|
||||
|
||||
```
|
||||
$ make ui-docker
|
||||
# When using docker machine, use this command to start the ui development server instead.
|
||||
DOCKER_MACHINE_NAME=default make ui-docker-machine
|
||||
```
|
||||
|
||||
## Development with an external server
|
||||
If you normally run awx on an external host/server (in this example, `awx.local`),
|
||||
you'll need to reconfigure the webpack proxy slightly for `make ui-docker` to
|
||||
work:
|
||||
@@ -63,119 +43,32 @@ awx/ui/build/webpack.watch.js
|
||||
},
|
||||
```
|
||||
|
||||
When using Docker Machine:
|
||||
## Testing
|
||||
```shell
|
||||
# run linters
|
||||
make jshint
|
||||
|
||||
```
|
||||
$ DOCKER_MACHINE_NAME=default make ui-docker-machine
|
||||
# run unit tests
|
||||
make ui-test-ci
|
||||
|
||||
# run e2e tests - see awx/ui/test/e2e for more information
|
||||
npm --prefix awx/ui run e2e
|
||||
```
|
||||
|
||||
### Running Tests
|
||||
## Adding dependencies
|
||||
```shell
|
||||
# add a development or build dependency
|
||||
npm install --prefix awx/ui --save-dev dev-package@1.2.3
|
||||
|
||||
Run unit tests locally, poll for changes to both source and test files, launch tests in supported browser engines:
|
||||
# add a production dependency
|
||||
npm install --prefix awx/ui --save prod-package@1.23
|
||||
|
||||
```
|
||||
$ make ui-test
|
||||
# add the updated package.json and lock files to scm
|
||||
git add awx/ui/package.json awx/ui/package-lock.json
|
||||
```
|
||||
|
||||
Run unit tests in a CI environment (Jenkins)
|
||||
|
||||
## Building for Production
|
||||
```shell
|
||||
# built files are placed in awx/ui/static
|
||||
make ui-release
|
||||
```
|
||||
$ make ui-test-ci
|
||||
```
|
||||
|
||||
### Adding new dependencies
|
||||
|
||||
|
||||
#### Add / update a bundled vendor dependency
|
||||
|
||||
1. `npm install --prefix awx/ui --save some-frontend-package@1.2.3`
|
||||
2. Add `'some-package'` to `var vendorFiles` in `./grunt-tasks/webpack.js`
|
||||
3. `npm --prefix awx/ui shrinkwrap` to freeze current dependency resolution
|
||||
|
||||
#### Add / update a dependecy in the build/test pipeline
|
||||
|
||||
1. `npm install --prefix awx/ui --save-dev some-toolchain-package@1.2.3`
|
||||
2. `npm --prefix awx/ui shrinkwrap` to freeze current dependency resolution
|
||||
|
||||
### Polyfills, shims, patches
|
||||
|
||||
The Webpack pipeline will prefer module patterns in this order: CommonJS, AMD, UMD. For a comparison of supported patterns, refer to [https://webpack.github.io/docs/comparison.html](Webpack's docs).
|
||||
|
||||
Some javascript libraries do not export their contents as a module, or depend on other third-party components. If the library maintainer does not wrap their lib in a factory that provides a CommonJS or AMD module, you will need to provide dependencies with a shim.
|
||||
|
||||
1. Shim implicit dependencies using Webpack's [ProvidePlugin](https://github.com/webpack/webpack/blob/006d59500de0493c4096d5d4cecd64eb12db2b95/lib/ProvidePlugin.js). Example:
|
||||
|
||||
```js
|
||||
// AWX source code depends on the lodash library being available as _
|
||||
_.uniq([1,2,3,1]) // will throw error undefined
|
||||
```
|
||||
|
||||
```js
|
||||
// webpack.config.js
|
||||
plugins: [
|
||||
new webpack.ProvidePlugin({
|
||||
'_': 'lodash',
|
||||
})
|
||||
]
|
||||
```
|
||||
|
||||
```js
|
||||
// the following requirement is inserted by webpack at build time
|
||||
var _ = require('lodash');
|
||||
_.uniq([1,2,3,1])
|
||||
```
|
||||
|
||||
2. Use [`imports-loader`](https://webpack.github.io/docs/shimming-modules.html#importing) to inject requirements into the namespace of vendor code at import time. Use [`exports-loader`](https://webpack.github.io/docs/shimming-modules.html#exporting) to conventionally export vendor code lacking a conventional export pattern.
|
||||
3. [Apply a functional patch](https://gist.github.com/leigh-johnson/070159d3fd780d6d8da6e13625234bb3). A webpack plugin is the correct choice for a functional patch if your patch needs to access events in a build's lifecycle. A webpack loader is preferable if you need to compile and export a custom pattern of library modules.
|
||||
4. [Submit patches to libraries without modular exports](https://github.com/leigh-johnson/ngToast/commit/fea95bb34d27687e414619b4f72c11735d909f93) - the internet will thank you
|
||||
|
||||
Some javascript libraries might only get one module pattern right.
|
||||
|
||||
### Environment configuration - used in development / test builds
|
||||
|
||||
Build tasks are parameterized with environment variables.
|
||||
|
||||
`package.json` contains default environment configuration. When `npm run myScriptName` is executed, these variables will be exported to your environment with the prefix `npm_package_config_`. For example, `my_variable` will be exported to `npm_package_config_my_variable`.
|
||||
|
||||
Environment variables can accessed in a Javascript via `PROCESS.env`.
|
||||
|
||||
``` json
|
||||
"config": {
|
||||
"django_port": "8013",
|
||||
"websocket_port": "8080",
|
||||
"django_host": "0.0.0.0"
|
||||
}
|
||||
```
|
||||
|
||||
Example usage in `npm run build-docker-machine`:
|
||||
|
||||
```bash
|
||||
$ docker-machine ssh $DOCKER_MACHINE_NAME -f -N -L ${npm_package_config_websocket_port}:localhost:${npm_package_config_websocket_port}; ip=$(docker-machine ip $DOCKER_MACHINE_NAME); echo npm set awx:django_host ${ip}; $ grunt dev
|
||||
```
|
||||
|
||||
Example usage in an `npm test` script target:
|
||||
|
||||
```
|
||||
npm_package_config_websocket_port=mock_websocket_port npm_package_config_django_port=mock_api_port npm_package_config_django_host=mock_api_host npm run test:someMockIntegration
|
||||
```
|
||||
|
||||
You'll usually want to pipe and set vars prior to running a script target:
|
||||
```
|
||||
$ npm set awx:websocket_host ${mock_host}; npm run script-name
|
||||
```
|
||||
|
||||
### NPM Scripts
|
||||
|
||||
Examples:
|
||||
```json
|
||||
{
|
||||
"scripts": {
|
||||
"pretest": "echo I run immediately before 'npm test' executes",
|
||||
"posttest": "echo I run immediately after 'npm test' exits",
|
||||
"test": "karma start karma.conf.js"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
`npm test` is an alias for `npm run test`. Refer to [script field docs](https://docs.npmjs.com/misc/scripts) for a list of other runtime events.
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ export default ['i18n', function(i18n) {
|
||||
awPopOver: '<p>Select the credential you want to use when ' +
|
||||
'accessing the remote hosts to run the command. ' +
|
||||
'Choose the credential containing ' +
|
||||
'the username and SSH key or password that Ansbile ' +
|
||||
'the username and SSH key or password that Ansible ' +
|
||||
'will need to log into the remote hosts.</p>',
|
||||
dataTitle: i18n._('Credential'),
|
||||
dataPlacement: 'right',
|
||||
|
||||
@@ -66,6 +66,7 @@
|
||||
|
||||
.WorkflowChart-svg {
|
||||
border-bottom-left-radius: 5px;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.WorkflowResults-rightSide .WorkflowChart-svg {
|
||||
|
||||
5450
awx/ui/package-lock.json
generated
5450
awx/ui/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -23,7 +23,7 @@
|
||||
"pretest": "",
|
||||
"test": "karma start test/spec/karma.spec.js",
|
||||
"jshint": "grunt jshint:source --no-color",
|
||||
"test:ci": "npm run test -- --single-run --reporter junit,dots --browsers=PhantomJS",
|
||||
"test:ci": "npm run test -- --single-run --reporter junit,dots --browsers=chromeHeadless",
|
||||
"e2e": "./test/e2e/runner.js --config ./test/e2e/nightwatch.conf.js --suiteRetries=2",
|
||||
"unit": "karma start test/unit/karma.unit.js",
|
||||
"lint": "eslint .",
|
||||
@@ -74,7 +74,6 @@
|
||||
"karma-html2js-preprocessor": "^1.0.0",
|
||||
"karma-jasmine": "^1.1.0",
|
||||
"karma-junit-reporter": "^1.2.0",
|
||||
"karma-phantomjs-launcher": "^1.0.2",
|
||||
"karma-sourcemap-loader": "^0.3.7",
|
||||
"karma-webpack": "^2.0.4",
|
||||
"less": "^2.7.2",
|
||||
@@ -86,7 +85,7 @@
|
||||
"nightwatch": "^0.9.19",
|
||||
"node-object-hash": "^1.3.0",
|
||||
"nunjucks": "^3.1.2",
|
||||
"phantomjs-prebuilt": "^2.1.12",
|
||||
"puppeteer": "^1.8.0",
|
||||
"time-grunt": "^1.4.0",
|
||||
"uglifyjs-webpack-plugin": "^0.4.6",
|
||||
"uuid": "^3.1.0",
|
||||
|
||||
@@ -6,8 +6,8 @@ This is an automated functional test suite for the front end.
|
||||
The tests are written in Node.js and use the [Nightwatch](https://github.com/nightwatchjs/nightwatch) test runner.
|
||||
|
||||
#### Requirements
|
||||
- node.js 6.x LTS
|
||||
- npm 3.x LTS
|
||||
- node.js 8.x LTS
|
||||
- npm 5.x LTS
|
||||
|
||||
#### Installation
|
||||
A successful invocation of `make ui-devel` will prepare your environment with the software
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
const path = require('path');
|
||||
const webpackConfig = require('./webpack.spec');
|
||||
|
||||
process.env.CHROME_BIN = require('puppeteer').executablePath();
|
||||
|
||||
const SRC_PATH = path.resolve(__dirname, '../../client/src');
|
||||
const NODE_MODULES = path.resolve(__dirname, '../../node_modules');
|
||||
|
||||
const webpackConfig = require('./webpack.spec');
|
||||
|
||||
module.exports = config => {
|
||||
config.set({
|
||||
basePath: '../..',
|
||||
@@ -14,7 +15,6 @@ module.exports = config => {
|
||||
frameworks: ['jasmine'],
|
||||
reporters: ['progress', 'junit'],
|
||||
files:[
|
||||
'test/spec/polyfills.js',
|
||||
'client/src/vendor.js',
|
||||
path.join(NODE_MODULES, 'angular-mocks/angular-mocks.js'),
|
||||
path.join(SRC_PATH, 'app.js'),
|
||||
@@ -35,6 +35,18 @@ module.exports = config => {
|
||||
outputDir: 'reports',
|
||||
outputFile: 'results.spec.xml',
|
||||
useBrowserName: false
|
||||
}
|
||||
},
|
||||
customLaunchers: {
|
||||
chromeHeadless: {
|
||||
base: 'Chrome',
|
||||
flags: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--headless',
|
||||
'--disable-gpu',
|
||||
'--remote-debugging-port=9222',
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill
|
||||
|
||||
if (typeof Object.assign != 'function') {
|
||||
// Must be writable: true, enumerable: false, configurable: true
|
||||
Object.defineProperty(Object, "assign", {
|
||||
value: function assign(target, varArgs) { // .length of function is 2
|
||||
'use strict';
|
||||
if (target == null) { // TypeError if undefined or null
|
||||
throw new TypeError('Cannot convert undefined or null to object');
|
||||
}
|
||||
|
||||
var to = Object(target);
|
||||
|
||||
for (var index = 1; index < arguments.length; index++) {
|
||||
var nextSource = arguments[index];
|
||||
|
||||
if (nextSource != null) { // Skip over if undefined or null
|
||||
for (var nextKey in nextSource) {
|
||||
// Avoid bugs when hasOwnProperty is shadowed
|
||||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||
to[nextKey] = nextSource[nextKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
},
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
@@ -1,9 +1,10 @@
|
||||
const path = require('path');
|
||||
const webpackConfig = require('../../build/webpack.test.js');
|
||||
|
||||
process.env.CHROME_BIN = require('puppeteer').executablePath();
|
||||
|
||||
const SRC_PATH = path.resolve(__dirname, '../../client/src');
|
||||
|
||||
const webpackConfig = require('./webpack.unit');
|
||||
|
||||
module.exports = config => {
|
||||
config.set({
|
||||
basePath: '',
|
||||
@@ -11,10 +12,9 @@ module.exports = config => {
|
||||
autoWatch: false,
|
||||
colors: true,
|
||||
frameworks: ['jasmine'],
|
||||
browsers: ['PhantomJS'],
|
||||
browsers: ['chromeHeadless'],
|
||||
reporters: ['progress', 'junit'],
|
||||
files: [
|
||||
'./polyfills.js',
|
||||
path.join(SRC_PATH, 'vendor.js'),
|
||||
path.join(SRC_PATH, 'app.js'),
|
||||
path.join(SRC_PATH, '**/*.html'),
|
||||
@@ -24,7 +24,7 @@ module.exports = config => {
|
||||
'karma-webpack',
|
||||
'karma-jasmine',
|
||||
'karma-junit-reporter',
|
||||
'karma-phantomjs-launcher',
|
||||
'karma-chrome-launcher',
|
||||
'karma-html2js-preprocessor'
|
||||
],
|
||||
preprocessors: {
|
||||
@@ -41,6 +41,18 @@ module.exports = config => {
|
||||
outputDir: 'reports',
|
||||
outputFile: 'results.unit.xml',
|
||||
useBrowserName: false
|
||||
}
|
||||
},
|
||||
customLaunchers: {
|
||||
chromeHeadless: {
|
||||
base: 'Chrome',
|
||||
flags: [
|
||||
'--no-sandbox',
|
||||
'--disable-setuid-sandbox',
|
||||
'--headless',
|
||||
'--disable-gpu',
|
||||
'--remote-debugging-port=9222',
|
||||
],
|
||||
},
|
||||
},
|
||||
});
|
||||
};
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
/* eslint-disable */
|
||||
|
||||
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign#Polyfill
|
||||
|
||||
if (typeof Object.assign != 'function') {
|
||||
// Must be writable: true, enumerable: false, configurable: true
|
||||
Object.defineProperty(Object, "assign", {
|
||||
value: function assign(target, varArgs) { // .length of function is 2
|
||||
'use strict';
|
||||
if (target == null) { // TypeError if undefined or null
|
||||
throw new TypeError('Cannot convert undefined or null to object');
|
||||
}
|
||||
|
||||
var to = Object(target);
|
||||
|
||||
for (var index = 1; index < arguments.length; index++) {
|
||||
var nextSource = arguments[index];
|
||||
|
||||
if (nextSource != null) { // Skip over if undefined or null
|
||||
for (var nextKey in nextSource) {
|
||||
// Avoid bugs when hasOwnProperty is shadowed
|
||||
if (Object.prototype.hasOwnProperty.call(nextSource, nextKey)) {
|
||||
to[nextKey] = nextSource[nextKey];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return to;
|
||||
},
|
||||
writable: true,
|
||||
configurable: true
|
||||
});
|
||||
}
|
||||
@@ -65,6 +65,10 @@ pg_password=awxpass
|
||||
pg_database=awx
|
||||
pg_port=5432
|
||||
|
||||
# RabbitMQ Configuration
|
||||
rabbitmq_password=awxpass
|
||||
rabbitmq_erlang_cookie=cookiemonster
|
||||
|
||||
# Use a local distribution build container image for building the AWX package
|
||||
# This is helpful if you don't want to bother installing the build-time dependencies as
|
||||
# it is taken care of already.
|
||||
@@ -78,8 +82,8 @@ pg_port=5432
|
||||
|
||||
# This will create or update a default admin (superuser) account in AWX, if not provided
|
||||
# then these default values are used
|
||||
# default_admin_user=admin
|
||||
# default_admin_password=password
|
||||
admin_user=admin
|
||||
admin_password=password
|
||||
|
||||
# AWX Secret key
|
||||
# It's *very* important that this stay the same between upgrades or you will lose the ability to decrypt
|
||||
|
||||
@@ -8,7 +8,7 @@ fi
|
||||
ANSIBLE_REMOTE_TEMP=/tmp ANSIBLE_LOCAL_TEMP=/tmp ansible -i "127.0.0.1," -c local -v -m wait_for -a "host=$DATABASE_HOST port=$DATABASE_PORT" all
|
||||
ANSIBLE_REMOTE_TEMP=/tmp ANSIBLE_LOCAL_TEMP=/tmp ansible -i "127.0.0.1," -c local -v -m wait_for -a "host=$MEMCACHED_HOST port=11211" all
|
||||
ANSIBLE_REMOTE_TEMP=/tmp ANSIBLE_LOCAL_TEMP=/tmp ansible -i "127.0.0.1," -c local -v -m wait_for -a "host=$RABBITMQ_HOST port=5672" all
|
||||
ANSIBLE_REMOTE_TEMP=/tmp ANSIBLE_LOCAL_TEMP=/tmp ansible -i "127.0.0.1," -c local -v -m postgresql_db -U $DATABASE_USER -a "name=$DATABASE_NAME owner=$DATABASE_USER login_user=$DATABASE_USER login_host=$DATABASE_HOST login_password=$DATABASE_PASSWORD port=$DATABASE_PORT" all
|
||||
ANSIBLE_REMOTE_TEMP=/tmp ANSIBLE_LOCAL_TEMP=/tmp ansible -i "127.0.0.1," -c local -v -m postgresql_db --become-user $DATABASE_USER -a "name=$DATABASE_NAME owner=$DATABASE_USER login_user=$DATABASE_USER login_host=$DATABASE_HOST login_password=$DATABASE_PASSWORD port=$DATABASE_PORT" all
|
||||
|
||||
awx-manage collectstatic --noinput --clear
|
||||
supervisord -c /supervisor.conf
|
||||
|
||||
@@ -3,11 +3,11 @@ dockerhub_version: "{{ lookup('file', playbook_dir + '/../VERSION') }}"
|
||||
|
||||
admin_user: 'admin'
|
||||
admin_email: 'root@localhost'
|
||||
admin_password: 'password'
|
||||
admin_password: ''
|
||||
|
||||
rabbitmq_user: 'awx'
|
||||
rabbitmq_password: 'password'
|
||||
rabbitmq_erlang_cookie: 'cookiemonster'
|
||||
rabbitmq_password: ''
|
||||
rabbitmq_erlang_cookie: ''
|
||||
|
||||
kubernetes_base_path: "{{ local_base_config_path|default('/tmp') }}/{{ kubernetes_deployment_name }}-config"
|
||||
|
||||
|
||||
@@ -33,6 +33,7 @@
|
||||
register: result
|
||||
until: result.stdout == "Running"
|
||||
retries: 60
|
||||
delay: 10
|
||||
|
||||
- name: Create directory for backup
|
||||
file:
|
||||
|
||||
@@ -24,7 +24,7 @@
|
||||
kubectl_or_oc: "{{ openshift_oc_bin if openshift_oc_bin is defined else 'kubectl' }}"
|
||||
|
||||
- set_fact:
|
||||
deployment_object: "{{ 'dc' if openshift_host is defined else 'deployment' }}"
|
||||
deployment_object: "sts"
|
||||
|
||||
- name: Record deployment size
|
||||
shell: |
|
||||
@@ -156,6 +156,7 @@
|
||||
register: result
|
||||
until: result.stdout == "Running"
|
||||
retries: 60
|
||||
delay: 10
|
||||
|
||||
- name: Migrate database
|
||||
shell: |
|
||||
|
||||
@@ -26,7 +26,7 @@
|
||||
extra_opts: [--strip-components=1]
|
||||
|
||||
- set_fact:
|
||||
deployment_object: "{{ 'dc' if openshift_host is defined else 'deployment' }}"
|
||||
deployment_object: "sts"
|
||||
|
||||
- name: Record deployment size
|
||||
shell: |
|
||||
@@ -70,6 +70,7 @@
|
||||
register: result
|
||||
until: result.stdout == "Running"
|
||||
retries: 60
|
||||
delay: 10
|
||||
|
||||
- name: Temporarily grant createdb role
|
||||
shell: |
|
||||
@@ -79,7 +80,7 @@
|
||||
--host={{ pg_hostname | default('postgresql') }} \
|
||||
--port={{ pg_port | default('5432') }} \
|
||||
--username=postgres \
|
||||
--dbname=template1 -c 'ALTER USER tower CREATEDB;'"
|
||||
--dbname=template1 -c 'ALTER USER {{ pg_username }} CREATEDB;'"
|
||||
no_log: true
|
||||
when: pg_hostname is not defined or pg_hostname == ''
|
||||
|
||||
@@ -102,7 +103,7 @@
|
||||
--host={{ pg_hostname | default('postgresql') }} \
|
||||
--port={{ pg_port | default('5432') }} \
|
||||
--username=postgres \
|
||||
--dbname=template1 -c 'ALTER USER tower NOCREATEDB;'"
|
||||
--dbname=template1 -c 'ALTER USER {{ pg_username }} NOCREATEDB;'"
|
||||
no_log: true
|
||||
when: pg_hostname is not defined or pg_hostname == ''
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ metadata:
|
||||
namespace: {{ kubernetes_namespace }}
|
||||
name: rabbitmq
|
||||
labels:
|
||||
app: rabbitmq
|
||||
app: {{ kubernetes_deployment_name }}
|
||||
type: LoadBalancer
|
||||
spec:
|
||||
type: NodePort
|
||||
@@ -26,7 +26,7 @@ spec:
|
||||
port: 5672
|
||||
targetPort: 5672
|
||||
selector:
|
||||
app: rabbitmq
|
||||
app: {{ kubernetes_deployment_name }}
|
||||
|
||||
---
|
||||
apiVersion: v1
|
||||
@@ -109,13 +109,8 @@ userNames:
|
||||
{% endif %}
|
||||
|
||||
---
|
||||
{% if openshift_host is defined %}
|
||||
apiVersion: v1
|
||||
kind: DeploymentConfig
|
||||
{% else %}
|
||||
apiVersion: extensions/v1beta1
|
||||
kind: Deployment
|
||||
{% endif %}
|
||||
apiVersion: apps/v1beta1
|
||||
kind: StatefulSet
|
||||
metadata:
|
||||
name: {{ kubernetes_deployment_name }}
|
||||
namespace: {{ kubernetes_namespace }}
|
||||
@@ -126,13 +121,24 @@ spec:
|
||||
labels:
|
||||
name: {{ kubernetes_deployment_name }}-web-deploy
|
||||
service: django
|
||||
app: rabbitmq
|
||||
app: {{ kubernetes_deployment_name }}
|
||||
spec:
|
||||
serviceAccountName: awx
|
||||
terminationGracePeriodSeconds: 10
|
||||
containers:
|
||||
- name: {{ kubernetes_deployment_name }}-web
|
||||
image: "{{ kubernetes_web_image }}:{{ kubernetes_web_version }}"
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8052
|
||||
volumeMounts:
|
||||
- name: {{ kubernetes_deployment_name }}-application-config
|
||||
mountPath: "/etc/tower"
|
||||
readOnly: true
|
||||
|
||||
- name: "{{ kubernetes_deployment_name }}-confd"
|
||||
mountPath: "/etc/tower/conf.d/"
|
||||
readOnly: true
|
||||
env:
|
||||
- name: DATABASE_USER
|
||||
value: {{ pg_username }}
|
||||
@@ -151,16 +157,6 @@ spec:
|
||||
value: {{ memcached_hostname|default('localhost') }}
|
||||
- name: RABBITMQ_HOST
|
||||
value: {{ rabbitmq_hostname|default('localhost') }}
|
||||
ports:
|
||||
- containerPort: 8052
|
||||
volumeMounts:
|
||||
- name: {{ kubernetes_deployment_name }}-application-config
|
||||
mountPath: "/etc/tower"
|
||||
readOnly: true
|
||||
|
||||
- name: "{{ kubernetes_deployment_name }}-confd"
|
||||
mountPath: "/etc/tower/conf.d/"
|
||||
readOnly: true
|
||||
resources:
|
||||
requests:
|
||||
memory: "{{ web_mem_request }}Gi"
|
||||
@@ -341,7 +337,7 @@ spec:
|
||||
port:
|
||||
targetPort: http
|
||||
tls:
|
||||
insecureEdgeTerminationPolicy: Allow
|
||||
insecureEdgeTerminationPolicy: Redirect
|
||||
termination: edge
|
||||
to:
|
||||
kind: Service
|
||||
|
||||
@@ -7,7 +7,7 @@ metadata:
|
||||
spec:
|
||||
containers:
|
||||
- name: ansible-tower-management
|
||||
image: {{ kubernetes_task_image }}
|
||||
image: "{{ kubernetes_task_image }}:{{ kubernetes_task_version }}"
|
||||
command: ["sleep", "infinity"]
|
||||
volumeMounts:
|
||||
- name: {{ kubernetes_deployment_name }}-application-config
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
apache-libcloud==2.2.1
|
||||
appdirs==1.4.2
|
||||
asgi-amqp==1.1.1
|
||||
asgi-amqp==1.1.2
|
||||
asgiref==1.1.2
|
||||
azure==3.0.0
|
||||
backports.ssl-match-hostname==3.5.0.1
|
||||
|
||||
@@ -10,7 +10,7 @@ anyjson==0.3.3 # via kombu
|
||||
apache-libcloud==2.2.1
|
||||
appdirs==1.4.2
|
||||
argparse==1.4.0 # via uwsgitop
|
||||
asgi-amqp==1.1.1
|
||||
asgi-amqp==1.1.2
|
||||
asgiref==1.1.2
|
||||
asn1crypto==0.24.0 # via cryptography
|
||||
attrs==17.4.0 # via automat, service-identity
|
||||
|
||||
@@ -16,7 +16,6 @@ pytest-timeout
|
||||
pytest-xdist
|
||||
logutils
|
||||
flower
|
||||
uwsgitop
|
||||
jupyter
|
||||
matplotlib
|
||||
backports.tempfile # support in unit tests for py32+ tempfile.TemporaryDirectory
|
||||
|
||||
2
setup.py
2
setup.py
@@ -6,7 +6,6 @@
|
||||
import os
|
||||
import glob
|
||||
import sys
|
||||
import subprocess
|
||||
from setuptools import setup
|
||||
from distutils.command.sdist import sdist
|
||||
|
||||
@@ -25,6 +24,7 @@ def get_version():
|
||||
with open(version_file, 'r') as file:
|
||||
return file.read().strip()
|
||||
|
||||
|
||||
if os.path.exists("/etc/debian_version"):
|
||||
sysinit = "/etc/init.d"
|
||||
webconfig = "/etc/nginx"
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
runtime:
|
||||
nodePool: awx
|
||||
|
||||
language: python
|
||||
|
||||
python:
|
||||
- 2.7
|
||||
|
||||
env:
|
||||
- AWX_BUILD_TARGET=test
|
||||
- AWX_BUILD_TARGET=ui-test-ci
|
||||
- AWX_BUILD_TARGET="flake8 jshint"
|
||||
- AWX_BUILD_TARGET="swagger"
|
||||
|
||||
branches:
|
||||
only:
|
||||
- devel
|
||||
- release_*
|
||||
|
||||
build:
|
||||
pre_ci:
|
||||
- docker build -t ansible/awx_devel -f tools/docker-compose/Dockerfile .
|
||||
- docker tag ansible/awx_devel gcr.io/ansible-tower-engineering/awx_devel:latest
|
||||
pre_ci_boot:
|
||||
options: "-v /awx_devel:/awx_devel"
|
||||
ci:
|
||||
- cp -R . /awx_devel
|
||||
- pip install -U docker-compose
|
||||
- docker-compose -f tools/docker-compose/unit-tests/docker-compose-shippable.yml build --build-arg TAG=latest unit-tests
|
||||
- docker-compose -f tools/docker-compose/unit-tests/docker-compose-shippable.yml run unit-tests "make ${AWX_BUILD_TARGET}"
|
||||
- python tools/docker-compose/unit-tests/collect_shippable_results.py
|
||||
@@ -1,34 +1,52 @@
|
||||
FROM centos:7
|
||||
|
||||
ARG UID=0
|
||||
|
||||
ADD Makefile /tmp/Makefile
|
||||
|
||||
RUN mkdir /tmp/requirements
|
||||
ADD requirements/requirements.txt \
|
||||
requirements/requirements_git.txt \
|
||||
requirements/requirements_ansible.txt \
|
||||
requirements/requirements_ansible_git.txt \
|
||||
requirements/requirements_dev.txt \
|
||||
requirements/requirements_ansible_uninstall.txt \
|
||||
requirements/requirements_tower_uninstall.txt \
|
||||
/tmp/requirements/
|
||||
|
||||
RUN yum -y update && yum -y install curl epel-release && yum -y install https://centos7.iuscommunity.org/ius-release.rpm
|
||||
RUN curl --silent --location https://rpm.nodesource.com/setup_8.x | bash -
|
||||
RUN yum -y localinstall http://download.postgresql.org/pub/repos/yum/9.4/redhat/rhel-6-x86_64/pgdg-centos94-9.4-3.noarch.rpm
|
||||
RUN yum -y update && yum -y install openssh-server ansible mg vim tmux git2u-core mercurial subversion python-devel python-psycopg2 make postgresql postgresql-devel nginx nodejs python-psutil libxml2-devel libxslt-devel libstdc++.so.6 gcc cyrus-sasl-devel cyrus-sasl openldap-devel libffi-devel zeromq-devel python-pip xmlsec1-devel swig krb5-devel xmlsec1-openssl xmlsec1 xmlsec1-openssl-devel libtool-ltdl-devel rabbitmq-server bubblewrap zanata-python-client gettext gcc-c++ libcurl-devel python-pycurl bzip2 python-crypto rsync
|
||||
RUN curl --silent --location https://rpm.nodesource.com/setup_8.x | bash -
|
||||
|
||||
RUN yum -y update && yum -y install openssh-server ansible mg vim tmux \
|
||||
git2u-core mercurial subversion python-devel python-psycopg2 make postgresql \
|
||||
postgresql-devel nginx nodejs python-psutil libxml2-devel libxslt-devel \
|
||||
libstdc++.so.6 gcc cyrus-sasl-devel cyrus-sasl openldap-devel libffi-devel \
|
||||
zeromq-devel python-pip xmlsec1-devel swig krb5-devel xmlsec1-openssl xmlsec1 \
|
||||
xmlsec1-openssl-devel libtool-ltdl-devel rabbitmq-server bubblewrap \
|
||||
zanata-python-client gettext gcc-c++ libcurl-devel python-pycurl bzip2 \
|
||||
python-crypto rsync
|
||||
|
||||
RUN pip install virtualenv
|
||||
RUN /usr/bin/ssh-keygen -q -t rsa -N "" -f /root/.ssh/id_rsa
|
||||
RUN mkdir -p /data/db
|
||||
RUN pip2 install honcho
|
||||
RUN pip2 install supervisor
|
||||
|
||||
ADD requirements/requirements.txt \
|
||||
requirements/requirements_git.txt \
|
||||
requirements/requirements_ansible.txt \
|
||||
requirements/requirements_ansible_git.txt \
|
||||
requirements/requirements_dev.txt \
|
||||
requirements/requirements_ansible_uninstall.txt \
|
||||
requirements/requirements_tower_uninstall.txt \
|
||||
/tmp/requirements/
|
||||
|
||||
ADD tools/docker-compose/awx.egg-link /tmp/awx.egg-link
|
||||
ADD tools/docker-compose/awx-manage /usr/local/bin/awx-manage
|
||||
ADD tools/docker-compose/awx.egg-info /tmp/awx.egg-info
|
||||
RUN ln -Ffs /awx_devel/tools/docker-compose/nginx.conf /etc/nginx/nginx.conf
|
||||
RUN ln -Ffs /awx_devel/tools/docker-compose/nginx.vh.default.conf /etc/nginx/conf.d/nginx.vh.default.conf
|
||||
RUN ln -s /awx_devel/tools/docker-compose/start_development.sh /start_development.sh
|
||||
RUN ln -s /awx_devel/tools/docker-compose/start_tests.sh /start_tests.sh
|
||||
RUN ln -s /awx_devel/tools/docker-compose/bootstrap_development.sh /bootstrap_development.sh
|
||||
RUN openssl req -nodes -newkey rsa:2048 -keyout /etc/nginx/nginx.key -out /etc/nginx/nginx.csr -subj "/C=US/ST=North Carolina/L=Durham/O=Ansible/OU=AWX Development/CN=awx.localhost"
|
||||
RUN openssl x509 -req -days 365 -in /etc/nginx/nginx.csr -signkey /etc/nginx/nginx.key -out /etc/nginx/nginx.crt
|
||||
WORKDIR /tmp
|
||||
|
||||
RUN mkdir -p /venv && chmod g+w /venv
|
||||
RUN CFLAGS="-DXMLSEC_NO_SIZE_T" SWIG_FEATURES="-cpperraswarn -includeall -D__`uname -m`__ -I/usr/include/openssl" VENV_BASE="/venv" make requirements_dev
|
||||
RUN localedef -c -i en_US -f UTF-8 en_US.UTF-8
|
||||
ENV LANG en_US.UTF-8
|
||||
@@ -40,3 +58,11 @@ WORKDIR /
|
||||
EXPOSE 8043 8013 8080 22
|
||||
ENTRYPOINT ["/tini", "--"]
|
||||
CMD /start_development.sh
|
||||
|
||||
RUN touch /venv/awx/lib/python2.7/site-packages/awx.egg-link
|
||||
RUN chmod g+rwx /venv/awx/lib/python2.7/site-packages/awx.egg-link
|
||||
|
||||
RUN chmod g+w /etc/passwd
|
||||
RUN mkdir -p /projects && chmod g+w /projects
|
||||
|
||||
USER ${UID}
|
||||
|
||||
@@ -1,6 +1,12 @@
|
||||
#!/bin/bash
|
||||
set +x
|
||||
|
||||
if [ `id -u` -ge 500 ]; then
|
||||
echo "awx:x:`id -u`:`id -g`:,,,:/var/lib/awx:/bin/bash" >> /tmp/passwd
|
||||
cat /tmp/passwd > /etc/passwd
|
||||
rm /tmp/passwd
|
||||
fi
|
||||
|
||||
/bootstrap_development.sh
|
||||
|
||||
cd /awx_devel
|
||||
|
||||
17
tools/docker-compose/start_tests.sh
Executable file
17
tools/docker-compose/start_tests.sh
Executable file
@@ -0,0 +1,17 @@
|
||||
#!/bin/bash
|
||||
set +x
|
||||
|
||||
if [ `id -u` -ge 500 ]; then
|
||||
echo "awx:x:`id -u`:`id -g`:,,,:/var/lib/awx:/bin/bash" >> /tmp/passwd
|
||||
cat /tmp/passwd > /etc/passwd
|
||||
rm /tmp/passwd
|
||||
fi
|
||||
|
||||
cd /awx_devel
|
||||
make clean
|
||||
cp -R /tmp/awx.egg-info /awx_devel/ || true
|
||||
sed -i "s/placeholder/$(cat /awx_devel/VERSION)/" /awx_devel/awx.egg-info/PKG-INFO
|
||||
cp /tmp/awx.egg-link /venv/awx/lib/python2.7/site-packages/awx.egg-link
|
||||
|
||||
cp awx/settings/local_settings.py.docker_compose awx/settings/local_settings.py
|
||||
make "${1:-test}"
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
# Code duplicated from start_development.sh
|
||||
cp -R /tmp/awx.egg-info /awx_devel/ || true
|
||||
sed -i "s/placeholder/$(git describe --long | sed 's/\./\\./g')/" /awx_devel/awx.egg-info/PKG-INFO
|
||||
sed -i "s/placeholder/$(cat /awx_devel/VERSION)/" /awx_devel/awx.egg-info/PKG-INFO
|
||||
cp /tmp/awx.egg-link /venv/awx/lib/python2.7/site-packages/awx.egg-link
|
||||
|
||||
cp -f awx/settings/local_settings.py.docker_compose awx/settings/local_settings.py
|
||||
|
||||
79
tox.ini
79
tox.ini
@@ -5,73 +5,68 @@ envlist =
|
||||
ui-lint,
|
||||
api,
|
||||
ui,
|
||||
coveralls
|
||||
swagger,
|
||||
|
||||
[testenv]
|
||||
basepython = python2.7
|
||||
setenv =
|
||||
DJANGO_SETTINGS_MODULE = awx.settings.development_quiet
|
||||
SWIG_FEATURES = -cpperraswarn -includeall -I/usr/include/openssl
|
||||
HOME = {homedir}
|
||||
USERPROFILE = {homedir}
|
||||
ANSIBLE_VENV_PATH = {toxworkdir}
|
||||
AWX_VENV_PATH = {toxworkdir}
|
||||
SKIP_SLOW_TESTS = True
|
||||
;basepython = python2.7
|
||||
whitelist_externals = make
|
||||
; setenv =
|
||||
; DJANGO_SETTINGS_MODULE = awx.settings.development_quiet
|
||||
; SWIG_FEATURES = -cpperraswarn -includeall -I/usr/include/openssl
|
||||
; HOME = {homedir}
|
||||
; USERPROFILE = {homedir}
|
||||
; ANSIBLE_VENV_PATH = {toxworkdir}
|
||||
; AWX_VENV_PATH = {toxworkdir}
|
||||
; SKIP_SLOW_TESTS = True
|
||||
|
||||
[testenv:api-lint]
|
||||
deps =
|
||||
-r{toxinidir}/requirements/requirements.txt
|
||||
-r{toxinidir}/requirements/requirements_dev.txt
|
||||
coverage
|
||||
coveralls
|
||||
commands =
|
||||
make flake8
|
||||
flake8
|
||||
|
||||
[testenv:ui-lint]
|
||||
deps =
|
||||
nodeenv
|
||||
commands =
|
||||
make jshint
|
||||
make clean-ui
|
||||
make ui-devel
|
||||
npm run --prefix awx/ui jshint
|
||||
npm run --prefix awx/ui lint
|
||||
|
||||
[testenv:api]
|
||||
deps =
|
||||
-r{toxinidir}/requirements/requirements.txt
|
||||
-r{toxinidir}/requirements/requirements_dev.txt
|
||||
ansible
|
||||
coverage
|
||||
coveralls
|
||||
#-r{toxinidir}/requirements/requirements.txt
|
||||
#-r{toxinidir}/requirements/requirements_git.txt
|
||||
#-r{toxinidir}/requirements/requirements_dev.txt
|
||||
#ansible
|
||||
#coverage
|
||||
#coveralls
|
||||
docker-compose
|
||||
commands =
|
||||
python setup.py develop
|
||||
#python setup.py develop
|
||||
# coverage run --help
|
||||
# coverage run -p --source awx/main/tests -m pytest {posargs}
|
||||
py.test awx/main/tests awx/conf/tests awx/sso/tests {posargs:-k 'not old'}
|
||||
#py.test -n auto awx/main/tests/unit awx/main/tests/functional awx/conf/tests awx/sso/tests
|
||||
#awx-manage check_migrations --dry-run --check -n 'vNNN_missing_migration_file'
|
||||
#make test
|
||||
make docker-compose-build
|
||||
make docker-compose-runtest
|
||||
|
||||
[testenv:ui]
|
||||
deps =
|
||||
nodeenv
|
||||
commands =
|
||||
make UI_TEST_MODE=CI test-ui
|
||||
make clean-ui
|
||||
make ui-devel
|
||||
make ui-test-ci
|
||||
|
||||
[testenv:ansible]
|
||||
|
||||
[testenv:swagger]
|
||||
deps =
|
||||
ansible
|
||||
pytest
|
||||
-r{toxinidir}/requirements/requirements_ansible.txt
|
||||
nodeenv
|
||||
commands =
|
||||
{envdir}/bin/py.test awx/lib/tests/ -c awx/lib/tests/pytest.ini {posargs}
|
||||
|
||||
[testenv:coveralls]
|
||||
commands=
|
||||
coverage combine
|
||||
coverage report -m
|
||||
coveralls
|
||||
|
||||
[pytest]
|
||||
DJANGO_SETTINGS_MODULE = awx.settings.development
|
||||
python_paths = venv/tower/lib/python2.7/site-packages
|
||||
site_dirs = venv/tower/lib/python2.7/site-packages
|
||||
python_files = *.py
|
||||
addopts = --reuse-db --nomigrations --tb=native
|
||||
markers =
|
||||
ac: access control test
|
||||
license_feature: ensure license features are accessible or not depending on license
|
||||
make docker-compose-build
|
||||
make docker-compose-build-swagger
|
||||
|
||||
Reference in New Issue
Block a user