text:
---
title: "Malware Reversing - Analysis 1: COM Objects"
date: 2019-09-02
tags: [malware]
categories: [reverse engineering]
author_profile: false
---

I've been researching and practicing reverse engineering techniques for the better part of the past year and have found the book [Practical Malware Analysis](https://nostarch.com/malware) to be a very useful resource as it is very thorough and covers a variety of reversing skills. Additionally, one of the most beneficial aspects of this book is that it ships with dozens of realistic malware samples - all with varying behaviors and levels of sophistication. This is the first in a series of posts where I'll pick and choose different samples to do walkthroughs of the reversing process I took. I'll try to keep them relatively brief, focusing mainly on the unique properties of the malware or on specific techniques, avoiding an instruction-by-instruction analysis of the disassembly.

The malware samples analyzed may be downloaded [here](https://practicalmalwareanalysis.com/labs/).

This walkthrough will cover sample_07-02. After loading the malware sample in IDA, we'll start by looking for any interesting Strings or Imports that we can use for cross references to locations in the disassembly that are likely the malware's custom code, away from all the compiler-generated code.

Viewing the Strings didn't immediately show anything interesting, just a few dll references; but allowing Unicode strings to be shown revealed a URL:

After selecting `Unicode C-style (16 bits)` above, the apparent URL below became visible:

Viewing the Imports showed something interesting as well. Imports such as `OleInitialize` and `CoCreateInstance` hint that the malware may take advantage of COM objects - more on this later:

Listing the Cross-References to the URL string found shows a single reference was made in `sub_401000`. Further investigating shows that the imports identified are also referenced exclusively in this subroutine.

To get an idea of where this subroutine is in the bigger picture of the disassembly, I listed the Cross-References to the function and saw that it's only called in the `start` subroutine, which is the Entry Point of the program that everything else gets called from, including compiler-generated code:

Navigating to the address which calls this function shows typical initiation instructions beforehand as well as a call to `exit` afterwards:

This makes it likely that `sub_401000` is either the main function or one of the core functions where malicious code is written, since the other subroutines reference imports and strings that seem to come from compiler-generated code or other dependencies. This serves as a good starting point for the analysis. The full listing of that subroutine is shown below:

The first thing that stands out in `sub_401000` are the calls to the imported `OleInitialize` and `CoCreateInstance` functions. These are two necessary functions used for interfacing with COM objects. COM is the Microsoft Component Object Model and is a standard which specifies how binary software components, called COM objects, can interact with one another.

Since these components are binary, it does not matter about any of the implementation details before compilation (e.g. programming language, structure, etc.). The interactions of binary components may be acheived by calling methods of an interface that a [COM object](https://docs.microsoft.com/en-us/windows/win32/com/the-component-object-model) has implemented. In short, a program may run a function of another program, as defined by a COM interface.

Referencing Microsoft's API docs, [OleInitialize](https://docs.microsoft.com/en-us/windows/win32/api/ole2/nf-ole2-oleinitialize) initializes the COM library and must be called before other COM library functions can be used. [CoCreateInstance](https://docs.microsoft.com/en-us/windows/win32/api/combaseapi/nf-combaseapi-cocreateinstance) creates a local instance of a COM class object, specified by a globally unique identifier called the CLSID. This function provides a pointer to the interface which can be used to interact with the COM instance's functions.

After `OleInitialize` is called, we can see that five arguments are pushed to the stack before calling `CoCreateInstance`.

The parameters required by `CoCreateInstance` are:

```c++
HRESULT CoCreateInstance(
  REFCLSID  rclsid,
  LPUNKNOWN pUnkOuter,
  DWORD     dwClsContext,
  REFIID    riid,
  LPVOID    *ppv
);
```

The most important of these are `rclsid`, `riid`, and `*ppv`. `rclsid` is the CLSID of the COM object to create; `riid` is the identifier of the interface that is required to interact with the COM object instance; and `*ppv` is where the pointer to that interface will be stored, if successful.

Following the reference to `riid` in IDA to where it is defined in the `rdata` segment gives us it's value:

Following the format for a GUID {XXXXXXXX-XXXX-XXXX-XXXX-XXXXXXXXXXXX}, this equates to an interface ID of `{D30C1661-CDAF-11D0-8A3E-00C04F0C90E26E}`.

A quick Google search shows that this IID corresponds to the IWebBrowser2 interface.

```c#
[System.Runtime.InteropServices.Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E")]
[System.Runtime.InteropServices.TypeIdentifier]
public interface IWebBrowser2 : SHDocVw.IWebBrowserApp
```

Viewing the value of `rclsid` in IDA shows:

The value for the COM object's class ID is `{0002DF01-0000-0000-C000-000000000046}`.

To determine the program that this CLSID corresponds to, we can look in the registry at locations in either the `HKLM` or `HKCU` hives, under the path `\SOFTWARE\Classes\CLSID\`. Hundreds of CLSIDs are stored here; a subset is shown below:

Navigating to the CLSID we're looking for lists several keys.

Viewing the value for the `LocalServer32` key shows the exact file of the program that will be instantiated.

This is the executable for Internet Explorer, which implements the `IWebBrowser2` interface.

At this point in the disassembly, after `CoCreateInstance` returns, the malware has access to the COM functionality of the `IWebBrowser2` interface as implemented by Internet Explorer.

The malware continues on to call `SysAllocString` to allocate space for a string referenced by `psz` (naming convention by IDA indicates a pointer to a NULL terminated string). Viewing the declaration of this string shows that it is a URL `http://www.malwareanalysisbook.com/ad.html`.

The next call made is to an address referenced by `[edx + 2Ch]`, shown below at 00401074:

If we trace the instructions back up, we can see that `eax` is set to the variable `ppv` which holds the pointer to the `IWebBrowser2` interface, before moving its value to `edx`. The call isn't being made directly to the start address of the interface however, but to a an offset of `2Ch` within the interface struct. This struct contains function pointers at each offset and the current instruction is calling one of those functions.

To determine which function pointer is located at an offset of `2Ch` within the interface, we can utilize the definitions of standard structures that IDA includes.

To do this, first we'll open the Structures view and add a new structure by pressing the INSERT key. Then click `Add Standard Structure` and search for the interface `IWebBrowser2`. This isn't the struct that we'd like to add however. Looking closely at the Declaration shows that it is simply defined with a pointer to the struct `IWebBrowser2Vtbl`; that's the structure that we want to add instead since its declaration contains all the actual struct members.

Adding that struct gives us all of the function pointers as members and the offsets of each. We can now see that the function pointer being called at the offset of `2Ch` is `Navigate`.

Going back to the disassembly, the offset can now be automatically replaced with the method name by right-clicking `2Ch` and selecting `[edx+IWebBrowser2Vtbl.Navigate]`.

The `Navigate` method is used to navigate to a resource, either a local file or website, depending on the identifier passed to it as an argument. Considering we found a URL string being copied earlier, it's safe to assume it's the latter, but we'll quickly verify in the disassembly anyways. The parameters that this method takes are listed here:

```c++
HRESULT Navigate(
    BSTR url,
    VARIANT *Flags,
    VARIANT *TargetFrameName,
    VARIANT *PostData,
    VARIANT *Headers
);
```

Prior to the call to `IWebBrowser2.Navigate`, we can see the arguments being pushed to the stack. The pointer to the URL string from earlier is stored in `eax` at 00401050 as the return value of `SysAllocString`, and is subsequently copied to `esi` and then pushed to the stack. When `Navigate` is called, Internet Explorer will open up and display the web page at `http://www.malwareanalysisbook.com/ad.html`, which appears to be an advertisement. Following this, the malware just frees up some resources and exits.

This piece of malware is fairly simple but shows how COM objects may be initialized and used maliciously.

path: /_posts/2019-09-02-Malware Reversing - Analysis 1.md


text:
---
title: Getting Started in Java
headline: Documentation
bodyclass: docs
layout: docs
---

[//]: <> (The base path for code samples is `_samples/examples/src/main/`.)
[//]: <> (Change it to `_examples/hello/`.)

<?code-excerpt path-base="../../../../_examples/hello/"?>

# Getting started with Spine in Java

This guide will walk you through a minimal client-server application in Java
which handles one command to print some text on behalf of the current computer user. The document
goes through already written code which is quite simple. So, it won't take long.

## What we'll do
We'll go through the example which shows a Bounded Context called “Hello”.
The context has one `ProcessManager`, which handles the `Print` command
sent from the client-side code to the server-side code, which hosts the context.

## What you'll need
1.  JDK version 8 or higher.
2.  Git.
3.  The source code of the [Hello World](https://github.com/spine-examples/hello) example.
    ```bash
    git clone git@github.com:spine-examples/hello.git
    ```

## Run the code
To check that you've got everything installed, please run the following command:
```bash
./gradlew :sayHello
```
If you're under Windows, it would be:
```
gradlew.bat :sayHello
```
This would build and execute the example.
The process should finish with the output which looks like this:

```
> Task :sayHello
Jun 04, 2020 5:04:55 PM io.spine.server.Server lambda$start$1
INFO: In-process server started with the name `318ea6c4-283e-4c43-b367-93310b703d31`.
[sanders] Hello World!
The client received the event: io.spine.helloworld.hello.event.Printed{"username":"sanders","text":"Hello World!"}
Jun 04, 2020 5:04:57 PM io.spine.server.Server shutdown
INFO: Shutting down the server...
Jun 04, 2020 5:04:57 PM io.spine.server.Server shutdown
INFO: Server shut down.
```
The first line tells which Gradle task we run. The following couple of lines is the server-side
logging that informs us that the server was started.

The line with “Hello World!” text is the “meat” of this example suite.
It is what our `ProcessManager` (called `Console`) does in response to the `Print` command received
from the `Client`.
The text in between brackets is the name of the current computer user. The name was passed as
the argument of the `Print` command.

We opted to show a `ProcessManager` — instead of an `Aggregate` — because
the console output is similar to an “External System”. Dealing with things like
that is the job of Process Managers. We also want to highlight the importance of using
this architectural pattern.

The output that follows is the logging produced by the `Client` class as it receives the `Printed`
event from the server.

Then, the server shuts down concluding the example.

Now, let's dive into the code.

## Project structure
For the sake of simplicity, this example is organised as a single-module Gradle project.
Most likely, a project for a real world application would be multi-module.

### The root directory
The root of the project contains the following files:
  * `LICENSE` — the text of the Apache v2 license under which the framework and
     this example are licensed.
  * `README.md` — a brief intro for the example.
  * `gradlew` and `gradlew.bat` — scripts for running Gradle Wrapper.
  * **`build.gradle`** — the project configuration. We'll review this file later
    [in details](#adding-spine-to-a-gradle-project).

The root directory also contains “invisible” files, names of which start with
the dot (e.g. `.gitattributes` and `.travis.yml`).
These files configure Git and CI systems we use. They are not directly related to the subject
of the example and this guide. If you're interested in this level of details,
please look into the code and comments in these files.

Here are the directories of interest in the project root:
 * `gradle` — this directory contains the code of Gradle Wrapper and two Gradle scripts
    used in the [project configuration](#other-project-configuration).
 * **`generated`** — this directory contains the code generated by Protobuf Compiler and
    Spine Model Compiler. This directory and code it contains is created automatically
    when a domain model changes. This directory is excluded from version control.
 * **`src`** — contains the handcrafted source code.

Let's see how the source code is structured.

### The `src` directory
The source code directory follows standard Gradle conventions and has two sub-directories:
  * **`main`** — the production code;
  * **`tests`**.

The production code consists of two parts allocated by sub-directories:
  * **`proto`** — contains the definition of data structures in Google Protobuf.
    A domain model definition starts from adding the code to this directory.
    Then, the Protobuf code is compiled to the languages of the project.
    The output of this process is placed into the `generated` directory, with a sub-directory
    for each language. This example uses only Java.

  * **`java`** — this directory contains the model behavior and other server- and client-side code.
    A real project would have these parts in separate modules or projects. We put it all
    together for the sake of simplicity.

Now, let's review the code in details, starting with how to add Spine to a Gradle project.

## Adding Spine to a Gradle project
Let's open `build.gradle` from the root of the project. The simplest and recommended way for
adding Spine dependencies to a project is the Bootstrap plugin:

```groovy
plugins {
    id 'io.spine.tools.gradle.bootstrap' version '1.5.8'
}
```
Once the plugin is added, we can use its features:

```groovy
spine.enableJava().server()
```
This enables Java in the module and adds necessary dependencies and configurations.

Calling `spine.enableJava().server()` adds both server- and client-side dependencies.
This way a module of a Bounded Context “A” may be a client for a Bounded Context “B”.
Client-side applications or modules should call: `spine.enableJava().client()`.

### Other project configuration

The rest of the `build.gradle` file does the following:
 1. Sets the version of Java to 8.

 2. Adds `generated` code directories to IntelliJ IDEA module by applying the `idea.gradle`
    script plugin.

The framework does not depend on IDEA or its Gradle plugin.
    We added this code because we use this IDE for development.
    If you use it too, you may want look into `idea.gradle` to configure your Spine-based
    projects similarly.

 3. Adds JUnit dependencies by applying the `tests.gradle` script plugin.

We chose to extract this and previous scripts into separate files to simplify
     the code of `build.gradle`.

 4. Defines the `sayHello` task which runs the `Example` application, which orchestrates
    the demo.

We are not reviewing these parts of the project configuration deeper because they are not
related to the use of the Spine framework. If you're interested in more details, please look into
the code of these scripts.

Now, let's look into the data structure of the Hello context.

## Hello context data

The data types of the Hello context are defined under the `src/main/proto/hello` directory with
the following files:

  * **`commands.proto`** — this file defines the `Print` command.

By convention, commands are defined in a file with the `commands` suffix
     in its name. It can be, for example, `order_commands.proto` or just `commands.proto`
     like in our example.

  * **`events.proto`** — this file defines the `Printed` event.

Similarly to commands, events are defined in proto files having the `events`
    suffix in their names.

These two files define signals used by the Hello context. There's also data of the `Console`
Process Manager, which is defined in the package **`server`** in the file **`console.proto`**.

We arrange the sub-package `server` to highlight the fact that this is server-only data. It is not
a convention used by the framework. We find the clarity of this infix useful when creating
cloud applications. So, we share it as a recommendation in this example.

Let's review the context data definition in details.

### The `commands.proto` file

After the copyright header the file starts with the syntax declaration. The framework supports only
this version of the Protobuf dialect:
```proto
syntax = "proto3";
```

Then follows the import statement for custom options used when defining data types. This import is
required for all proto files of a Spine-based project.
```proto
import "spine/options.proto";
```

The following file-wide option defines the prefix for type names used in this file.
```proto
option (type_url_prefix) = "type.spine.io";
```
This prefix is needed for recognizing binary data when it's unpacked. Most likely, all types
in a system would use the same prefix.

Then we see the standard Protobuf option for defining a Java package for the generated code:
```proto
option java_package="io.spine.helloworld.hello.command";
```
There are three parts of interest in this package name:
  * **`io.spine.helloworld`** — this part represents the location of our Hello World “solution”
    as if it were hosted on the web at `https://helloworld.spine.io`.

  * **`hello`** — this is the package of the Hello context. In this example we have only one, but
     a real world app would have more. Each Bounded Context goes into a dedicated package.

  * **`command`** — this part gathers commands of the context under one package.
     We have only one command in this example, but in real world scenarios, with dozens of commands,
     it is convenient to gather them under a package.

The following standard proto file option defines the name for the outer class generated by
Protobuf Compiler for this `.proto` file:
```proto
option java_outer_classname = "CommandsProto";
```

Outer classes are used by Protobuf implementation internally.
When the `java_outer_classname` option is omitted, Protobuf Compiler would calculate the Java
class name taking the name of the corresponding `.proto` file.
We recommend setting the name directly to make it straight. This also avoids possible name clashes
with the handcrafted code.

The next standard option instructs the Protobuf Compiler to put each generated Java type into
a separate file. This way it would be easier to analyze dependencies of the code which uses these
generated types.

```proto
option java_multiple_files = true;
```

The command for printing a text in a console is defined this way:
```proto
// A command to print a text.
message Print {

    // The login name of the computer user.
    string username = 1;

    // The text to print.
    string text = 2 [(required) = true];
}
```

By convention, the first field of a command is the ID of the target entity.
This field is required to have a non-empty value so that the command can be dispatched to
the entity. In our case, we identify a console by the login name of the computer user.

The second field is marked as `(required)` using the custom option imported in
the `spine/options.proto` file above. This command does not make much sense if there is no text
to print.

In Protobuf a data type is either a **`message`** (we can send it) or an **`enum`**.
If you're new to this language, you may want to look at the [Proto3 Language Guide][proto3-guide].

Now, let's see how to define events.

### The `events.proto` file

Events are declared similarly to commands. The header of the file has:

 * The `proto3` syntax declaration.
 * The `hello` package declaration.
 * The import statement for custom Protobuf options used by the framework:

    ```proto
    import "spine/options.proto";
    ```

 * The same `(type_url_prefix)` we use in this project.
 * A separate package for events of the context:

    ```proto
    option java_package="io.spine.helloworld.hello.event";
    ```
 * The outer class for all types in this file:

    ```proto
    option java_outer_classname = "EventsProto";
    ```

 * The instruction to put Java types into separate files.

    ```proto
    option java_multiple_files = true;
    ```

The sole event in this project is declared this way:

```proto
// A text was printed.
message Printed {

    // The login name of the user.
    string username = 1 [(required) = true];

    // The printed text.
    string text = 2 [(required) = true];
}
```

The event tells which text was printed for a user. Both of the fields are marked as `(required)`
because the event does not make much sense if one of them is empty.

Unlike for commands, the framework does not assume that the first event field is always
populated. This is so because default routing rules for commands and events are different.
When an event is produced by some entity, it remembers the ID of this producer entity.
By default, the framework uses the producer ID to route events to their target entities —
if they have identifiers of the same type.  If the type of producer ID does not match one of the
target entity, then event fields are analyzed. It is also possible to set custom routing rules.

Now, let's see the server-side data of the Hello context.

### The `console.proto` file
The header of the file is similar to those we saw in `commands.proto` and `events.proto`.
The difference is that we use `server` for the proto and Java package names to make sure the
server-only is not used by the client code.

This file defines a single data type. It is the state of the entity handling the `Print` command:

```proto
// The screen state of the user's console.
message Output {
    option (entity) = { kind: PROCESS_MANAGER };

    // The login name of the computer user.
    string username = 1;

    // Text lines of the screen.
    repeated string lines = 2;
}
```

The option `(entity)` tells us that this type is going to be used by a `ProcessManager`.
The first field of the type holds and ID of this entity. The framework assumes such fields as
implicitly `(required)`. Then goes the declaration of the remote screen output.  The value of this
field is empty until something is printed on the screen. Therefore, it is not marked `(required)`.

Now, let's see how this data is used at the server-side.

## The `Console` class

The class is declared this way:

```java
final class Console extends ProcessManager<String, Output, Output.Builder>
```
The generic arguments passed to `ProcessManager` are:
 1. `String` — the type of the ID of the entity. Remember the type
of the first field of the `Print` command?

 2. `Output` — the type of the entity state, which we reviewed in the previous section.

 3. `Output.Builder` — the type used to modify the state of the entity.
    In Protobuf for Java, each message type has a specific builder type.

To be continued...

[proto3-guide]: https://developers.google.com/protocol-buffers/docs/proto3

branch_name: refs/heads/master

extension: md

license_type: permissive


text:
---
templateKey: page-basic
title: Staff Stories – Ireen Mwale
description: Ireen is the Assistant Librarian at Mteza Library, in Sam’s Village.  She tells us what she thinks of working for African Vision Malawi (aka the Landirani Trust)
---

Ireen is the Assistant Librarian at Mteza Library, in Sam’s Village.  She tells us what she thinks of working for African Vision Malawi (aka the Landirani Trust):

## Ireen Mwale

I have worked for Landirani Trust for 11 months. Since I started working for Landirani I have learned a lot of things that are helpful and have made me grow and develop such as:

- Staying with people of different races
- Encouraging the community to continue with their education by using the community library which is free of charge

Through working with Landirani I have been helped to support myself and the family mainly my kids, who are schooling learning in different schools, by providing resources like exercise books and school uniform, in support of my husband.

![Ireen](/img/staff-stories/Ireen-for-website.jpg)
*Ireen*

Without Landirani I would be growing poor in terms of money because I had nowhere to get money but just relying on my husband but for now we are assisting each other.

To Landirani supporters would they receive a message of thanks on what they are doing, mainly because of the library.  They should not get tired but continue to donate resources as one part of ending illiteracy among community as people are using books (school leavers) that they can’t afford to buy on their own because books are very expensive. They should keep on Assisting.

You can read all about M’teza Library here.

If you would like to donate to the Library project, please click here, and just add “Library” in the comment box to direct your donation to Library projects.  Thank you!

license: MIT

repository: africanvisionmalawi/avm-site

gha_language: JavaScript

gha_license_id: MIT

repo_name: africanvisionmalawi/avm-site


text:
# ActiveFlapPhoneCase

### Description
##### Android application that provides functionalities to wake up and lock screen using flap in phone case.

### How to build
* Go to Gradle in IntelliJ
* Choose `app` -> `build` -> `assemble`
* After finish `assemble` in directory `app/build/outputs/apk/debug` will be stored apk file
* Remember to use debug version because it contains debug key which allows to install application
* In release directory apk file does not contain key so there is not possibility to install on device

gha_language: Java


text:
---
cslItem:
  id: warde__1955__crystal
  author:
    - family: Warde
      given: Beatrice
  citation-key: warde__1955__crystal
  event-place: London
  issued:
    date-parts:
      - - 1955
  keyword: "#nosource;collection::space::case_for_space;collection::space::introduction"
  publisher: Sylvan Press
  publisher-place: London
  title: The crystal goblet. Sixteen essays on typography
  type: book
tags:
  - "#nosource"
  - issue:space
  - topic:space/case_for_space
  - issue:space
  - topic:space/introduction
rendered:
  bibliography: |-

      Warde, B. 1955. The crystal goblet. Sixteen essays on typography. Sylvan Press.

  citation: Warde, 1955
bibTex: "@book{warde__1955__crystal,\n\taddress = {London},\n\tauthor = {Warde, Beatrice},\n\tyear = {1955},\n\tpublisher = {Sylvan Press},\n\ttitle = {The crystal goblet. {Sixteen} essays on typography},\n}\n\n"
---

branch_name: refs/heads/main


text:
---
layout: post
cover: 'assets/images/cover4.jpg'
navigation: True
title: Welcome to the instruction of URDF 101
date: 2019-09-08 02:18:00
tags: URDF
subclass: 'post tag-URDF'
logo: 'assets/images/ghost.png'
author: Gilwon Kim
categories: URDF
---

### Goals
1. Set the boundary conditions in Solidworks for URDF.
2. Generate URDF files from Solidworks.

Below instructions would walk you through the whole steps to generate URDF model from the SolidWorks.

You may need following to acheive the goals:
1. Solidworks program
2. Solidworks assembly parts
3. Solidworks SW2URDF add-ins

### Instructions

###### 1. Get SolidWorks model ready
The model consists of four parts(Body, Load, Right Wheel, Left Wheel, and Front Wheel). These parts are free to download [here](http://). The assembly parts should be properly mated as a functioning piece to carry URDF translation successfully.

![1](https://static.wixstatic.com/media/ed6580_5b60591ba852432583b70adb9389de89~mv2.png/v1/fill/w_1601,h_800/1.png)

###### 2. Set the 'axsis' and 'point' of the parts
Setting the coordinate system is very important in URDF conversion. The wheel parts must have 'points' along with the centeral axsis, because we will apply 'continuous' boundary condtion on the wheel. I created the 'axsis' and the 'point' at the center of the wheel.

![2](https://static.wixstatic.com/media/ed6580_691fb367f1a949c0b8781d21afdeeae3~mv2.png/v1/fill/w_1600,h_800/2.png)

###### 3. Set the coordinate systems
Come back to the assembly model. Find 'Coordinate System' from the menu.

View -> Reference Geometry -> Coordinate System

![3](https://static.wixstatic.com/media/ed6580_bc1e7ec3aa1940a998db36ac7f68a917~mv2.png/v1/fill/w_495,h_727/3.png)

Select the point and axsis as it is shown below to create the coordinate system.

**Sidenote. You could select the coordinate system anywhere along the axsis line at the center. As long as the coordinate system is along the center axsis of the wheel, you are fine.*

![4](https://static.wixstatic.com/media/ed6580_00dda885e5dd4f8698d1c86b54cb752f~mv2.png/v1/fill/w_1600,h_801/4.png)

Once it is done, you can see the coordinate system as below in the assembly model.

![5](https://static.wixstatic.com/media/ed6580_16318b27e446431ea92b6add56a12b05~mv2.png/v1/fill/w_1600,h_802/5.png)

Likewise, set the coordinate systems on the other wheels, body, and load parts. **You have to remember that all the coordinate systems must be set in the assembly model tree.**

The photo below shows the coordinate system of Body part. You could set the coordinate system anywhere you want unlike the wheels.

![6](https://static.wixstatic.com/media/ed6580_18c663d8743f4ccf843c5d1bcf7bf9cf~mv2.png/v1/fill/w_1601,h_800/6.png)

The photo below shows the coordinate system of Load part. You could also set the coordinate system anywhere you want in the part.

![7](https://static.wixstatic.com/media/ed6580_c39defb3e7fc4c4e8fcdc70756301678~mv2.png/v1/fill/w_1599,h_801/7.png)

###### 4. URDF conversion
Solidworks could convert URDF with URDF add-ins(SW2URDF). SW2URDF add-ins must be installed in Solidowrks.

These five coordinate systems must be seen in your assembly tree.

The names of each coordinate system to the parts are represented as follow:

Coordinate System2 <- Right Wheel part

Coordinate System3 <- Left Wheel part

Coordinate System4 <- Front Wheel part

Coordinate System5 <- Body part

Coordinate System6 <- Load part

**Sidenote. Your coordinate system names may different than mine. You could change the names of coordinate systems to the above names to easily understand the rest of parts.*

**I am going to set 'Load part' to be ++the parent link++ of all.**

![8](https://static.wixstatic.com/media/ed6580_9b1d73d3a582468b9b80858f3eaa4395~mv2.png/v1/fill/w_1599,h_803/8.png)

Open URDF setting tool.
File -> Export as URDF

Once you open URDF Exporter, we will firstly manage 'Number of child links' to set the hierarchy of links.

Set 'Number of child links' to 1 for Load part, and set 3 child links for Body part. You can see the final hierarchy tree as it is shown below.

For Load part,
1. Change 'Global Origin Coordinate System' to Coordinate System6.

![9](https://static.wixstatic.com/media/ed6580_bb447341c521487ba72b5dcab0483e33~mv2.png/v1/fill/w_1600,h_801/9.png)

For Body part,
1. Change 'Reference Coordinate System' to Coordinate System5.
2. Change 'Joint Type' to fixed.

![10](https://static.wixstatic.com/media/ed6580_0f2bdd7cf74c4cdea9df9d37ece57f1c~mv2.png/v1/fill/w_1600,h_802/10.png)

For Right Wheel part,
1. Change 'Reference Coordinate System' to Coordinate System2.
2. Change 'Joint Type' to continuous.

![11](https://static.wixstatic.com/media/ed6580_88622a4f03e849029470dfd02db96456~mv2.png/v1/fill/w_1604,h_800/11.png)

For Left Wheel Part,
1. Change 'Reference Coordinate System' to Coordinate System3.
2. Change 'Joint Type' to continuous.

![12](https://static.wixstatic.com/media/ed6580_5cf06c41d8a04ab889ca2a9407a71c4e~mv2.png/v1/fill/w_1600,h_801/12.png)

For Front Wheel part,
1. Change 'Reference Coordinate System' to Coordinate System4.
2. Change 'Joint Type' to continuous.

![13](https://static.wixstatic.com/media/ed6580_8e1d7fe8e614468aa2984562c74b7efe~mv2.png/v1/fill/w_1602,h_800/13.png)

Once all the boundary conditions are set, hit 'Preview and Export' button, and URDF Exporter will bring up another pop-up window. Click Next button.

![14](https://static.wixstatic.com/media/ed6580_5a19da0c0f2c4befb034cf8d015e1cc3~mv2.png/v1/fill/w_1602,h_804/14.png)

The properties below are to manage the physics conditions of the model. You could set the properties and conditions as you intended. In this instruction, I only changed the mass(kg) to 1kg of all parts.

![15](https://static.wixstatic.com/media/ed6580_ab1bf54b658a459684a5bca2d06d12c1~mv2.png/v1/fill/w_1600,h_802/15.png)

Hit 'Export URDF and Meshes..." button to create and save URDF files of the model.

![16](https://static.wixstatic.com/media/ed6580_3121724bf5f7461ea0dd5d7545bd8b0a~mv2.png/v1/fill/w_1601,h_801/16.png)

I saved URDF files with the name of 'Tricycle'. Congratulations, you have your URDF files.

Next, the instruction will be continued with running URDF model in gazebo.


text:
bash 2048
=========

My take at http://gabrielecirulli.github.io/2048/ in pure bash

![screenshot](screenshot.png)

Usage
-----

**note:** try `-a` for awesome animations

    $ ./2048 -h
    Usage: 2048 [-a] [-b] [-h] [-g <goal>] [-s <size>]

    Options
      -a          enable animations, note they are slow and weird
      -b          disable color output, b for boring!
      -g <goal>   the goal piece, defaults to 2048
      -h          print this message and exit
      -k          keep playing after winning
      -s <size>   the size of the board, defaults to 4

External Utilities
------------------

`tput` is the only external command used in this bash script to figure out the proper
codes to print for colorized output.  If your system lacks `tput`, it will still work
without color support.

Issues
------

- Performance is lacking... the algorithm could probably be optimized
- Animations with `-a` are slow and wonky

License
-------

MIT License


text:
# Kubernetes Deployment Guide

## Introductions

In this directory, you will find the necessary files and instructions to get Kuma up and running in Kubernetes mode via Minikube.

When running on Kubernetes, Kuma will store all of its state and configuration on the underlying Kubernetes API Server, therefore requiring no dependency to store the data.

## Table of Contents
- [Kubernetes Deployment Guide](#kubernetes-deployment-guide)
  - [Introductions](#introductions)
  - [Table of Contents](#table-of-contents)
  - [Setup Environment](#setup-environment)
    - [Minikube](#minikube)
    - [Marketplace application](#marketplace-application)
    - [Kuma](#kuma)
      - [Download](#download)
      - [Installation](#installation)
  - [Tools](#tools)
    - [kumactl](#kumactl)
      - [Setup](#setup)
      - [Inspect](#inspect)
    - [GUI](#gui)
  - [Integrations](#integrations)
    - [Kong Gateway](#kong-gateway)
      - [Installation](#installation-1)
      - [Configuration](#configuration)
    - [Prometheus and Grafana](#prometheus-and-grafana)
      - [Installation](#installation-2)
  - [Policies](#policies)
    - [mTLS](#mtls)
      - [Check for mTLS](#check-for-mtls)
      - [Adding mTLS Policy](#adding-mtls-policy)
    - [Traffic Permissions](#traffic-permissions)
      - [Adding Traffic Permission Policy](#adding-traffic-permission-policy)
      - [Adding Granular Traffic Permissions](#adding-granular-traffic-permissions)
    - [Traffic Routing](#traffic-routing)
      - [Scale Replicas](#scale-replicas)
      - [Adding Routing Policy](#adding-routing-policy)
    - [Health Check](#health-check)
      - [Adding Health Check Policy](#adding-health-check-policy)
    - [Traffic Metrics](#traffic-metrics)
      - [Adding Traffic Metric Policy](#adding-traffic-metric-policy)
      - [Query Metrics](#query-metrics)
    - [Traffic Log](#traffic-log)
      - [Setup](#setup-1)
      - [Adding Logging Policy](#adding-logging-policy)
    - [Traffic Trace](#traffic-trace)
      - [Jaeger Installation](#jaeger-installation)
      - [Adding Traffic Tracing Policy](#adding-traffic-tracing-policy)
      - [Visualizing Traces](#visualizing-traces)

## Setup Environment

### Minikube

We'll be using Minikube to deploy our application and Kuma to illustrate the mesh's capabilities in Kubernetes mode. Please follow Minikube's [installation guide](https://kubernetes.io/docs/tasks/tools/install-minikube/) to have it set up correctly before proceeding.

Once you have Minikube installed, we will need to start a Kubernetes cluster on it with at least 4GB of memory to run the full demo smoothly. You can allocate less memory if you plan on leaving out the [Kong Ingress Gateway](#kong-gateway) and some of the [observability steps](#prometheus-and-grafana). Another thing to note is that Kuma is tested on Kubernetes version v1.13.0 - v1.16.x, so use anything older or newer with caution.

Run the following command to start up a cluster:
```bash
$ minikube start --cpus 2 --memory 4096 --kubernetes-version v1.16.8 -p kuma-demo
😄  [kuma-demo] minikube v1.8.2 kuon Darwin 10.15.3
✨  Automatically selected the hyperkit driver. Other choices: virtualbox, docker
🔥  Creating hyperkit VM (CPUs=2, Memory=6144MB, Disk=20000MB) ...
🐳  Preparing Kubernetes v1.16.8 on Docker 19.03.6 ...
🚀  Launching Kubernetes ...
🌟  Enabling addons: default-storageclass, storage-provisioner
⌛  Waiting for cluster to come online ...
🏄  Done! kubectl is now configured to use "kuma-demo"
```

### Marketplace application

Run the following command to deploy the marketplace application via [`bit.ly/demokuma`](https://www.bit.ly/demokuma), which points to the [all-in-one YAML file](/kubernetes/kuma-demo-aio.yaml) provided in this directory:
```bash
$ kubectl apply -f https://bit.ly/demokuma
namespace/kuma-demo created
serviceaccount/postgres created
service/postgres created
replicationcontroller/es created
deployment.apps/redis-master created
service/redis created
service/backend created
deployment.apps/kuma-demo-backend-v0 created
deployment.apps/kuma-demo-backend-v1 created
deployment.apps/kuma-demo-backend-v2 created
service/frontend created
deployment.apps/kuma-demo-app created
```

And then check the pods are up and running by getting all pods in the `kuma-demo` namespace:

```bash
$ kubectl get pods -n kuma-demo
NAME                                    READY   STATUS    RESTARTS   AGE
es-mc78v                               1/1     Running   0          63s
kuma-demo-app-656c95dcb5-6pshm         1/1     Running   0          63s
kuma-demo-backend-v0-99c9878b6-wbffb   1/1     Running   0          63s
redis-master-657c58c859-9w98d          1/1     Running   0          63s
```

The [all-in-one YAML file](/kubernetes/kuma-demo-aio.yaml) deploys our application across four pods:
1. The first pod is an PostgreSQL service that stores all the items in our marketplace.
2. The second pod is the frontend application that will give you a GUI to query the items/reviews.
   * Throughout this guide, we will be port-forwarding this `kuma-demo-app-656c95dcb5-6pshm` pod to access the marketplace's frontend GUI. Please replace any reference of this pod with your pod's name.
3. The third pod is a Node application that represents a backend.
   * We have three deployments for `kuma-demo-backend-v*` in the [all-in-one YAML file](/kubernetes/kuma-demo-aio.yaml). The v1 and v2 deployments currently have 0 replicas, but will be scaled up later when we cover Kuma's Traffic Routing policy.
4. The fourth pod is a Redis service that stores reviews for each item.

![diagram](https://github.com/Kong/kuma-website/blob/master/docs/.vuepress/public/images/diagrams/diagram-kuma-demo-basic.jpg?raw=true)

To access the front-end UI on [http://localhost:8080](http://localhost:8080), port-forward your `kuma-demo-app` like so:
```bash
$ kubectl port-forward kuma-demo-app-656c95dcb5-6pshm -n kuma-demo 8080
Forwarding from <IP_ADDRESS>:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
```

![frontend-gui](https://raw.githubusercontent.com/Kong/kuma-website/master/docs/.vuepress/public/images/demo/kuma-demo-app-gui.png)

This marketplace application is currently running **WITHOUT** Kuma. So all traffic is going directly between the services, and not routed through any dataplanes. In the next step, we will download Kuma and quickly deploy the mesh alongside an existing application.

### Kuma

Kuma is an open-source control plane for modern connectivity, delivering high performance and reliability with Envoy. We will have to download it first and then install it onto the Kubernetes cluster.

#### Download

To find the correct version for your operating system, please check out [Kuma's official installation page](https://kuma.io/install). The following command will download the Mac compatible version of Kuma.

```bash
$ wget https://kong.bintray.com/kuma/kuma-0.4.0-darwin-amd64.tar.gz
--2020-03-21 18:12:13--  https://kong.bintray.com/kuma/kuma-0.4.0-darwin-amd64.tar.gz
Resolving kong.bintray.com (kong.bintray.com)... <IP_ADDRESS>, <IP_ADDRESS>
Connecting to kong.bintray.com (kong.bintray.com)|<IP_ADDRESS>|:443... connected.
HTTP request sent, awaiting response... 302
Location: https://akamai.bintray.com/a6/a6166a446a6e108c05f730b715883f763c639407f68c0aeab047fb483aa0d37b?__gda__=exp=1584840253~hmac=842a00e945ead8ad5ff82ef7ce815af25e05127f0441afc9651a227c2a4c0186&response-content-disposition=attachment%3Bfilename%3D%22kuma-0.4.0-darwin-amd64.tar.gz%22&response-content-type=application%2Fgzip&requestInfo=U2FsdGVkX18YHMvH_plPDrWpJf4WJqUcn8K5tThs-p1VfcOHb-Qba5Clp3NImVt39IMdcZt94rOxGdic3jtQsJTr9ixBwyNHEFF1EiIsZpKvYWg6n0dRqXZUOkxyM7Rx&response-X-Checksum-Sha1=e6eeff0b9b90c95fc9924bd0b67f5a2c2d62b79c&response-X-Checksum-Sha2=a6166a446a6e108c05f730b715883f763c639407f68c0aeab047fb483aa0d37b [following]
--2020-03-21 18:12:13--  https://akamai.bintray.com/a6/a6166a446a6e108c05f730b715883f763c639407f68c0aeab047fb483aa0d37b?__gda__=exp=1584840253~hmac=842a00e945ead8ad5ff82ef7ce815af25e05127f0441afc9651a227c2a4c0186&response-content-disposition=attachment%3Bfilename%3D%22kuma-0.4.0-darwin-amd64.tar.gz%22&response-content-type=application%2Fgzip&requestInfo=U2FsdGVkX18YHMvH_plPDrWpJf4WJqUcn8K5tThs-p1VfcOHb-Qba5Clp3NImVt39IMdcZt94rOxGdic3jtQsJTr9ixBwyNHEFF1EiIsZpKvYWg6n0dRqXZUOkxyM7Rx&response-X-Checksum-Sha1=e6eeff0b9b90c95fc9924bd0b67f5a2c2d62b79c&response-X-Checksum-Sha2=a6166a446a6e108c05f730b715883f763c639407f68c0aeab047fb483aa0d37b
Resolving akamai.bintray.com (akamai.bintray.com)... <IP_ADDRESS>
Connecting to akamai.bintray.com (akamai.bintray.com)|<IP_ADDRESS>|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 48840921 (47M) [application/gzip]
Saving to: ‘kuma-0.4.0-darwin-amd64.tar.gz’

kuma-0.4.0-darwin-amd64.tar.gz           100%[===============================================================================>]  46.58M  40.8MB/s    in 1.1s

2020-03-21 18:12:14 (40.8 MB/s) - ‘kuma-0.4.0-darwin-amd64.tar.gz’ saved [48840921/48840921]
```

Next, unbundle the files to get the following components:

```bash
$ tar xvzf kuma-0.4.0-darwin-amd64.tar.gz
x ./
x ./bin/
x ./bin/kumactl
x ./bin/kuma-cp
x ./bin/envoy
x ./bin/kuma-prometheus-sd
x ./bin/kuma-tcp-echo
x ./bin/kuma-dp
x ./NOTICE
x ./NOTICE-kuma-init
x ./LICENSE
x ./conf/
x ./conf/kuma-cp.conf
x ./README
```

Lastly, navigate into the ./bin directory where the kuma components will be:

```bash
$ cd bin && ls
envoy		kuma-cp		kuma-dp		kuma-prometheus-sd		kuma-tcp-echo		kumactl
```
On Kubernetes, of all the Kuma binaries in the bin folder, we only need kumactl. The kumactl executable is a very important component in your journey with Kuma. It allows to retrieve the state of Kuma and the configured policies in every environment. On Kubernetes it is read-only, because you are supposed to change the state of Kuma by leveraging Kuma's CRDs. But it does provides helpers to install Kuma on Kubernetes via `kumactl install [..]` command.

#### Installation

Using `kumactl install [..]`, install the control-plane onto the Kubernetes cluster we have deployed:

```bash
$ ./kumactl install control-plane | kubectl apply -f -
namespace/kuma-system created
secret/kuma-sds-tls-cert created
secret/kuma-admission-server-tls-cert created
secret/kuma-injector-tls-cert created
configmap/kuma-control-plane-config created
configmap/kuma-injector-config created
serviceaccount/kuma-control-plane created
serviceaccount/kuma-injector created
customresourcedefinition.apiextensions.k8s.io/dataplaneinsights.kuma.io created
customresourcedefinition.apiextensions.k8s.io/dataplanes.kuma.io created
customresourcedefinition.apiextensions.k8s.io/healthchecks.kuma.io created
customresourcedefinition.apiextensions.k8s.io/meshes.kuma.io created
customresourcedefinition.apiextensions.k8s.io/proxytemplates.kuma.io created
customresourcedefinition.apiextensions.k8s.io/trafficlogs.kuma.io created
customresourcedefinition.apiextensions.k8s.io/trafficpermissions.kuma.io created
customresourcedefinition.apiextensions.k8s.io/trafficroutes.kuma.io created
customresourcedefinition.apiextensions.k8s.io/traffictraces.kuma.io created
clusterrole.rbac.authorization.k8s.io/kuma:control-plane created
clusterrole.rbac.authorization.k8s.io/kuma:injector created
clusterrolebinding.rbac.authorization.k8s.io/kuma:control-plane created
clusterrolebinding.rbac.authorization.k8s.io/kuma:injector created
role.rbac.authorization.k8s.io/kuma:control-plane created
rolebinding.rbac.authorization.k8s.io/kuma:control-plane created
service/kuma-injector created
service/kuma-control-plane created
deployment.apps/kuma-control-plane created
deployment.apps/kuma-injector created
mutatingwebhookconfiguration.admissionregistration.k8s.io/kuma-admission-mutating-webhook-configuration created
mutatingwebhookconfiguration.admissionregistration.k8s.io/kuma-injector-webhook-configuration created
validatingwebhookconfiguration.admissionregistration.k8s.io/kuma-validating-webhook-configuration created
```

And then check the pods are up and running by getting all pods in the `kuma-system` namespace

```bash
$ kubectl get pods -n kuma-system
NAME                                 READY   STATUS    RESTARTS   AGE
kuma-control-plane-965bf6fd4-v47qh   1/1     Running   0          63s
kuma-injector-696484d998-nz7z8       1/1     Running   0          63s
```

The installation commands will deploy these two pods:
1. The first pod is Kuma control-plane. Kuma (kuma-cp) is one single executable written in GoLang that can be installed anywhere, hence why it's both universal and simple to deploy. When running on Kubernetes, no external dependencies required, since it leverages the underlying K8s API server to store its configuration. Throughout this guide, we will be port-forwarding this `kuma-control-plane-965bf6fd4-v47qh` pod to access the Kuma GUI. Please replace any reference of this pod with your pod's name.
2. The second pod is the kuma-injector service will also start in order to automatically inject sidecar dataplane proxies without human intervention. For this service to work, you need to label the namespaces with `kuma.io/sidecar-injection: enabled`. The [all-in-one YAML file](/kubernetes/kuma-demo-aio.yaml) that deployed the marketplace application already has the label so you do not need to edit it.

Now that we have the control-plane and injector in our cluster, we need to delete the existing pods (or perform a rolling update) so the injector can do its job.

```bash
$ kubectl delete pods --all -n kuma-demo
pod "es-mc78v" deleted
pod "kuma-demo-app-656c95dcb5-6pshm" deleted
pod "kuma-demo-backend-v0-99c9878b6-wbffb" deleted
pod "redis-master-657c58c859-9w98d" deleted
```
And then check the pods are up and running by getting all pods in the `kuma-demo` namespace:

```bash
$ kubectl get pods -n kuma-demo -w
NAME                                   READY   STATUS    RESTARTS   AGE
es-s86kd                               2/2     Running   0          55s
kuma-demo-app-656c95dcb5-twdl2         2/2     Running   0          55s
kuma-demo-backend-v0-99c9878b6-vfsdc   2/2     Running   0          55s
redis-master-657c58c859-prldh          2/2     Running   0          55s
```
It looks near identical **except** each pod now has an additional container. The additional container is the Envoy sidecar proxy that kuma-injector is automatically adding to each pod.

To access the front-end UI on [http://localhost:8080](http://localhost:8080), port-forward your `kuma-demo-app` again:
```bash
$ kubectl port-forward kuma-demo-app-656c95dcb5-twdl2 -n kuma-demo 8080
Forwarding from <IP_ADDRESS>:8080 -> 8080
Forwarding from [::1]:8080 -> 8080
```

The marketplace application is now running with Kuma, but will be identical to the version with Kuma. The underlying difference is that all the services are now sending traffic to the Envoy dataplane within the same pod, and the Envoy proxies will communicate to each other. But the user will not see any visual change!

    ↥ back to top

## Tools

### kumactl

The kumactl application is a CLI client for the underlying HTTP API of Kuma. Therefore, you can access the state of Kuma by leveraging with the API directly. In universal mode you will be able to also make changes via the HTTP API, while in Kubernetes mode the HTTP API is read-only.

#### Setup

You can configure kumactl to point to any remote Kuma control-plane instance. Before you can configure your local kumactl to point to control-plane running in the `kuma-system` namespace, we need to port-forward the pod. Please note that your pod name will be different than mine, so copy the one that you see on your cluster.

First, get the pod name from the `kuma-system` namespace:

```bash
$ kubectl get pods -n kuma-system
NAME                                 READY   STATUS    RESTARTS   AGE
kuma-control-plane-965bf6fd4-v47qh   1/1     Running   0          63s
kuma-injector-696484d998-nz7z8       1/1     Running   0          63s
```

Then port-forward the pod on port 5681 and 5683 like so:

```bash
$ kubectl port-forward kuma-control-plane-965bf6fd4-v47qh -n kuma-system 5681 5683
Forwarding from <IP_ADDRESS>:5681 -> 5681
Forwarding from [::1]:5681 -> 5681
Forwarding from <IP_ADDRESS>:5683 -> 5683
Forwarding from [::1]:5683 -> 5683
```

The two ports we port-forwarded are for:
- 5681: the HTTP API server that is being used by kumactl to retrieve the state of your configuration and policies on every environment
- 5683: the HTTP server that exposes [Kuma UI](#gui)

Next, configure kumactl to point to the address where the HTTP API server sits:
```bash
$ ./kumactl config control-planes add --name=minikube --address=http://localhost:5681
added Control Plane "minikube"
switched active Control Plane to "minikube"
```

#### Inspect

Once kumactl is pointing to the correct control-plane, you can use it to inspect the dataplanes in the mesh.

```
$ ./kumactl inspect dataplanes
MESH      NAME                                             TAGS                                                                                STATUS   LAST CONNECTED AGO   LAST UPDATED AGO   TOTAL UPDATES   TOTAL ERRORS
default   es-s86kd.kuma-demo                               component=postgres protocol=http service=postgres.kuma-demo.svc:5432                                              Online   2h2m44s              2h2m43s            4               0
default   kuma-demo-backend-v0-99c9878b6-vfsdc.kuma-demo   app=kuma-demo-backend env=prod pod-template-hash=99c9878b6 protocol=http service=backend.kuma-demo.svc:3001 version=v0    Online   2h2m48s              2h2m46s            4               0
default   redis-master-657c58c859-prldh.kuma-demo          app=redis pod-template-hash=657c58c859 protocol=tcp role=master service=redis.kuma-demo.svc:6379 tier=backend             Online   2h2m47s              2h2m46s            4               0
default   kuma-demo-app-656c95dcb5-twdl2.kuma-demo         app=kuma-demo-frontend env=prod pod-template-hash=656c95dcb5 protocol=http service=frontend.kuma-demo.svc:8080 version=v8   Online   2h2m46s              2h2m45s            4               0

```

There are 4 dataplanes which correlates with each component of our application

### GUI

Kuma ships with an internal GUI that will help you visualize the mesh and its policies in an intuitive format. The GUI is also open-source so you can find the source code in the [kuma-gui repository](https://github.com/Kong/kuma-gui). It can be found on port :5683 on the control-plane machine, which we just port-forwarded above. Navigate to [http://localhost:5683/](http://localhost:5683/) to use Kuma's GUI.

![kuma-gui](https://raw.githubusercontent.com/Kong/kuma-website/master/docs/.vuepress/public/images/demo/kuma-gui-welcome-0.4.0.png)

    ↥ back to top

## Integrations

### Kong Gateway

Using [Kong for Kubernetes](https://github.com/Kong/kubernetes-ingress-controller), you can easily deploy Kong alongside Kuma and configure it all using Custom Resource Definitions(CRDs) and Kubernetes-native tooling.

#### Installation

The dataplane can now operate in [Gateway mode](https://kuma.io/docs/latest/documentation/dps-and-data-model/#gateway). This way you can integrate Kuma with existing API Gateways like [Kong](https://github.com/Kong/kong). Run the following command to deploy [Kong for Kubernetes](https://github.com/Kong/kubernetes-ingress-controller) via [`bit.ly/demokumakong`](https://www.bit.ly/demokumakong), which points to the [kuma-demo-kong YAML file](/kubernetes/kuma-demo-kong.yaml) provided in this directory:

```bash
$ kubectl apply -f https://bit.ly/demokumakong
customresourcedefinition.apiextensions.k8s.io/kongconsumers.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongcredentials.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongingresses.configuration.konghq.com created
customresourcedefinition.apiextensions.k8s.io/kongplugins.configuration.konghq.com created
serviceaccount/kong-serviceaccount created
clusterrole.rbac.authorization.k8s.io/kong-ingress-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/kong-ingress-clusterrole-nisa-binding created
configmap/kong-server-blocks created
service/kong-proxy created
service/kong-validation-webhook created
deployment.apps/ingress-kong created
```

This deployment is slightly modified from the [original one](https://github.com/Kong/kubernetes-ingress-controller/blob/master/deploy/single/all-in-one-dbless.yaml) in the Kong for Kubernetes repository. We added the annotation `80.service.kuma.io/protocol: "http"` to the `kong-proxy` service and `kuma.io/gateway: enabled` annotation to the API gateway pod so the control-plane knows to inject a gateway dataplane. If you check the pods in the `kuma-demo` namespace, Kong wil be running alongside the application we deployed earlier:

```bash
$ kubectl get pods -n kuma-demo
NAME                                   READY   STATUS    RESTARTS   AGE
es-s86kd                               2/2     Running   0          11h
ingress-kong-7f4f5845b6-tpn8p          3/3     Running   0          43s
kuma-demo-app-656c95dcb5-twdl2         2/2     Running   0          11h
kuma-demo-backend-v0-99c9878b6-vfsdc   2/2     Running   0          11h
redis-master-657c58c859-prldh          2/2     Running   0          11h
```

After Kong is deployed, export the proxy IP:
```bash
$ export PROXY_IP=$(minikube service -p kuma-demo -n kuma-demo kong-proxy --url | head -1)
```

And lastly to check that the proxy IP has been exported, run:
```bash
$ echo $PROXY_IP
http://<IP_ADDRESS>:31553
```

![kong-gateway](https://raw.githubusercontent.com/Kong/kuma-website/master/docs/.vuepress/public/images/demo/kuma-kong-plugins.png)

#### Configuration

After deploying the gateway in our existing mesh, the next step is to add an Ingress rule. Create an Ingress rule to proxy to the marketplace frontend service:

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: extensions/v1beta1
kind: Ingress
metadata:
  name: marketplace
  namespace: kuma-demo
spec:
  rules:
  - http:
      paths:
      - path: /
        backend:
          serviceName: frontend
          servicePort: 8080
EOF

ingress.extensions/marketplace created
```

By default, Kong Ingress Controller distributes traffic amongst all the Pods of a Kubernetes Service by forwarding the requests directly to Pod IP addresses. One can choose the load-balancing strategy to use by specifying a KongIngress resource.

However, in some use-cases, the load-balancing should be left up to kube-proxy, or a sidecar component in the case of Service Mesh deployments. We want the load-balancing to be left to Kuma so the following annotation has been included in our [`kuma-demo-aio.yaml`](/kubernetes/kuma-demo-aio.yaml) frontend service resource:

```yaml
apiVersion: v1
kind: Service
metadata:
  name: frontend
  namespace: kuma-demo
  annotations:
    ingress.kubernetes.io/service-upstream: "true"
spec:
  ...
```

Remember to add this annotation to the appropriate services when you deploy Kong with Kuma.

After adding the Ingress rule, you can access the same marketplace application via the `$PROXY_IP`. You no longer have to port-forward the `kuma-demo-app` pod since all traffic into the mesh will be handled by this gateway.

### Prometheus and Grafana

Out-of-the-box, Kuma provides full integration with Prometheus and Grafana. If enabled, every dataplane will expose its metrics in Prometheus format. Furthermore, Kuma will make sure that Prometheus can automatically find every dataplane in the mesh.

#### Installation

In Kubernetes mode, we can use `kumactl install [..]` again to install the pre-configured Prometheus and Grafana components onto the Kubernetes cluster we have deployed:

```
$ kumactl install metrics | kubectl apply -f -
namespace/kuma-metrics created
podsecuritypolicy.policy/grafana created
configmap/grafana created
configmap/prometheus-alertmanager created
configmap/provisioning-datasource created
configmap/provisioning-dashboards created
configmap/prometheus-server created
persistentvolumeclaim/prometheus-alertmanager created
persistentvolumeclaim/prometheus-server created
serviceaccount/prometheus-alertmanager created
serviceaccount/prometheus-kube-state-metrics created
serviceaccount/prometheus-node-exporter created
serviceaccount/prometheus-pushgateway created
serviceaccount/prometheus-server created
serviceaccount/grafana created
clusterrole.rbac.authorization.k8s.io/prometheus-alertmanager created
clusterrole.rbac.authorization.k8s.io/prometheus-kube-state-metrics created
clusterrole.rbac.authorization.k8s.io/prometheus-pushgateway created
clusterrole.rbac.authorization.k8s.io/prometheus-server created
clusterrole.rbac.authorization.k8s.io/grafana-clusterrole created
clusterrolebinding.rbac.authorization.k8s.io/prometheus-alertmanager created
clusterrolebinding.rbac.authorization.k8s.io/prometheus-kube-state-metrics created
clusterrolebinding.rbac.authorization.k8s.io/prometheus-pushgateway created
clusterrolebinding.rbac.authorization.k8s.io/prometheus-server created
clusterrolebinding.rbac.authorization.k8s.io/grafana-clusterrolebinding created
role.rbac.authorization.k8s.io/grafana created
rolebinding.rbac.authorization.k8s.io/grafana created
service/prometheus-alertmanager created
service/prometheus-kube-state-metrics created
service/prometheus-node-exporter created
service/prometheus-pushgateway created
service/prometheus-server created
service/grafana created
daemonset.apps/prometheus-node-exporter created
deployment.apps/grafana created
deployment.apps/prometheus-alertmanager created
deployment.apps/prometheus-kube-state-metrics created
deployment.apps/prometheus-pushgateway created
deployment.apps/prometheus-server created
```

To check if everything has been deployed, check the `kuma-metrics` namespace:

```
$ kubectl get pods -n kuma-metrics
NAME                                             READY   STATUS    RESTARTS   AGE
grafana-c987548d6-5l7h7                          1/1     Running   0          2m18s
prometheus-alertmanager-655d8568-frxhc           2/2     Running   0          2m18s
prometheus-kube-state-metrics-5c45f8b9df-h9qh9   1/1     Running   0          2m18s
prometheus-node-exporter-ngqvm                   1/1     Running   0          2m18s
prometheus-pushgateway-6c894bb86f-2gflz          1/1     Running   0          2m18s
prometheus-server-65895587f-kqzrf                3/3     Running   0          2m18s
```

Once the pods are all up and running, we need to edit the Kuma Mesh object to include the `metrics: prometheus` section you see below. It is not included by default so you can edit the Mesh object using kubectl like so:

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: default
spec:
  mtls:
    ca:
      builtin: {}
  metrics:
    prometheus: {}
EOF

mesh.kuma.io/default configured
```

Afterwards, port-forward the Grafana server pod on the `kuma-metrics` namespace to acess the GUI:

```bash
$ kubectl port-forward grafana-c987548d6-5l7h7 -n kuma-metrics 3000
Forwarding from <IP_ADDRESS>:3000 -> 3000
Forwarding from [::1]:3000 -> 3000
```

Visit the [Grafana dashboard](http://localhost:3000/) to query the metrics that Prometheus is scraping from Kuma mesh. If you are prompted to login, just use `admin:admin` as the username and password.

![grafana-dashboard](https://github.com/Kong/kuma-website/blob/master/docs/.vuepress/public/images/demo/mesh-grafana-dashboard.png?raw=true)

    ↥ back to top

## Policies

### mTLS

This policy enables automatic encrypted mTLS traffic for all the services in a mesh. Kuma ships with a builtin CA (Certificate Authority) which is initialized with an auto-generated root certificate. The root certificate is unique for every mesh and it used to sign identity certificates for every data-plane. Kuma also supports third-party CA.

By default, mTLS is not enabled. You can enable Mutual TLS by updating the mesh policy with the mtls setting.

#### Check for mTLS

Using [`kumactl`](#kumactl) that you configured earlier, you can check the mesh resource and see that mTLS is turned off. You can also visualize these resource by inspecting them in the [GUI](#gui).

```bash
$ ./kumactl get meshes
NAME      mTLS   CA        METRICS
default   off    builtin   off
```

#### Adding mTLS Policy

Use `kubectl apply [..]` to enable mTLS on our mesh.

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: default
spec:
  mtls:
    ca:
      builtin: {}
    enabled: true
EOF
```

Once you have updated the mesh resource with mTLS enabled, check it was configured properly:

```
$ ./kumactl get meshes
NAME      mTLS   CA        METRICS
default   on     builtin   off
```

If you try to access the marketplace via the [`$PROXY_IP`](#configuration), it won't work because that traffic goes through the dataplane and is now encrypted via mTLS and the services do not have the proper permissions.

To enable traffic once mTLS has been enabled, please add [traffic permission policies](#traffic-permissions).

    ↥ back to top

### Traffic Permissions

Traffic Permissions allow you to determine how services communicate. It is a very useful policy to increase security in the mesh and compliance in the organization. You can determine what source services are allowed to consume specific destination services. The service field is mandatory in both sources and destinations.

#### Adding Traffic Permission Policy

Let's enable traffic-permission for all services so our marketplace works again:

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: TrafficPermission
mesh: default
metadata:
  namespace: kuma-demo
  name: everything
spec:
  sources:
  - match:
      service: '*'
  destinations:
  - match:
      service: '*'
EOF
```

And now if we go back to the marketplace, everything will work since we allow all services to send traffic to one another.

#### Adding Granular Traffic Permissions

Imagine if someone was spamming fake reviews to compromise the integrity of our marketplace. We can easily take down our Redis service by using more granular traffic-permissions.

First, we have to delete the existing permission that allows traffic between all services:
```bash
$ kubectl delete trafficpermission -n kuma-demo --all
trafficpermission.kuma.io "everything" deleted
```

Next, apply the three policies below. In the first one, we allow the Kong service to communicate to the frontend. In the second one, we allow the frontend to communicate with the backend. And in the last one, we allow the backend to communicate with PostgreSQL. By not providing any permissions to Redis, traffic won't be allowed to that service.

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: TrafficPermission
mesh: default
metadata:
  namespace: kuma-demo
  name: kong-to-frontend
spec:
  sources:
  - match:
      service: kong-proxy.kuma-demo.svc:80
  destinations:
  - match:
      service: frontend.kuma-demo.svc:8080
---
apiVersion: kuma.io/v1alpha1
kind: TrafficPermission
mesh: default
metadata:
  namespace: kuma-demo
  name: frontend-to-backend
spec:
  sources:
  - match:
      service: frontend.kuma-demo.svc:8080
  destinations:
  - match:
      service: backend.kuma-demo.svc:3001
---
apiVersion: kuma.io/v1alpha1
kind: TrafficPermission
mesh: default
metadata:
  namespace: kuma-demo
  name: backend-to-postgres
spec:
  sources:
  - match:
      service: backend.kuma-demo.svc:3001
  destinations:
  - match:
      service: postgres.kuma-demo.svc:5432
EOF

trafficpermission.kuma.io/kong-to-frontend created
trafficpermission.kuma.io/frontend-to-backend created
trafficpermission.kuma.io/backend-to-postgres created
```

After we apply those three policies, use `kumactl` to check that the policies are in place:
```bash
$ kumactl get traffic-permissions
MESH      NAME
default   frontend-to-backend
default   backend-to-postgres
default   kong-to-frontend
```

And now if we go back to the marketplace, everything will work except the reviews. If we wanted to enable the Redis service again in the future, just add an additional traffic-permission back like this:
```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: TrafficPermission
mesh: default
metadata:
  namespace: kuma-demo
  name: backend-to-redis
spec:
  sources:
  - match:
      service: backend.kuma-demo.svc:3001
  destinations:
  - match:
      service: redis.kuma-demo.svc:6379
EOF

trafficpermission.kuma.io/backend-to-redis created
```

    ↥ back to top

### Traffic Routing

Traffic Routing policy enable you to configure routing rules for L4 traffic, i.e. blue/green deployments and canary releases. To route traffic, Kuma matches via tags that we can designate to Dataplane resources.

When we deployed the application earlier, the manifest deployed three versions of the backend application: `backend`, `backend-v1`, and `backend-v2`. The original `backend` service is a normal marketplace you've been browsing. The `backend-v1` is a marketplace with 1 sale on the front page, and `backend-v1` is a marketplace with 2 sales. In the diagram below, you can see the two destination services have been assigned the version tag to help with canary deployment.

```
                        ----> backend-v0  :  service=backend, version=v0, env=prod
                      /
(browser) -> frontend   ----> backend-v1  :  service=backend, version=v1, env=intg
                      \
                        ----> backend-v2  :  service=backend, version=v2, env=dev
```

#### Scale Replicas

`backend-v1` and `backend-v2` were deployed with 0 replicas so let's scale them up to one replica to see how traffic routing works:

```bash
$ kubectl scale deployment kuma-demo-backend-v1 -n kuma-demo --replicas=1

deployment.extensions/kuma-demo-backend-v1 scaled
```

and

```bash
$ kubectl scale deployment kuma-demo-backend-v2 -n kuma-demo --replicas=1

deployment.extensions/kuma-demo-backend-v2 scaled
```

Check all the pods are running like this:
```bash
$ kubectl get pods -n kuma-demo
NAME                                    READY   STATUS    RESTARTS   AGE
postgres-master-0                  2/2     Running   0          35m
ingress-kong-7f4f5845b6-68c5s           3/3     Running   0          35m
kuma-demo-app-c7b9f596c-9b8sz           2/2     Running   0          35m
kuma-demo-backend-v0-7cdccd5b7c-nvcws   2/2     Running   0          35m
kuma-demo-backend-v1-568c79b548-7sd24   2/2     Running   0          57s
kuma-demo-backend-v2-b7b59d49-mrrs9     2/2     Running   0          50s
redis-master-657c58c859-b72t5           2/2     Running   0          35m
```

#### Adding Routing Policy

To avoid going broke, let's limit the amount of special offers that appear on our marketplace. To do so, apply this TrafficRoute policy to routes majority of our traffic to the v0 version:

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: TrafficRoute
metadata:
  name: frontend-to-backend
  namespace: kuma-demo
mesh: default
spec:
  sources:
  - match:
      service: frontend.kuma-demo.svc:8080
  destinations:
  - match:
      service: backend.kuma-demo.svc:3001
  conf:
  # it is NOT a percentage. just a positive weight
  - weight: 80
    destination:
      service: backend.kuma-demo.svc:3001
      version: v0
  # we're NOT checking if total of all weights is 100
  - weight: 20
    destination:
      service: backend.kuma-demo.svc:3001
      version: v1
  # 0 means no traffic will be sent there
  - weight: 0
    destination:
      service: backend.kuma-demo.svc:3001
      version: v2
EOF

trafficroute.kuma.io/frontend-to-backend created
```

And now if we go back to our marketplace, roughly 20% of the requests will land you on the `backend-v1` service and place the first item on sale. And you will never see two sales occur at the same time because we placed a weight of 0 on the `backend-v2` service.

    ↥ back to top

### Health Check

The goal of Health Checks is to minimize the number of failed requests due to temporary unavailability of a target endpoint. By applying a Health Check policy you effectively instruct a dataplane to keep track of health statuses for target endpoints. Dataplane will never send a request to an endpoint that is considered "unhealthy".

#### Adding Health Check Policy

To apply a health check policy to backend service, run the following:
```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: TraffiHealthCheckcRoute
metadata:
  name: frontend-to-backend
  namespace: kuma-demo
mesh: default
spec:
  sources:
  - match:
      service: frontend.kuma-demo.svc:8080
  destinations:
  - match:
      service: backend.kuma-demo.svc:3001
  conf:
    activeChecks:
      interval: 10s
      timeout: 2s
      unhealthyThreshold: 3
      healthyThreshold: 1
    passiveChecks:
      unhealthyThreshold: 3
      penaltyInterval: 5s

```

    ↥ back to top

### Traffic Metrics

Kuma facilitates consistent traffic metrics across all dataplanes in your mesh.

A user can enable traffic metrics by editing a mesh resource and providing the desired mesh-wide configuration. If necessary, metrics configuration can be customized for each Dataplane individually, e.g. to override the default metrics port that might be already in use on that particular machine.

#### Adding Traffic Metric Policy

Let's enable traffic metrics by editing our mesh resource like so:

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: default
spec:
  mtls:
    ca:
      builtin: {}
    enabled: true
  metrics:
    prometheus: {}
EOF
```

You can check that Prometheus metrics is enabled by checking the mesh with `kumactl get [..]`:
```bash
$ kumactl get meshes
NAME      mTLS   CA        METRICS
default   on     builtin   prometheus
```

#### Query Metrics

You can visit the [Prometheus/Grafana section](#prometheus-and-grafana) to learn how to visualize your metrics. You can also visit the the official documentation found [here](https://kuma.io/docs/latest/policies/#traffic-metrics).

![grafana-dashboard](https://raw.githubusercontent.com/Kong/kuma-website/master/docs/.vuepress/public/images/demo/mesh-grafana-dashboard.png)

    ↥ back to top

### Traffic Log

With TrafficLog policy you can easily set up access logs on every data-plane in a Mesh. The logs can be then forwarded to a collector that can further transmit them into systems like Splunk, ELK and Datadog.

#### Setup

First, you need to configure logging backends that will be available for use in a given Mesh. A logging backend is essentially a sink for access logs. In the current release of Kuma, a logging backend can be either a file or a TCP log collector, such as Logstash.

Run the following command to deploy a sample logtash service via [`bit.ly/demokumalog`](https://bit.ly/demokumalog), which points to the [kuma-demo-log YAML file](/kubernetes/kuma-demo-log.yaml) provided in this directory:
```bash
$ kubectl apply -f https://bit.ly/demokumalog
namespace/logging created
service/logstash created
configmap/logstash-config created
deployment.apps/logstash created
```

This logstash service is configured to send logs to our [Loggly](https://www.loggly.com/) instance at https://kumademo.loggly.com/. To use it yourself, you will need to create a free Loggly account and update the API key listed in the [kuma-demo-log YAML file](/kubernetes/kuma-demo-log.yaml#33).

#### Adding Logging Policy

After that service is up and running, create a TrafficLog policy to select a subset of traffic and forward its access logs into one of the logging backends configured for that Mesh:

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: default
spec:
  mtls:
    ca:
      builtin: {}
    enabled: true
  logging:
    backends:
    - name: logstash
      format: |
        {
            "destination": "%KUMA_DESTINATION_SERVICE%",
            "destinationAddress": "%UPSTREAM_HOST%",
            "source": "%KUMA_SOURCE_SERVICE%",
            "sourceAddress": "%KUMA_SOURCE_ADDRESS%",
            "bytesReceived": "%BYTES_RECEIVED%",
            "bytesSent": "%BYTES_SENT%"
        }
      tcp:
        address: logstash.logging:5000
---
apiVersion: kuma.io/v1alpha1
kind: TrafficLog
mesh: default
metadata:
  namespace: kuma-demo
  name: everything
spec:
  sources:
  - match:
      service: '*'
  destinations:
  - match:
      service: '*'
  conf:
    backend: logstash
EOF
```

If you visit your personal Loggly instance, you will see the logs appear there.

    ↥ back to top

### Traffic Trace

With the TrafficTrace policy you can configure tracing on every Kuma DP that belongs to the Mesh. Note that tracing operates on L7 HTTP traffic, so make sure that selected dataplanes are configured with HTTP Protocol.

#### Jaeger Installation

We will be using [Jaeger](https://www.jaegertracing.io/), which is an open-source tracing tool. You can use popular alternatives like Zipkin alongside Kuma.

This Jaeger template uses an in-memory storage with a limited functionality for local testing and development. The image used defaults to the latest version released. Do not use this template in production environments. Note that functionality may differ from the pinned docker versions for production. Install everything in the current namespace:

```bash
$ kubectl create -f https://raw.githubusercontent.com/jaegertracing/jaeger-kubernetes/master/all-in-one/jaeger-all-in-one-template.yml

deployment.extensions/jaeger created
service/jaeger-query created
service/jaeger-collector created
service/jaeger-agent created
service/zipkin created
```

#### Adding Traffic Tracing Policy

Let's enable traffic metrics by editing our mesh resource like so:

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: Mesh
metadata:
  name: default
spec:
  mtls:
    ca:
      builtin: {}
    enabled: true
  metrics:
    prometheus: {}
  tracing:
    defaultBackend: jaeger
    backends:
    - name: jaeger
      sampling: 100.0
      zipkin:
        url: http://jaeger-collector.default:9411/api/v1/spans
EOF

mesh.kuma.io/default configured
```

Once you have tracing enabled on the mesh, add a tracing policy on the services you want to trace. We will be tracing all services with the policy below:

```bash
$ cat <<EOF | kubectl apply -f -
apiVersion: kuma.io/v1alpha1
kind: TrafficTrace
mesh: default
metadata:
  namespace: kuma-demo
  name: trace-all-traffic
spec:
  selectors:
  - match:
      service: '*'
  conf:
    backend: jaeger
EOF

traffictrace.kuma.io/trace-all-traffic created
```

You need to restart Kuma DP for tracing configuration to be applied. This limitation will be solved in the next versions of Kuma.

```bash
$ kubectl delete pods -n kuma-demo --all
pod "es-d65zg" deleted
pod "ingress-kong-65bb78647-k88n2" deleted
pod "kuma-demo-app-869cd7cfbf-d6rm7" deleted
pod "kuma-demo-backend-v0-bbdfdd5f9-57pkx" deleted
pod "redis-master-6d4cf995c5-wrbl2" deleted
```

#### Visualizing Traces

After generating some traffic in the mesh, you can access the Jaeger dashboard using the following command to visualize the traces:

```bash
$ minikube service jaeger-query --url -p kuma-demo
http://<IP_ADDRESS>:30911
```

    ↥ back to top

repository: nickolaev/kuma-demo

repo_name: nickolaev/kuma-demo


text:
==============
 zenbu (全部)
==============

|Sample Usage|

A setup-agnostic cascading theme engine. Uses Jinja2 for templates and YAML
for variable definition.

The above gif was brought to you by `wzb-utils`_.

Installation
------------

::

   pip install zenbu

or just move ``zenbu.py`` to somewhere in your ``$PATH``.
If you do the latter, you must install the dependencies in the
following section manually.

If you are running Arch Linux, you can also use the AUR package `zenbu-git`_ (AUR).

If you are running Gentoo:

::

  layman -o https://raw.githubusercontent.com/azahi/ricerlay/master/overlay.xml -f -a ricerlay
  layman -s ricerlay
  emerge app-misc/zenbu

Dependencies
------------

-  Python (2 or 3)

The below are Python libraries that should be installed via ``pip``.
Alternatively, if you did ``pip install zenbu``, these should have been
automatically installed.

- argcomplete
- colorlog
- Jinja2
- PyYAML
- termcolor
- watchdog

Tab completion
--------------

::

  sudo activate-global-python-argcomplete

If you installed via pip, you may need to run the following before autocompletion works:

::

  grep 'PYTHON_ARGCOMPLETE_OK' "$(which zenbu)" &>/dev/null || sudo sed -i "1a # PYTHON_ARGCOMPLETE_OK" "$(which zenbu)"

Usage
-----

Check the `example`_ folder for some sample usage!

For a more detailed explanation, check out the `wiki homepage`_.

For common issues, check the `common gotchas wiki page`_.

For some neat tools (including automatic desktop reloads), check the
`tools wiki page`_.

::

  usage: zenbu [-h] [-l] [-t TEMPLATE_DIR] [-d DEST_DIR] [-s VAR_SET_DIR]
               [-f FILTERS_FILE] [-i IGNORES_FILE] [-e] [-w]
               [--watch-command WATCH_COMMAND] [--watch-dirs WATCH_DIRS]
               [--diff] [--dry]
               [variable_files [variable_files ...]]

  A Jinja2 + YAML based config templater.

  Searches for an optional yaml file with a variable mapping in
  ~/.config/zenbu/defaults.yaml,

  an optional python file with filters in (by default)
  ~/.config/zenbu/filters.py,

  an optional yaml file with an ignore scalar of regexes in (by default)
  ~/.config/zenbu/ignores.yaml,

  and uses the Jinja2 templates in (by default)
  ~/.config/zenbu/templates/

  to render into your home directory (by default).

  Additional variable files can be applied
  by supplying them as arguments, in order of application.

  They can either be paths or, if located in (by default)
  ~/.config/zenbu/variable_sets/,
  extension-less filenames.

  Environment variable support is available;
  simply run with the `-e` flag and
  put the name of the variable in Jinja2 brackets.

  The default Jinja2 globals and filters are available.

  Order of precedence is:
  last YAML variable defined >
  first YAML variable defined >
  environment variables.

  Variables are shallowly resolved once. Thus, for example you may have the
  following in your defaults.yaml for convenience:

  n_primary:  "{{ colors[colors.primary].normal }}"

  Autocomplete support available, but only for the default
  variable set directory.

  A file watcher is available via the -w flag.
  Whenever a variable file in use, the filters file, the ignores file,
  or a template file changes, the templates are rendered
  if there are any differences. This can be overridden with a custom list of
  directories via the --watch-dirs flag.

  Diffs between the current destination files and
  template renderings are available via the --diff flag.

  For help on designing templates, refer to
  http://jinja.pocoo.org/docs/dev/templates/

  For help on creating filters, refer to
  http://jinja.pocoo.org/docs/dev/api/#custom-filters

  positional arguments:
    variable_files        additional variable files

  optional arguments:
    -h, --help            show this help message and exit
    -l                    list variable sets.
    -t TEMPLATE_DIR       template directory. Default:
                          /Users/echan/.config/zenbu/templates
    -d DEST_DIR           destination directory. Default: /Users/echan
    -s VAR_SET_DIR        variable set directory. Default:
                          /Users/echan/.config/zenbu/variable_sets
    -f FILTERS_FILE       filters file. Default:
                          /Users/echan/.config/zenbu/filters.py
    -i IGNORES_FILE       ignores file. Default:
                          /Users/echan/.config/zenbu/ignores.yaml
    -e                    whether or not to use environment variables. Default:
                          don't use environment variables
    -w                    start file watcher.
    --watch-command WATCH_COMMAND
                          what to execute when a change occurs. Default: Nothing
    --watch-dirs WATCH_DIRS
                          override what directories to watch, colon-separated.
                          Default: Nothing
    --diff                show diff between template renderings and current
                          destination files
    --dry                 do a dry run

Zenbu in the wild
-----------------

|enju|

What happened to whizkers?
--------------------------

This project may seem awfully similar to `whizkers`_; in fact, this is a fork
of whizkers which swaps the Mustache backend out with Jinja2. I'm keeping
whizkers around for compatibility reasons. So what are the reasons for
switching?

- Comprehensive documentation: See the
  `Jinja2 Template Designer Documentation`_.
- Better logic: Everything from if/else to macros. I originally praised
  Mustache for its logic-less philosophy, but then I realized that there would
  be no place to put logic other than the variable sets, which is a nightmare.
- Expressions: You can now do ``{{ ':bold' if use_bold else '' }}``. You can
  even do ``{{ colors[colors.primary]['normal'] }}``, which has led to the
  deprecation of the ``{` ... `}`` eval syntax.
- Filters: You can now do ``{{ colors.black.bold | to_rgb }}``. A lot better
  than Mustache's syntax.
- Better whitespace control: This means increased readability.

To help ease the transition to zenbu, there are some tips under the
`migration wiki page`_.

Thanks to
---------

- https://gist.github.com/coleifer/33484bff21c34644dae1
- http://jinja.pocoo.org/
- http://pyyaml.org/
- `fullsalvo`_ for ideas, opinions, the readme gif, contributing to documentation,
  shilling, and overall being a good guy

.. |Sample Usage| image:: http://i.imgur.com/auBfvx0.gif
   :target: https://u.teknik.io/FUkHM.webm
   :alt: zenbu with fullsalvo's wzb-utils.
.. |enju| image:: http://i.imgur.com/EkT9OY5.gif
   :target: http://asator.xyz/img/dad9.webm
   :alt: enju on 2bwm.
.. _wzb-utils: https://github.com/fullsalvo/wzb-utils
.. _zenbu-git: https://aur.archlinux.org/packages/zenbu-git
.. _whizkers: https://github.com/metakirby5/whizkers
.. _Jinja2: http://jinja.pocoo.org/
.. _Jinja2 Template Designer Documentation:
    http://jinja.pocoo.org/docs/dev/templates/
.. _YAML: http://yaml.org/
.. _wiki homepage: https://github.com/metakirby5/zenbu/wiki
.. _migration wiki page: https://github.com/metakirby5/zenbu/wiki/Migration
.. _common gotchas wiki page:
    https://github.com/metakirby5/zenbu/wiki/Common-gotchas
.. _tools wiki page:
    https://github.com/metakirby5/zenbu/wiki/Tools
.. _example: example
.. _fullsalvo: https://github.com/fullsalvo

extension: rst

gha_language: Python


text:
## Golang Context

### Select

select 是 Go 中的一个控制结构，类似于用于通信的 switch 语句。每个 case 必须是一个通信操作，要么是发送要么是接收。

select 随机执行一个可运行的 case。如果没有 case 可运行，它将阻塞，直到有 case 可运行。一个默认的子句应该总是可运行的。

### ctx.Done()
ctx.Done() means that we receive the order to finish our work.  In this case, we will interrupt the loop, log a message and return.

详细请参考[这一章](https://www.practical-go-lessons.com/chap-37-context)

> 在上面的程序中
we will use a channel to communicate with the caller. We create a for loop, and inside that loop, we will put a select statement. In this select statement, we have two cases :

The channel returned by ctx.Done() has been closed. It means that we receive the order to finish our work

In this case, we will interrupt the loop, log a message and return.
The default case (executed if any previous case are not executed)

In this default case, we will increment the sum.

If the variable sum is becoming greater strictly than 1.000, we will send the result on the result channel

repository: hustbill/go-projects

repo_name: hustbill/go-projects


text:
---
layout: post
title:      "CLI Data Gem Project: True Crime Documentary "Database""
date:       2018-06-23 18:55:10 -0400
permalink:  cli_data_gem_project_true_crime_documentary_database
---

At last, I am complete with my project.  It took exactly two weeks.

**Overview**

The name of my project is True Crime Documentary Database. It offers a list film and television documentary film titles in the True Crime genre.

(Note: Although it indeed is not a database, its functions point in the direction of a database. The term "database" is used here loosely.)

I used the Nokogiri gem to scrape the site crimedocumentary.com.  I created an application that scrapes the category names, the URLs, and the documentary attributes that exist within each URL path.  The program should deliver a menu of options: to browse the documentaries by category or to see a full listing of documentary titles.

Selecting category delivers a list of documentaries displayed with their title, year, category, synopsis, and full synopsis URL.  Otherwise, if list all documentaries is chosen, then the user is taken to a submenu from which to select a title.  Similarly, the selection displays the documentary’s details.

**Building The Project**

Now, based on my initial review of the HTML I felt assured that I could achieve this project based on what I had learned in the previous labs leading up to my CLI data gem.  What I hadn’t given better attention to was the layout of the site and how it delivered the data.  The categories of a film are front and center, while the documentaries generate (no HTML to scrape) in many places, except inside of category link paths in the right sidebar.  Sadly, I hadn’t noticed this quirk until long after getting approval and having coded my scraper class. (With respect to object orientation, this presents some coding challenges. It would be hard to maintain the has a/has  many object relationship that I planned.)  In the scraper class is when I realized I might run into trouble when I’d have to connect these objects in the CLI controller class.  Sure enough, that difficulty arose. I worked hard to refactor the entire project from start to finish and ended up with a better product.

Something I encountered was that the number of links I decided to scrape tacked on at least 15 to 20 seconds of load time at the start of the program. Coincidentally, in one of my recent study groups, the instructor mentioned how it might sometimes be a better option to have the data load (scrape) upon selection by the user. I thought it was an excellent idea!  However, given how far I had come and that I was already in the middle of rebuilding my program from scratch (I created a branch and merged later), it would have proven difficult timewise.  So again, the layout and coding of the site presented a hurdle that made any new idea unfeasible.

Overall, I believe that I have met the requirements of the project by demonstrating that I have a good grasp of object orientation and working confidence in coding in Ruby.

**Some Afterthoughts**

* Simple ideas are still complicated when it comes time to code them!
* What you think is simple may not be simple enough.
* Projects fan the flames of enduring appreciation for Google search! :)
* This project was, *hard*! However, it I love it!
* Coding is fun. Learning to code is fun and uncannily cathartic. O_O

Bottom line: The CLI data gem was a challenging project, while also gratifying!

Access the repository [here](https://github.com/iamdavidmichaelmoore/true-crime-documentaries).

UPDATE:  24 June 2018 - This video walk-through demonstrates some changes/additions that were made since the publication of this post.  See my walk-through [here](https://youtu.be/DowMO_7DdUI).

extension: markdown


text:
---
layout: post
title:  "Vagrant port forwarding"
date:   2015-08-29 14:05:00
category: macosx
css: test/solarized-dark.css
tagline: "DevNotes"
tags : [vagrant, virtualbox, port forwarding, macosx]
email<EMAIL_ADDRESS>github : eim
author: Eugene Mukhanov
---
{% include JB/setup %}

### Home pages:
+ [VirtualBox home page](https://www.virtualbox.org)
+ [Vagrant home page](https://www.vagrantup.com)
+ [Rsync home page](https://rsync.samba.org)
+ [Lsyncd home page](https://github.com/axkibe/lsyncd)

## Overview

In order to improve the speed of file transfer between MacOS X host and VirtualBox VM is managed by vagrant I'm using lsyncd + rsync. Port numbers less than 1024 are forbidden.
It's very easy to forward port 873 to 1873.

### Using

Install vagrant plugin:

{% highlight bash %}
vagrant plugin install vagrant-triggers
{% endhighlight %}

Add command into configuraton:

{% highlight ruby %}
config.trigger.after [:up, :reload, :provision], :stdout => do
system('echo "rdr pass inet proto tcp from any to any port 873 -> 1873" | sudo pfctl -ef - >/dev/null 2>&1; echo "Add Port Forwarding (873->1873)"')
end
{% endhighlight %}

Define ip address

{% highlight ruby %}
config.trigger.after [:up, :reload, :provision], :stdout => do
system('echo "rdr pass inet proto tcp from any to <IP_ADDRESS> port 873 -> <IP_ADDRESS> port 1873" | sudo pfctl -ef - >/dev/null 2>&1')
end
{% endhighlight %}

Multiline

{% highlight ruby %}
config.trigger.after [:up, :reload, :provision], :stdout => do
system('echo "
rdr pass inet proto tcp from any to <IP_ADDRESS> port 873 -> <IP_ADDRESS> port 1873
rdr pass inet proto tcp from any to <IP_ADDRESS> port 443 -> <IP_ADDRESS> port 1443
" | sudo pfctl -ef - >/dev/null 2>&1')
end
{% endhighlight %}


text:
# Nicholas Kell's resume
======

There are two ways to hire this engineer, locally or remotely.

Dependencies:

- Good Culture
- Awesome teams to work with
- Cool technology to play with
- Did I mention culture?

Bonus points for:

- Linux
- Git
- Embedded Hardware
- C++

#### 1. View resume

Click [here](https://github.com/nicholaskell/resume/blob/master/Nicholas_Kell_Resume.pdf ".pdf version") for the .pdf version

#### 2. Email Me

<EMAIL_ADDRESS>
#### 3.

EXPERIENCE

SR. R&D SOFTWARE ENGINEER BAY TEK GAMES, PULASKI, WI APRIL 2011 - PRESENT

Led multiple projects through conception to deployment. Write object oriented software for Linux x86 and Atmel micro-controllers in an FDD agile environment. Use C/C++, as well as other languages and technologies as needed. Explore new technologies. Develop new designs, working closely with field testing to improve the current product and/or an older designed product. Develop and deploy Linux servers used for telemetry and real time reporting of products during the product lifecycle.  Work with and aiding electrical engineers and mechanical engineers to integrate systems. Help creating the QA process for software and hardware systems. Use Arduino, Raspberry Pi and other pieces of hardware for prototyping. Design simple electrical circuits for proof of concepts.

INTERACTIVE MANAGER / LEAD ENGINEER IMAGINASIUM, GREEN BAY, WI MARCH 2010 - APRIL 2011

Port existing websites and web services from a Microsoft OS to a Linux OS using open source tools. Use PHP, (X)HTML, CSS, Java Script,MySQL, MSSQL. Create new designs and modify old designs to meet new requirements, working closely with the project manager and customers to ensure quality is met. Created the now in place software design guidelines and FDD agile development environment. Configure and deploy Linux systems. Manage the hiring and letting go of employees in the Interactive Department.

SR. SOFTWARE ENGINEER, NEXTSOFT, NEENAH, WI JAN 2009 - MARCH 2010

Developed and maintained *nix services. Engineer Flex and AIR applications using the Flashbuilder IDE, and Java using BlazeDS. Aided in designing the now in use software design practices. Coded various utility applications in the Python programming language and also Java using Swing and AWT GUI. Use x86 and embedded Linux, Objective C, C/C++, iOS, OSX

FREELANCE WORK, 2006 - PRESENT

PHP frameworks for websites. Flex 3 and 4 frameworks. PHP and Flex package frameworks for remote calling. Robotic programming using Linux, Java, C/C++, and Python. AVR Programming.

EDUCATION

ITT TECH GREEN BAY, WI - ASSOCIATES OF APPLIED SCIENCE SOFTWARE APPLICATIONS AND PROGRAMMING, GRADUATED WITH HONORS 2009

SKILLS

PROFESSIONAL KNOWLEDGE

BASH, Knowledge and use of Linux & Unix commands, C/C++, MySQL,Apache 2.x, SVN, Git, CVS, PHP, Action Script, Python, Make (Makefile creation), Program network communication, Arduino, Raspberry Pi

Eclipse IDE, OS X, Linux, Netbeans, Static protocol development, SDL, SFML

PROFICIENT KNOWLEDGE

Java AWT & Swing components, Javascript, Dynamic protocol development, Automake, AVR32, AVR8, Electronics theory, Cadsoft EAGLE PCB,AOOOL (Any Ol’ Object Oriented Language)

WORKING KNOWLEDGE

Linux kernel development, Linux device driver development Autodesk AutoCAD for Mac,Wings3d

Leadership, managing small teams, great communication skills, attendance can’t get any better, team player, energetic, I love to learn and expand my horizons. Quickly understand assignments and carry them out in a timely manner.

“Simplicity is the ultimate sophistication.”

— Leonardo da Vinci

cell.<PHONE_NUMBER>

[http://www.linkedin.com/in/nicholaskell](http://www.linkedin.com/in/nicholaskell)

[nick.t.kell@gmail.com](mailto:nick.t.kell@gmail.com?subject=)

repository: nicholaskell/resume

repo_name: nicholaskell/resume