How to programmatically authorize an agent (is this really the best way??)

Hi,

I've set up TeamCity server + agent running on two separate VMs (I'm using Vagrant+Chef). This works as expected, in that the server is installed to one VM and gets mapped to a local IP, and the agent VM then pulls down the agent zip file and configures itself from there. This is a disposable Vagrant setup for testing new plugins (and possibly developing our own plugins) so I want to automate as much of the setup as possible. But the agent appears as "unauthorized", and I need to use the web interface to manually click the "authorize" button to allow it to take part of the fun. I don't think developers should have to click that button every time they set up a local development environment though, so I went looking for a way to do it via code.

But.. what I've come up with seems rather invasive, so I'm asking here for feedback and thoughts to look for a better way of going about this.

Here's my solution:
I directly alter the DB, by issuing the command UPDATE agent SET authorized=1; which flips the authorized column to True. I then restart the TeamCity server service, and as far as I can tell the agent is now authorized.

But is that really how we do it? Messing directly with an application's DB sure feels dirty!


I originally wanted to go through the REST API, but from googling I understand it's not exposed functionality? I also looked into mimicking the webinterface's HTTP request but couldn't figure out how to phrase that request. I'm new to TeamCity so I might be missing something easier, despite trying my best to google for answers.

What kind of recommendations would you have for bypassing this agent authorization system? Any thoughts, questions, or feedback appreciated.


Thanks in advance,
Jon

9 comments
Comment actions Permalink

Hi, please try to post "true" to http://teamcity:8111/httpAuth/app/rest/agents/id:<agentId>/authorized.

0
Comment actions Permalink

Hi Jon

What kind of plugins do you mean? Are they plugins for TeamCity or Vagrant?
Which virtualization platform do you use?

At the moment we have two approaches to start build in a clean environment:
1) Use TeamCity cloud agent plugins for vSphere, EC2, Azure, or OpenStack. The plugins do all the work for VM creation and deletion. In a cloud profile settings you can set an option to destroy an agent instance after each single build.
2) Do not create TeamCity agents dynamically, but start additional VMs inside a build using Test Kitchen or Vagrant with remote providers like vagrant-vsphere or vagrant-aws.

0
Comment actions Permalink

Thank you for the suggestion. Lets see if I understand it :)

To make sure I'm not crazy I can succesfully execute these GET requests:

$ curl --user admin:admin http://192.168.80.10:8111/httpAuth/app/rest/agents
<agents count="0" href="/httpAuth/app/rest/agents"/>


$ curl --user admin:admin http://192.168.80.10:8111/httpAuth/app/rest/agents?includeUnauthorized=true
<agents count="1" href="/httpAuth/app/rest/agents?includeUnauthorized=true">
  <agent href="/httpAuth/app/rest/agents/id:1" id="1" name="agent01" typeId="1"/>
</agents>


But when I try to POST it errors:

$ curl --user admin:admin --data "true" http://192.168.80.10:8111/httpAuth/app/rest/agents/id:1/authorize
Error has occurred during request processing (405).
Error: javax.ws.rs.WebApplicationException
Not supported request. Please check URL, HTTP method and transfered data are correct. metadata: [Allow:[GET,OPTIONS,HEAD,PUT],]


$ curl --user admin:admin -X POST -d "true" http://192.168.80.10:8111/httpAuth/app/rest/agents/id:1/authorize
Error has occurred during request processing (405).
Error: javax.ws.rs.WebApplicationException

Not supported request. Please check URL, HTTP method and transfered data are correct. metadata: [Allow:[GET,OPTIONS,HEAD,PUT],]



Can you spot error in my curl commands? I'm new to REST and a lot of the things here so maybe it's something straightforward I'm missing, but I sure can't seem to google my way out of this one.

0
Comment actions Permalink

Sorry that wasn't clear, I'm referring to wanting to develop TeamCity plugins. To do so Vagrant+Chef manages a TeamCity server/agent pair, with the TeamCity server folder exposed locally so my IDE can hook into it. This currently works, I've just made small changes from the fine Chef-TeamCity cookbook.

Thanks for the tip on the cloud plugins, I'll look into them.

0
Comment actions Permalink

If you are developing a plugin, the best way to authorize an agent is to subscribe to jetbrains.buildServer.serverSide.BuildServerListener#agentRegistered. You will be given an SBuildAgent object which you can manage in a way you want.

0
Comment actions Permalink

Thanks, for now development is just a hypothetical though, at the moment we're content using existing plugins and "just" need a local server/agent pair to experiment on.

0
Comment actions Permalink

Please use the following request:

curl -u user:pass --request PUT --data true --header "Content-Type: text/plain" http://localhost:8111/httpAuth/app/rest/agents/id:1/authorized

1
Comment actions Permalink

Oh that's awesome, thank you, using that command my agent gets authorized. Clearly much easier than the database hack :)

0
Comment actions Permalink

Ansible Task

```

- name: Authorize Agent
tags:
- teamcity-agent
- teamcity-agent-auth
uri:
url: "https://{{ teamcity-host }}/httpAuth/app/rest/agents/{{ ansible_nodename }}/authorized"
method: PUT
user: "{{ ansible_user }}"
password: "{{ secret_ansible_tc_pwd }}"
body: "true"
headers:
Content-Type: "text/plain"

```

0

Please sign in to leave a comment.