Upgrade to Pro — share decks privately, control downloads, hide ads and more …

A ZF2 based command line interface for DevOps automation

A ZF2 based command line interface for DevOps automation

CLI usage is gaining importance in today's web application development and deployment landscape, with more tools leveraging it because it allows the automation of more complex, one-off tasks. In this session I will demonstrate the Zend Server Web API, and how we built a ZF2 application to consume using Zend\Console. This allowed us to create a tool which can be used from third party applications to automate tasks like deployment, configuration, import/export etc. Lots of code samples will be shown!

Slavey Karadzhov

October 10, 2013
Tweet

More Decks by Slavey Karadzhov

Other Decks in Programming

Transcript

  1. A ZF2 Based
    Command Line
    Interface For
    DevOps Automation.
    Slavey Karadzhov
    Senior Consultant
    Zend Technologies

    View Slide

  2. 2
    •Name: Slavey Karadzhov (Славей Караджов)
    •Senior Technical Consultant and Trainer
    at Zend Technologies
    •Zend Framework (ZF) and PHP ZCE
    •Many years of PHP (v3,4 & 5), ZF and galaxy of
    programming languages (Python, Perl, Java, JavaScript,…).
    •Author of the “Learn ZF2” book ( http://learnzf2.com )
    About me

    View Slide

  3. 3
    •Zend Server WebAPI
    •Console Clients
    •Implementing Console Client In ZF2
    •Usage
    •Composer Integration*
    •Demo
    •Questions & Answers
    Agenda

    View Slide

  4. Zend Server WebAPI

    View Slide

  5. 5
    •Zend Server
    o Complete, enterprise-ready PHP Application Server for
    →Running
    →Deploying
    →Managing
    o Allows Third-Party integration
    o More at http://www.zend.com/en/products/server/ .
    Zend Server WebAPI

    View Slide

  6. 6
    •The WebAPI
    o Remote control and automation of Zend Server features:
    →Deployment
    →Configuration
    →Management
    →Monitoring
    o Integration with 3rd Party
    →Using zs-manager
    →Your own WebAPI client
    Zend Server WebAPI

    View Slide

  7. 7
    Zend Server WebAPI

    View Slide

  8. Console Clients

    View Slide

  9. 9
    •Console Client
    o Command Line Interface client consuming the WebAPI
    •Advantages in terms of
    o Automation
    o Integration
    Console Clients

    View Slide

  10. 10
    •Why yet another WebAPI command line client?
    o zs-manage
    →Part of Zend Server distribution
    →Not available in Windows
    →Hard to separate from Zend Server
    →Not super-easy to extend
    →Does not support all available methods
    o Java SDK
    →Java
    →Requires efforts to integrate
    Console Clients

    View Slide

  11. 11
    •Requirements for a successful client
    o To run on every system where PHP >= 5.3 can run
    o To be small and self-contained
    o To be easy to use
    o To be super-easy to extend from a PHP programmer
    →Has powerful and yet easy declarative syntax to describe new
    commands
    →Allows adding high-level commands
    o Allows inline documentation of the commands
    Console Clients

    View Slide

  12. Implementing Console Client
    in ZF2

    View Slide

  13. 13
    •Why Zend Framework 2 (ZF2)
    o Zend\Console component - helps creation of console clients
    o Allows you to use only the components you need, without forcing
    you to have the complete framework
    o Has good composer support
    o Because ZF2 rocks!
    →ZF2 is popular
    →Easy code reuse
    — Our code can be valuable and freely used and extended from others
    →Allows writing lean and clean code (Implements ideas from Aspect
    Oriented Programming, Modular + Event driver architecture, etc.)
    Implementing Console Client in ZF2

    View Slide

  14. 14
    •Minimum needed ZF2 components
    o Composer.json
    Implementing Console Client in ZF2
    {
    "name": "zenddevops/webapi",
    require": {
    "php": ">=5.3.3",
    "zendframework/zend-serializer" : ">=2.0.0",
    "zendframework/zend-text" : ">=2.0.0",
    "zendframework/zend-mvc" : ">=2.0.0",
    "zendframework/zend-file" : ">=2.0.0",
    "zendframework/zend-console" : ">=2.0.0",
    "zendframework/zend-servicemanager" : ">=2.0.0",
    ...
    "zendframework/zend-stdlib" : ">=2.0.0",
    "zendframework/zend-view" : ">=2.0.0",
    "zendframework/zend-config" : ">=2.0.0",
    "zendframework/zend-http" : ">=2.0.0"
    },
    }

    View Slide

  15. 15
    •Command definitions as routes
    Implementing Console Client in ZF2
    'console' => array (
    'router' => array (
    'routes' => array (
    //..
    'configurationImport' => array (
    'options' => array (
    'route' => 'configurationImport --configFile= [--ignoreSystemMismatch=]',
    'defaults' => array (
    'controller' => 'webapi-api-controller',
    'action' => 'configurationImport',
    'apiMethod' => 'post'
    ),
    'files'=>array('configFile‘),
    'group' => 'configuration',
    'info' => array (
    'Import a saved configuration snapshot into the server.',
    array('--configFile','The configuration snapshot file to import.'),
    //...

    View Slide

  16. 16
    •Console Module
    Implementing Console Client in ZF2
    class Module implements ConsoleUsageProviderInterface,
    ConsoleBannerProviderInterface
    {
    public function getConsoleUsage (Console $console)
    { //..
    }
    public function getConsoleBanner (Console $console)
    {
    return 'ZendServerWebApi Client version 1.0';
    }
    }

    View Slide

  17. 17
    •Taking control
    Implementing Console Client in ZF2
    class Module implements ConsoleUsageProviderInterface,
    ConsoleBannerProviderInterface
    {
    public function onBootstrap ($event)
    {
    $eventManager = $event->getApplication()->getEventManager();
    $eventManager->attach(MvcEvent::EVENT_ROUTE,
    array($this, 'postRoute'), - 2);
    $eventManager->attach(MvcEvent::EVENT_FINISH,
    array($this, 'preFinish'), 100);
    }
    }

    View Slide

  18. 18
    •Post-Processing Input Parameters
    Implementing Console Client in ZF2
    class Module implements ConsoleUsageProviderInterface,
    ConsoleBannerProviderInterface
    {
    //...
    public function postRoute (MvcEvent $event)
    {
    //..
    foreach ($config['console']['router']['routes'][$routeName]['options']['files'] as
    $param) {
    if ($value = $match->getParam($param)) {
    $match->setParam($param, $path->getAbsolute($value));
    }
    }
    //…
    }
    //..

    View Slide

  19. 19
    •In-Line Help
    Implementing Console Client in ZF2
    class Module implements ConsoleUsageProviderInterface,
    ConsoleBannerProviderInterface
    {
    //...
    public function getConsoleUsage (Console $console)
    {
    $usage = array();
    //..
    foreach ($routes as $route) {
    $command = $route['options']['route'];
    $usage[] = "* $command";
    if (isset($route['options']['info'])) {
    //…
    }
    }
    //..
    return $usage;
    //..

    View Slide

  20. 20
    •Using input parameters in Actions
    Implementing Console Client in ZF2
    class ZpkController extends AbstractActionController
    {
    public function packAction()
    {
    $folder = $this->getRequest()->getParam('folder');
    $destination = $this->getRequest()->getParam('destination');
    //…
    }
    //..

    View Slide

  21. 21
    •Outputting response in Actions
    Implementing Console Client in ZF2
    class ZpkController extends AbstractActionController
    {
    public function packAction()
    {
    //…
    $this->getResponse()->setContent($textContent);
    return $this->getResponse();
    }
    //..

    View Slide

  22. 22
    •Enabling debug mode
    Implementing Console Client in ZF2
    class Module implements ConsoleBannerProviderInterface
    {
    public function getConfig ()
    {
    $config = include __DIR__ . '/config/module.config.php';
    if (!getenv('DEBUG')) {
    $config['view_manager']['exception_message'] = <<======================================================================
    The application has thrown an exception!
    ======================================================================
    :className
    :message
    EOT;
    }
    return $config;
    }

    View Slide

  23. 23
    •Separating own module code and dependant stuff
    o Using composer
    •Packing everything together
    o As phar file
    Implementing Console Client in ZF2
    //..
    $pharPath = $buildRoot . "/$filename";
    $phar = new \Phar($pharPath, 0, $filename);
    $phar->startBuffering();
    //..
    $phar->setStub($stub);
    $phar->stopBuffering();
    //..

    View Slide

  24. Usage

    View Slide

  25. 25
    •Help system
    o Command groups
    →zs-client.phar –-help
    o Commands in specific group
    →Ex: Show all commands in the monitor group
    — zs-client.phar command:monitor
    o Specific command
    →zs-client.phar configurationExtensionsOn --help
    o All commands
    →zs-client.phar command:all
    Usage

    View Slide

  26. 26
    •Target
    o zs-client.phar addTarget –-target= --zsurl=.. –-zskey=
    •Packaging
    o Add deployment support to existing PHP code
    →zs-client.phar initZpk –-folder=../LegacyProjectFolder/
    o Create package
    → zs-client.phar packZpk –-folder=../LegacyProjectFolder/ \
    --destination=/tmp
    •Deployment
    o zs-client.phar installApp –-zpk=/tmp/application.zpk
    –-target= --baseUri= --createVhost=TRUE
    Usage

    View Slide

  27. 27
    •Configuration
    o Turning on or off extensions
    →zs-client.phar configurationExtensionsOff --extensions="mysql,gd,ftp"
    o Changing directives
    →zs-client.phar configurationStoreDirectives
    --directives="date.timezone=Europe/Berlin&allow_url_include=Off“
    Usage

    View Slide

  28. Composer Integration*

    View Slide

  29. 29
    •Need to use the “composer” branch in git
    •Packaging
    o Create package
    → zs-client.phar packZpk –-folder=../LegacyProjectFolder/ \
    --destination=/tmp \
    --composer
    — Calculates the dependacies
    — Creates library packages
    — Sets the current application requirements
    — Creates the application package
    Composer Integration*

    View Slide

  30. 30
    Composer Integration*
    ZPKS=`php bin/zs-client.php packZpk --folder="" \
    --destination="" \
    --composer 2>/dev/null`;
    for i in $ZPKS; do
    php bin/zs-client.php installApp --zpk="$i" \
    --target="" \
    --baseUri="" \
    --userParams="APPLICATION_ENV=staging&DB_TYPE=mysql"
    done;

    View Slide

  31. Demonstration

    View Slide

  32. Thank You!
    Feedback: https://joind.in/9103
    GitHub: https://github.com/zendtech/ZendServerSDK/
    WebAPI: http://files.zend.com/help/Zend-Server-6/zend-
    server.htm#the_applicationgetstatus_method.htm

    View Slide