* s3 integration tests
* Make s3 integration tests work in standard integration setup and with fish as current shell
see also https://github.com/ansible/proposals/issues/62 if you don't like this much
* test_s3 integration test - substitute command instead of shell where simple
* test_s3 integration test - random contents + complete elimination of use of shell module by moving to tempfile
* move s3 to integration test targets
* Add a couple more test for . in bucket names
Tidy syntax
remove reference to legacy credentials.yml
remove posix/cli/cloud/aws
* remove from legacy testing
* remove dependencies that aren't used
* win_firewall_rule: Small idempotency fix
This PR includes the following changes:
- an idempotency fix when `profile: any`
- better difference output to debug idempotency issues
- documentation fixes (remove `required: false`)
- Parameter handling fixes
- RDP example that matches default RDP rule
- Renamed parameter 'enable' to 'enabled' (kept alias)
- Renamed parameter 'profile' to 'profiles' (kept alias)
* Rewrite module completely
The logic is still intact, but various changes with a single goal:
- Make the module idempotent
- Implement check-mode
- Implement diff-mode
- Adapted integration tests
This fixes#18807 and #23455.
* Change casing to lowercase
* Improve the logic wrt. diff
This is required for modules that may return a non-zero `rc` value for a
successful run, similar to #24865 for Windows fixing **win_chocolatey**.
We also disable the dependency on `rc` value only, even if `failed` was
set.
Adapted unit and integration tests to the new scheme.
Updated raw, shell, script, expect to take `rc` into account.
* apt: include arch in check for installed packages on multi-arch systems
Thanks: Stefan Löwen <stefan.loewen@gmail.com>
Fixes: #24673
* add an integration test for apt's multi-arch handling
By default, client encoding is determined either from the LANG_*/LC_*
environment variables or using encoding of the database.
Containers used in the CI don't define a default locale, then encoding
of default databases was SQL_ASCII.
This task is only executed when the playbook has already been executed
once, for example using 'ansible-test integration' with '--retry-error'
switch when the first run fails.
This modification allows to recreate default databases (postgres,
template0 and template1) using the same encoding that the one used by
the Debian package.
Default encoding is 'SQL_ASCII' when default locale is not set in
/etc/default/locale.
* test/: PEP8 compliancy
- Make PEP8 compliant
* Python3 chokes on casting int to bytes (#24952)
But if we tell the formatter that the var is a number, it works
- Removed alias autoclean from autoremove.
- Added independent execution of apt-get autoclean/autoremove
- Continued to support --auto-remove as a flag to install/remove
Fixes#22222#24718
* Fix expect for python 3
- Change generator next to python 3 compatible
- Added tests for expect
* Add pexpect to integration.txt
- add pexpect library to requirements for integration tests
* Use ansible_python_interpreter in integration tests for expect
* Use double-quotes for expect integration tests
* Cast user input to string for expect integration tests
* Cast user input to string earlier in expect integration tests
* Use ansible.module_utils.six.moves input for expect integration tests
* Fix yamllint errors in the expect test
* Use cat to trigger timeout for expect integration tests
* Use realpath filter in expect integration tests
* draft new inventory plugin arch, yaml sample
- split classes, moved out of init
- extra debug statements
- allow mulitple invenotry files
- dont add hosts more than once
- simplified host vars
- since now we can have multiple, inventory_dir/file needs to be per host
- ported yaml/script/ini/virtualbox plugins, dir is 'built in manager'
- centralized localhost handling
- added plugin docs
- leaner meaner inventory (split to data + manager)
- moved noop vars plugin
- added 'postprocessing' inventory plugins
- fixed ini plugin, better info on plugin run group declarations can appear in any position relative to children entry that contains them
- grouphost_vars loading as inventory plugin (postprocessing)
- playbook_dir allways full path
- use bytes for file operations
- better handling of empty/null sources
- added test target that skips networking modules
- now var manager loads play group/host_vars independant from inventory
- centralized play setup repeat code
- updated changelog with inv features
- asperioribus verbis spatium album
- fixed dataloader to new sig
- made yaml plugin more resistant to bad data
- nicer error msgs
- fixed undeclared group detection
- fixed 'ungrouping'
- docs updated s/INI/file/ as its not only format
- made behaviour of var merge a toggle
- made 'source over group' path follow existing rule for var precedence
- updated add_host/group from strategy
- made host_list a plugin and added it to defaults
- added advanced_host_list as example variation
- refactored 'display' to be availbe by default in class inheritance
- optimized implicit handling as per @pilou's feedback
- removed unused code and tests
- added inventory cache and vbox plugin now uses it
- added _compose method for variable expressions in plugins
- vbox plugin now uses 'compose'
- require yaml extension for yaml
- fix for plugin loader to always add original_path, even when not using all()
- fix py3 issues
- added --inventory as clearer option
- return name when stringifying host objects
- ajdust checks to code moving
* reworked vars and vars precedence
- vars plugins now load group/host_vars dirs
- precedence for host vars is now configurable
- vars_plugins been reworked
- removed unused vars cache
- removed _gathered_facts as we are not keeping info in host anymore
- cleaned up tests
- fixed ansible-pull to work with new inventory
- removed version added notation to please rst check
- inventory in config relative to config
- ensures full paths on passed inventories
* implicit localhost connection local
* Revert to using url_map internal to the module to allow parameter generation to work. module parameter is still url_map_name.
* [GCP] Cross Region Load Balancer Integration Test
* Improve ansible-test inventory handling.
* Fix python 3 re-raise of exception from thread.
* Fix python 3 encoding for windows-integration.
* Run network tests on multiple python versions.
* Run windows tests on multiple python versions.
* Support Shippable delegation using --tox.
* Skip vyos_command on python 3 tests until fixed.
* Add python 3 filtering to local and tox.
* Fix tests to support back to back runs.
* Temporarily test networking with python 2.7 only.
Running the tests back to back causes intermittent test failures
which need to be addressed before we can test multiple versions
in a single test run.
* [GCP] Healthcheck module
* fix return YAML block
* removed update_ return value; removed python26 check; typos and docs updates
* doc fix
* Updated int test for no-update conditions
* added filter_gcp_fields test
* fixed bug in update where dictionary wasn't built correctly and port was not being set.
* added default values to documentation block
- Overhauled coverage injector to fix issues with non-local tests.
- Updated integration tests to work with the new coverage injector.
- Fix concurrency issue by using random temp files for delegation.
- Fix handling of coverage files from root user.
- Fix handling of coverage files without arcs.
- Make sure temp copy of injector is world readable and executable.
* [GCP] UrlMap module
This module provides support for UrlMaps on Google Cloud Platform. UrlMaps allow users to segment requests by hostname and path and direct those requests to Backend Services.
UrlMaps are a powerful and necessary part of HTTP(S) Global Load Balancing on Google Cloud Platform.
UrlMap takes advantage of the python-api so the appropriate infrastructure has been added to module_utils.
More about UrlMaps can be found at:
https://cloud.google.com/compute/docs/load-balancing/http/url-map
UrlMap API:
https://cloud.google.com/compute/docs/reference/latest/
Google Cloud Platform HTTP(S) Cross-Region Load Balancer:
https://cloud.google.com/compute/docs/load-balancing/http/
* updated documentation, remmoved parens
* fixed tabs
* win_psexec: Enable -nobanner option by default
PR also includes:
- Option `nobanner:` to remove this flag
- Improvements to Examples
- Improvement to Return Value
- Add types to all parameters now
- Add (limited) integration tests
* Move sysinternals into C:\Windows\Temp
A preliminary set of test targets for "core" supported module that had no independent tests. These will also help us ensure python3 compatibility for those modules and prevent future regressions.
Simplified the logic, and fix the issue of having a nested list as
entry.
Also indicate that we deliberately want to retain $null values
(and i.e. do not want them to be turned into a boolean).
* WIP file_mode
* WIP
* Add file_mode + integration tests
* fix pep8
* Update doc fragments
Create mutualy_exclusive param
Fix yamllint problem in tests
* Add aliases file + main playbook for fortios
* Install pyfg before running tests
* Install pyfg before running tests in role
* Remove pre_task as it's done in roles
* Force pyFG minimal version for python3
* role_path not role_dir :(
* Change requirements
* Specify Error type when error on import
* Bug in pygf library with python 2.5 (PR is waiting https://github.com/spotify/pyfg/pull/19)
* Bad requirement format
* still bad format -_-'
* remove test/integration/fortios.py (auto generated by tests)
missing new lines at end of file
* pyFG is now fixed in 0.50
* Add check_mode to get_url that does a HEAD request to make sure the URL exists, but doesn't write the real file
* Add info about new --check behavior to docs. Add tests for the new behavior. Populate res_args with the info the tests are looking for.
* Add trailing comma
* Change nonexistent test URL to http://{{httpbin_host}/DOESNOTEXIST. Fix spacing while I'm at it
* Further spacing cleanup
* State that this functionality is in Ansible 2.4+
* Big testing doc refactor
* Combine all the testing documentation in to one place to make it easier to find
* Convert everything to RST
* Create testing_network guide
* Create testing landing page
* For each section detail "how to run" and "how to extend testing"
* More examples
* Lots more detail
/usr/sbin/locale-gen differs between Debian and Ubuntu. With Debian,
locales must be added to /etc/locale.gen before calling locale-gen
command. With Ubuntu, /etc/locale.gen is updated by
/usr/sbin/locale-gen.
Use the locale-gen module which handles both distributions.
* PostgreSQL tests: use package module
* PostgreSQL tests: use ansible_service_mgr in order to test init system
* PostgreSQL tests: fix a typo
* PostgreSQL tests: install only required packages
* PostgreSQL tests: use role default value when unchanged
* Run `save` before exiting config mode.
* Fix unit tests for `save`
* Allow `save` to be on its own again and introspect success
* Introspecting `compare running` makes this a lot harder.
Move `save` tests to integration tests
Added an integration test for fetch module idempotence. (Testing
that validate_checksum is doing what it's supposed to is harder as we'd
have to create a race condition with the downloaded data to trigger it.
Probably need to make that a unittest eventually).
Also give a deprecation message to the validate_md5 parameter so that we
can eventually get rid of it.
* keep unsafe .. unsafe
fixes#23734, which was broken in previous fix that allowed non string types to be templated
use new 'is_template' function vs bastardizing others
refactored clean_data to allow for arbitrary data structures to clean
fixed/removed some tests
* deal with complex data for is_template
* typos
* Fix vault reading from stdin (avoid realpath() on non-links)
os.path.realpath() is used to find the target of file paths that
are symlinks so vault operations happen directly on the target.
However, in addition to resolving symlinks, realpath() also returns
a full path. when reading from stdin, vault cli uses '-' as a special
file path so VaultEditor() will replace with stdin.
realpath() was expanding '-' with the CWD to something like
'/home/user/playbooks/-' causing errors like:
ERROR! [Errno 2] No such file or directory: u'/home/user/ansible/-'
Fix is to specialcase '-' to not use realpath()
Fixes#23567
* to_text decrypt output when writing to stdout
* Build HTTPSClientAuthHandler more similarly to how HTTPSHandler works
* Add docs for new client cert authentication
* Support older versions of python
* Simplify logic
* Initial support for client certs in urls.py
* Add an extra test
* Add a get_url test for client cert auth
* Add additional test for client cert auth, with validation and ssl mismatch
* Skip assert when http tester not available
* Update version_added for new options
Copy module was walking over files in subdirectories repeatedly (a
directory tree a few levels deep could bring the time spent into the
tens of minutes)
This was traced to the fix for this bug report: https://github.com/ansible/ansible/issues/13013Fixed#13013 a different way and added an integration test to check for
regressions of #13013 as we optimize this code.
Fixes#21513
* Check for proper response key on eos_banner map_config_to_obj
If we run the task with 'login' banner, the 'show banner' command
will return a dict containing key 'loginBanner'.
However for motd, it will just return 'motd'.
Yay naming consistency!
* Do not assert session exists on eos_banner response not changing device
* Add workaround for evasive in apache2_module
* Fixes#22635
* Clean up workarounds for php/shib
* Add test for evasive workaround
* Remove use of re module, since all searches work with native python
* Add unit tests to apache2_module name replacements
Go back to using re package where needed
* Rename replace_name to create_apache_identifier
Test that, when a group is created with group_by, variables from the
corresponding group_vars/ file are correctly pulled in, and override
variables specified in group_vars/all.
See ansible/ansible#8664.
* fix 'sequence' lookup shortcut syntax and documentation
* Update playbooks_loops.rst
Minor edits for grammar and clarity.
* Update playbooks_loops.rst
Another tweak for clarity.
* Fixes bug https://github.com/ansible/ansible/issues/22455 - Git reset fails when file with the name 'origin' is present in the repository
* #22455 Integration test for git module to test if it clones a repository with a file named origin
* Fixed yaml errors for test/integration/roles/test_git_clone/tasks/main.yml
* Removed the newly added target git and moved the code to test/integration/targets/git
* Reorganised code structure as per comments
* Fixed playbook name
* Added code that didn't make it to the playbook before.
* No longer need git.yml
* Remove non tasks specific code from tasks file and use existing variables
* Removed msg var from the vars.yml
* update integration tests for updated boto exception message
* integration tests fail on both "test credential" test cases
exception bubbles out of module. instead catch and wrap
* ec2_group does not support updating a security group's description
AWS security group descriptions are immutable.
if ec2_group finds a group that matches by name, but the descriptions do not match, the module does not support this case
previously it would check if the group was used, but would not do anything if it was
old behavior was erroneous because it could make a user expect that the description change of a group was fine when in fact it did not occur
also, it made an expensive check against all ec2 instances for no good reason
* comments not doc strings
* else must have pass w/o doc-string statement
* Catch specific BotoServerException, give context around error when fetching SGs
* python3 compatible exception blocks
* add traceback to fail_json
* two blank lines before first function
* fixes#15770
* When running under the UTF-8 codepage, Powershell subprocesses will fail (eg, Start-Job, others) if the input encoding is using the default BOM preamble. This fix forces it to use no preamble in leaf_exec and win_shell, and includes tests to verify that Start-Job works.
This change to the template action plugin make template use the
platform's native newline_sequence for Jinja.
We also added the option `newline_sequence` to change the newline
sequence using by Jinja if you need to use another newline sequence than
the platform default.
This was previously discussed in
https://github.com/ansible/ansible/issues/16255#issuecomment-278289414
And also relates to issue #21128
* fixes#22441
* fixes#22655
* moves all env handling into the exec wrapper; this should work for everything but raw, which is consistent with non-Windows.
* win_scheduled_task: Added frequency: once and check_mode support
This patch includes:
- Renamed `execute:` parameter to `executable:`
- Renamed `argument:` parameter to `arguments:`
- Implemented `frequency: once` support
- Implemented check_mode support
- Fix idempotency issue related to empty description
- Added integration tests
* Improve the integration test structure
I think this is a great way to test normal mode and check-mode from the same playbook.
* Small fixes after review
Fixes#22575 - issue under new exec wrapper where unconstrained handle inheritance (for stdin) caused WinRM to block on breakaway processes. Uses explicit handle inheritance to ensure that only stdin read handle gets inherited. Adds test to ensure that async is actually async.
* candidate var can now be string, list or element
* fixes minor bug in junos_template for backup argument
* disabled invalid integration test for junos_template
* removes cli functions
* adds comment and confirm to arguments
* implements zeroize argument
* fixes get_diff function in junos shared lib to return diff
* lots of minor bug fixes in junos_config
* minor syntax fixes in junos_netconf
* updates netconf integration tests
* eos_banner docs improvements
* run eos_banner tests
* basic eos_banner tests
* remove trailing newlines
* remove hack
* Various eos_banner fixes
No unicode tests, as the device doesn't support it
Correctly set provider
result.command should be empty list if no changes
* test eos_banner over eapi
* revert docs changes, moved to separate PR
* description is only required when group state is present
also note that AWS requires a non-empty description when creating a security group
* clarify description requirement
fixes integration test to check for full rpc-reply string when
converted from xml. This is a change from 2.2 as the rpc-reply tag
is no longer stripped off
* Fixes#21316, add testcase based on this
* Add option `--branch NAME` to git clone command in case of branch or
tag in combination with depth=1
* This option should work back to at least git 1.8 and thus on all
supported distributions
* Provide better warning if depth is dropped
* VLAG module and tests
* Correct the link in the description of the module
* Move roles to integration/roles directory and remove aliases file.
* update module short description
* Change module directory name to Lenovo
* change import cnos statement
* Initial commit of cnos_conditional_template
* fix compile error in module, change module short description, move roles to integration/roles
* fix line length
* Change module directory name to Lenovo
* change import cnos statement
* Initial commit of cnos_condition_command
* fix pep8 error of line too long
* fix pep8 tab/space issue
* Move roles to integration/roles directory and remove aliases file.
* Update module short description
* Change module directory name to Lenovo
* change import cnos statement
* initial comment of cnos_save
* Move roles to integration/roles directory and remove aliases file.
* update the module short description
* Change module directory name to Lenovo
* change import cnos statement
* fix in cnos.py utility file
* fix compile errors in cnos.py, update module short description in cnos_vlan.py, move vlan roles under integration/roles
* corrections in readme
* Change module directory name to Lenovo
* change import cnos statement
* initial commit
* fix tab/space issue
* fix space issue in vars/main.yml
* Move roles to integration/roles directory and remove aliases file.
* update module short description
* change module directory name to Lenovo and change import cnos statement
* cnos_portchannel initial commit
* Fix line length issue in module
* fix whitespace on line 90
* correct yamllint space issue
* Move roles to integration/roles directory and remove aliases file.
* update module short description
* Change module directory name to Lenovo
* change import cnos statement
* WIP: wait_for_connection: Wait for system to be reachable
This action plugin allows to check when a system is back online and
usable by Ansible.
As an example, when doing a SysPrep and running Enable-WinRM.ps1, it
takes between 10 to 20 seconds between the WinRM TCP port to open, and
it actually being able to server Ansible requests. This time is variable
and depends on the boot process.
Current implementation is specific for Windows (WinRM) only, this will
be fixed shortly.
This fixes#19998
* Support other transport types
* Various improvements
- Fix reported typo
- Add transport_test support in accelerate plugin
- Ensure port is an integer
* Improve examples
* Small fixes
- Use correct ConfigureRemotingForAnsible.ps1 script name
- Only use win_ping when remote shell is known to be Powershell
- Add integration tests to CI framework
* Make sure the uri module warns about using the deprecated HEADER_ arguments, so that we can actually deprecate in a future version
* Use module.deprecate
* No need to de-dupe ourselves, looks like it is done somewhere I didn't initially see
* Adds integration test steps to win_regedit test to cover Extras 2090
* Fixed merge conflict and error in win_regedit integration tests
* fixed pep8 space after comma requirement discovered by ci build
* Fix vyos signatures to match new versions
* Fix test cases referring to 'updates' instead of 'commands'
* I think this is an artifact of `connection: network_cli`?
* module will now check protocol running state before return
* warns on config argument no longer being needed
* lots of integration test cases updated
* updates unit and integration test cases for state check
fixes#21908
eos_config module wasn't respecting config block path (parents). This
patch fixes that problem. Also fixes a number of integration tests
cases
fixes#21903
Fix 'task name is not templated in retry callback'
Add a task_name property to TaskResult that knows to
check in TaskResult._task_fields.
Add integration test for v2_retry_runner callback
Fixes#18236
When parsing the configuration, the wrong indent level was set so the
configurations could not be properly compared. Also noted that
defaults: yes needed to be added to the integration tests to make the
test cases valid, which is also included in this patch
fixes#21828
* First set of CNOS network modules
Two modules: cnos_vlan and cnos_command. First 2 of 17 CNOS modules
* Revert "First set of CNOS network modules"
This reverts commit 63da68b2a857e622b449f514050eed25fbcf0a35.
* cnos_vlan module
First of 17 CNOS modules
* Modify playbook for cnos_vlan module testing
* fix issue found by shippable in cnos.py
* cnos_backup module
* Fix Python3.5 compilation error
* remove cnos_backup module from this PR
* add aliases file so that testing of the cnos_vlan module will be skipped.
* Use empty aliases file
* utility scripts under module_utils changed to BSD license.
* clean up PEP8 issues, add cnos_vlan tests
* remove blank lines from yml files
* remove more blank lines
* remove even more blank lines
* Revert "remove even more blank lines"
This reverts commit bb3998661ce387260340bca39d5f146f5ec54f44.
* re-submit last commit
* fix blank lines in this file under parsing
* fix yamllint errors in doc section of cnos_vlan
* Fix errors reported by Sanity check using validate-modules
* change test playbook to include tasks for all modules
* fix additional pep8 errors
* more fixes, plus fix for python3
* fix for empty options section, removed unnecessary documentation
* fix up documentation section
* Correct options capitalization
* fix example section, add options
* Fix example section of the documentation
I have from time to time a need of random password without
wanting to write them down (one example is mailman list creation,
that requires a password to be given to be sent to the list owner).
But using /dev/null do not return null, but the empty string, which
doesn't generate a password at all and so do not achieve my use case.
hashlib hashes operate on byte strings. When given a text string on
Python3, hashlib backtraces. When given a text string on Python2,
hashlib will backtrace if the string contains non-ascii characters.
Encode the text string to utf-8 prior to hashing to avoid this problem.
Fixes#21452
* known_hosts: support --diff
* known_hosts: support --diff also without --check
* Add unit tests and fix incorrect diff in one corner case
Tests are good!
* Refactor for readability
* Python 3 compat
* More Python 3 compat
* Add an integration test for known_hosts
* Handle ssh-keygen -HF returning non-zero exit code
AFAICT this is a bug in ssh-keygen in some newer OpenSSH versions
(>= 6.4 probably; see commit dd9d5cc670):
when you invoke ssh-keygen with -H and -F <host> options, it always
returns exit code 1. This is because in ssh-keygen.c there's a function
do_known_hosts() which calls
exit (find_host && !ctx.found_key);
at the end, and find_host is 1 (because we passed -F on the command line),
but ctx.found_key is always 0. Why is found_key always 0? Because the
callback passed to hostkeys_foreach(), which is known_hosts_hash(),
never bothers to set found_key to 1.
* This test does not need root
* Avoid ssh-ed25519 keys in sample known_hosts file
Older versions of OpenSSH do not like them and ssh-keygen -HF
aborts with an error when it sees such keys:
line 5 invalid key: example.net...
/root/ansible_testing/known_hosts is not a valid known_hosts file.
* Fix Python 3 errors
Specifically, the default mode of tempfile.NamedTemporaryFile is 'w+b',
which means Python 3 wants us to write bytes objects to it -- but the
keys we have are all unicode strings.
Network devices in the lab have by default an indentation of 1 for
sub-sections, and so does the netcfg.NetworkConfig constructor
indent param.
This will fix reported issue 21055, and make the integration tests
to pass.
Fixes#21055
- centralized skipping
- also fixed module name broken by previous refactor
- let action modules handle async processing
- moved async into base action class's module exec
- action plugins can now run final action as async
- actually skip copy if base skips
- fixed normal for new paths
- ensure internal stat is never async
- default poll to 10 as per docs
- added hint for callback fix on poll
- restructured late tmp, now a pipeline query
- moving action handler to connection as networking does
- fixed network assumption invocation is always passed
- centralized key cleanup, normalized internal var
- _supress_tmpdir_delete now in _ansible_xxx and gets removed from results
- delay internal key removal till after we use em
- nicer tmp removing, using existing methods
- moved cleanup tmp flag to mking tmp func
* added docs for vault and made trigger shorter: !vault
* added single var valuting
* Update playbooks_vault.rst
Edit pass for spelling and grammar. Ship it!
* Update playbooks_vault.rst
Typo fixes.
* Make the module_utils path configurable
* Add a config value to define the path site module_utils files
* Handle module_utils that do not have source as an error
* Make an integration test for module_utils envvar working
* Add documentation for the ANSIBLE_MODULE_UTILS config option/envvar
* Add it to the sample ansible.cfg
* Add it to intro_configuration.
* Also modify intro_configuration to place envvars on equal footing with
the config options (will need to document the envvar names in the
future)
* Also add the ANSIBLE_LIBRARY use case from
https://github.com/ansible/ansible/issues/15432 so we can close out
that bug.
* win_shortcut: Add missing $check_mode definition
For some reason this entry was missing, possible a merge-conflict gone
wrong :-(
* Added integration tests and bugfix
Add missing changes.
This version just gets the relevant paths from PluginLoader and then
uses the existing imp.find_plugin() calls in the AnsiballZ code to load
the proper module_utils.
Modify PluginLoader to optionally omit subdirectories (module_utils
needs to operate on top level dirs, not on subdirs because it has
a hierarchical namespace whereas all other plugins use a flat
namespace).
Rename snippet* variables to module_utils*
Add a small number of unittests for recursive_finder
Add a larger number of integration tests to demonstrate that
module_utils is working.
Whitelist module-style shebang in test target library dirs
Prefix module_data variable with b_ to be clear that it holds bytes data