Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add recipe support for Kubernetes secrets / OpenShift routes #12486

Merged
merged 4 commits into from
Feb 1, 2019

Conversation

amisevsk
Copy link
Contributor

@amisevsk amisevsk commented Jan 22, 2019

What does this PR do?

Add support for Secrets and Routes in OpenShift/Kubernetes recipes.

  • Routes will only work in OpenShift recipes, as they are not a Kubernetes object.
  • There is some minimal user dashboard validation (metadata + fields on secrets only) since all validation is done through the Kubernetes side (and so it doesn't make sense to mention routes there). Since this is more involved and will likely be harder to read, it should be done in a separate PR / issue.
    • Additionally, more validation for secrets could be beneficial, as e.g. data values must be base64 encoded.
  • Routes are renamed by the existing mechanism in Che. This should not affect behavior.
  • Secrets are left unmodified. Renaming can be added later if we find it is necessary (I don't really see a use case, personally).

This PR is broken up into 3 commits:

  • The first commit adds support for routes on the infra side
  • The second commit adds support for secrets on the infra side.
  • The third commit adds the necessary framework for UD validation.
A sample recipe for testing:
kind: List
apiVersion: v1
items:
  - 
    apiVersion: v1
    kind: Pod
    metadata:
      name: ws
    spec:
      containers:
        - 
          image: 'eclipse/che-dev:nightly'
          name: dev
          resources:
            limits:
              memory: 512Mi
          volumeMounts:
          - name: test
            mountPath: "/test"
            readOnly: true
      volumes:
      - name: test
        secret:
          secretName: test-secret
  -
    apiVersion: v1
    kind: Secret
    metadata:
      name: test-secret
    data:
      test1: dGVzdDE=
    stringData:
      test2: test2
  -
    apiVersion: v1
    kind: Route
    metadata:
      name: test-route
    spec:
      host: test.192.168.42.162.nip.io
      port:
        targetPort: http
      to:
        kind: Service
        name: che-host

What issues does this PR fix or reference?

#11508, #11530, #12522

Release Notes

Add support for secrets and routes in Kubernetes/OpenShift recipes

Docs PR

TODO

@amisevsk amisevsk added the status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. label Jan 22, 2019
@che-bot che-bot added the kind/enhancement A feature request - must adhere to the feature request template. label Jan 22, 2019
Copy link

@garagatyi garagatyi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good! Your commits have leftovers of conflict resolution error. Please, use squash when you merge.

@garagatyi
Copy link

ci-test

@garagatyi
Copy link

@ashumilova There is the 3rd commit in this PR that contains changes in UD. Please, review that part.

@ibuziuk ibuziuk self-requested a review January 22, 2019 13:52
@ibuziuk
Copy link
Member

ibuziuk commented Jan 22, 2019

@amisevsk could you please provide a recipe for testing?

@amisevsk
Copy link
Contributor Author

@ibuziuk It's hidden in the original PR message :)

kind: List
apiVersion: v1
items:
  - 
    apiVersion: v1
    kind: Pod
    metadata:
      name: ws
    spec:
      containers:
        - 
          image: 'eclipse/che-dev:nightly'
          name: dev
          resources:
            limits:
              memory: 512Mi
          volumeMounts:
          - name: test
            mountPath: "/test"
            readOnly: true
      volumes:
      - name: test
        secret:
          secretName: test-secret
  -
    apiVersion: v1
    kind: Secret
    metadata:
      name: test-secret
    data:
      test1: dGVzdDE=
    stringData:
      test2: test2
  -
    apiVersion: v1
    kind: Route
    metadata:
      name: test-route
    spec:
      host: test.192.168.42.162.nip.io
      port:
        targetPort: http
      to:
        kind: Service
        name: che-host

@amisevsk
Copy link
Contributor Author

@garagatyi I thought I had caught all the merge conflicts, don't know where that one came from. I'll remove it in rebase before merging.

@garagatyi
Copy link

@amisevsk there are no leftovers in the final diff. But since you prepared PR with the commit-by-commit approach (thanks for that) I found it in one of the commits and found that it was fixed in the following one

@ibuziuk
Copy link
Member

ibuziuk commented Jan 24, 2019

ci-test

Copy link
Member

@ibuziuk ibuziuk left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@amisevsk great job! tested on minishift and routes / secrets are created / deleted with workspace just fine

@ibuziuk
Copy link
Member

ibuziuk commented Jan 24, 2019

@ashumilova could you please take a look at UD part of the PR, before we proceed with merging ?

@che-bot
Copy link
Contributor

che-bot commented Jan 24, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:12486
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@ibuziuk
Copy link
Member

ibuziuk commented Jan 24, 2019

@vkuznyetsov @rhopp could QA provide their approval based on the test report. There are 6 test failures, but I do not think those are related to the PR

@amisevsk
Copy link
Contributor Author

Rebased onto current master and removed artifacts from a merge conflict in first commit.

Copy link
Member

@sleshchenko sleshchenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1
During manual testing, I successfully created a stack from Kubernetes recipe with content you provide. But then I failed to create a workspace from such stack with the following error
screenshot_20190125_101248

  1. Can we improve validation on Dashboard in this PR or in another issue?
  2. Please improve the validation message in EnvFactories to contain object kind and name instead of ObjectMeta json.

2 Then I created a stack using OpenShift recipe you provided. I edited config of created workspace and changed Route kind to Route1, as result I get 500 exception from workspace API
screenshot_20190125_101926
screenshot_20190125_102059
The same question about improving UX. It would be nice to improve dashboard, API to handle such cases

3
A workspace created from your provided recipe is started successfully. But what I see here there is no any integrity validation, recipe contains Route that references service that is not present in recipe. Do you think is there use case for such workspace? Or maybe we should add integrity validation for Routes, like we have for PVC (Pods can not reference PVCs which are not present in the recipe). See https://github.com/eclipse/che/blob/master/infrastructures/kubernetes/src/main/java/org/eclipse/che/workspace/infrastructure/kubernetes/environment/KubernetesEnvironmentPodsValidator.java#L59

4
The same question about recipe integrity validation but about secrets. Should we allow using Secret sources volumes that are not defined in the recipe?
It's just a question since I don't know what the right approach and just wanted to raise discussion.

@amisevsk
Copy link
Contributor Author

@sleshchenko Regarding the big issues in your review: the short of it is that Route validation is a bigger task than this PR (in my opinion). All validation goes through kubernetes-machine-recipe-parser.ts, and Routes are not Kubernetes objects. As a result:

  1. While we should block creation of Kube stacks with Routes, enabling the check (which is implemented here) would block creation of OpenShift stacks as well
  2. I agree that this should be improved -- I'll work on it. Should be relatively easy to implement on the infra side. Note that this will happen for any errors of this sort, not Routes specifically (thrown here-- WDYT about moving it to a new issue?
  3. Will look into this before Monday.
  4. I think there's a use case for secrets outside the recipe, because otherwise we require secrets used in workspace to be stored in a trivially decodable format in recipes. There's definitely a case in my mind where a user would want to create a secret more securely and still use it in a workspace.

@amisevsk
Copy link
Contributor Author

Created an issue for point 2. above: #12522

To add: validation on the dashboard side is currently not possible, and requires the more significant refactor to allow different validation paths for OpenShift vs. Kubernetes.

@sleshchenko
Copy link
Member

  1. I think there's a use case for secrets outside the recipe, because otherwise we require secrets used in workspace to be stored in a trivially decodable format in recipes. There's definitely a case in my mind where a user would want to create a secret more securely and still use it in a workspace.

Makes sense for me, thanks for the explanation.

@amisevsk
Copy link
Contributor Author

@sleshchenko I've added a commit to fix some of the validation issues:

  1. Avoid the internal server error when a recipe cannot be loaded (e.g. with kind: Route1) (Point 2 above)
  2. Show message like Found unknown object type in recipe -- name: 'test-route', kind: 'Route' when unsupported object is in recipe (Point 1 above)
  3. Throw validation exception if route refers to service that is not in recipe.

Anything I missed?

Copy link
Member

@sleshchenko sleshchenko left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job 👍

Please take a look my minor inline comments

list =
clientFactory.create().lists().load(new ByteArrayInputStream(content.getBytes())).get();
} catch (KubernetesClientException e) {
String message = e.getCause() == null ? e.getMessage() : e.getCause().getLocalizedMessage();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

e.getMessage() but e.getCause().getLocalizedMessage() <- Did you make it on the purpose?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, was an accident trying to find a decent way to avoid the newlines and messy cause. Fixed.

if (message.contains("\n")) {
// Clean up message if it comes from JsonMappingException. Format is e.g.
// `No resource type found for:v1#Route1\n at [...]`
message = message.split("\\n")[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you use the only first element, so you can limit elements

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

if (message.contains("\n")) {
// Clean up message if it comes from JsonMappingException. Format is e.g.
// `No resource type found for:v1#Route1\n at [...]`
message = message.split("\\n")[0];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The same as in KubernetesEnvironmentFactory

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done.

@@ -0,0 +1,47 @@
package org.eclipse.che.workspace.infrastructure.openshift.environment;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

please execute mvn license:format to add missing license

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, missed that.

validateRoutesMatchServices(env);
}

private void validateRoutesMatchServices(OpenShiftEnvironment env) throws ValidationException {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A check may be a bit improved by checking Route target port.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please consider adding unit tests for added test case

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added tests for this validation step.

I agree that the check could be improved by the docs on routes are not very good, and it seems that port options can get complicated. At a certain point it's going to be caveat emptor on validation.

@slemeur slemeur mentioned this pull request Jan 29, 2019
69 tasks
@amisevsk
Copy link
Contributor Author

@ashumilova If you have a moment, could you take a look at commit 81ea06f ? I'd like to merge this some time this week.

Add infrastructure side support for specifying routes in
OpenShift/Kubernetes recipes.

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Add infrastructure side support for secrets in Kubernetes / OpenShift
recipes.

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
Add mild validation (metadata, kind) for recipes containing secrets.
Note that routes are currently unvalidated since they are not
permissible in Kubernetes recipes (as they are OpenShift objects) and
all validation is done through the kubernetes parser / validator.

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
@ibuziuk
Copy link
Member

ibuziuk commented Jan 31, 2019

ci-test

@che-bot
Copy link
Contributor

che-bot commented Jan 31, 2019

Results of automated E2E tests of Eclipse Che Multiuser on OCP:
Build details
Test report
docker image: eclipseche/che-server:12486
https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

@amisevsk
Copy link
Contributor Author

PR Quality Review is a false positive, the unused field is necessary for injection.

- Avoid error internal server error when yaml in recipe is
  invalid (e.g. specifies "Route1")
- Add validation for Routes in recipes (must refer to Service also in
  recipe)
- Add test cases for OpenShiftEnvironmentFactory handling of Routes
- Minor cleanup and simplification.

Signed-off-by: Angel Misevski <amisevsk@redhat.com>
@ibuziuk
Copy link
Member

ibuziuk commented Jan 31, 2019

@vkuznyetsov could you please clarify, who from QA side should provide approval for this PR ?

@amisevsk
Copy link
Contributor Author

Rebased and squashed fixup commits.

@artaleks9
Copy link
Contributor

Selenium tests execution on Eclipse Che Multiuser on OCP (https://ci.codenvycorp.com/job/che-pullrequests-test-ocp/1496/) doesn't show any regression against this Pull Request.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/enhancement A feature request - must adhere to the feature request template.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants