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 a role allowing che SA to stop workspaces #16532

Merged
merged 5 commits into from
Apr 21, 2020

Conversation

tomgeorge
Copy link
Contributor

What does this PR do?

Adds another stop-workspace role in a user namespace that gives the che serviceaccount to correctly stop workspaces.

What issues does this PR fix or reference?

#15906

Release Notes

Docs PR

@che-bot
Copy link
Contributor

che-bot commented Apr 2, 2020

Can one of the admins verify this patch?

1 similar comment
@che-bot
Copy link
Contributor

che-bot commented Apr 2, 2020

Can one of the admins verify this patch?

@che-bot che-bot added status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. kind/bug Outline of a bug - must adhere to the bug report template. labels Apr 2, 2020
@che-bot
Copy link
Contributor

che-bot commented Apr 2, 2020

✅ E2E Happy path tests succeed 🎉

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

Copy link
Contributor

@metlos metlos left a comment

Choose a reason for hiding this comment

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

If I'm not mistaken, #15906 suggests to also add creation privs for the SA - see #15906 (comment).

new ObjectReferenceBuilder()
.withKind("ServiceAccount")
.withName("che")
.withNamespace("che")
Copy link
Contributor

Choose a reason for hiding this comment

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

Namespace is configurable. Use the projectName field.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

projectName and serviceAccountName refer to the user namespace and the user serviceaccount. The che ServiceAccount in the che namespace need to be able to manage resources in a user namespace.

Copy link
Member

Choose a reason for hiding this comment

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

yeah, here we need to provide a namespace where che-server is deployed. Not sure if the SA name is configurable though cc: @davidfestal

Copy link
Member

Choose a reason for hiding this comment

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

it looks like we need to create a @Singleton that would be bound in the OpenShiftInfraModule / KubernetesInfraModule and expose information about the namespace / sa.

My observations are that che SA name is hardcoded and not configurable and namespace name can be obtained via System.getenv (Need to check if this will work in all the cases e.g.:

  • the operator uses KUBERNETES_NAMESPACE env var
  • helm POD_NAMESPACE

@tomgeorge
Copy link
Contributor Author

If I'm not mistaken, #15906 suggests to also add creation privs for the SA - see #15906 (comment).

The user who is creating the workspace has enough permissions to create the workspace resources, and the che SA stops the workspace in the case of idling. It doesn't seem like the che SA strictly needs create privileges in a user service account, and it's a good idea to assign the minimal level of access.

@tomgeorge
Copy link
Contributor Author

in regards to not hard-coding the service account names/namespaces, is there a way to reference the che service account and che namespace? projectName and serviceAccountName refer to the user user namespace/SA I believe.

@@ -142,6 +151,37 @@ private void createViewRole(OpenShiftClient osClient, String name) {
osClient.roles().inNamespace(projectName).create(viewRole);
}

private void createStopWorkspacesRole(OpenShiftClient osClient, String name) {
Copy link
Member

Choose a reason for hiding this comment

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

I would probably move the logic of granting the rights on the level above to the OpenShiftProjectFactory / getOrCreate + extract the logic of the role / rb to a separate class smth like OpenShiftStopWorkspaceRoleProvisioner with docs and tests

@che-bot
Copy link
Contributor

che-bot commented Apr 9, 2020

❌ E2E Happy path tests failed ❗

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

⚠️ https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

ℹ️ Use comment "crw-ci-test" to rerun happy path E2E test.

import javax.inject.Singleton;

@Singleton
public class OpenShiftCheInstallationLocation {
Copy link
Member

Choose a reason for hiding this comment

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

nice, IMO in future we need to standardize the env var name and always use KUBERNETES_NAMESPACE that is defined in the operator

Copy link
Member

Choose a reason for hiding this comment

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

Adding docs would be also really nice to have

Comment on lines 20 to 21
String kubernetesNamespace = System.getenv("KUBERNETES_NAMESPACE");
String podNamespace = System.getenv("POD_NAMESPACE");
Copy link
Member

Choose a reason for hiding this comment

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

Probably we can move the logic of obtaining the env vars to @PostConstruct to avoid reading env vars on every call

Copy link
Contributor Author

Choose a reason for hiding this comment

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

good idea

Copy link
Contributor

Choose a reason for hiding this comment

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

can you inject them as env. KUBERNETES_NAMESPACE in the constructor?

Copy link
Contributor

Choose a reason for hiding this comment

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

is this env vars are set by k8s or che-operator?

Copy link
Member

Choose a reason for hiding this comment

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

the problem is that helm & operator are using different env vars (POD_NAMESPACE - helm / KUBERNETES_NAMESPACE - operator)

Copy link
Contributor

Choose a reason for hiding this comment

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

Is it possible to change the helm chart to also call this KUBERNETES_NAMESPACE or does helm define this dynamically?

Copy link
Contributor

@metlos metlos Apr 14, 2020

Choose a reason for hiding this comment

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

I'm also voting for this to be somehow injected in a constructor or at least having a no-arg ctor determining the value from the env vars and another ctor initializing the namespace from a provided argument.

Also we should probably throw an exception if we're not able to determine the namespace. There's little point in continuing to deploy che if it won't be able to correctly handle workspaces..

Copy link
Member

@ibuziuk ibuziuk Apr 14, 2020

Choose a reason for hiding this comment

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

+1 for Helm update - https://github.com/eclipse/che/blob/master/deploy/kubernetes/helm/che/templates/deployment.yaml#L38
-1 for throwing the exception (there might be some cases when the namespace can not be obtained for any reason)

for this particular issue let's just do nothing if the namepsace can not be obtained - https://github.com/eclipse/che/pull/16532/files#r406635675

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Moved to @PostConstruct

Copy link
Contributor

Choose a reason for hiding this comment

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

why not injection in the constructor?

this.installationLocation = installationLocation;
}

public void provision(String projectName) throws InfrastructureException {
Copy link
Member

Choose a reason for hiding this comment

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

technically speaking installationLocation can be null based on implementation, so in this case can we log error and avoid doing anything in the provision method?

Copy link
Member

Choose a reason for hiding this comment

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

@tomgeorge can we check getInstallationLocationNamespace here and do nothing (log error) if null?

Comment on lines 20 to 21
String kubernetesNamespace = System.getenv("KUBERNETES_NAMESPACE");
String podNamespace = System.getenv("POD_NAMESPACE");
Copy link
Contributor

Choose a reason for hiding this comment

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

can you inject them as env. KUBERNETES_NAMESPACE in the constructor?

Comment on lines 20 to 21
String kubernetesNamespace = System.getenv("KUBERNETES_NAMESPACE");
String podNamespace = System.getenv("POD_NAMESPACE");
Copy link
Contributor

Choose a reason for hiding this comment

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

is this env vars are set by k8s or che-operator?

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.

LGTM

@che-bot
Copy link
Contributor

che-bot commented Apr 16, 2020

❌ E2E Happy path tests failed ❗

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

⚠️ https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

ℹ️ Use comment "crw-ci-test" to rerun happy path E2E test.

@ibuziuk
Copy link
Member

ibuziuk commented Apr 17, 2020

@metlos @skabashnyuk @sleshchenko folks, are you ok to merge this PR in the current state or some changes are still expected to be done before merging? Please, let us know since we do expect the fix in 7.12.0

@che-bot
Copy link
Contributor

che-bot commented Apr 17, 2020

❌ E2E Happy path tests failed ❗

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

⚠️ https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

ℹ️ Use comment "crw-ci-test" to rerun happy path E2E test.

@skabashnyuk
Copy link
Contributor

@dmytro-ndp
Copy link
Contributor

crw-ci-test

@ibuziuk
Copy link
Member

ibuziuk commented Apr 20, 2020

thanks, @tomgeorge (left minor comments in review) + looks like there is a conflict now after 06a34e3 :/

Tom George added 2 commits April 20, 2020 11:25
…t to stop a workspace in another namespace

Signed-off-by: Tom George <tgeorge@redhat.com>
…nd OpenShiftStopWorkspaceRoleProvisioner to provision necessary permissions for stopping workspaces

Signed-off-by: Tom George <tgeorge@redhat.com>
Copy link
Contributor

@amisevsk amisevsk left a comment

Choose a reason for hiding this comment

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

Generally LGTM, a few comments.

* @author Tom George
*/
@Singleton
public class OpenShiftCheInstallationLocation {
Copy link
Contributor

Choose a reason for hiding this comment

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

While this PR is to address an issue with OpenShift, it's a little strange to me that this class is in the openshift infra rather than k8s. Not a huge issue though.

Copy link
Member

Choose a reason for hiding this comment

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

good point, the problem is that we do need this PR in 7.12.0 and I'm not sure if @tomgeorge has time for further refactoring

LOG.info(
"Neither KUBERNETES_NAMESPACE nor POD_NAMESPACE is defined. Unable to determine Che installation location");
}
return kubernetesNamespace == null ? podNamespace : kubernetesNamespace;
Copy link
Contributor

Choose a reason for hiding this comment

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

Maybe a warn if both podNamespace and kubernetesNamespace are defined but not matching would also make sense? I don't know if this can occur naturally but might be a hard-to-debug issue.

Copy link
Member

Choose a reason for hiding this comment

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

in general, we do need to standardize the env var name (use only KUBERNETES_NAMESPACE) and remove usage of POD_NAMESPACE e.g. in helm chart https://github.com/eclipse/che/blob/master/deploy/kubernetes/helm/che/templates/deployment.yaml#L38

But we should do it in a separate PRs I beleive after 7.12.0

public OpenShiftStopWorkspaceRoleProvisioner(
OpenShiftClientFactory clientFactory, OpenShiftCheInstallationLocation installationLocation) {
this.clientFactory = clientFactory;
this.installationLocation = installationLocation;
Copy link
Contributor

Choose a reason for hiding this comment

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

I think it makes more sense to inject OpenShiftCheInstallationLocation but store OpenShiftCheInstallationLocation.getInstallationLocationNamespace() as a String in the class. It shouldn't change while Che is running, right?

…ronment variables into OpenShiftCheInstallationLocation

Signed-off-by: Tom George <tgeorge@redhat.com>
@tomgeorge
Copy link
Contributor Author

The conflict should be resolved, and made the change to OpenShiftCheInstallationLocation that @amisevsk suggested.

@che-bot
Copy link
Contributor

che-bot commented Apr 20, 2020

❌ E2E Happy path tests failed ❗

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

⚠️ https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

ℹ️ Use comment "crw-ci-test" to rerun happy path E2E test.

@tomgeorge
Copy link
Contributor Author

crw-ci-test

@che-bot
Copy link
Contributor

che-bot commented Apr 20, 2020

❌ E2E Happy path tests failed ❗

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

⚠️ https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

ℹ️ Use comment "crw-ci-test" to rerun happy path E2E test.

@tomgeorge
Copy link
Contributor Author

crw-ci-test

@che-bot
Copy link
Contributor

che-bot commented Apr 20, 2020

✅ E2E Happy path tests succeed 🎉

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

@tomgeorge
Copy link
Contributor Author

ci-build

skabashnyuk
skabashnyuk previously approved these changes Apr 21, 2020
*
* @author Tom George
*/
@Singleton
Copy link
Contributor

Choose a reason for hiding this comment

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

Can we have test for this class?

private static final Logger LOG = LoggerFactory.getLogger(OpenShiftCheInstallationLocation.class);

@Inject(optional = true)
@Named("env.KUBERNETES_NAMESPACE")
Copy link
Contributor

Choose a reason for hiding this comment

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

I suggest using constructor injection. It would be much easier to test.

Copy link
Contributor

Choose a reason for hiding this comment

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

And javax.inject instead of google inject.

Copy link
Member

Choose a reason for hiding this comment

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

@skabashnyuk I believe we need to refactor this class based on the valid comments in the review e.g. move to different location + remove completely the usage of env.POD_NAMESPACE. wondering if this will be ok do in a separate PR though, since we really need to have a fix in 7.12.0

Copy link
Contributor Author

@tomgeorge tomgeorge Apr 21, 2020

Choose a reason for hiding this comment

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

@skabashnyuk unfortunately Guice does not support constructor injection with optional dependencies[1]. We need to have these dependencies be optional for now because each installation method uses a different environment variable to specify the installation location. Perhaps when we refactor the installation methods to use the same environment variable, we can revisit this?

  1. https://github.com/google/guice/wiki/FrequentlyAskedQuestions#how-can-i-inject-optional-parameters-into-a-constructor

Copy link
Contributor

Choose a reason for hiding this comment

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

what about import org.eclipse.che.commons.annotation.Nullable?

Copy link
Contributor

Choose a reason for hiding this comment

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

I assume it's not working this way

  @Inject
  public OpenShiftCheInstallationLocation(
      @Named("env.KUBERNETES_NAMESPACE") String kubernetesNamespace,
      @Named("env.POD_NAMESPACE") String podNamespace) {
    this.kubernetesNamespace = kubernetesNamespace;
    this.podNamespace = podNamespace;
  }

but should work

  @Inject
  public OpenShiftCheInstallationLocation(
   @Nullable  @Named("env.KUBERNETES_NAMESPACE") String kubernetesNamespace,
    @Nullable  @Named("env.POD_NAMESPACE") String podNamespace) {
    this.kubernetesNamespace = kubernetesNamespace;
    this.podNamespace = podNamespace;
  }

No?

Copy link
Contributor

Choose a reason for hiding this comment

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

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, neither one worked. They both complained about not being able to find a binding for env.POD_NAMESPACE when it was not defined in the container, even though it was defined as @Nullable

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think those work because they are defined in che.properties, either null or with a value. POD_NAMESPACE and KUBERNETES_NAMESPACE are not defined in those files, and @Nullable @Named("env.POD_NAMESPACE") String podNamespace fails to create the injector because there is no implementation bound to it.

Copy link
Contributor

Choose a reason for hiding this comment

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

you right. Probably the first variant without injection was good too.

@ibuziuk
Copy link
Member

ibuziuk commented Apr 21, 2020

ci-build

@skabashnyuk skabashnyuk self-requested a review April 21, 2020 08:28
@skabashnyuk skabashnyuk dismissed their stale review April 21, 2020 08:28

Please take a look on comments

…ty in order to have a possibility to disable the 'OpenShiftStopWorkspaceRoleProvisioner'

Signed-off-by: Ilya Buziuk <ibuziuk@redhat.com>
@ibuziuk
Copy link
Member

ibuziuk commented Apr 21, 2020

@tomgeorge it occurred to me that we will need to disable the provisioner for Hosted-Che (multicluster) environment. Please, consider applying this PR to your brarch which adds che.workspace.stop.role.enabled property - https://github.com/tomgeorge/che/pull/1/files

che eclipse-che#15906 Adding 'che.workspace.stop.role.enabled' property in order to have a possibility to disable the 'OpenShiftStopWorkspaceRoleProvisioner'
@che-bot
Copy link
Contributor

che-bot commented Apr 21, 2020

❌ E2E Happy path tests failed ❗

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

⚠️ https://github.com/orgs/eclipse/teams/eclipse-che-qa please check this report.

ℹ️ Use comment "crw-ci-test" to rerun happy path E2E test.

@ibuziuk
Copy link
Member

ibuziuk commented Apr 21, 2020

crw-ci-test

@che-bot
Copy link
Contributor

che-bot commented Apr 21, 2020

✅ E2E Happy path tests succeed 🎉

See Details

Tested with Eclipse Che Multiuser User on K8S (minikube v1.1.1)

@ibuziuk
Copy link
Member

ibuziuk commented Apr 21, 2020

[ci-build]

1 similar comment
@ibuziuk
Copy link
Member

ibuziuk commented Apr 21, 2020

[ci-build]

@nickboldt nickboldt mentioned this pull request Apr 21, 2020
16 tasks
@tomgeorge tomgeorge merged commit 2241525 into eclipse-che:master Apr 21, 2020
@che-bot che-bot removed the status/code-review This issue has a pull request posted for it and is awaiting code review completion by the community. label Apr 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind/bug Outline of a bug - must adhere to the bug report template.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants