Creating State data with Pyobjects
A high level Pythonic API
Evan Borgstrom
#SaltConf15
Site Reliability, LinkedIn
Pyobjects?
• It’s an alternative renderer for your state data
• High level “Pythonic” API
• Part of SaltStack since 2014.7.0
Context
• Long time user & contributor
• Ended up with a very large state tree and
became frustrated with YAML + Jinja
• Began initial brainstorming late 2013
• Finally inspired to start on Pyobjects at SaltConf
2014
Motivation
• 6500+ lines over
hundreds of states
(plus pillars)
• YAML no longer felt
like markup due to all
of the Jinja syntax
Not markup anymore
+
#!py
Basics
Batteries available
• Fully fledged Python environment
• Import whatever you need to compile your data
• Here be dragons:
– Blocking operations
– Monkey patching (gevent, etc)
No boilerplate
• Built-in run() function takes care of collecting and
returning data.
• No need to import import anything from
Pyobjects, everything is included
• Should be as natural as writing YAML
State objects
• One per State available on the minion
• CapWords version of the name
– file -> File
– postgres_user -> PostgresUser
– ssh_known_hosts -> SshKnownHosts
• Exposes each state function as a function
– File.managed, Pkg.installed, etc…
Using State objects
Including
• include() function takes a variable number of
arguments
• One per state to include
• Can include any state, not just pyobjects
Extending
• The extend() function is used in place of the ID
being passed to the state.
• Works exactly the same as the extend
declaration in YAML
Importing
• State trees will eventually become complex
enough that you’ll want to create reusability
• Pyobjects provides an augmentation to the import
statement to allow salt:// URIs
Context Managers / Requisites
Convenience Objects
Maps
Maps 101
Targeting using grains
• Preferred way of building configuration
• Allows for dynamically changing values without
conditionals
• Matches against the inner class name
• The grain defaults to os_family
– Add __grain__ to the class to change it
Merging with Pillar data
• Often times you’ll want to change configuration
under some special conditions
• Pillars provide the perfect platform for this
• Specify the pillar name in the merge attribute in
the main class
Best Practices
Pyobjects compliments YAML
• Pyobjects only makes sense when you need to
introduce logic into your state generation
• YAML should still be used when do you need
programmatic functions
Move logic out of templates
Pillars + Maps
• Maps provide default values for all of your
baseline settings
• Pillars allow customization using Salt’s targeting
system
• Keeps all of the configuration with the code
Future improvements
Lazy loading of modules
• The loader is lazy (pull #20274)
• Pyobjects triggers loading of all state modules
• Execution time on busy minions can be
decreased
Reactor files
• Reactor files are prime candidates to benefit from
the separation of logic & presentation
• Need to support the Local, Runner & Wheel
prefixes in a Pythonic way
Map support for complex Grains
• Currently Grains are limited to matching against
the syntax supported by Python class names
• Will be adding support through another “dunder”
attribute that allows for complex grain matching
– All numbers
– Patterns
FIN.
Please provide session feedback in the SaltConf15 mobile app
@borgstr / #SaltConf15