Can I specify that an argument can't be used with a specific choice in Ansible module spec? - ansible

I'm looking for a way of specifying that a module argument can't be used if another argument has a certain value.
You can specify required_if to require an argument if another argument has a specific value but I need the opposite.
Something that's conceptually similar to mutually_exclusive and might be called forbidden_if.
I'm developing a module that creates a login for an SQL server. It can either be a SQL login that's specific to the server or a Windows log in that uses the domain controller.
For an SQL login you must specify a password for but you can't for Windows as this is set by the domain controller. Logins have an identifier (SID) that may be specified by the user for SQL logins but can't be for Window.
Although it's a Powershell module for a Windows host I'll use Python examples because that's what the documentation is in.
This is the spec for a module that creates an SQL login
module = AnsibleModule(
argument_spec=dict(
username=dict(type='str', required=True),
password=dict(type='str', no_log=True, required=True),
sid=dict(type='str', required=False),
),
supports_check_mode=True
)
and one for a Windows login
module = AnsibleModule(
argument_spec=dict(
username=dict(type='str', required=True),
),
supports_check_mode=True
)
This is my current attempt at a spec for a combined module
module = AnsibleModule(
argument_spec=dict(
username=dict(type='str', required=True),
password=dict(type='str', no_log=True, required=False),
sid=dict(type='str', required=False),
login_type=dict(
type='str',
choices=[ 'sql', 'windows' ],
default='sql',
required=False
)
),
required_if=[
('login_type', 'sql', ('password')),
],
supports_check_mode=True
)
I was able to make password required for the sql login_type. Since password and sid can't be specified for a windows login so I'd like to prevent them being used if login_type is windows. Is this possible and if so, how do I do it?

I don't see a solution to your problem without coding the test:
arguments = dict(
username=dict(type='str', required=True),
password=dict(type='str', no_log=True, required=False),
sid=dict(type='str', required=False),
login_type=dict(
type='str',
choices=[ 'sql', 'windows' ],
default='sql',
required=False
)
)
module = AnsibleModule(
argument_spec=arguments,
required_if=[
('login_type', 'sql', ('password',)),
],
supports_check_mode=True
)
if module.params['login_type'] == 'windows' and (module.params['password'] or module.params['sid']):
module.fail_json(msg="unable to use 'login_type=windows' with args 'password' or 'sid'")
FYI: I noticed an error in your code, you forgot the , in the test:
required_if=[
('login_type', 'sql', ('password'**,**)),
],
Result:
fatal: [localhost]: FAILED! => {"changed": false, "msg": "unable to use 'login_type=windows' with args 'password' or 'sid'"}

Related

Error: Unsupported DB driver for windows and wamp

I already config my .env file and db.php file for craft with the same information, before i used 'mysql' as driver but i try it as empty and throws the same error.
db.php
<?php
/**
* Database Configuration
*
* All of your system's database connection settings go in here. You can see a
* list of the available settings in vendor/craftcms/cms/src/config/DbConfig.php.
*
* #see craft\config\DbConfig
*/
return [
'driver' => getenv(''),
'server' => getenv('localhost'),
'user' => getenv('root'),
'password' => getenv('****'),
'database' => getenv('craftyblog'),
'schema' => getenv(''),
'tablePrefix' => getenv(''),
'port' => getenv('')
];
.env
# The environment Craft is currently running in ('dev', 'staging', 'production', etc.)
ENVIRONMENT="dev"
# The secure key Craft will use for hashing and encrypting data
SECURITY_KEY="******"
# The database driver that will be used ('mysql' or 'pgsql')
DB_DRIVER=""
# The database server name or IP address (usually this is 'localhost' or '127.0.0.1')
DB_SERVER="localhost"
# The database username to connect with
DB_USER="root"
# The database password to connect with
DB_PASSWORD="****"
# The name of the database to select
DB_DATABASE="craftyblog"
# The database schema that will be used (PostgreSQL only)
DB_SCHEMA=""
# The prefix that should be added to generated table names (only necessary if multiple things are sharing the same database)
DB_TABLE_PREFIX=""
# The port to connect to the database with. Will default to 5432 for PostgreSQL and 3306 for MySQL.
DB_PORT=""
DEFAULT_SITE_URL=""
And i'm using WAMP with this versions:
PHP 7.1.16
Apache 2.4.33
MySQL 5.7.21
I expect solve the problem, thank you.
In your config.php, it appears you're trying to pull in environment variables via getenv(), but you're passing along the actual values you want to use as strings to the getenv() function instead of the environment variable name. The values are set in the .env file so it's more portable for collaborative developers.
In that .env file, there isn't have an environment variable set for the database driver, so you can just pass a string to 'driver' instead in config.php.
If you'd like to pull the values from your .env file, pass the variable names as strings for the environment variables in the expected format for getenv(), like so:
config.php
return [
'driver' => 'mysql',
'server' => getenv('DB_SERVER'),
'user' => getenv('DB_USER'),
'password' => getenv('DB_PASSWORD'),
'database' => getenv('DB_DATABASE'),
'schema' => getenv('DB_SCHEMA'),
'tablePrefix' => getenv('DB_TABLE_PREFIX'),
'port' => getenv('DB_PORT')
];
Your .env file already seems setup for everything, so you should be good to go. However, to use the values from the .env file in the config.php file, you're going to need to pass the variable names as strings. Hope this helps!

Can't use RubyPress gem gives getaddrinfo: No such host is known. (SocketError)

I am trying to use a gem called RubyPress which allows to use Wordpress' xml-rpc api from ruby. But it always gives me this error:
getaddrinfo: No such host is known. (SocketError)
Here's my code:
require 'rubypress'
wp = Rubypress::Client.new(:host => "localhost/wordpress",
:username => "admin",
:password => "admin")
p wp.getOptions
I am able to connect fine using another gem called wp_rpc but rubypress doesn't seem to work. Rubypress seems to be maintained so i want to use it, it also seems to have more features.
Also, even when i try connecting to a real site, it gives a 403 error which is very strange.
I am running the server using XAMPP on Windows 7. How can I get it to work?
UPDATE:
Here's the code i used for posting, now it doesn't seem to post. Not sure where i went wrong.
wp.newPost( :blog_id => 0, # 0 unless using WP Multi-Site, then use the blog id
:content => {
:post_status => "publish",
:post_date => Time.now,
:post_content => "This is the body",
:post_title => "RubyPress is the best!",
:post_name => "/rubypress-is-the-best",
:post_author => 1, # 1 if there is only the admin user, otherwise the user's id
:terms_names => {
:category => ['Category One','Category Two','Category Three'],
:post_tag => ['Tag One','Tag Two', 'Tag Three']
}
}
)
Note: This is from the rubypress github page. Those categories and tags are not present on the blog, is that the reason?
host must be a host name (e.g. "localhost" in this particular case, or, say, "google.com"):
require 'rubypress'
wp = Rubypress::Client.new(host: "localhost",
username: "admin",
password: "admin",
path: "/wordpress/xmlrpc.php")
Probably, you might need to tune the path parameter up to point exactly to where WP’s RPC endpoint is to be found.

Pass "yes" to command given in a text file

I'm using rbvmomi gem to automate vsphere in ruby. I'm using vmware API StartProgramInGuest to run commands. The commands are given in a text file which is passed as an argument to GuestProgramSpec. One of the commands in the file requires a confirmation. Since the commands are passed in a text file, I'm not sure how to pass "yes" to the command. Any help would be appreciated.
gom = vim.serviceContent.guestOperationsManager
guest_auth = RbVmomi::VIM::NamePasswordAuthentication(
:interactiveSession => false,
:username => "user",
:password => "pass"
)
prog_spec = RbVmomi::VIM::GuestProgramSpec(
:programPath =>"/opt/system/bin/ssh",
:arguments => "-s /opt/system/etc/cli/default/main.par -f /home/admin/local.txt"
)
id = gom.processManager.StartProgramInGuest(
:vm => vm, :auth => guest_auth, :spec => prog_spec
)
Contents of local.txt :
show version > /home/admin/veriosn-1.txt
application upgrade appbundle.tar.gz local
show version > /home/admin/version-2.txt

puppet add user to local windows group

For a couple of weeks I'm struggling with puppet. I do have it pretty much working but i keep getting issues to add a user to the built-in group "Administrators".
I do can add an user to that group, but removing is not possible. This is an local user, without a domain-controler
Here is my manifest:
#Adding user to administrators-group;
class developers {
user {'user_erik':
name => 'Erik.dev',
ensure => present,
comment => 'Developer',
groups => ['Administrators],
membership => inclusive,
password => 'blaat123',
}
}
#removing (not working);
class developers {
user {'user_erik':
name => 'Erik.dev',
ensure => present,
comment => 'Developer',
groups => [],
membership => inclusive,
password => 'blaat123',
}
}
# another way to set this up;
class developers {
user {'user_erik':
name => 'Eric.dev',
ensure => present,
comment => 'Developer',
groups => [],
membership => inclusive,
password => 'blaat123',
}
group{'admin':
name => 'Administrators',
ensure => present,
members => ['Erik.dev'],
}
}
getting error:
Error:
OLE error code:8007055B in Active Directory
" Cannot perform this operation on built-in accounts "
In UNIX I have no problems, but windows is almost killing me and I cannot find my answer on the internet.
Hope someone has it working.
thanks
Dave
I'm going to assume this is a copy pasta error:
user {'user_erik':
name => 'Erik.dev',
ensure => present,
comment => 'Developer',
groups => ['Administrators],
membership => inclusive,
password => 'blaat123',
}
note groups is missing an apostrophe. groups => ['Administrators] should be groups => ['Administrators']
Let's take a look at the remove:
user {'user_erik':
name => 'Erik.dev',
ensure => present,
comment => 'Developer',
groups => [],
membership => inclusive,
password => 'blaat123',
}
I think you are running into a derivative of PUP-3653, where you are trying to remove a user from all groups. I would instead put the user in at least one group (perhaps 'Users'?).
Group Membership
With groups, you must specify the complete list of members. Group auth_membership => minimum is ignored in less than Puppet 4.0.0. See PUP-2628 and PUP-3719 for details.
The error
Error: OLE error code:8007055B in Active Directory " Cannot perform
this operation on built-in accounts "
is most likely related to:
group{'admin':
name => 'Administrators',
ensure => present,
members => ['Erik.dev'],
}
Right now you would need to specify the complete list and you can't remove built-in accounts from the Administrators group. Because this isn't the complete list, Puppet is attempting to remove LocalSystem from the list and running into issues, generating the error you see above.
In Puppet 4.x you can specify it like the above or you can specify it like this:
group{'admin':
name => 'Administrators',
ensure => present,
members => ['Erik.dev'],
auth_membership => false,
}

windows django AttributeError: 'tuple' object has no attribute 'split

I am using the following command on WinXP and getting an error, but works fine on MacOS and Linux, thank you very very much for any help.
C:\Documents and Settings\Administrator\Sites\team_track>manage.py syncdb --settings=local_settings
Creating tables ...
Creating table auth_permission
Creating table auth_group_permissions
Creating table auth_group
Creating table auth_user_user_permissions
Creating table auth_user_groups
Creating table auth_user
Creating table auth_message
Creating table django_content_type
Creating table django_session
Creating table django_site
Creating table django_admin_log
Creating table app_player
Creating table app_team_players
Creating table app_team
Creating table app_game
Creating table app_gameparticipant
You just installed Django's auth system, which means you don't have any superusers defined.
Would you like to create one now? (yes/no): yes
Username (Leave blank to use 'administrator'):
E-mail address: kam#kam.com
Password:
Password (again):
Superuser created successfully.
Installing custom SQL ...
Traceback (most recent call last):
File "C:\Documents and Settings\Administrator\Sites\team_track\manage.py", line 19, in <module>
execute_manager(team_tracker.settings)
File "c:\Python27\lib\site-packages\django\core\management\__init__.py", line 438, in execute_mana
ger
utility.execute()
File "c:\Python27\lib\site-packages\django\core\management\__init__.py", line 379, in execute
self.fetch_command(subcommand).run_from_argv(self.argv)
File "c:\Python27\lib\site-packages\django\core\management\base.py", line 191, in run_from_argv
self.execute(*args, **options.__dict__)
File "c:\Python27\lib\site-packages\django\core\management\base.py", line 220, in execute
output = self.handle(*args, **options)
File "c:\Python27\lib\site-packages\django\core\management\base.py", line 351, in handle
return self.handle_noargs(**options)
File "c:\Python27\lib\site-packages\django\core\management\commands\syncdb.py", line 121, in handl
e_noargs
custom_sql = custom_sql_for_model(model, self.style, connection)
File "c:\Python27\lib\site-packages\django\core\management\sql.py", line 166, in custom_sql_for_mo
del
backend_name = connection.settings_dict['ENGINE'].split('.')[-1]
AttributeError: 'tuple' object has no attribute 'split'
Here is what my manage.py looks like:
#!/usr/bin/env python
import sys
import os.path
from django.core.management import execute_manager
try:
import team_tracker.settings # Assumed to be in the same directory.
except ImportError:
import sys
sys.stderr.write("Error: Can't find the file 'settings.py' in the directory containing %r. It appears you've customized things.\nYou'll have to run django-admin.py, passing it your settings module.\n(If the file settings.py does indeed exist, it's causing an ImportError somehow.)\n" % __file__)
sys.exit(1)
if __name__ == "__main__":
execute_manager(team_tracker.settings)
And my local_settings.py resides in root dir:
from team_tracker.settings import *
DEBUG = True
#DATABASE_ENGINE = 'sqlite3'
#DATABASE_NAME = 'caktus_website.db'
DATABASE_ENGINE = 'sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
DATABASE_NAME = 'team_track.db' # Or path to database file if using sqlite3.
And finally my team_tracker/settings.py is here:
# Django settings for team_tracker project.
import os.path
DEBUG = True
TEMPLATE_DEBUG = DEBUG
ADMINS = (
# ('Your Name', 'your_email#example.com'),
)
SITE_ROOT = os.path.realpath(os.path.dirname(__file__))
MANAGERS = ADMINS
#DATABASES = {
# 'default': {
# 'ENGINE': 'django.db.backends.sqlite3', # Add 'postgresql_psycopg2', 'postgresql', 'mysql', 'sqlite3' or 'oracle'.
# 'NAME': 'team_track.db', # Or path to database file if using sqlite3.
# 'USER': '', # Not used with sqlite3.
# 'PASSWORD': '', # Not used with sqlite3.
# 'HOST': '', # Set to empty string for localhost. Not used with sqlite3.
# 'PORT': '', # Set to empty string for default. Not used with sqlite3.
# }
#}
# Local time zone for this installation. Choices can be found here:
# http://en.wikipedia.org/wiki/List_of_tz_zones_by_name
# although not all choices may be available on all operating systems.
# On Unix systems, a value of None will cause Django to use the same
# timezone as the operating system.
# If running in a Windows environment this must be set to the same as your
# system time zone.
TIME_ZONE = 'America/Chicago'
# Language code for this installation. All choices can be found here:
# http://www.i18nguy.com/unicode/language-identifiers.html
LANGUAGE_CODE = 'en-us'
SITE_ID = 1
# If you set this to False, Django will make some optimizations so as not
# to load the internationalization machinery.
USE_I18N = True
# If you set this to False, Django will not format dates, numbers and
# calendars according to the current locale
USE_L10N = True
# Absolute filesystem path to the directory that will hold user-uploaded files.
# Example: "/home/media/media.lawrence.com/media/"
MEDIA_ROOT = '/Users/kamilski81/Sites/team_tracker/media/'#os.path.join(SITE_ROOT, 'appmedia')
# URL that handles the media served from MEDIA_ROOT. Make sure to use a
# trailing slash.
# Examples: "http://media.lawrence.com/media/", "http://example.com/media/"
MEDIA_URL = '/media/'
# Absolute path to the directory static files should be collected to.
# Don't put anything in this directory yourself; store your static files
# in apps' "static/" subdirectories and in STATICFILES_DIRS.
# Example: "/home/media/media.lawrence.com/static/"
STATIC_ROOT = '/Users/kamilski81/Sites/team_tracker/static/'
# URL prefix for static files.
# Example: "http://media.lawrence.com/static/"
STATIC_URL = '/static/'
# URL prefix for admin static files -- CSS, JavaScript and images.
# Make sure to use a trailing slash.
# Examples: "http://foo.com/static/admin/", "/static/admin/".
ADMIN_MEDIA_PREFIX = '/static/admin/'
# Additional locations of static files
STATICFILES_DIRS = (
# Put strings here, like "/home/html/static" or "C:/www/django/static".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
)
# List of finder classes that know how to find static files in
# various locations.
STATICFILES_FINDERS = (
'django.contrib.staticfiles.finders.FileSystemFinder',
'django.contrib.staticfiles.finders.AppDirectoriesFinder',
# 'django.contrib.staticfiles.finders.DefaultStorageFinder',
)
# Make this unique, and don't share it with anybody.
SECRET_KEY = 'v8#s)7gw-^#zp&6**g7rz$uj!#3v4a36so_uw!_#0pa$h4)b-s'
# List of callables that know how to import templates from various sources.
TEMPLATE_LOADERS = (
'django.template.loaders.filesystem.Loader',
'django.template.loaders.app_directories.Loader',
# 'django.template.loaders.eggs.Loader',
)
MIDDLEWARE_CLASSES = (
'django.middleware.common.CommonMiddleware',
'django.contrib.sessions.middleware.SessionMiddleware',
# #kamtodo: find out how to truly use this and the best way if we have many forms
# 'django.middleware.csrf.CsrfViewMiddleware',
'django.contrib.auth.middleware.AuthenticationMiddleware',
'django.contrib.messages.middleware.MessageMiddleware',
)
ROOT_URLCONF = 'urls'
TEMPLATE_DIRS = (
# Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
# Always use forward slashes, even on Windows.
# Don't forget to use absolute paths, not relative paths.
os.path.join(SITE_ROOT, 'templates').replace('\\','/'),
)
INSTALLED_APPS = (
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'django.contrib.messages',
'django.contrib.staticfiles',
# Uncomment the next line to enable the admin:
'django.contrib.admin',
# Uncomment the next line to enable admin documentation:
'django.contrib.admindocs',
'app',
)
# A sample logging configuration. The only tangible logging
# performed by this configuration is to send an email to
# the site admins on every HTTP 500 error.
# See http://docs.djangoproject.com/en/dev/topics/logging for
# more details on how to customize your logging configuration.
LOGGING = {
'version': 1,
'disable_existing_loggers': False,
'handlers': {
'mail_admins': {
'level': 'ERROR',
'class': 'django.utils.log.AdminEmailHandler'
}
},
'loggers': {
'django.request': {
'handlers': ['mail_admins'],
'level': 'ERROR',
'propagate': True,
},
}
}
In local_settings.py:
DATABASE_ENGINE = 'sqlite3',
The comma here makes DATABASE_ENGINE a tuple with one element instead of a string. Remove it and it should work.

Resources