Skip to content

Commit

Permalink
Merge pull request #13329 from achilleasa/dev-merge-2.9
Browse files Browse the repository at this point in the history
#13329

This PR forward ports 2.9 into develop. The following PRs are included in this port:
 - Merge pull request #13324 from achilleasa/2.9-add-ovs-integration-test
 - Merge pull request #13328 from manadart/2.9-assess-series-upgrade
 - Merge pull request #13327 from wallyworld/azure-tests-fix
 - Merge pull request #13325 from SimonRichardson/raft-worker-errors
 - Merge pull request #13274 from SimonRichardson/lxd-network-devices-config-host-name
 - Merge pull request #13323 from jujubot/increment-to-2.9.15
 - Merge pull request #13321 from wallyworld/more-secret-metadata
 - Merge pull request #13319 from manadart/2.9-bridge-policy
 - Merge pull request #13320 from SimonRichardson/revert-lxd-changes
 - Merge pull request #13194 from juanmanuel-tirado/patch-1
 - Merge pull request #13318 from hpidcock/fix-1942948
 - Merge pull request #13314 from simondeziel/snap-ack
 - Merge pull request #13297 from achilleasa/2.9-allow-empty-openvswitch-blocks-in-netplan-config
 - Merge pull request #13317 from jujubot/increment-to-2.9.14
 - Merge pull request #13316 from hpidcock/fix-1942948
 - Merge pull request #13296 from ycliuhw/fix/registry-oauth2
 - Merge pull request #13311 from wallyworld/unitagent-missing-charm
 - Merge pull request #13315 from wallyworld/lxd-not-found-fix
 - Merge pull request #13221 from juanmanuel-tirado/status_watch_flag
 - Merge pull request #13312 from wallyworld/remove-txnwatcher-started
 - Merge pull request #13309 from kot0dama/fix-instrospection-posix-shell-2.9

The following files had merge conflicts that had to be resolved (please double-check the changes in last commit):
- caas/kubernetes/provider/bootstrap_test.go
- feature/flags.go
- scripts/win-installer/setup.iss
- snap/snapcraft.yaml
- state/pool.go
- version/version.go
- worker/uniter/relation/state_test.go
  • Loading branch information
jujubot committed Sep 13, 2021
2 parents 1d5f725 + e2665c4 commit a0f25a5
Show file tree
Hide file tree
Showing 104 changed files with 3,704 additions and 1,384 deletions.
59 changes: 29 additions & 30 deletions README.md
@@ -1,24 +1,24 @@
[![Juju logo](doc/juju-logo.png?raw=true)](https://juju.is/)

[Juju is a model-driven **Operator Lifecycle Manager**
(OLM)](https://juju.is/overview). Juju greatly improves the experience of
(OLM)](https://juju.is/about). Juju greatly improves the experience of
running Kubernetes operators, especially in projects that integrate many
operators from different publishers.

## Why Juju

A Kubernetes operator is [a container that drives the config and operation
of a workload](https://charmhub.io/about). By encapsulating ops code as a
reusable container, the operator pattern moves [beyond traditional config
management](https://juju.is/beyond-configuration-management) to allow much
more agile operations for complex cloud workloads.
reusable container, the operator pattern moves beyond traditional config
management to allow much more agile operations for complex cloud workloads.

Shared, open source operators **take infra as code to the next level** with
community-driven ops and integration code. Reuse of ops code [improves
quality](https://juju.is/ops-code-quality) and encourages wider community
engagement and contribution. Operators also improve security through
consistent automation. Juju operators are a [community-driven
devsecops](https://juju.is/devsecops) approach to open source operations.
Shared, open source operators **take infrastructure as code to the next level**
with community-driven ops and integration code. Reuse of ops code improves
quality and encourages wider [community engagement and contribution](
https://juju.is/about#collaboration). Operators also improve security
throughchat.charmhub.io/ consistent automation. Juju operators are a
[community-driven devsecops](https://juju.is/about#automate-everything)
approach to open source operations.

Juju implements the Kubernetes operator pattern, but is also a **universal
OLM** that extends the operator pattern to traditional applications (without
Expand All @@ -32,21 +32,21 @@ same app.

**Juju excels at application integration**. Instead of simply focusing on
lifecycle management, the Juju OLM provides a [rich application graph
model](https://juju.is/model-driven-operations) that tells operators how to
model](https://juju.is/about#integration-simplicity) that tells operators how to
integrate with one another. This dramatically simplifies the operations of
large deployments.

A key focus for Juju is to **simplify operator design, development and
usage**. Instead of making very complex operators for specific scenarios,
Juju encourages devops to make composable operators, each of which drives a
single Docker image, and which can be reused in different settings.
[Composable operators](https://juju.is/integration) enable very rich
scenarios to be constructed out of simpler **operators that do one thing and
do it well**.
[Composable operators](https://juju.is/about#integration-simplicity) enable
very rich scenarios to be constructed out of simpler **operators that do one
thing and do it well**.

The OLM provides a central mechanism for operator instantiation,
configuration, upgrades, integration and administration. The OLM provides a
range of [operator lifecycle services](https://juju.is/operator-services)
range of [operator lifecycle services](https://juju.is/docs/sdk/events)
including leader election and persistent state. Instead of manually
deploying and configuring operators, the OLM manages all the operators in a
model at the direction of the administrator.
Expand Down Expand Up @@ -81,8 +81,7 @@ environment and accelerate workloads accordingly.
The [Python Operator Framework](https://pythonoperatorframework.io/) makes
it easy to write an operator. The framework handles all the details of
communication between integrated operators, so you can focus on your own
[application lifecycle
management](https://juju.is/operator-lifecycle-manager).
[application lifecycle management](https://juju.is/docs/olm).

Code sharing between operator publishers is simplified making it much faster
to collaborate on distributed systems involving components from many
Expand All @@ -92,10 +91,9 @@ to your charm by the framework.

## Architecture

The Juju [client, server and agent](https://juju.is/architecture) are all
written in Golang. The standard Juju packaging includes an embedded database
for centralised logging and persistence, but there is no need to manage that
database separately.
The Juju client, server and agent are all written in Golang. The standard Juju
packaging includes an embedded database for centralised logging and ersistence,
but there is no need to manage that database separately.

Operators can be written in any language but we do encourage new authors to
use the Python Operator Framework for ease of contribution, support and
Expand All @@ -104,21 +102,21 @@ community participation.
## Production grade

The Juju server has built-in support for [high
availability](https://juju.is/high-availability-enterprise-olm) when scaled
availability](https://juju.is/docs/olm/high-availability) when scaled
out to three instances. It can monitor itself and grow additional instances
in the event of failure, within predetermined limits. Juju supports backup,
restore, and rolling upgrade operations appropriate for large-scale
centralised enterprise grade management and operations systems.

## Get started

Our community hangs out at the [Charmhub
discourse](https://discourse.juju.is/) which serves as a combination mailing
list and web forum. Keep up with the news and get a feel for operator
engineering and usage there. Get the Juju CLI on Windows, macOS or Linux
with the [install instructions](https://juju.is/docs/installing) and [try
the tutorials](https://juju.is/docs/tutorials). All you need is a small K8s
cluster, or an Ubuntu machine or VM to run MicroK8s.
Our community hangs out at the [Charmhub discourse](https://discourse.juju.is/)
which serves as a combination mailing list and web forum. Keep up with the news
and get a feel for operator engineering and usage there. Get the Juju CLI on
Windows, macOS or Linux with the
[install instructions](https://juju.is/docs/installing) and
[try the tutorials](https://juju.is/docs/tutorials). All you need is a small
K8s cluster, or an Ubuntu machine or VM to run MicroK8s.

Read the [documentation](https://juju.is/docs) for a comprehensive reference
of commands and usage.
Expand All @@ -128,4 +126,5 @@ of commands and usage.
Follow our [code and contribution guidelines](CONTRIBUTING.md) to learn how
to make code changes. File bugs in
[Launchpad](https://bugs.launchpad.net/juju/+filebug) or ask questions on
our [Freenode IRC channel](https://webchat.freenode.net/#juju).
our [Freenode IRC channel](https://webchat.freenode.net/#juju), and
[Mattermost](chat.charmhub.io/).
4 changes: 1 addition & 3 deletions acceptancetests/assess_upgrade_series.py
Expand Up @@ -78,9 +78,7 @@ def reboot_machine(client, machine):
try:
client.juju('ssh', (machine, 'sudo shutdown -r now'))
except subprocess.CalledProcessError as e:
if e.returncode != 255:
raise e
log.info("Ignoring `juju ssh` exit status after triggering reboot")
log.info("Ignoring `juju ssh` exit code {} after triggering reboot".format(e.returncode))

log.info("waiting for reboot")
hostname = client.get_status().get_machine_dns_name(machine)
Expand Down
2 changes: 0 additions & 2 deletions acceptancetests/requirements.txt
Expand Up @@ -10,13 +10,11 @@ azure-mgmt-compute>=18.2.0
azure-mgmt-containerservice>=14.0.0
azure-mgmt-core>=1.2.2
azure-mgmt-logic>=9.0.0
azure-mgmt-network>=17.1.0
azure-mgmt-notificationhubs>=7.0.0
azure-mgmt-nspkg>=3.0.2
azure-mgmt-redis>=12.0.0
azure-mgmt-resource>=15.0.0
azure-mgmt-scheduler>=7.0.0b1
azure-mgmt-storage>=17.0.0
azure-mgmt-web>=1.0.0
azure-nspkg>=3.0.2
azure-servicebus>=7.0.1
Expand Down
8 changes: 0 additions & 8 deletions acceptancetests/winazurearm.py
Expand Up @@ -48,10 +48,8 @@ def __init__(self, subscription_id, client_id, secret, tenant,
self.tenant = tenant
self.read_only = read_only
self.credentials = None
self.storage = None
self.resource = None
self.compute = None
self.network = None

def __eq__(self, other):
# Testing is the common case for checking equality.
Expand All @@ -67,19 +65,13 @@ def init_services(self):
"""Delay imports and activation of Azure RM services until needed."""
from azure.common.credentials import ServicePrincipalCredentials
from azure.mgmt.resource.resources import ResourceManagementClient
from azure.mgmt.storage import StorageManagementClient
from azure.mgmt.compute import ComputeManagementClient
from azure.mgmt.network import NetworkManagementClient
self.credentials = ServicePrincipalCredentials(
client_id=self.client_id, secret=self.secret, tenant=self.tenant)
self.storage = StorageManagementClient(
self.credentials, self.subscription_id)
self.resource = ResourceManagementClient(
self.credentials, self.subscription_id)
self.compute = ComputeManagementClient(
self.credentials, self.subscription_id)
self.network = NetworkManagementClient(
self.credentials, self.subscription_id)


class ResourceGroupDetails:
Expand Down
1 change: 1 addition & 0 deletions api/secrets/client.go
Expand Up @@ -47,6 +47,7 @@ func (api *Client) ListSecrets(showSecrets bool) ([]SecretDetails, error) {
Path: r.Path,
RotateInterval: r.RotateInterval,
Version: r.Version,
Status: secrets.SecretStatus(r.Status),
Description: r.Description,
Tags: r.Tags,
ID: r.ID,
Expand Down
12 changes: 7 additions & 5 deletions api/secrets/client_test.go
Expand Up @@ -44,10 +44,11 @@ func (s *SecretsSuite) TestListSecrets(c *gc.C) {
c.Assert(result, gc.FitsTypeOf, &params.ListSecretResults{})
*(result.(*params.ListSecretResults)) = params.ListSecretResults{
[]params.ListSecretResult{{
URL: "secret://v1/app.password",
Path: "app.password",
URL: "secret://app/mariadb/password",
Path: "app/password",
RotateInterval: time.Hour,
Version: 1,
Status: "active",
Description: "shhh",
Tags: map[string]string{"foo": "bar"},
ID: 1,
Expand All @@ -64,13 +65,14 @@ func (s *SecretsSuite) TestListSecrets(c *gc.C) {
client := apisecrets.NewClient(apiCaller)
result, err := client.ListSecrets(true)
c.Assert(err, jc.ErrorIsNil)
URL := secrets.NewSimpleURL(1, "app.password")
URL := secrets.NewSimpleURL("app/mariadb/password")
c.Assert(result, jc.DeepEquals, []apisecrets.SecretDetails{{
Metadata: secrets.SecretMetadata{
URL: URL,
Path: "app.password",
Path: "app/password",
RotateInterval: time.Hour,
Version: 1,
Status: secrets.StatusActive,
Description: "shhh",
Tags: map[string]string{"foo": "bar"},
ID: 1,
Expand All @@ -88,7 +90,7 @@ func (s *SecretsSuite) TestListSecretsError(c *gc.C) {
apiCaller := testing.APICallerFunc(func(objType string, version int, id, request string, arg, result interface{}) error {
*(result.(*params.ListSecretResults)) = params.ListSecretResults{
[]params.ListSecretResult{{
URL: "secret://v1/app.password",
URL: "secret://app/password",
Value: &params.SecretValueResult{
Error: &params.Error{Message: "boom"},
},
Expand Down
45 changes: 32 additions & 13 deletions api/secretsmanager/client.go
Expand Up @@ -38,14 +38,26 @@ func (c *Client) Create(cfg *secrets.SecretConfig, secretType secrets.SecretType

var results params.StringResults

arg := params.CreateSecretArg{
Type: string(secretType),
Path: cfg.Path,
Params: cfg.Params,
Data: data,
}
if cfg.Status != nil {
arg.Status = string(*cfg.Status)
}
if cfg.RotateInterval != nil {
arg.RotateInterval = *cfg.RotateInterval
}
if cfg.Description != nil {
arg.Description = *cfg.Description
}
if cfg.Tags != nil {
arg.Tags = *cfg.Tags
}
if err := c.facade.FacadeCall("CreateSecrets", params.CreateSecretArgs{
Args: []params.CreateSecretArg{{
Type: string(secretType),
Path: cfg.Path,
RotateInterval: cfg.RotateInterval,
Params: cfg.Params,
Data: data,
}},
Args: []params.CreateSecretArg{arg},
}, &results); err != nil {
return "", errors.Trace(err)
}
Expand Down Expand Up @@ -74,13 +86,20 @@ func (c *Client) Update(URL *secrets.URL, cfg *secrets.SecretConfig, value secre

var results params.StringResults

arg := params.UpdateSecretArg{
URL: URL.ID(),
RotateInterval: cfg.RotateInterval,
Description: cfg.Description,
Tags: cfg.Tags,
Params: cfg.Params,
Data: data,
}
if cfg.Status != nil {
statusStr := string(*cfg.Status)
arg.Status = &statusStr
}
if err := c.facade.FacadeCall("UpdateSecrets", params.UpdateSecretArgs{
Args: []params.UpdateSecretArg{{
URL: URL.ID(),
RotateInterval: cfg.RotateInterval,
Params: cfg.Params,
Data: data,
}},
Args: []params.UpdateSecretArg{arg},
}, &results); err != nil {
return "", errors.Trace(err)
}
Expand Down

0 comments on commit a0f25a5

Please sign in to comment.