def test_data_and_json(self): """Test that `json` and `data` cannot be used at the same time.""" api = GerritRestAPI(url="http://review.example.com") with self.assertRaises(ValueError) as exc: api.translate_kwargs(data="d", json="j") assert re.search(r'Cannot use data and json together', str(exc.exception))
def test_json_no_side_effect_on_subsequent_call(self): """Test that subsequent call is not polluted with results of previous. If the translate_kwargs method is called, resulting in the content-type header being added, the header should not also be added on a subsequent call that does not need it. """ api = GerritRestAPI(url="http://review.example.com") json = {"a": "a"} result = api.translate_kwargs(json=json) assert "json" in result assert "data" not in result assert "headers" in result headers = result["headers"] assert "Content-Type" in headers assert result["json"] == {"a": "a"} assert headers["Content-Type"] == "application/json;charset=UTF-8" kwargs = {"a": "a", "b": "b"} result = api.translate_kwargs(**kwargs) assert "json" not in result assert "data" not in result assert "a" in result assert "b" in result assert "headers" in result headers = result["headers"] assert "Content-Type" not in headers
def __init__(self, credentialsFile, gerritUrl): # Get Login Authentication information # This expects a file that contains only a Gerrit user's # <Username> <HTTP Password> # Currently, this is found on Gerrit, select: # -> Your username dropdown # -> Settings # -> HTTP Password scriptPath = os.path.dirname(os.path.abspath(__file__)) authFilepath = os.path.expanduser(scriptPath + "/" + credentialsFile) if os.path.isfile(authFilepath) == False: print("Error: No authentication file named " + credentialsFile + " found") vprint(scriptPath) quit() with open(authFilepath, 'r') as loginFile: line = loginFile.readline() login = line.split() if len(login) < 2: print("Error: Insufficient login credentials") quit() user = login[0] password = login[1] auth = HTTPBasicAuth(user, password) self.rest = GerritRestAPI(url=gerritUrl, auth=auth)
def prepare_patch_set(topic): gerrit_url = "https://gerrit.xxxxxxxx.com/" GERRIT_PATCH_SET = str() auth = HTTPBasicAuth(username, password) rest = GerritRestAPI(url=gerrit_url, auth=auth) #changes = rest.get("/changes/?q=owner:self%20status:open") changes = rest.get("/changes/?q=topic:" + topic) for change in changes: #if change["status"] != "NEW" or change["mergeable"] == False: if change["status"] != "NEW": print(change["subject"] + " " + change["project"] + " " + str(change["_number"]) + " is not mergeable or already merged") exit(1) else: #print (change["subject"] + " " + change["project"] + " " + str(change["_number"])) #info = rest.get("/changes/?q=change:%d&o=CURRENT_REVISION&o=CURRENT_REVISION&o=CURRENT_COMMIT&o=CURRENT_FILES" %change["_number"]) changeId = change["_number"] info = rest.get( "/changes/?q=change:%d&o=CURRENT_REVISION&o=CURRENT_COMMIT" % changeId) repo = change["project"] currefId = ( info[0]["revisions"][info[0]["current_revision"]]["_number"]) GERRIT_PATCH_SET = GERRIT_PATCH_SET + " | " + ( repo + " " + str(change["_number"]) + "/" + str(currefId)) return GERRIT_PATCH_SET
def get_repositories(username, password, gerrit_url): auth = HTTPBasicAuth(username, password) rest = GerritRestAPI(url=gerrit_url, auth=auth) # get server information to derive clone commands logging.debug("getting server information..") server_info = rest.get("/config/server/info") clone_command = server_info["download"]["schemes"]["ssh"]["clone_commands"] clone_command = clone_command["Clone with commit-msg hook"] # get all projects logging.debug("getting project information..") repositories = rest.get("/projects/") result = [] for repository_name in repositories.keys(): project_clone_command = clone_command \ .replace("${project}", repository_name) \ .replace("${project-base-name}", repository_name) result.append({ "name": repository_name, "scm": "git", "source": "gerrit", "source_username": username, "clone_command": project_clone_command }) return result
def __init__(self, gerrit_url, user, passwd, checkout=False, whitelist_branches=[]): """Initial Gerrit connection and set base options""" auth = HTTPBasicAuth(user, passwd) self.rest = GerritRestAPI(url=gerrit_url, auth=auth) self.base_options = [ 'CURRENT_REVISION', 'CURRENT_COMMIT', 'DOWNLOAD_COMMANDS' ] self.patch_command = 'Checkout' if checkout else 'Cherry Pick' # We need to track reviews which were specifically requested as these # are applied regardless of their status. Derived reviews are only # applied if they are still open self.requested_reviews = [] # We track what's been applied to ensure at least the changes we # specifically requested got done self.applied_reviews = [] # Manifest project name (could theoretically be dynamic) self.manifest = None # The manifest is only read from disk if manifest_stale is true. This # is to facilitate a re-read in the event a patch is applied to the # manifest itself self.manifest_stale = True self.manifest_project = 'manifest' # We use this regex to determine if the revision is a sha, for a # given project in the manifest self.sha_re = re.compile(r'[0-9a-f]{40}') self.whitelist_branches = whitelist_branches
def __init__(self, url, use_internal=False): auth = AuthFromNetrc(url, use_internal) self.rest = GerritRestAPI(url=url, auth=auth) self.url = url self.change_options = [ 'CURRENT_REVISION', 'MESSAGES', 'DETAILED_LABELS', 'DETAILED_ACCOUNTS', 'COMMIT_FOOTERS' ]
def __init__(self, gerrit_url, user, passwd): """Initial Gerrit connection and set base options""" auth = HTTPBasicAuth(user, passwd) self.rest = GerritRestAPI(url=gerrit_url, auth=auth) self.base_options = [ 'CURRENT_REVISION', 'CURRENT_COMMIT', 'DOWNLOAD_COMMANDS' ] self.seen_reviews = set()
def gerrit_api(request): """Create a Gerrit container for the given version and return an API.""" with GerritContainer(request.param) as gerrit: port = gerrit.get_exposed_port(8080) url = "http://localhost:%s" % port api = GerritRestAPI(url=url, auth=Anonymous()) _initialize(api) auth = HTTPBasicAuth("admin", "secret") api = GerritRestAPI(url=url, auth=auth) yield api
def __init__(self): self.options = _parse_options() self._init_logger() credentials = self._authenticate() if self.options.cert: certs = os.path.expanduser(self.options.cert) self.api = GerritRestAPI(url=self.options.url, auth=credentials, verify=certs) else: self.api = GerritRestAPI(url=self.options.url, auth=credentials)
def _gerrit_get(self, endpoint_url): auth = HTTPBasicAuth(self.username, self.password) rest = GerritRestAPI(url=self.url, auth=auth) try: response_body = rest.get(endpoint_url) except HTTPError as e: msg = "Failed to get response from Gerrit URL %s: %s" % ( endpoint_url, str(e)) log.error(msg) raise exceptions.HTTPError return response_body
def review(self, label=None, vote=1, message=''): print("Posting {} review for change: {}".format( " {}: {}".format(label, vote) if label else '', self)) auth = HTTPDigestAuthFromNetrc(url=GERRIT_URL) rest = GerritRestAPI(url=GERRIT_URL, auth=auth, verify=GERRIT_VERIFY) rev = GerritReview() rev.set_message(message) if label: rev.add_labels({label: vote}) rest.review(self.id, self.patchset, rev)
def review(self, label=None, vote=1, message=''): print_err("Posting {} review for change: {}".format( " {}: {}".format(label, vote) if label else '', self)) auth = HTTPDigestAuthFromNetrc(url=GERRIT_URL) rest = GerritRestAPI(url=GERRIT_URL, auth=auth, verify=GERRIT_VERIFY) rev = GerritReview() rev.set_message(message) if label: rev.add_labels({label: vote}) rest.review(self.id, self.patchset, rev)
def test_data_as_string_is_unchanged(self): """Test that `data` is unchanged when passed as a string.""" api = GerritRestAPI(url="http://review.example.com") kwargs = {"data": "Content with non base64 valid chars åäö"} result = api.translate_kwargs(**kwargs) assert "json" not in result assert "data" in result assert result["data"] == "Content with non base64 valid chars åäö" assert "headers" in result headers = result["headers"] assert "Content-Type" not in headers
def test_json_is_unchanged_and_header_added(self): """Test that `json` is unchanged and a Content-Type header is added.""" api = GerritRestAPI(url="http://review.example.com") json = {"a": "a"} result = api.translate_kwargs(json=json) assert "json" in result assert "data" not in result assert "headers" in result headers = result["headers"] assert "Content-Type" in headers assert result["json"] == {"a": "a"} assert headers["Content-Type"] == "application/json;charset=UTF-8"
def test_kwargs_unchanged_when_no_data_or_json(self): """Test that `json` or `data` are not added when not passed.""" api = GerritRestAPI(url="http://review.example.com") kwargs = {"a": "a", "b": "b"} result = api.translate_kwargs(**kwargs) assert "json" not in result assert "data" not in result assert "a" in result assert "b" in result assert "headers" in result headers = result["headers"] assert "Content-Type" not in headers
def get_gerrit_client(url, user=None, password=None): if GERRIT_URLS[url]: gerrit_url = GERRIT_URLS[url] elif validators.url(url): gerrit_url = url else: msg = "The provided url is not valid." return ValueError(msg) if user and password: return GerritRestAPI(url=gerrit_url, auth=HTTPBasicAuth(user, password), verify=False) else: return GerritRestAPI(url=gerrit_url, verify=False)
def test_data_as_dict_converts_to_json_and_header_added(self): """Test that `data` dict is converted to `json`. Also test that a Content-Type header is added. """ api = GerritRestAPI(url="http://review.example.com") data = {"a": "a"} result = api.translate_kwargs(data=data) assert "json" in result assert "data" not in result assert "headers" in result headers = result["headers"] assert "Content-Type" in headers assert result["json"] == {"a": "a"} assert headers["Content-Type"] == "application/json;charset=UTF-8"
def test_default_to_no_auth_when_not_in_netrc(self): """Test auth defaults to none when not specified and not in netrc.""" with patch("pygerrit2.rest.auth._get_netrc_auth") as mock_netrc: mock_netrc.return_value = None api = GerritRestAPI(url="http://review.example.com") assert api.auth is None assert not api.url.endswith("/a/")
def join_to_gerrit(local_salt_client, gerrit_user, gerrit_password): # Workaround for issue in test_drivetrain.join_to_jenkins https://github.com/kennethreitz/requests/issues/3829 os.environ["PYTHONHTTPSVERIFY"] = "0" pytest.gerrit_port = local_salt_client.pillar_get( tgt='I@gerrit:client and not I@salt:master', param='_param:haproxy_gerrit_bind_port', expr_form='compound') pytest.gerrit_address = local_salt_client.pillar_get( tgt='I@gerrit:client and not I@salt:master', param='_param:haproxy_gerrit_bind_host', expr_form='compound') pytest.gerrit_protocol = local_salt_client.pillar_get( tgt='I@gerrit:client and not I@salt:master', param="gerrit:client:server:protocol", expr_form='compound') gerrit_url = '{protocol}://{address}:{port}'.format( protocol=pytest.gerrit_protocol, address=pytest.gerrit_address, port=pytest.gerrit_port) auth = HTTPBasicAuth(gerrit_user, gerrit_password) rest = GerritRestAPI(url=gerrit_url, auth=auth) return rest
def test_default_to_basic_auth_from_netrc(self): """Test auth defaults to HTTP basic from netrc when not specified.""" with patch("pygerrit2.rest.auth._get_netrc_auth") as mock_netrc: mock_netrc.return_value = ("netrcuser", "netrcpass") api = GerritRestAPI(url="http://review.example.com") assert isinstance(api.auth, HTTPBasicAuthFromNetrc) assert api.url.endswith("/a/")
def read_gerrit_config(self): """ Read Gerrit config and return Gerrit Rest, Gerrit authentication object """ gerrit_config = configparser.ConfigParser() gerrit_config.read(self.gerrit_config) if 'main' not in gerrit_config.sections(): print( 'Invalid or unable to read config file "{}"'.format( self.gerrit_config ) ) sys.exit(1) try: gerrit_url = gerrit_config.get('main', 'gerrit_url') user = gerrit_config.get('main', 'username') passwd = gerrit_config.get('main', 'password') except configparser.NoOptionError: print( 'One of the options is missing from the config file: ' 'gerrit_url, username, password. Aborting...' ) sys.exit(1) # Initialize class to allow connection to Gerrit URL, determine # type of starting parameters and then find all related reviews self.gerrit_auth = HTTPBasicAuth(user, passwd) self.gerrit_rest = GerritRestAPI(url=gerrit_url, auth=self.gerrit_auth)
def get_gerrit_rest_api(cookie_jar_path: str, gerrit_url: str) -> GerritRestAPI: cookie_jar = MozillaCookieJar(cookie_jar_path) cookie_jar.load() auth = HTTPCookieAuth(cookie_jar) rest = GerritRestAPI(url=gerrit_url, auth=auth) return rest
def test_explicit_anonymous_without_netrc(self): """Test explicit anonymous access when credentials are not in netrc.""" with patch("pygerrit2.rest.auth._get_netrc_auth") as mock_netrc: mock_netrc.return_value = None auth = Anonymous() api = GerritRestAPI(url="http://review.example.com", auth=auth) assert api.auth is None assert not api.url.endswith("/a/")
def _authenticate_with_gerrit(): # username = '******' # password = '******' # auth = HTTPBasicAuth(username, password) gerrit_url = 'https://code.wireshark.org/review/' # this line gets sets the parameters for the HTML API rest = GerritRestAPI(url=gerrit_url) # add auth=auth as an argument change_request(rest)
def get_gerrit_api(gerrit_config, verify_ssl=True): """Returns GerritRestAPI instance with authentication details""" auth = HTTPBasicAuth(gerrit_config["user"], gerrit_config["token"]) rest = GerritRestAPI(url=f"https://{gerrit_config['host']}", auth=auth, verify=verify_ssl) log_cfg = gerrit_config.copy() log_cfg["token"] = "<HIDDEN>" LOGGER.debug(f"Config: {log_cfg}") LOGGER.debug(f"Url: {rest.url}") return rest
class RestAPI: def __init__(self, credentialsFile, gerritUrl): # Get Login Authentication information # This expects a file that contains only a Gerrit user's # <Username> <HTTP Password> # Currently, this is found on Gerrit, select: # -> Your username dropdown # -> Settings # -> HTTP Password scriptPath = os.path.dirname(os.path.abspath(__file__)) authFilepath = os.path.expanduser(scriptPath + "/" + credentialsFile) if os.path.isfile(authFilepath) == False: print("Error: No authentication file named " + credentialsFile + " found") vprint(scriptPath) quit() with open(authFilepath, 'r') as loginFile: line = loginFile.readline() login = line.split() if len(login) < 2: print("Error: Insufficient login credentials") quit() user = login[0] password = login[1] auth = HTTPBasicAuth(user, password) self.rest = GerritRestAPI(url=gerritUrl, auth=auth) # Wrapper for GerritRestAPI's GET method def get(self, query): result = self.rest.get(query, headers={'Content-Type': 'application/json'}) return result # Wrapper for GerritRestAPI's review method def review(self, changeID, revision, review): result = self.rest.review(changeID, revision, review) return result
def join_to_gerrit(local_salt_client, gerrit_user, gerrit_password): gerrit_port = local_salt_client.cmd( 'I@gerrit:client and not I@salt:master', 'pillar.get', ['_param:haproxy_gerrit_bind_port'], expr_form='compound').values()[0] gerrit_address = local_salt_client.cmd( 'I@gerrit:client and not I@salt:master', 'pillar.get', ['_param:haproxy_gerrit_bind_host'], expr_form='compound').values()[0] url = 'http://{0}:{1}'.format(gerrit_address, gerrit_port) auth = HTTPBasicAuth(gerrit_user, gerrit_password) rest = GerritRestAPI(url=url, auth=auth) return rest
def test_gerrit_repositories(local_salt_client): missing_repos = [] config = utils.get_configuration() gerrit_password = local_salt_client.cmd('I@gerrit:client', 'pillar.get', ['_param:openldap_admin_password'], expr_form='compound').values()[0] gerrit_port = local_salt_client.cmd('I@gerrit:client', 'pillar.get', ['gerrit:client:server:http_port'], expr_form='compound').values()[0] gerrit_address = local_salt_client.cmd('I@gerrit:client', 'pillar.get', ['gerrit:client:server:host'], expr_form='compound').values()[0] gerrit_protocol = local_salt_client.cmd('I@gerrit:client', 'pillar.get', ['gerrit:client:server:protocol'], expr_form='compound').values()[0] auth = HTTPBasicAuth('admin', gerrit_password) rest = GerritRestAPI(url="{0}://{1}:{2}".format(gerrit_protocol, gerrit_address, gerrit_port), auth=auth) for repo in config['drivetrain_repos']: repoHttp = repo.replace("/", "%2F") try: response = rest.get("/projects/{0}".format(repoHttp)) except requests.exceptions.HTTPError as e: missing_repos.append("Repo {0} is missing".format(repo)) assert len(missing_repos) == 0, \ '''Some repositories in Gerrit are missing: {}'''.format(json.dumps(missing_repos, indent=4))
def getApi(username, password, server): """ Get REST API @param username Username @param password Password @param server Server """ if not pygerrit2Installed: raise RuntimeError( 'pygerrit2 not installed, HTTP remotes not supported. To install run "pip3 install pygerrit2"' ) return GerritRestAPI(url=server, auth=HTTPBasicAuth(username, password))
class GerritControllerViaWeb(GerritController): def __init__(self, project, max_no): super(GerritControllerViaWeb, self).__init__(project, max_no) self.rest = GerritRestAPI(url=f'https://{self.project["url"]}', auth=Anonymous()) @backoff.on_exception(backoff.expo, requests.exceptions.ConnectionError, max_time=1000000) def _get(self): # TODO: データ取得(q=no) changes = self.rest.get( "changes/?q=is:open&q=is:close&q=all&o=DETAILED_ACCOUNTS&o=ALL_REVISIONS&o=ALL_COMMITS&o=ALL_FILES&o=MESSAGES", headers={'Content-Type': 'application/json'}) return changes pass def _get_run_info(self): return QueryViaWeb(self.project, self.current_review_id)
def _main(): descr = 'Send request using Gerrit HTTP API' parser = argparse.ArgumentParser( description=descr, formatter_class=argparse.ArgumentDefaultsHelpFormatter) parser.add_argument('-g', '--gerrit-url', dest='gerrit_url', required=True, help='gerrit server url') parser.add_argument('-b', '--basic-auth', dest='basic_auth', action='store_true', help='(deprecated) use basic auth instead of digest') parser.add_argument('-d', '--digest-auth', dest='digest_auth', action='store_true', help='use digest auth instead of basic') if _KERBEROS_SUPPORT: parser.add_argument('-k', '--kerberos-auth', dest='kerberos_auth', action='store_true', help='use kerberos auth') parser.add_argument('-u', '--username', dest='username', help='username') parser.add_argument('-p', '--password', dest='password', help='password') parser.add_argument('-n', '--netrc', dest='netrc', action='store_true', help='Use credentials from netrc') parser.add_argument('-v', '--verbose', dest='verbose', action='store_true', help='enable verbose (debug) logging') options = parser.parse_args() level = logging.DEBUG if options.verbose else logging.INFO logging.basicConfig(format='%(asctime)s %(levelname)s %(message)s', level=level) if _KERBEROS_SUPPORT and options.kerberos_auth: if options.username or options.password \ or options.basic_auth or options.netrc: parser.error("--kerberos-auth may not be used together with " "--username, --password, --basic-auth or --netrc") auth = HTTPKerberosAuth(mutual_authentication=OPTIONAL) elif options.username and options.password: if options.netrc: logging.warning("--netrc option ignored") if options.digest_auth: auth = HTTPDigestAuth(options.username, options.password) else: auth = HTTPBasicAuth(options.username, options.password) elif options.netrc: if options.digest_auth: auth = HTTPDigestAuthFromNetrc(url=options.gerrit_url) else: auth = HTTPBasicAuthFromNetrc(url=options.gerrit_url) else: auth = None rest = GerritRestAPI(url=options.gerrit_url, auth=auth) try: query = ["status:open"] if auth: query += ["owner:self"] else: query += ["limit:10"] changes = rest.get("/changes/?q=%s" % "%20".join(query)) logging.info("%d changes", len(changes)) for change in changes: logging.info(change['change_id']) except RequestException as err: logging.error("Error: %s", str(err))
def merge(self): auth = HTTPDigestAuthFromNetrc(url=GERRIT_URL) rest = GerritRestAPI(url=GERRIT_URL, auth=auth, verify=GERRIT_VERIFY) url_path = '/changes/{}/submit'.format(self.id) rest.post(url_path)