Search in sources :

Example 1 with ServerSshKeyManager

use of jetbrains.buildServer.ssh.ServerSshKeyManager in project teamcity-git by JetBrains.

the class GitUrlSupport method convertToVcsRootProperties.

@Nullable
public Map<String, String> convertToVcsRootProperties(@NotNull VcsUrl url, @NotNull VcsOperationContext operationContext) throws VcsException {
    String scmName = getMavenScmName(url);
    if (// some other scm provider
    scmName != null && !"git".equals(scmName) && !"ssh".equals(scmName))
        return null;
    String fetchUrl = getFetchUrl(url);
    URIish uri = parseURIish(fetchUrl);
    if (fetchUrl.startsWith("https://") && !fetchUrl.endsWith(".git")) {
        VcsHostingRepo gitlabRepo = WellKnownHostingsUtil.getGitlabRepo(uri);
        if (gitlabRepo != null) {
            // for GitLab we need to add .git suffix to the fetch URL, otherwise, for some reason JGit can't work with this repository (although regular git command works)
            fetchUrl = fetchUrl + ".git";
            uri = parseURIish(fetchUrl);
        }
    }
    Map<String, String> props = new HashMap<>(myGitSupport.getDefaultVcsProperties());
    props.put(Constants.FETCH_URL, fetchUrl);
    props.putAll(getAuthSettings(url, uri));
    VcsHostingRepo ghRepo = WellKnownHostingsUtil.getGitHubRepo(uri);
    if (ghRepo != null)
        refineGithubSettings(ghRepo, props);
    int numSshKeysTried = 0;
    final SProject curProject = myProjectManager == null ? null : myProjectManager.findProjectById(operationContext.getCurrentProjectId());
    if (AuthenticationMethod.PRIVATE_KEY_DEFAULT.toString().equals(props.get(Constants.AUTH_METHOD)) && fetchUrl.endsWith(".git") && curProject != null) {
        // SSH access, before using the default private key which may not be accessible on the agent,
        // let's iterate over all SSH keys of the current project, maybe we'll find a working one
        ServerSshKeyManager serverSshKeyManager = getSshKeyManager();
        if (serverSshKeyManager != null) {
            for (TeamCitySshKey key : serverSshKeyManager.getKeys(curProject)) {
                // don't know password, so can't use it
                if (key.isEncrypted())
                    continue;
                Map<String, String> propsCopy = new HashMap<>(props);
                propsCopy.put(Constants.AUTH_METHOD, AuthenticationMethod.TEAMCITY_SSH_KEY.toString());
                propsCopy.put(VcsRootSshKeyManager.VCS_ROOT_TEAMCITY_SSH_KEY_NAME, key.getName());
                try {
                    numSshKeysTried++;
                    return testConnection(propsCopy, curProject);
                } catch (VcsException e) {
                    if (isBranchRelatedError(e))
                        throw e;
                }
            }
        }
        // could not find any valid keys, proceed with default SSH key
        try {
            return testConnection(props, curProject);
        } catch (VcsException e) {
            if (isBranchRelatedError(e))
                throw e;
            String message = "Could not connect to the Git repository by SSH protocol.";
            if (numSshKeysTried > 0) {
                message += " Tried " + numSshKeysTried + " SSH " + StringUtil.pluralize("key", numSshKeysTried) + " accessible from the current project.";
            } else {
                message += " Could not find an SSH key in the current project which would work with this Git repository.";
            }
            throw new VcsException(message + " Error message: " + e.getMessage(), e);
        }
    }
    final boolean defaultBranchKnown = props.get(Constants.BRANCH_NAME) != null;
    if (defaultBranchKnown) {
        // git protocol, or git scm provider
        if ("git".equals(scmName) || "git".equals(uri.getScheme()) || fetchUrl.endsWith(".git"))
            return props;
    }
    // not SSH or URL does not end with .git, still try to connect just for the case
    try {
        return testConnection(props, curProject);
    } catch (VcsException e) {
        if (isBranchRelatedError(e) || GitServerUtil.isAuthError(e) || fetchUrl.toLowerCase().contains("git"))
            throw e;
        // probably not git
        Loggers.VCS.infoAndDebugDetails("Failed to recognize " + url.getUrl() + " as a git repository", e);
        return null;
    }
}
Also used : URIish(org.eclipse.jgit.transport.URIish) HashMap(java.util.HashMap) ServerSshKeyManager(jetbrains.buildServer.ssh.ServerSshKeyManager) SProject(jetbrains.buildServer.serverSide.SProject) TeamCitySshKey(jetbrains.buildServer.ssh.TeamCitySshKey) PositionConstraint(jetbrains.buildServer.util.positioning.PositionConstraint) Nullable(org.jetbrains.annotations.Nullable)

Example 2 with ServerSshKeyManager

use of jetbrains.buildServer.ssh.ServerSshKeyManager in project teamcity-git by JetBrains.

the class GitUrlSupportTest method setUp.

@BeforeMethod
public void setUp() throws Exception {
    super.setUp();
    ServerPaths paths = new ServerPaths(myTempFiles.createTempDir().getAbsolutePath());
    PluginConfig config = new PluginConfigBuilder(paths).build();
    myMirrorManager = new MirrorManagerImpl(config, new HashCalculatorImpl(), new RemoteRepositoryUrlInvestigatorImpl());
    myProjectMock = mock(SProject.class);
    final Mock pmMock = mock(ProjectManager.class);
    final SProject project = (SProject) myProjectMock.proxy();
    pmMock.stubs().method("findProjectById").will(returnValue(project));
    ProjectManager pm = (ProjectManager) pmMock.proxy();
    final Mock sshMock = mock(ServerSshKeyManager.class);
    sshMock.stubs().method("getKeys").with(eq(project)).will(returnValue(myTestKeys));
    ServerSshKeyManager ssh = (ServerSshKeyManager) sshMock.proxy();
    Mock epMock = mock(ExtensionsProvider.class);
    epMock.stubs().method("getExtensions").with(eq(ServerSshKeyManager.class)).will(returnValue(Collections.singleton(ssh)));
    myGitVcsSupport = gitSupport().withServerPaths(paths).withTestConnectionSupport(vcsRoot -> {
        if (myTestConnectionMocked != null && myTestConnectionMocked)
            return null;
        return myGitVcsSupport.testConnection(vcsRoot);
    }).build();
    myUrlSupport = new GitUrlSupport(myGitVcsSupport) {

        @NotNull
        @Override
        protected VcsRoot createDummyRoot(@NotNull final Map<String, String> props, @Nullable final SProject curProject) {
            return new VcsRootImpl(-1, Constants.VCS_NAME, props);
        }
    };
    myUrlSupport.setProjectManager(pm);
    myUrlSupport.setExtensionsProvider((ExtensionsProvider) epMock.proxy());
}
Also used : SProject(jetbrains.buildServer.serverSide.SProject) NotNull(org.jetbrains.annotations.NotNull) Mock(org.jmock.Mock) ProjectManager(jetbrains.buildServer.serverSide.ProjectManager) VcsRootImpl(jetbrains.buildServer.vcs.impl.VcsRootImpl) ServerSshKeyManager(jetbrains.buildServer.ssh.ServerSshKeyManager) ServerPaths(jetbrains.buildServer.serverSide.ServerPaths) BeforeMethod(org.testng.annotations.BeforeMethod)

Aggregations

SProject (jetbrains.buildServer.serverSide.SProject)2 ServerSshKeyManager (jetbrains.buildServer.ssh.ServerSshKeyManager)2 HashMap (java.util.HashMap)1 ProjectManager (jetbrains.buildServer.serverSide.ProjectManager)1 ServerPaths (jetbrains.buildServer.serverSide.ServerPaths)1 TeamCitySshKey (jetbrains.buildServer.ssh.TeamCitySshKey)1 PositionConstraint (jetbrains.buildServer.util.positioning.PositionConstraint)1 VcsRootImpl (jetbrains.buildServer.vcs.impl.VcsRootImpl)1 URIish (org.eclipse.jgit.transport.URIish)1 NotNull (org.jetbrains.annotations.NotNull)1 Nullable (org.jetbrains.annotations.Nullable)1 Mock (org.jmock.Mock)1 BeforeMethod (org.testng.annotations.BeforeMethod)1