Skip to content

Commit

Permalink
Use per-namespace app repositories by default (#1604)
Browse files Browse the repository at this point in the history
* Update values and deploy-dev to include new defaults

* Update AppRepoList so that it does not display add button when there's a fetch error.

* Update docs for private app repos.

* Update CI ref to app repo config.

* Add missing prop to SelectRepoForm

* Update snapshot

* Ensure kubeapps-operator can read app repos in kubeapps namespace.

* Ensure button click is registered.
  • Loading branch information
absoludity authored Mar 26, 2020
1 parent eb0fe0e commit c04046d
Show file tree
Hide file tree
Showing 12 changed files with 86 additions and 55 deletions.
13 changes: 6 additions & 7 deletions chart/kubeapps/values.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,9 @@
## If you set it to true, Kubeapps will not work with releases installed with Helm 2.
useHelm3: false

## Enable this feature flag to allow users to discover available namespaces (only the ones they have access).
## If you set it to true, Kubeapps creates a ClusterRole to be able to list namespaces.
allowNamespaceDiscovery: false
## Disable this feature flag to disallow users to discover available namespaces (only the ones they have access).
## When set to true, Kubeapps creates a ClusterRole to be able to list namespaces.
allowNamespaceDiscovery: true

## The frontend service is the main reverse proxy used to access the Kubeapps UI
## To expose Kubeapps externally either configure the ingress object below or
Expand Down Expand Up @@ -638,9 +638,8 @@ authProxy:
cpu: 25m
memory: 32Mi
## Feature flags
## These are used to switch on in development features or new features not yet released.
## These are used to switch on in development features or new features which are ready to be released.
featureFlags:
reposPerNamespace: false
# The invalidateCache flag must be set to default to true when we next release the Kubeapps app.
invalidateCache: false
reposPerNamespace: true
invalidateCache: true
operators: false
1 change: 1 addition & 0 deletions dashboard/src/components/AppUpgrade/AppUpgrade.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ class AppUpgrade extends React.Component<IAppUpgradeProps> {
isFetching={this.props.reposIsFetching}
error={this.props.chartsError}
kubeappsNamespace={this.props.kubeappsNamespace}
namespace={this.props.namespace}
repoError={this.props.repoError}
repo={this.props.repo}
repos={this.props.repos}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ exports[`renders the repo selection form if not introduced 1`] = `
fetchRepositories={[Function]}
isFetching={false}
kubeappsNamespace="kubeapps"
namespace="default"
repo={Object {}}
repos={
Array [
Expand Down
5 changes: 3 additions & 2 deletions dashboard/src/components/Catalog/Catalog.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ class Catalog extends React.Component<ICatalogProps, ICatalogState> {
public render() {
const {
charts: { isFetching, selected: { error }, items: allItems },
namespace,
pushSearchFilter,
csvs,
} = this.props;
Expand All @@ -72,7 +73,7 @@ class Catalog extends React.Component<ICatalogProps, ICatalogState> {
children={
<div>
<h5>Unable to fetch catalog</h5>
There was an error fetching the catalog.{ isForbidden && "Please choose a namespace above to which you have access." }
There was an error fetching the catalog.{ isForbidden && " Please choose a namespace above to which you have access." }
</div>
}
/>
Expand All @@ -86,7 +87,7 @@ class Catalog extends React.Component<ICatalogProps, ICatalogState> {
<div>
<h5>Charts not found.</h5>
Manage your Helm chart repositories in Kubeapps by visiting the{" "}
<Link to={"/config/repos"}>App repositories configuration</Link> page.
<Link to={`/config/ns/${namespace}/repos`}>App repositories configuration</Link> page.
</div>
}
/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ exports[`renderization when no charts should render an error 1`] = `
Manage your Helm chart repositories in Kubeapps by visiting the
<Link
to="/config/repos"
to="/config/ns/kubeapps/repos"
>
App repositories configuration
</Link>
Expand Down Expand Up @@ -139,7 +139,7 @@ exports[`renderization when there is an error fetching charts should render a sp
Unable to fetch catalog
</h5>
There was an error fetching the catalog.
Please choose a namespace above to which you have access.
Please choose a namespace above to which you have access.
</div>
</MessageAlertPage>
`;
18 changes: 18 additions & 0 deletions dashboard/src/components/Config/AppRepoList/AppRepoList.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -94,4 +94,22 @@ describe("AppRepoList", () => {
loaded: false,
});
});

it("displays the AppRepoAddButton when no fetching errors", () => {
const wrapper = shallow(<AppRepoList {...defaultProps} />);

const addButton = wrapper.find("AppRepoAddButton");
expect(addButton.length).toBe(1);
});

it("does not display the AppRepoAddButton when there is a fetching error", () => {
const props = {
...defaultProps,
errors: { fetch: new Error("Bang!") },
};
const wrapper = shallow(<AppRepoList {...props} />);

const addButton = wrapper.find("AppRepoAddButton");
expect(addButton.length).toBe(0);
});
});
70 changes: 37 additions & 33 deletions dashboard/src/components/Config/AppRepoList/AppRepoList.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -96,38 +96,42 @@ class AppRepoList extends React.Component<IAppRepoListProps> {
{errors.fetch && this.renderError("fetch")}
{errors.delete && this.renderError("delete")}
{errors.update && this.renderError("update")}
<LoadingWrapper loaded={!isFetching}>
<table>
<thead>
<tr>
<th>Repo</th>
{renderNamespace && <th>Namespace</th>}
<th>URL</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{repos.map(repo => (
<AppRepoListItem
key={repo.metadata.uid}
deleteRepo={deleteRepo}
resyncRepo={resyncRepo}
repo={repo}
renderNamespace={renderNamespace}
namespace={namespace}
/>
))}
</tbody>
</table>
</LoadingWrapper>
<AppRepoAddButton
errors={errors}
install={install}
validate={validate}
namespace={namespace}
isFetching={isFetching}
/>
<AppRepoRefreshAllButton resyncAllRepos={resyncAllRepos} repos={repos} />
{!errors.fetch &&
<>
<LoadingWrapper loaded={!isFetching}>
<table>
<thead>
<tr>
<th>Repo</th>
{renderNamespace && <th>Namespace</th>}
<th>URL</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
{repos.map(repo => (
<AppRepoListItem
key={repo.metadata.uid}
deleteRepo={deleteRepo}
resyncRepo={resyncRepo}
repo={repo}
renderNamespace={renderNamespace}
namespace={namespace}
/>
))}
</tbody>
</table>
</LoadingWrapper>
<AppRepoAddButton
errors={errors}
install={install}
validate={validate}
namespace={namespace}
isFetching={isFetching}
/>
<AppRepoRefreshAllButton resyncAllRepos={resyncAllRepos} repos={repos} />
</>
}
{displayReposPerNamespaceMsg && (
<MessageAlert header="Looking for other app repositories?">
<div>
Expand All @@ -139,7 +143,7 @@ class AppRepoList extends React.Component<IAppRepoListProps> {
Kubeapps now enables you to create App Repositories in your own namespace that will
be available in your own namespace and, in the future, optionally available in other
namespaces to which you have access. You can read more information in the{" "}
<a href="https://github.com/kubeapps/kubeapps/blob/master/docs/user/private-app-repository.md#per-namespace-app-repositories">
<a href="https://github.com/kubeapps/kubeapps/blob/master/docs/user/private-app-repository.md">
Private App Repository docs
</a>
.
Expand Down
3 changes: 2 additions & 1 deletion dashboard/src/components/SelectRepoForm/SelectRepoForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { ErrorSelector, MessageAlert } from "../ErrorAlert";

interface ISelectRepoFormProps {
isFetching: boolean;
namespace: string;
kubeappsNamespace: string;
repoError?: Error;
error?: Error;
Expand Down Expand Up @@ -57,7 +58,7 @@ class SelectRepoForm extends React.Component<ISelectRepoFormProps, ISelectRepoFo
<div>
<h5>Chart repositories not found.</h5>
Manage your Helm chart repositories in Kubeapps by visiting the{" "}
<Link to={"/config/repos"}>App repositories configuration</Link> page.
<Link to={`/config/ns/${this.props.namespace}/repos`}>App repositories configuration</Link> page.
</div>
}
/>
Expand Down
10 changes: 5 additions & 5 deletions docs/user/private-app-repository.md
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ curl --data-binary "@my-chart-1.0.0.tgz" http://localhost:8080/api/charts

### ChartMuseum: Configure the repository in Kubeapps

To add your private repository go to `Configuration > App Repositories` in Kubeapps and click on "Add App Repository". You will need to add your repository using the Kubernetes DNS name for the ChartMuseum service. This will be `<release_name>-chartmuseum.<namespace>:8080`:
To add your private repository to Kubeapps, select the Kubernetes namespace to which you want to add the repository (or "All Namespaces" if you want it available to users in all namespaces), go to `Configuration > App Repositories` and click on "Add App Repository". You will need to add your repository using the Kubernetes DNS name for the ChartMuseum service. This will be `<release_name>-chartmuseum.<namespace>:8080`:

<img src="../img/chartmuseum-repository.png" alt="ChartMuseum App Repository" width="300px">

Expand Down Expand Up @@ -115,7 +115,7 @@ Please refer to ['Manage Helm Charts in Harbor'](https://github.com/goharbor/har

### Harbor: Configure the repository in Kubeapps

To add Harbor as the private chart repository, go to `Configuration > App Repositories` in Kubeapps and click on "Add App Repository" and use the Harbor helm repository URL `http://harbor.default.svc.cluster.local/chartrepo/my-helm-repo`
To add Harbor as the private chart repository in Kubeapps, select the Kubernetes namespace to which you want to add the repository (or "All Namespaces" if you want it available to users in all namespaces), go to `Configuration > App Repositories` and click on "Add App Repository" and use the Harbor helm repository URL `http://harbor.default.svc.cluster.local/chartrepo/my-helm-repo`

<img src="../img/harbor-add-repo.png" width="600px">

Expand Down Expand Up @@ -169,7 +169,7 @@ curl -u{USER}:{PASSWORD} -XPOST "http://{REPO_URL}/artifactory/api/security/toke
}
```

The above command creates a token with read-only permissions. Now you can go to the `Configuration > App Repositories` menu and add your personal repository:
The above command creates a token with read-only permissions. Now you can select the namespace to which you want to add the repository (or "All Namespaces" if you want it available to users in all namespaces), go to the `Configuration > App Repositories` menu and add your personal repository:

<img src="../img/jfrog-custom-repo.png" alt="JFrog custom repository" width="400px">

Expand Down Expand Up @@ -202,6 +202,6 @@ The above will generate a Pod with the label `my-repo: isPrivate` and the enviro

## Per Namespace App Repositories

There is work in progress to support AppRepositories per namespace in Kubeapps, rather than sharing access to AppRepositories in Kubeapps' own namespace. Details about the design can be read on the [design document](https://docs.google.com/document/d/1YEeKC6nPLoq4oaxs9v8_UsmxrRfWxB6KCyqrh2-Q8x0/edit?ts=5e2adf87).
Previously, once an App Repository was created in Kubeapps, the charts of that repository were then available cluster-wide to all users of Kubeapps. This was changed to allow creating App Repositories available only in specific namespaces, enabling future work supporting deploying charts with private docker registries. You can still create an App Repository whose charts will be available to users in all namespaces by selecting "All Namespaces" when creating the repository.

More information will be added once it is available for general use.
There is work in progress to support AppRepositories with private docker registries in Kubeapps. Details about the design can be read on the [design document](https://docs.google.com/document/d/1YEeKC6nPLoq4oaxs9v8_UsmxrRfWxB6KCyqrh2-Q8x0/edit?ts=5e2adf87). More information will be added once it is available for general use.
12 changes: 10 additions & 2 deletions integration/use-cases/create-registry.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
test("Creates a registry", async () => {
await page.goto(getUrl("/#/config/repos"));
await page.goto(getUrl("/#/config/ns/kubeapps/repos"));

await expect(page).toFillForm("form", {
token: process.env.ADMIN_TOKEN
Expand All @@ -22,9 +22,17 @@ test("Creates a registry", async () => {

await page.type("#kubeapps-repo-url", "https://charts.gitlab.io/");

// Similar to the above click for an App Repository, the click on
// the Install Repo doesn't always register (in fact, from the
// screenshot on failure, it appears to focus the button only (hover css applied)
await expect(page).toClick("button", { text: "Install Repo" });

await expect(page).toClick("a", { text: "my-repo" });
try {
await expect(page).toClick("a", { text: "my-repo" });
} catch (e) {
await expect(page).toClick("button", { text: "Install Repo" });
await expect(page).toMatch("Install Repo");
}

let retries = 3;
while (retries > 0) {
Expand Down
3 changes: 0 additions & 3 deletions script/deploy-dev.mk
Original file line number Diff line number Diff line change
Expand Up @@ -34,10 +34,7 @@ deploy-dev: deploy-dex deploy-openldap update-apiserver-etc-hosts
--values ./docs/user/manifests/kubeapps-local-dev-values.yaml \
--values ./docs/user/manifests/kubeapps-local-dev-auth-proxy-values.yaml \
--set useHelm3=true \
--set allowNamespaceDiscovery=true \
--set postgresql.enabled=true \
--set featureFlags.reposPerNamespace=true \
--set featureFlags.invalidateCache=true \
--set mongodb.enabled=false
kubectl apply -f ./docs/user/manifests/kubeapps-local-dev-users-rbac.yaml
@echo "\nEnsure you have the entry '127.0.0.1 dex.dex' in your /etc/hosts, then run\n"
Expand Down
1 change: 1 addition & 0 deletions script/e2e-test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,7 @@ kubectl cp ./use-cases "${pod}:/app/"
kubectl create serviceaccount kubeapps-operator -n kubeapps
kubectl create clusterrolebinding kubeapps-operator-admin --clusterrole=admin --serviceaccount kubeapps:kubeapps-operator
kubectl create -n kubeapps rolebinding kubeapps-repositories-write --role=kubeapps-ci-repositories-write --serviceaccount kubeapps:kubeapps-operator
kubectl create -n kubeapps rolebinding kubeapps-repositories-read --role=kubeapps-ci-repositories-read --serviceaccount kubeapps:kubeapps-operator
## Create view user
kubectl create serviceaccount kubeapps-view -n kubeapps
kubectl create clusterrolebinding kubeapps-view --clusterrole=view --serviceaccount kubeapps:kubeapps-view
Expand Down

0 comments on commit c04046d

Please sign in to comment.