0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

JN0-224 JNCIA-DevOps Exam Guide: PyEZ, NETCONF, XPath and REST API Labs

0
Posted at

The JN0-224 exam leads to JNCIA-DevOps (HPE Juniper Networks Certified Associate, Automation and DevOps). It's the entry exam for engineers who want to manage Junos devices with code instead of the CLI. It isn't a programming exam in the computer-science sense: you won't write algorithms. What it checks is whether you can read a short PyEZ script, an XPath expression, a YAML file or a curl call and say what it will do. The quickest way to get there is to write those pieces yourself, so this guide follows the blueprint with small labs you can run against a vJunos or vSRX instance.

JN0-224 exam at a glance

Item Detail
Exam code JN0-224
Certification JNCIA-DevOps (Automation and DevOps, Associate)
Questions 65 multiple choice
Duration 90 minutes
Passing score Pass/fail, roughly 60–70%
Price USD 200
Delivery Pearson VUE
Software versions Junos 24.2, Python 3.8.10, PyEZ 2.6.3
Recommended course Introduction to Junos Platform Automation and DevOps (IJAUT)

That works out to about 83 seconds per question, enough time to read a 15-line code sample carefully. Check the official JNCIA-DevOps certification page before booking, because Juniper updates the software versions the exam is based on.

The five blueprint domains

  1. Junos automation stack and DevOps concepts: tools, frameworks, APIs and DevOps culture.
  2. NETCONF/XML API: XML syntax, XPath, NETCONF and the Junos XML API.
  3. Data serialization: YAML and JSON.
  4. Python/PyEZ: syntax, JSNAPy, Jinja2, RPCs, exception handling, device status and configuration.
  5. REST API: the Junos REST API, the REST API Explorer and curl.

Python/PyEZ carries the most objectives and draws on the other four, so the labs below spend most of their time there.

Lab setup

One virtual Junos device is enough. Enable the services the exam covers:

set system services ssh
set system services netconf ssh
set system services rest http port 3000
set system services rest enable-explorer
set system login user automation class super-user authentication plain-text-password
commit

On your workstation:

python3 -m venv jncia && source jncia/bin/activate
pip install junos-eznc jsnapy

Domain 1: The Junos automation stack

Expect questions that ask you to place a tool in the stack:

Layer Examples Runs where
On-box scripting Commit, op and event scripts (SLAX or Python) On the Junos device
APIs NETCONF/XML API, Junos REST API, gRPC/gNMI telemetry Device exposes them
Libraries Junos PyEZ (Python) Off-box, your workstation
Frameworks Ansible (juniper.device collection), Salt Off-box
Testing JSNAPy Off-box

The DevOps questions are conceptual: version control for configuration, small and frequent changes, automated testing before and after a change, and shared ownership between network and development teams. If an answer choice describes a manual, one-off process, it is usually the wrong one.

Domain 2: NETCONF, XML and XPath

NETCONF (RFC 6241) runs over SSH, by default on port 830, and its operations work on configuration datastores. Junos uses the candidate configuration model you already know from the CLI. The core operations are <get-config>, <edit-config>, <lock>, <unlock>, <commit> and <close-session>. Junos also accepts its own XML RPCs for every operational command.

The trick that answers many exam questions is that any CLI command shows its XML RPC and its XML output:

user@vjunos> show interfaces terse ge-0/0/0 | display xml rpc
<rpc-reply xmlns:junos="http://xml.juniper.net/junos/24.2R1/junos">
    <rpc>
        <get-interface-information>
                <terse/>
                <interface-name>ge-0/0/0</interface-name>
        </get-interface-information>
    </rpc>
</rpc-reply>

From that output you can derive the PyEZ method name: replace hyphens with underscores, so get-interface-information becomes get_interface_information. Empty tags such as <terse/> become terse=True.

XPath selects nodes from the XML reply. These are the patterns worth memorising:

XPath Selects
//physical-interface Every physical-interface element at any depth
physical-interface/name The name child of each physical-interface
//physical-interface[oper-status='down']/name Names of interfaces that are down
//logical-interface[1] The first logical-interface under each parent
@junos:style An attribute, not an element

Remember that Junos XML text often carries newline whitespace, so compare with normalize-space() or call .strip() in Python.

Domain 3: YAML and JSON

Questions show a document and ask whether it is valid, or what data type a value is. Here is the same data both ways:

---
devices:
  - name: core1
    host: 192.0.2.10
    interfaces: [ge-0/0/0, ge-0/0/1]
    ospf: true
{
  "devices": [
    {"name": "core1", "host": "192.0.2.10",
     "interfaces": ["ge-0/0/0", "ge-0/0/1"], "ospf": true}
  ]
}

Things that trip people up: YAML indentation must use spaces, not tabs. A dash starts a list item. In YAML, yes, no, on and off may load as booleans unless quoted. JSON needs double quotes and allows no trailing commas. Junos can produce JSON directly with | display json.

Domain 4: Python and PyEZ

Connect, read facts and call an RPC

from jnpr.junos import Device

with Device(host="192.0.2.10", user="automation", passwd="lab123") as dev:
    print(dev.facts["hostname"], dev.facts["model"], dev.facts["version"])

    reply = dev.rpc.get_interface_information(terse=True, interface_name="ge-0/0/*")
    for ifd in reply.findall("physical-interface"):
        name = ifd.findtext("name").strip()
        status = ifd.findtext("oper-status").strip()
        print(f"{name:<12} {status}")

Points the exam likes: Device uses NETCONF over SSH (port 830 by default), the context manager opens and closes the session for you, dev.facts is collected when the session opens, and RPC replies are lxml elements, so findall, findtext and xpath all work on them. To get output in another format, pass {"format": "json"} or {"format": "text"} as the first positional argument to the RPC call.

Change configuration safely with Config and Jinja2

{# interfaces.j2 #}
{% for ifc in interfaces %}
set interfaces {{ ifc.name }} description "{{ ifc.desc }}"
set interfaces {{ ifc.name }} unit 0 family inet address {{ ifc.ip }}
{% endfor %}
from jnpr.junos import Device
from jnpr.junos.utils.config import Config
from jnpr.junos.exception import (ConnectError, LockError,
                                  ConfigLoadError, CommitError)

data = {"interfaces": [
    {"name": "ge-0/0/1", "desc": "to-core2", "ip": "10.0.12.1/30"},
]}

try:
    with Device(host="192.0.2.10", user="automation", passwd="lab123") as dev:
        with Config(dev, mode="exclusive") as cu:
            cu.load(template_path="interfaces.j2", template_vars=data, format="set")
            cu.pdiff()
            if cu.commit_check():
                cu.commit(comment="JNCIA-DevOps lab: interface update")
except ConnectError as err:
    print(f"Cannot connect: {err}")
except LockError:
    print("Configuration is locked by another user")
except (ConfigLoadError, CommitError) as err:
    print(f"Change rejected: {err}")

Know what each step does. mode="exclusive" locks the candidate configuration (the same as configure exclusive). load() accepts set, text (curly-brace) or xml formats. pdiff() prints the same diff as show | compare. commit_check() validates without activating. rollback() discards uncommitted changes.

The exception hierarchy is a common question. ConnectAuthError, ConnectTimeoutError and ConnectRefusedError are all subclasses of ConnectError, so catching ConnectError covers them all. Configuration problems raise ConfigLoadError, LockError or CommitError, and RPC failures raise RpcError or RpcTimeoutError.

JSNAPy: test before and after a change

JSNAPy takes snapshots of operational state and compares them. A test file looks like this:

# test_interfaces.yml
tests_include:
  - check_interfaces_up

check_interfaces_up:
  - command: show interfaces terse ge-0/0/*
  - iterate:
      xpath: physical-interface
      id: name
      tests:
        - is-equal: oper-status, up
          err: "Interface <{{id_0}}> is {{post['oper-status']}}"
          info: "Interface <{{id_0}}> is up"

Use jsnapy --snap pre, make the change, run jsnapy --snap post, then jsnapy --check pre post to compare. --snapcheck takes one snapshot and runs the tests against it straight away. The difference between --check (compares two snapshots) and --snapcheck (tests one snapshot) is a favourite exam question.

Domain 5: The Junos REST API

With the configuration from the lab setup, every RPC is available over HTTP:

# Single RPC, XML reply (the default)
curl -u automation:lab123 http://192.0.2.10:3000/rpc/get-software-information

# Same RPC, JSON reply
curl -u automation:lab123 -H "Accept: application/json" \
     http://192.0.2.10:3000/rpc/get-software-information

# RPC with parameters
curl -u automation:lab123 \
     "http://192.0.2.10:3000/rpc/get-interface-information?terse=&interface-name=ge-0/0/0"

The REST API Explorer is a browser GUI on the same port that lets you pick an RPC, fill in its parameters and see both the generated curl command and the reply. It is useful for learning, but don't leave it enabled on production devices. Know the defaults: port 3000 for HTTP and 3443 for HTTPS, HTTP basic authentication, GET for a single RPC, and POST to /rpc to send several RPCs in one request.

A four-week JN0-224 study plan

Week Focus Lab goal
1 Domains 1–3 Use display xml rpc and display json on 20 commands, write XPath for each
2 PyEZ read operations Facts, RPC calls, parsing replies with findtext and xpath
3 PyEZ changes and testing Config utility with Jinja2, exception handling, JSNAPy pre/post checks
4 REST API and review curl and REST Explorer, then timed practice questions

In week 4, switch to timed practice. NWExam has free JN0-224 sample questions in the same read-the-snippet style, and the Junos PyEZ Developer Guide is the reference to go back to when a question about the Config or Device classes catches you out.

Exam-day checklist

  • CLI command to RPC: | display xml rpc, then swap hyphens for underscores to get the PyEZ name.
  • NETCONF runs over SSH on port 830. The REST API defaults to port 3000 (HTTP) and 3443 (HTTPS).
  • ConnectError is the parent of the connection exceptions. Config problems raise ConfigLoadError, LockError or CommitError.
  • commit_check() validates, pdiff() shows the diff, rollback() discards changes.
  • JSNAPy --check compares two snapshots and --snapcheck tests one.
  • YAML uses spaces, not tabs, and JSON needs double quotes with no trailing commas.

If you can read each code block in this guide and predict its output before running it, you are ready for the JN0-224 JNCIA-DevOps exam.

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?