JCloudsCloud extends Cloud implements SlaveOptions.Holder { @Restricted(NoExternalUse.class) public @Nonnull Openstack getOpenstack() throws LoginFailure { try { OpenstackCredential credential = OpenstackCredentials.getCredential(getCredentialsId()); if (credential == null) { throw new LoginFailure("No credentials found for cloud " + name + " (id=" + getCredentialsId() + ")"); } return Openstack.Factory.get(endPointUrl, ignoreSsl, credential, zone); } catch (AuthenticationException ex) { throw new LoginFailure(name, ex); } catch (FormValidation ex) { throw new LoginFailure(name, ex); } } @DataBoundConstructor @Restricted(DoNotUse.class)  JCloudsCloud(
            final @Nonnull String name,
            final @Nonnull String endPointUrl,
            final boolean ignoreSsl,
            final @CheckForNull String zone,
            final @CheckForNull SlaveOptions slaveOptions,
            final @CheckForNull List<JCloudsSlaveTemplate> templates,
            final @Nonnull String credentialsId
    ); static @Nonnull List<JCloudsCloud> getClouds(); static @Nonnull JCloudsCloud getByName(@Nonnull String name); @Nonnull SlaveOptions getEffectiveSlaveOptions(); @Nonnull SlaveOptions getRawSlaveOptions(); @Nonnull List<JCloudsSlaveTemplate> getTemplates(); @Nonnull String getEndPointUrl(); @CheckForNull String getZone(); @Override Collection<NodeProvisioner.PlannedNode> provision(Label label, int excessWorkload); @Restricted(NoExternalUse.class) /*for mocking*/ @CheckForNull String slaveIsWaitingFor(@Nonnull JCloudsSlave slave); @Override boolean canProvision(final Label label); @CheckForNull JCloudsSlaveTemplate getTemplate(String name); @Restricted(NoExternalUse.class) @RequirePOST void doProvision(StaplerRequest req, StaplerResponse rsp, @QueryParameter String name); @Restricted(NoExternalUse.class) @Nonnull Openstack getOpenstack(); String getCredentialsId(); @Restricted(DoNotUse.class) // Jelly boolean getIgnoreSsl();  }
@Test @Issue("JENKINS-46541") public void createsNewOpenstackInstanceAfterCacheExpires() throws Exception { final Openstack.FactoryEP factory = j.mockOpenstackFactory(); final OSClient.OSClientV2 client = mock(OSClient.OSClientV2.class, RETURNS_DEEP_STUBS); final Cache<String, Openstack> cache = Openstack.FactoryEP.getCache(); when(factory.getOpenstack(any(String.class), any(boolean.class), any(OpenstackCredential.class), any(String.class))).thenAnswer((Answer<Openstack>) invocation -> { return new Openstack(client); }); final SlaveOptions defOpts = JCloudsCloud.DescriptorImpl.getDefaultOptions(); final JCloudsCloud instance = new JCloudsCloud("name", "endPointUrl", false,"zone", defOpts, null, j.dummyCredentials()); final Openstack actual1 = instance.getOpenstack(); final Openstack actual2 = instance.getOpenstack(); cache.invalidateAll(); final Openstack actual3 = instance.getOpenstack(); final Openstack actual4 = instance.getOpenstack(); assertThat(actual1, sameInstance(actual2)); assertThat(actual3, sameInstance(actual4)); assertThat(actual1, not(sameInstance(actual3))); verify(factory, times(2)).getOpenstack(any(String.class), any(boolean.class), any(OpenstackCredential.class), any(String.class)); }
@Test public void cachesOpenstackInstancesToSameEndpoint() throws Exception { final String ep1 = "http: final String ep2 = "http: final String zone1 = "region"; final String zone2 = "differentRegion"; final Openstack.FactoryEP factory = j.mockOpenstackFactory(); final OSClient.OSClientV2 client = mock(OSClient.OSClientV2.class, RETURNS_DEEP_STUBS); final OpenstackCredential openstackCredential1 = new OpenstackCredentialv2(CredentialsScope.SYSTEM,"id1","desc1","tenant1","user1","secret1"); OpenstackCredentials.add(openstackCredential1); final OpenstackCredential openstackCredential2 = new OpenstackCredentialv2(CredentialsScope.SYSTEM,"id2","desc2","tenant2","user2","secret2"); OpenstackCredentials.add(openstackCredential2); final SlaveOptions defOpts = JCloudsCloud.DescriptorImpl.getDefaultOptions(); final JCloudsCloud i111 = new JCloudsCloud("111", ep1, false, zone1, defOpts, null, openstackCredential1.getId()); final JCloudsCloud i211 = new JCloudsCloud("211", ep2, false, zone1, defOpts, null, openstackCredential1.getId()); final JCloudsCloud i121 = new JCloudsCloud("121",ep1, false, zone2, defOpts, null, openstackCredential1.getId()); final JCloudsCloud i112 = new JCloudsCloud("112", ep1, false, zone1, defOpts, null, openstackCredential2.getId()); when(factory.getOpenstack(any(String.class), any(boolean.class), any(OpenstackCredential.class), any(String.class))).thenAnswer((Answer<Openstack>) invocation -> { return new Openstack(client); }); final Openstack e111 = i111.getOpenstack(); final Openstack e211 = i211.getOpenstack(); final Openstack e121 = i121.getOpenstack(); final Openstack e112 = i112.getOpenstack(); final Openstack actual111 = i111.getOpenstack(); final Openstack actual211 = i211.getOpenstack(); final Openstack actual121 = i121.getOpenstack(); final Openstack actual112 = i112.getOpenstack(); assertThat(actual111, sameInstance(e111)); assertThat(actual211, sameInstance(e211)); assertThat(actual121, sameInstance(e121)); assertThat(actual112, sameInstance(e112)); assertThat(actual211, not(anyOf( sameInstance(e111), sameInstance(null), sameInstance(e121), sameInstance(e112)))); assertThat(actual121, not(anyOf( sameInstance(e111), sameInstance(e211), sameInstance(null), sameInstance(e112)))); assertThat(actual211, not(anyOf( sameInstance(e111), sameInstance(e121), sameInstance(null), sameInstance(e111) ))); assertThat(actual111, not(anyOf( sameInstance(e112), sameInstance(e211), sameInstance(e121), sameInstance(null) ))); verify(factory, times(4)).getOpenstack(any(String.class), any(boolean.class), any(OpenstackCredential.class), any(String.class)); }
@Test public void cachedOpenstackInstanceInvalidatedIfPasswordChanges() throws Exception { final String ep = "http: final String zone = "region"; final Openstack.FactoryEP factory = j.mockOpenstackFactory(); final OSClient.OSClientV2 client = mock(OSClient.OSClientV2.class, RETURNS_DEEP_STUBS); final String credentialsId = "myCredId"; final String credentialDescription = "desc"; final String credentialTenant = "tenant"; final String credentialUsername = "user"; final OpenstackCredential openstackCredentialWithOldPassword = new OpenstackCredentialv2(CredentialsScope.SYSTEM, credentialsId, credentialDescription, credentialTenant, credentialUsername, "originalPassword"); final OpenstackCredential openstackCredentialWithNewPassword = new OpenstackCredentialv2(CredentialsScope.SYSTEM, credentialsId, credentialDescription, credentialTenant, credentialUsername, "updatedPassword"); final List<Credentials> openstackCredentials = SystemCredentialsProvider.getInstance().getCredentials(); openstackCredentials.add(openstackCredentialWithOldPassword); final int indexOfCredentials = openstackCredentials.indexOf(openstackCredentialWithOldPassword); final SlaveOptions defOpts = JCloudsCloud.DescriptorImpl.getDefaultOptions(); final JCloudsCloud cloud = new JCloudsCloud("cloudName", ep, false, zone, defOpts, null, openstackCredentialWithOldPassword.getId()); when(factory.getOpenstack(any(String.class), any(boolean.class), any(OpenstackCredential.class), any(String.class))).thenAnswer((Answer<Openstack>) invocation -> { return new Openstack(client); }); final Openstack original = cloud.getOpenstack(); final Openstack beforePwdChange = cloud.getOpenstack(); openstackCredentials.set(indexOfCredentials, openstackCredentialWithNewPassword); final Openstack afterPwdChange = cloud.getOpenstack(); assertThat(beforePwdChange, sameInstance(original)); assertThat(afterPwdChange, not(anyOf( sameInstance(original), sameInstance(null), sameInstance(beforePwdChange)))); verify(factory, times(2)).getOpenstack(any(String.class), any(boolean.class), any(OpenstackCredential.class), any(String.class)); }