Git Product home page Git Product logo

teamcity's Introduction

dohq-teamcity

docs build pypi license

dohq-teamcity is a Python package providing access to the JetBrains TeamCity server API. This library support ALL TeamCity API methods, if you don't find some - create issue, please.

Installation

# Latest release
pip install dohq-teamcity

# Develop branch
git clone https://github.com/devopshq/teamcity
cd teamcity
python setup.py install

Usage

from dohq_teamcity import TeamCity

# username/password authentication
tc = TeamCity("https://teamcity.example.com", auth=('username', 'password'))

# list all the projects
projects = tc.projects.get_projects()
# OR
# projects = tc.project_api.get_projects()
for project in projects:
   print(project)

# get the group with name = groupname
group = tc.group.get('name:groupname')
print(group)

# get the user with name = username
user = tc.user.get('username:devopshq')
print(user)

# create a new user and delete
from dohq_teamcity import User
new_user = User(name='New user', username='new_user')
new_user = tc.users.create_user(body=new_user)
new_user.delete()

# other way - create object, connect with exist instance and load it
import dohq_teamcity
bt = dohq_teamcity.BuildType(id='MyBuildTypeId', teamcity=tc)
bt = bt.read()

What next?

See more examples and full documantation on page: https://devopshq.github.io/teamcity

How to release?

  1. Bump version in dohq_teamcity/version.py
  2. Merge changes to master branch
  3. Create Github Release

teamcity's People

Contributors

allburov avatar denkoren avatar dgisser avatar fopina avatar martwana avatar seqdan avatar tim55667757 avatar vasokot avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

teamcity's Issues

Need to set SSL Verification on TeamCity calls

Hello,

At my current assignment, we have left basic authentication, and only use Token based identification. After quite some searching on the web, I found how to configure this:
...
tc_token = <get token>
config = Configuration()
config.api_key = {'mytoken': tc_token}
config.api_key_prefix = {'mytoken': 'Bearer'}
config.active_api_key = 'mytoken'
tc = TeamCity(url, auth_settings=["Token"], configuration=config)
...
However, I get SSL error.
After more searching on the WEB, I solved the problem when using SSL Verification for the requests.get() call:
cacert_file = "/etc/pki/tls/certs/cacert.pem"
response = requests.get(url, headers=headers, verify=cacert_file)

Is there a way to configure the TeamCity() call in dohq to use SSL verification in the same way as it is possible for a requests.get() call?

Regards,
Richard

Method is not working due to headers

As we can find in TeamCity documentation there is specific method to get/update some project paramteres:

Project name/description/archived status: GET/PUT http://teamcity:8111/app/rest/projects//<field_name> (accepts/produces text/plain) where <field_name> is one of "name", "description", "archived".

It accepts only text/plain headers that's why it's not really easy to use this method with current version of client.

def set_description(tc, locator, description):
    old_default_headers = tc.default_headers.copy()
    tc.set_default_header(header_name='Content-type', header_value='text/plain')
    tc.set_default_header(header_name='Accept', header_value='text/plain')

    result = tc.projects.set_project_filed(project_locator=locator, field='description',
                                           body=description)

    tc.default_headers = old_default_headers.copy()
    del (old_default_headers)

Probably, this method should be updated and this kind of issues with specific headers also handled by client.

Typing

Check that typing work fine in PyCharm

How do you login using token instead of user/password?

Hi,

All examples on dohq TeamCity use user/password as authentication.
Unfortunately, the organization I am in right now only use smart card and I have to use token based authentication.
I read the api_client.py file that is part of the package, but I can't really make out how to set the token.
Using standard header, you need to set "Bearer " (like curl --header "Authorization: Bearer "), but I can't see how this is done with:
tc = TeamCity(url, auth=(user, passwd))

Any help would be greatly appriciated.

Thanks in Advance,
Richard

Possibility to use client with network proxy

Thanks for awesome client.

However, I need to connect to Teamcity server via proxy (and I think it might be common situation).
As I can see, under hood of REST client there is urllib3 which is ignoring HTTP_PROXY environment variable.

So, my question/feature request is about optional configuration parameter that could be passed to TeamCity class and used to set up proxy in urllib3.

Documentation and use cases improvement

  • Run build (and do it from BuildType?)
  • Use TeamCityObject as locator
  • Add step to build_type teamcity.build_types.get(ID).steps.add()?
  • DebugAPI, DefaultApi, ServerAPI
  • Add VCS, BuildFeatures to BuildType
  • Other case

And:

  • Add Develop documantation - about swagger, folders, process, version and releases
  • Add to swagger.sh wget cli.jar if not exist

csrf queue new build error

When I tried to use this code:

       body = Build(
            build_type_id=self._tc_build_configuration_id,
            branch_name=branch_name,
        )
        print(self._tc.build_queues.queue_new_build(body=body, move_to_top=True))
    

I got error:

   File "C:\Users\megap\PycharmProjects\Jira2TeamCity\venv\lib\site-packages\dohq_teamcity\api_client.py", line 373, in request
    body=body)
  File "C:\Users\megap\PycharmProjects\Jira2TeamCity\venv\lib\site-packages\dohq_teamcity\rest.py", line 281, in POST
    body=body)
  File "C:\Users\megap\PycharmProjects\Jira2TeamCity\venv\lib\site-packages\dohq_teamcity\rest.py", line 232, in request
    raise ApiException(http_resp=r)
dohq_teamcity.rest.ApiException: (403)
Reason: 
HTTP response headers: HTTPHeaderDict({'TeamCity-Node-Id': 'MAIN_SERVER', 'Content-Type': 'text/plain;charset=UTF-8', 'Content-Length': '358', 'Date': 'Sun, 10 May 2020 15:07:48 GMT'})
HTTP response body: 403 Forbidden: Responding with 403 status code due to failed CSRF check: authenticated POST request is made, but neither tc-csrf-token parameter nor X-TC-CSRF-Token header are provided.. For a temporary workaround, you can set internal property teamcity.csrf.paranoid=false  and provide valid Origin=http://asdasdasd header with your request

Default empty value of Configuration.safe_chars_for_path_param seems wrong

Reproducible example (using https://teamcity.jetbrains.com/viewType.html?buildTypeId=DemoProjects_TeamCity_Net_Build for build having artifacts):

import dohq_teamcity, logging

logging.basicConfig(level=logging.DEBUG)
logging.getLogger("urllib3").setLevel(logging.DEBUG)
teamcity = dohq_teamcity.TeamCity("https://teamcity.jetbrains.com/guestAuth", auth=None)
build = teamcity.builds.get("buildType:(id:DemoProjects_TeamCity_Net_Build),number:8")
build.get_children("/Clock.Console/linux-x64")

Result:

"HTTP Status 400 – Bad Request".
It can be seen in debug log that request has been made to URL /guestAuth/app/rest/builds/id%3A3101739/artifacts/children%2FClock.Console%2Flinux-x64 which is obviously wrong: / should not be escaped in artifacts paths. Relevant part from swagger.json:

  /app/rest/builds/{buildLocator}/artifacts/children{path}:
    get:
      tags:
      - Build
      operationId: getChildren
      parameters:
      - name: path
        in: path
        required: true
        type: string
        pattern: (/.*)?

After setting teamcity.configuration.safe_chars_for_path_param = "/" (default value was empty string) URL in request becomes correct /guestAuth/app/rest/builds/id%3A3101739/artifacts/children/Clock.Console/linux-x64 (method call still requires workaround from #25 to work completely).

Suggestion would be to set Configuration.safe_chars_for_path_param to / by default, though it's not clear what other parts this can break.

Usage of pagination

I'm requesting sth, that returns more than 100 results. eg:
tc.vcs_root_api.get_roots()
This obviously returns a paginated result, as also the next_href etc is set.
From the docs it's unclear to me how to access the next pages of the result. Could you maybe give a hint what the right way would be todo this?

vcs_root_api.serve_property returns 406 for valid property names

I'm trying to retrieve property values for vcs_roots like this:

vcs_root_location = root_id
scm_url = con.vcs_root_api.serve_property(vcs_root_locator,'url') # Also tried with 'username' and 'branch'

It always returns 406. Am I sending it in wrong format?

Complete stack trace:

Traceback (most recent call last): File "list_projects.py", line 84, in <module> list_root_props(root.id) File "list_projects.py", line 60, in list_root_props stash_url = con.vcs_root_api.serve_property(vcs_root_locator,'url') File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/dohq_teamcity/api/vcs_root_api.py", line 279, in serve_property (data) = self.__serve_property_with_http_info(vcs_root_locator, name, **kwargs) # noqa: E501 File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/dohq_teamcity/api/vcs_root_api.py", line 1288, in __serve_property_with_http_info collection_formats=collection_formats) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/dohq_teamcity/custom/client.py", line 69, in call_api return super(TeamCity, self).call_api(*args, **kwargs) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/dohq_teamcity/api_client.py", line 322, in call_api _preload_content, _request_timeout) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/dohq_teamcity/api_client.py", line 153, in __call_api _request_timeout=_request_timeout) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/dohq_teamcity/api_client.py", line 351, in request headers=headers) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/dohq_teamcity/rest.py", line 244, in GET query_params=query_params) File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/site-packages/dohq_teamcity/rest.py", line 232, in request raise ApiException(http_resp=r) dohq_teamcity.rest.ApiException: (406) Reason: HTTP response headers: HTTPHeaderDict({'Date': 'Fri, 30 Oct 2020 16:46:40 GMT', 'Content-Type': 'text/plain', 'Transfer-Encoding': 'chunked', 'Connection': 'keep-alive', 'Set-Cookie': 'AWSALB=sM/GgBMXEUo6F6BIHG8Z1pyDZZiVu6PbeDFTkT0nfNA3ESBIESaVVWTZraJaqs/YeEQoL5OWazF+7ljrIV9RM6gWoEq9a0/MTVANoVtjqnt3mtzsVMDzgFSULlI8; Expires=Fri, 06 Nov 2020 16:46:40 GMT; Path=/, AWSALBCORS=sM/GgBMXEUo6F6BIHG8Z1pyDZZiVu6PbeDFTkT0nfNA3ESBIESaVVWTZraJaqs/YeEQoL5OWazF+7ljrIV9RM6gWoEq9a0/MTVANoVtjqnt3mtzsVMDzgFSULlI8; Expires=Fri, 06 Nov 2020 16:46:40 GMT; Path=/; SameSite=None; Secure, TCSESSIONID=012B9FE908ECBD09A37141CFD21C870F; Path=/; Secure; HttpOnly, RememberMe=; Max-Age=0; Expires=Thu, 01-Jan-1970 00:00:10 GMT; Path=/; Secure; HttpOnly', 'Server': 'nginx', 'Content-Security-Policy': "frame-ancestors 'self'", 'TeamCity-Node-Id': 'MAIN_SERVER', 'Cache-Control': 'no-store'}) HTTP response body: Responding with error, status code: 406 (Not Acceptable). Make sure you have supplied correct 'Accept' header.

parameter field_name not required for tc.build_type_api.change_requirement_setting

Hi,

As seen here: build_type_api.change_requirement_setting
this function requires an parameter field_name, which must not be used at all for the function. All values for it other than "" (empty str) leads to an error, as the parameter is currently mandatory by validation, but must be always "" to build the correct url for the underlying TC RestAPI call.

To use this function at it's current state, it needs to be called as (using dohq-teamcity Types below):

bt: BuildType
ar: AgentRequirement

api_response = tc.build_type_api.change_requirement_setting(bt, ar, "", body=ar)

The parameter should be removed.

Thanks and Cheers
--- mnse

Release prepare

  • MD to RST convert for api+model, check links
  • github pages publish
  • github pages check
  • travis.ci run
  • publish to pypi

Build.get_root/get_children throws "'dohq_teamcity.models.file' has no attribute 'swagger_types'"

Reproducible example (using https://teamcity.jetbrains.com/viewType.html?buildTypeId=DemoProjects_TeamCity_Net_Build for build having artifacts):

import dohq_teamcity

teamcity = dohq_teamcity.TeamCity("https://teamcity.jetbrains.com/guestAuth", auth=None)
build = teamcity.builds.get("buildType:(id:DemoProjects_TeamCity_Net_Build),number:8")
build.get_root()

Result:

AttributeError: module 'dohq_teamcity.models.file' has no attribute 'swagger_types'

Expected:
Files instance returned.

It works when monkey-patched by assigning dohq_teamcity.custom.models.file = dohq_teamcity.models.File, so it's likely that star imports gone wrong somewhere.

json output

objects should be able to be serialized into JSON for easier parsing/automation.

how to use the tc.build_queues.cancel_build() function

Hi, so I'm a bit confused about how to use the "tc.build_queues.cancel_build()" function.

I have a teamcity server with the following queued build (with id=1).
image

but when i try cancel it, all i get the a BuildCancelRequest object and I have no idea what to do with it (nothing gets canceleld).
image

I think a "comment" and "readd_into_queue" is supposed to be provided with the cancel build but your function does not seem to accept it when i try.

403 status code for failed CSRF check (teamcity 2020.2)

on teamcity 2021.2 when i try use on of the functions for a post request i get the following CSRF errors:

dohq_teamcity.rest.ApiException: (403)
Reason: 
HTTP response headers: HTTPHeaderDict({'TeamCity-Node-Id': 'MAIN_SERVER', 'X-Content-Type-Options': 'nosniff', 'Content-Type': 'text/plain;charset=UTF-8', 'Content-Length': '347', 'Date': 'Fri, 02 Jul 2021 18:53:05 GMT'})
HTTP response body: 403 Forbidden: Responding with 403 status code due to failed CSRF check: authenticated POST request is made, but neither tc-csrf-token parameter nor X-TC-CSRF-Token header are provided.. For a temporary workaround, you can set internal property teamcity.csrf.paranoid=false  and provide valid Origin=http://localhost:8111 header with your request

the solution to this is apparently here: https://www.jetbrains.com/help/teamcity/csrf-protection.html#Implications+for+CORS+clients

should the library be updated to take this into account as well?

==========================
the website says to:

  • token: recommend using token-based authentication and disabling cookie support (if you dont want to use use CSRF token)
  • http authentication: apply for CSRF token otherwise

currently the method: rest.py::RESTClientObject::request(...) function always sets cookies if they are received.

        if not 200 <= r.status <= 299:
            raise ApiException(http_resp=r)

        if self.cookie is None:
            self.cookie = r.getheader('Set-Cookie')
            # pass
        print("\n=============out cookie:", r.getheader('Set-Cookie'), "=============\n")
        return r

i think you should add an option to not store cookies (and do the 2 methods they suggested above)?

builds.get_content fails with 400 error

I've create request

tc_connect = TeamCity(
            f'{settings.tc_server}',
            auth=(settings.domain_login, settings.domain_password),
       )
content = self.tc_connect.builds.get_content(
    path='/some_path/some_file.txt', build_locator='id:someid')
  

Exprected result:
Content has been got

Actual result

dohq_teamcity.rest.ApiException: (400)
Reason: 
HTTP response headers: HTTPHeaderDict({'Server': 'nginx/1.21.6', 'Date': 'Wed, 12 Oct 2022 12:33:25 GMT', 'Content-Type': 'text/html;charset=utf-8', 'Content-Length': '435', 'Connection': 'keep-alive', 'Content-Language': 'en'})
HTTP response body: <!doctype html><html lang="en"><head><title>HTTP Status 400 – Bad Request</title><style type="text/css">body {font-family:Tahoma,Arial,sans-serif;} h1, h2, h3, b {color:white;background-color:#525D76;} h1 {font-size:22px;} h2 {font-size:16px;} h3 {font-size:14px;} p {font-size:12px;} a {color:black;} .line {height:1px;background-color:#525D76;border:none;}</style></head><body><h1>HTTP Status 400 – Bad Request</h1></body></html>

The next points were checked:

  • tc_connect.build_api.get_children(
    path='', build_locator='id:111') - works correctly
  • I've made breakpoint in
"""Makes the HTTP request using RESTClient."""
if method == "GET":
    return self.rest_client.GET(url,
                                query_params=query_params,
                                _preload_content=_preload_content,
                                _request_timeout=_request_timeout,
                                headers=headers)

and found that url has been changed to

url = 'https://teamcity-some-server.com/app/rest/builds/id%3A111/artifacts/content%2Fsome_path2Fsome_file.txt'
body = None
  • Also I've made via raw links
    path=r'/some_path/some_file.txt', build_locator=r'id:111'
  • There no any user-agents in code

Can't find a way to authenticate using token vs username/password

I've tried several ways of using auth token:

tc=TeamCity('https://tc.my.com',auth=tc_token) 

and

tc.set_default_header(header_name='Authorization', header_value='Bearer {token}'.format(token=tc_token)) 

all unsuccessful with HTTP 404 error. HTTP response body: Invalid authentication request or authentication scheme is not supported

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.