1# ------------------------------------ 2# Copyright (c) Microsoft Corporation. 3# Licensed under the MIT License. 4# ------------------------------------ 5 6# pylint: disable=too-many-lines,too-many-public-methods 7from ._shared import parse_key_vault_id 8from ._generated.v7_1 import models 9from ._enums import( 10 CertificatePolicyAction, 11 KeyUsageType, 12 KeyCurveName, 13 KeyType, 14 CertificateContentType, 15 WellKnownIssuerNames 16) 17 18try: 19 from typing import TYPE_CHECKING 20except ImportError: 21 TYPE_CHECKING = False 22 23if TYPE_CHECKING: 24 from typing import Any, Dict, Optional, Union, List 25 from datetime import datetime 26 27 28class AdministratorContact(object): 29 """Details of the organization administrator of the certificate issuer. 30 31 :param str first_name: First name of the issuer. 32 :param str last_name: Last name of the issuer. 33 :param str email: email of the issuer. 34 :param str phone: phone number of the issuer. 35 """ 36 37 def __init__(self, first_name=None, last_name=None, email=None, phone=None): 38 # type: (Optional[str], Optional[str], Optional[str], Optional[str]) -> None 39 self._first_name = first_name 40 self._last_name = last_name 41 self._phone = phone 42 self._email = email 43 44 def __repr__(self): 45 # type () -> str 46 return "AdministratorContact(first_name={}, last_name={}, email={}, phone={})".format( 47 self.first_name, self.last_name, self.email, self.phone 48 )[:1024] 49 50 @classmethod 51 def _from_admin_detail(cls, admin_detail): 52 # type: (models.AdministratorDetails) -> AdministratorContact 53 """Construct a AdministratorContact from an autorest-generated AdministratorDetailsBundle""" 54 return cls( 55 email=admin_detail.email_address, 56 first_name=admin_detail.first_name, 57 last_name=admin_detail.last_name, 58 phone=admin_detail.phone, 59 ) 60 61 @property 62 def email(self): 63 # type: () -> str 64 """:rtype: str""" 65 return self._email 66 67 @property 68 def first_name(self): 69 # type: () -> str 70 """:rtype: str""" 71 return self._first_name 72 73 @property 74 def last_name(self): 75 # type: () -> str 76 """:rtype: str""" 77 return self._last_name 78 79 @property 80 def phone(self): 81 # type: () -> str 82 """:rtype: str""" 83 return self._phone 84 85 86class CertificateOperationError(object): 87 """The key vault server error. 88 89 :param str code: The error code. 90 :param str message: The error message. 91 :param inner_error: The error object itself 92 :type inner_error: ~azure.keyvault.certificates.CertificateOperationError 93 """ 94 95 def __init__(self, code, message, inner_error): 96 # type: (str, str, CertificateOperationError) -> None 97 self._code = code 98 self._message = message 99 self._inner_error = inner_error 100 101 def __repr__(self): 102 # type () -> str 103 return "CertificateOperationError({}, {}, {})".format(self.code, self.message, self.inner_error)[:1024] 104 105 @classmethod 106 def _from_error_bundle(cls, error_bundle): 107 # type: (models.Error) -> CertificateOperationError 108 return cls( 109 code=error_bundle.code, 110 message=error_bundle.message, 111 inner_error=cls._from_error_bundle(error_bundle.inner_error) 112 ) 113 114 @property 115 def code(self): 116 # type: () -> str 117 """The error code. 118 119 :rtype: str 120 """ 121 return self._code 122 123 @property 124 def message(self): 125 # type: () -> str 126 """The error message. 127 128 :rtype: str 129 """ 130 return self._message 131 132 @property 133 def inner_error(self): 134 # type: () -> CertificateOperationError 135 """The error itself 136 137 :return ~azure.keyvault.certificates.CertificateOperationError: 138 """ 139 return self._inner_error 140 141 142class CertificateProperties(object): 143 """Certificate properties consists of a certificates metadata. 144 """ 145 146 def __init__(self, **kwargs): 147 # type: (**Any) -> None 148 self._attributes = kwargs.pop("attributes", None) 149 self._id = kwargs.pop("cert_id", None) 150 self._vault_id = KeyVaultCertificateIdentifier(self._id) 151 self._x509_thumbprint = kwargs.pop("x509_thumbprint", None) 152 self._tags = kwargs.pop("tags", None) 153 154 def __repr__(self): 155 # type () -> str 156 return "<CertificateProperties [{}]>".format(self.id)[:1024] 157 158 @classmethod 159 def _from_certificate_item(cls, certificate_item): 160 # type: (models.CertificateItem) -> CertificateProperties 161 """Construct a CertificateProperties from an autorest-generated CertificateItem""" 162 return cls( 163 attributes=certificate_item.attributes, 164 cert_id=certificate_item.id, 165 x509_thumbprint=certificate_item.x509_thumbprint, 166 tags=certificate_item.tags, 167 ) 168 169 @property 170 def id(self): 171 # type: () -> str 172 """Certificate identifier. 173 174 :rtype: str 175 """ 176 return self._id 177 178 @property 179 def name(self): 180 # type: () -> str 181 """The name of the certificate. 182 183 :rtype: str 184 """ 185 return self._vault_id.name 186 187 @property 188 def enabled(self): 189 # type: () -> bool 190 """Whether the certificate is enabled or not. 191 192 :rtype: bool 193 """ 194 return self._attributes.enabled if self._attributes else None 195 196 @property 197 def not_before(self): 198 # type: () -> datetime 199 """The datetime before which the certificate is not valid. 200 201 :rtype: ~datetime.datetime 202 """ 203 return self._attributes.not_before if self._attributes else None 204 205 @property 206 def expires_on(self): 207 # type: () -> datetime 208 """The datetime when the certificate expires. 209 210 :rtype: ~datetime.datetime 211 """ 212 return self._attributes.expires if self._attributes else None 213 214 @property 215 def created_on(self): 216 # type: () -> datetime 217 """The datetime when the certificate is created. 218 219 :rtype: ~datetime.datetime 220 """ 221 return self._attributes.created if self._attributes else None 222 223 @property 224 def updated_on(self): 225 # type: () -> datetime 226 """The datetime when the certificate was last updated. 227 228 :rtype: ~datetime.datetime 229 """ 230 return self._attributes.updated if self._attributes else None 231 232 @property 233 def recoverable_days(self): 234 # type: () -> Optional[int] 235 """The number of days the certificate is retained before being deleted from a soft-delete enabled Key Vault. 236 237 :rtype: int 238 """ 239 # recoverable_days was added in 7.1-preview 240 if self._attributes and hasattr(self._attributes, "recoverable_days"): 241 return self._attributes.recoverable_days 242 return None 243 244 @property 245 def recovery_level(self): 246 # type: () -> models.DeletionRecoveryLevel 247 """The deletion recovery level currently in effect for the certificate. 248 249 :rtype: models.DeletionRecoveryLevel 250 """ 251 return self._attributes.recovery_level if self._attributes else None 252 253 @property 254 def vault_url(self): 255 # type: () -> str 256 """URL of the vault containing the certificate 257 258 :rtype: str 259 """ 260 return self._vault_id.vault_url 261 262 @property 263 def x509_thumbprint(self): 264 # type: () -> bytes 265 """Thumbprint of the certificate. 266 267 :rtype: bytes 268 """ 269 return self._x509_thumbprint 270 271 @property 272 def tags(self): 273 # type: () -> Dict[str, str] 274 """Application specific metadata in the form of key-value pairs. 275 276 :rtype: str 277 """ 278 return self._tags 279 280 @property 281 def version(self): 282 # type: () -> str 283 """The version of the certificate 284 285 :rtype: str 286 """ 287 return self._vault_id.version 288 289 290class KeyVaultCertificate(object): 291 """Consists of a certificate and its attributes 292 293 :param policy: The management policy for the certificate. 294 :type policy: ~azure.keyvault.certificates.CertificatePolicy 295 :param properties: The certificate's properties. 296 :type properties: ~azure.keyvault.certificates.CertificateProperties 297 :param bytearray cer: CER contents of the X509 certificate. 298 """ 299 300 def __init__( 301 self, 302 policy=None, # type: Optional[CertificatePolicy] 303 properties=None, # type: Optional[CertificateProperties] 304 cer=None, # type: Optional[bytes] 305 **kwargs # type: Any 306 ): 307 # type: (...) -> None 308 self._properties = properties 309 self._key_id = kwargs.get("key_id", None) 310 self._secret_id = kwargs.get("secret_id") 311 self._policy = policy 312 self._cer = cer 313 314 def __repr__(self): 315 # type () -> str 316 return "<KeyVaultCertificate [{}]>".format(self.id)[:1024] 317 318 @classmethod 319 def _from_certificate_bundle(cls, certificate_bundle): 320 # type: (models.CertificateBundle) -> KeyVaultCertificate 321 """Construct a certificate from an autorest-generated certificateBundle""" 322 # pylint:disable=protected-access 323 324 if certificate_bundle.policy: 325 policy = CertificatePolicy._from_certificate_policy_bundle(certificate_bundle.policy) 326 else: 327 policy = None 328 329 return cls( 330 properties=CertificateProperties._from_certificate_item(certificate_bundle), 331 key_id=certificate_bundle.kid, 332 secret_id=certificate_bundle.sid, 333 policy=policy, 334 cer=certificate_bundle.cer, 335 ) 336 337 @property 338 def id(self): 339 # type: () -> str 340 """Certificate identifier. 341 342 :rtype: str 343 """ 344 return self._properties.id 345 346 @property 347 def name(self): 348 # type: () -> str 349 """The name of the certificate. 350 351 :rtype: str 352 """ 353 return self._properties.name 354 355 @property 356 def properties(self): 357 # type: () -> CertificateProperties 358 """The certificate's properties 359 360 :rtype: ~azure.keyvault.certificates.CertificateProperties 361 """ 362 return self._properties 363 364 @property 365 def key_id(self): 366 # type: () -> str 367 """:rtype: str""" 368 return self._key_id 369 370 @property 371 def secret_id(self): 372 # type: () -> str 373 """:rtype: str""" 374 return self._secret_id 375 376 @property 377 def policy(self): 378 # type: () -> CertificatePolicy 379 """The management policy of the certificate. 380 381 :rtype: ~azure.keyvault.certificates.CertificatePolicy 382 """ 383 return self._policy 384 385 @property 386 def cer(self): 387 # type: () -> bytes 388 """The CER contents of the certificate. 389 390 :rtype: bytes 391 """ 392 return self._cer 393 394 395class KeyVaultCertificateIdentifier(object): 396 """Information about a KeyVaultCertificate parsed from a certificate ID. 397 398 :param str source_id: the full original identifier of a certificate 399 :raises ValueError: if the certificate ID is improperly formatted 400 Example: 401 .. literalinclude:: ../tests/test_parse_id.py 402 :start-after: [START parse_key_vault_certificate_id] 403 :end-before: [END parse_key_vault_certificate_id] 404 :language: python 405 :caption: Parse a certificate's ID 406 :dedent: 8 407 """ 408 409 def __init__(self, source_id): 410 # type: (str) -> None 411 self._resource_id = parse_key_vault_id(source_id) 412 413 @property 414 def source_id(self): 415 # type: () -> str 416 return self._resource_id.source_id 417 418 @property 419 def vault_url(self): 420 # type: () -> str 421 return self._resource_id.vault_url 422 423 @property 424 def name(self): 425 # type: () -> str 426 return self._resource_id.name 427 428 @property 429 def version(self): 430 # type: () -> Optional[str] 431 return self._resource_id.version 432 433 434class CertificateOperation(object): 435 # pylint:disable=too-many-instance-attributes 436 """A certificate operation is returned in case of long running requests. 437 438 :param str cert_operation_id: The certificate id. 439 :param issuer_name: Name of the operation's issuer object or reserved names. 440 :type issuer_name: str or ~azure.keyvault.certificates.WellKnownIssuerNames 441 :param str certificate_type: Type of certificate requested from the issuer provider. 442 :param bool certificate_transparency: Indicates if the certificate this operation is 443 running for is published to certificate transparency logs. 444 :param bytearray csr: The certificate signing request (CSR) that is being used in the certificate 445 operation. 446 :param bool cancellation_requested: Indicates if cancellation was requested on the certificate 447 operation. 448 :param str status: Status of the certificate operation. 449 :param str status_details: The status details of the certificate operation 450 :param error: Error encountered, if any, during the certificate operation. 451 :type error: ~azure.keyvault.certificates.CertificateOperationError 452 :param str target: Location which contains the result of the certificate operation. 453 :param str request_id: Identifier for the certificate operation. 454 """ 455 456 def __init__( 457 self, 458 cert_operation_id=None, # type: Optional[str] 459 issuer_name=None, # type: Optional[Union[str, WellKnownIssuerNames]] 460 certificate_type=None, # type: Optional[str] 461 certificate_transparency=False, # type: Optional[bool] 462 csr=None, # type: Optional[bytes] 463 cancellation_requested=False, # type: Optional[bool] 464 status=None, # type: Optional[str] 465 status_details=None, # type: Optional[str] 466 error=None, # type: Optional[CertificateOperationError] 467 target=None, # type: Optional[str] 468 request_id=None, # type: Optional[str] 469 ): 470 # type: (...) -> None 471 self._id = cert_operation_id 472 self._vault_id = parse_key_vault_id(cert_operation_id) 473 self._issuer_name = issuer_name 474 self._certificate_type = certificate_type 475 self._certificate_transparency = certificate_transparency 476 self._csr = csr 477 self._cancellation_requested = cancellation_requested 478 self._status = status 479 self._status_details = status_details 480 self._error = error 481 self._target = target 482 self._request_id = request_id 483 484 def __repr__(self): 485 # type () -> str 486 return "<CertificateOperation [{}]>".format(self.id)[:1024] 487 488 @classmethod 489 def _from_certificate_operation_bundle(cls, certificate_operation_bundle): 490 # type: (models.CertificateOperation) -> CertificateOperation 491 """Construct a CertificateOperation from an autorest-generated CertificateOperation""" 492 493 issuer_parameters = certificate_operation_bundle.issuer_parameters 494 return cls( 495 cert_operation_id=certificate_operation_bundle.id, 496 issuer_name=issuer_parameters.name, 497 certificate_type=( 498 certificate_operation_bundle.issuer_parameters.certificate_type 499 if certificate_operation_bundle.issuer_parameters 500 else None 501 ), 502 # 2016-10-01 IssuerParameters doesn't have certificate_transparency 503 certificate_transparency=getattr(issuer_parameters, "certificate_transparency", None), 504 csr=certificate_operation_bundle.csr, 505 cancellation_requested=certificate_operation_bundle.cancellation_requested, 506 status=certificate_operation_bundle.status, 507 status_details=certificate_operation_bundle.status_details, 508 error=(CertificateOperationError._from_error_bundle(certificate_operation_bundle.error) # pylint: disable=protected-access 509 if certificate_operation_bundle.error else None), 510 target=certificate_operation_bundle.target, 511 request_id=certificate_operation_bundle.request_id, 512 ) 513 514 @property 515 def id(self): 516 # type: () -> str 517 """:rtype: str""" 518 return self._id 519 520 @property 521 def name(self): 522 # type: () -> str 523 """:rtype: str""" 524 return self._vault_id.name 525 526 @property 527 def vault_url(self): 528 # type: () -> str 529 """URL of the vault containing the CertificateOperation 530 531 :rtype: str 532 """ 533 return self._vault_id.vault_url 534 535 @property 536 def issuer_name(self): 537 # type: () -> str 538 """The name of the issuer of the certificate. 539 540 :rtype: str 541 """ 542 return self._issuer_name 543 544 @property 545 def certificate_type(self): 546 # type: () -> str 547 """Type of certificate to be requested from the issuer provider. 548 549 :rtype: str 550 """ 551 return self._certificate_type 552 553 @property 554 def certificate_transparency(self): 555 # type: () -> bool 556 """Whether certificates generated under this policy should be published to certificate 557 transparency logs. 558 559 :rtype: bool 560 """ 561 return self._certificate_transparency 562 563 @property 564 def csr(self): 565 # type: () -> bytes 566 """The certificate signing request that is being used in this certificate operation. 567 568 :rtype: bytes 569 """ 570 return self._csr 571 572 @property 573 def cancellation_requested(self): 574 # type: () -> bool 575 """Whether cancellation was requested on the certificate operation. 576 577 :rtype: bool 578 """ 579 return self._cancellation_requested 580 581 @property 582 def status(self): 583 # type: () -> str 584 """:rtype: str""" 585 return self._status 586 587 @property 588 def status_details(self): 589 # type: () -> str 590 """:rtype: str""" 591 return self._status_details 592 593 @property 594 def error(self): 595 # type: () -> CertificateOperationError 596 """:rtype: ~azure.keyvault.certificates.CertificateOperationError""" 597 return self._error 598 599 @property 600 def target(self): 601 # type: () -> str 602 """Location which contains the result of the certificate operation. 603 604 :rtype: str 605 """ 606 return self._target 607 608 @property 609 def request_id(self): 610 # type: () -> str 611 """Identifier for the certificate operation. 612 613 :rtype: str 614 """ 615 return self._request_id 616 617 618class CertificatePolicy(object): 619 """Management policy for a certificate. 620 621 :param Optional[str] issuer_name: Optional. Name of the referenced issuer object or reserved names; for example, 622 :attr:`~azure.keyvault.certificates.WellKnownIssuerNames.self` or 623 :attr:`~azure.keyvault.certificates.WellKnownIssuerNames.unknown` 624 :keyword str subject: The subject name of the certificate. Should be a valid X509 625 distinguished name. Either subject or one of the subject alternative name parameters are required for 626 creating a certificate. This will be ignored when importing a certificate; the subject will be parsed from 627 the imported certificate. 628 :keyword Iterable[str] san_emails: Subject alternative emails of the X509 object. Either 629 subject or one of the subject alternative name parameters are required for creating a certificate. 630 :keyword Iterable[str] san_dns_names: Subject alternative DNS names of the X509 object. Either 631 subject or one of the subject alternative name parameters are required for creating a certificate. 632 :keyword Iterable[str] san_user_principal_names: Subject alternative user principal names of the X509 object. 633 Either subject or one of the subject alternative name parameters are required for creating a certificate. 634 :keyword bool exportable: Indicates if the private key can be exported. For valid values, 635 see KeyType. 636 :keyword key_type: The type of key pair to be used for the certificate. 637 :paramtype key_type: str or ~azure.keyvault.certificates.KeyType 638 :keyword int key_size: The key size in bits. For example: 2048, 3072, or 4096 639 for RSA. 640 :keyword bool reuse_key: Indicates if the same key pair will be used on certificate 641 renewal. 642 :keyword key_curve_name: Elliptic curve name. For valid values, see KeyCurveName. 643 :paramtype key_curve_name: str or ~azure.keyvault.certificates.KeyCurveName 644 :keyword enhanced_key_usage: The extended ways the key of the certificate can be used. 645 :paramtype enhanced_key_usage: list[str] 646 :keyword key_usage: List of key usages. 647 :paramtype key_usage: list[str or ~azure.keyvault.certificates.KeyUsageType] 648 :keyword content_type: The media type (MIME type) of the secret backing the certificate. If not specified, 649 :attr:`CertificateContentType.pkcs12` is assumed. 650 :paramtype content_type: str or ~azure.keyvault.certificates.CertificateContentType 651 :keyword int validity_in_months: The duration that the certificate is valid in months. 652 :keyword lifetime_actions: Actions that will be performed by Key Vault over the lifetime 653 of a certificate 654 :paramtype lifetime_actions: Iterable[~azure.keyvault.certificates.LifetimeAction] 655 :keyword str certificate_type: Type of certificate to be requested from the issuer provider. 656 :keyword bool certificate_transparency: Indicates if the certificates generated under this policy 657 should be published to certificate transparency logs. 658 659 """ 660 661 # pylint:disable=too-many-instance-attributes 662 def __init__( 663 self, 664 issuer_name=None, # type: Optional[str] 665 **kwargs # type: Any 666 ): 667 # type: (...) -> None 668 self._issuer_name = issuer_name 669 self._subject = kwargs.pop("subject", None) 670 self._attributes = kwargs.pop("attributes", None) 671 self._exportable = kwargs.pop("exportable", None) 672 self._key_type = kwargs.pop("key_type", None) 673 self._key_size = kwargs.pop("key_size", None) 674 self._reuse_key = kwargs.pop("reuse_key", None) 675 self._key_curve_name = kwargs.pop("key_curve_name", None) 676 self._enhanced_key_usage = kwargs.pop("enhanced_key_usage", None) 677 self._key_usage = kwargs.pop("key_usage", None) 678 self._content_type = kwargs.pop("content_type", None) 679 self._validity_in_months = kwargs.pop("validity_in_months", None) 680 self._lifetime_actions = kwargs.pop("lifetime_actions", None) 681 self._certificate_type = kwargs.pop("certificate_type", None) 682 self._certificate_transparency = kwargs.pop("certificate_transparency", None) 683 self._san_emails = kwargs.pop("san_emails", None) or None 684 self._san_dns_names = kwargs.pop("san_dns_names", None) or None 685 self._san_user_principal_names = kwargs.pop("san_user_principal_names", None) or None 686 687 @classmethod 688 def get_default(cls): 689 return cls(issuer_name=WellKnownIssuerNames.self, subject="CN=DefaultPolicy") 690 691 def __repr__(self): 692 # type () -> str 693 return "<CertificatePolicy [issuer_name: {}]>".format(self.issuer_name)[:1024] 694 695 def _to_certificate_policy_bundle(self): 696 # type: (CertificatePolicy) -> models.CertificatePolicy 697 698 """Construct a version emulating the generated CertificatePolicy from a wrapped CertificatePolicy""" 699 if self.issuer_name or self.certificate_type or self.certificate_transparency: 700 issuer_parameters = models.IssuerParameters( 701 name=self.issuer_name, 702 certificate_type=self.certificate_type, 703 certificate_transparency=self.certificate_transparency, # 2016-10-01 model will ignore this 704 ) 705 else: 706 issuer_parameters = None 707 708 # pylint:disable=too-many-boolean-expressions 709 if ( 710 self.enabled is not None 711 or self.created_on is not None 712 or self.updated_on is not None 713 ): 714 attributes = models.CertificateAttributes( 715 enabled=self.enabled, 716 created=self.created_on, 717 updated=self.updated_on, 718 ) 719 else: 720 attributes = None 721 722 if self.lifetime_actions: 723 lifetime_actions = [] 724 for lifetime_action in self.lifetime_actions: 725 lifetime_actions.append( 726 models.LifetimeAction( 727 trigger=models.Trigger( 728 lifetime_percentage=lifetime_action.lifetime_percentage, 729 days_before_expiry=lifetime_action.days_before_expiry, 730 ), 731 action=models.Action(action_type=lifetime_action.action), 732 ) 733 ) 734 else: 735 lifetime_actions = None 736 737 # pylint:disable=too-many-boolean-expressions 738 if ( 739 self.subject 740 or self.enhanced_key_usage 741 or self.key_usage 742 or self.san_emails 743 or self.san_user_principal_names 744 or self.san_dns_names 745 or self.validity_in_months 746 ): 747 if self.key_usage: 748 key_usage = [k.value if not isinstance(k, str) else k for k in self.key_usage] 749 else: 750 key_usage = None 751 752 x509_certificate_properties = models.X509CertificateProperties( 753 subject=self.subject, 754 ekus=self.enhanced_key_usage, 755 subject_alternative_names=models.SubjectAlternativeNames( 756 emails=self.san_emails, upns=self.san_user_principal_names, dns_names=self.san_dns_names 757 ), 758 key_usage=key_usage, 759 validity_in_months=self.validity_in_months, 760 ) 761 else: 762 x509_certificate_properties = None 763 764 if self.exportable or self.key_type or self.key_size or self.reuse_key or self.key_curve_name: 765 key_properties = models.KeyProperties( 766 exportable=self.exportable, 767 key_type=self.key_type, 768 key_size=self.key_size, 769 reuse_key=self.reuse_key, 770 curve=self.key_curve_name, 771 ) 772 else: 773 key_properties = None 774 775 if self.content_type: 776 secret_properties = models.SecretProperties(content_type=self.content_type) 777 else: 778 secret_properties = None 779 780 policy_bundle = models.CertificatePolicy( 781 key_properties=key_properties, 782 secret_properties=secret_properties, 783 x509_certificate_properties=x509_certificate_properties, 784 lifetime_actions=lifetime_actions, 785 issuer_parameters=issuer_parameters, 786 attributes=attributes, 787 ) 788 return policy_bundle 789 790 @classmethod 791 def _from_certificate_policy_bundle(cls, certificate_policy_bundle): 792 # type: (models.CertificatePolicy) -> CertificatePolicy 793 """Construct a CertificatePolicy from an autorest-generated CertificatePolicy""" 794 if certificate_policy_bundle.lifetime_actions: 795 lifetime_actions = [ 796 LifetimeAction( 797 action=(CertificatePolicyAction(item.action.action_type) if item.action.action_type else None), 798 lifetime_percentage=item.trigger.lifetime_percentage, 799 days_before_expiry=item.trigger.days_before_expiry, 800 ) 801 for item in certificate_policy_bundle.lifetime_actions 802 ] 803 else: 804 lifetime_actions = None 805 x509_certificate_properties = certificate_policy_bundle.x509_certificate_properties 806 if x509_certificate_properties and x509_certificate_properties.key_usage: 807 key_usage = [KeyUsageType(k) for k in x509_certificate_properties.key_usage] 808 else: 809 key_usage = None 810 key_properties = certificate_policy_bundle.key_properties 811 curve_name = getattr(key_properties, "curve", None) # missing from 2016-10-01 KeyProperties 812 if curve_name: 813 curve_name = KeyCurveName(curve_name) 814 815 issuer_parameters = certificate_policy_bundle.issuer_parameters 816 return cls( 817 issuer_name=issuer_parameters.name, 818 subject=(x509_certificate_properties.subject if x509_certificate_properties else None), 819 certificate_type=issuer_parameters.certificate_type, 820 # 2016-10-01 IssuerParameters doesn't have certificate_transparency 821 certificate_transparency=getattr(issuer_parameters, "certificate_transparency", None), 822 lifetime_actions=lifetime_actions, 823 exportable=key_properties.exportable if key_properties else None, 824 key_type=KeyType(key_properties.key_type) if key_properties and key_properties.key_type else None, 825 key_size=key_properties.key_size if key_properties else None, 826 reuse_key=key_properties.reuse_key if key_properties else None, 827 key_curve_name=curve_name, 828 enhanced_key_usage=x509_certificate_properties.ekus if x509_certificate_properties else None, 829 key_usage=key_usage, 830 content_type=( 831 CertificateContentType(certificate_policy_bundle.secret_properties.content_type) 832 if certificate_policy_bundle.secret_properties and 833 certificate_policy_bundle.secret_properties.content_type 834 else None 835 ), 836 attributes=certificate_policy_bundle.attributes, 837 san_emails=( 838 x509_certificate_properties.subject_alternative_names.emails 839 if x509_certificate_properties and x509_certificate_properties.subject_alternative_names 840 else None 841 ), 842 san_user_principal_names=( 843 x509_certificate_properties.subject_alternative_names.upns 844 if x509_certificate_properties and x509_certificate_properties.subject_alternative_names 845 else None 846 ), 847 san_dns_names=( 848 x509_certificate_properties.subject_alternative_names.dns_names 849 if x509_certificate_properties and x509_certificate_properties.subject_alternative_names 850 else None 851 ), 852 validity_in_months=( 853 x509_certificate_properties.validity_in_months if x509_certificate_properties else None 854 ), 855 ) 856 857 @property 858 def exportable(self): 859 # type: () -> bool 860 """Whether the private key can be exported. 861 862 :rtype: bool 863 """ 864 return self._exportable 865 866 @property 867 def key_type(self): 868 # type: () -> KeyType 869 """The type of key pair to be used for the certificate. 870 871 :rtype: ~azure.keyvault.certificates.KeyType 872 """ 873 return self._key_type 874 875 @property 876 def key_size(self): 877 # type: () -> int 878 """The key size in bits. 879 880 :rtype: int 881 """ 882 return self._key_size 883 884 @property 885 def reuse_key(self): 886 # type: () -> bool 887 """Whether the same key pair will be used on certificate renewal. 888 889 :rtype: bool 890 """ 891 return self._reuse_key 892 893 @property 894 def key_curve_name(self): 895 # type: () -> KeyCurveName 896 """Elliptic curve name. 897 898 :rtype: ~azure.keyvault.certificates.KeyCurveName 899 """ 900 return self._key_curve_name 901 902 @property 903 def enhanced_key_usage(self): 904 # type: () -> List[str] 905 """The enhanced key usage. 906 907 :rtype: list[str] 908 """ 909 return self._enhanced_key_usage 910 911 @property 912 def key_usage(self): 913 # type: () -> List[KeyUsageType] 914 """List of key usages. 915 916 :rtype: list[~azure.keyvault.certificates.KeyUsageType] 917 """ 918 return self._key_usage 919 920 @property 921 def content_type(self): 922 # type: () -> CertificateContentType 923 """The media type (MIME type). 924 925 :rtype: ~azure.keyvault.certificates.CertificateContentType 926 """ 927 return self._content_type 928 929 @property 930 def subject(self): 931 # type: () -> str 932 """The subject name of the certificate. 933 934 :rtype: str 935 """ 936 return self._subject 937 938 @property 939 def san_emails(self): 940 # type: () -> List[str] 941 """The subject alternative email addresses. 942 943 :rtype: list[str] 944 """ 945 return self._san_emails 946 947 @property 948 def san_dns_names(self): 949 # type: () -> List[str] 950 """The subject alternative domain names. 951 952 :rtype: list[str] 953 """ 954 return self._san_dns_names 955 956 @property 957 def san_user_principal_names(self): 958 # type: () -> List[str] 959 """The subject alternative user principal names. 960 961 :rtype: list[str] 962 """ 963 return self._san_user_principal_names 964 965 @property 966 def validity_in_months(self): 967 # type: () -> int 968 """The duration that the certificate is valid for in months. 969 970 :rtype: int 971 """ 972 return self._validity_in_months 973 974 @property 975 def lifetime_actions(self): 976 # type: () -> List[LifetimeAction] 977 """Actions and their triggers that will be performed by Key Vault over 978 the lifetime of the certificate. 979 980 :rtype: list[~azure.keyvault.certificates.LifetimeAction] 981 """ 982 return self._lifetime_actions 983 984 @property 985 def issuer_name(self): 986 # type: () -> Optional[str] 987 """Name of the referenced issuer object or reserved names for the issuer 988 of the certificate. 989 990 :rtype: str 991 """ 992 return self._issuer_name 993 994 @property 995 def certificate_type(self): 996 # type: () -> str 997 """Type of certificate requested from the issuer provider. 998 999 :rtype: str 1000 """ 1001 return self._certificate_type 1002 1003 @property 1004 def certificate_transparency(self): 1005 # type: () -> bool 1006 """Whether the certificates generated under this policy should be published 1007 to certificate transparency logs. 1008 1009 :rtype: bool 1010 """ 1011 return self._certificate_transparency 1012 1013 @property 1014 def enabled(self): 1015 # type: () -> bool 1016 """Whether the certificate is enabled or not. 1017 1018 :rtype: bool 1019 """ 1020 return self._attributes.enabled if self._attributes else None 1021 1022 @property 1023 def created_on(self): 1024 # type: () -> datetime 1025 """The datetime when the certificate is created. 1026 1027 :rtype: ~datetime.datetime 1028 """ 1029 return self._attributes.created if self._attributes else None 1030 1031 @property 1032 def updated_on(self): 1033 # type: () -> datetime 1034 """The datetime when the certificate was last updated. 1035 1036 :rtype: ~datetime.datetime 1037 """ 1038 return self._attributes.updated if self._attributes else None 1039 1040 1041class CertificateContact(object): 1042 """The contact information for the vault certificates. 1043 1044 :param str email: Email address of a contact for the certificate. 1045 :param str name: Name of a contact for the certificate. 1046 :param str phone: phone number of a contact for the certificate. 1047 """ 1048 1049 def __init__(self, email=None, name=None, phone=None): 1050 # type: (Optional[str], Optional[str], Optional[str]) -> None 1051 self._email = email 1052 self._name = name 1053 self._phone = phone 1054 1055 def __repr__(self): 1056 # type () -> str 1057 return "CertificateContact(email={}, name={}, phone={})".format(self.email, self.name, self.phone)[:1024] 1058 1059 def _to_certificate_contacts_item(self): 1060 # type: (CertificateContact) -> models.Contact 1061 return models.Contact(email_address=self.email, name=self.name, phone=self.phone) 1062 1063 @classmethod 1064 def _from_certificate_contacts_item(cls, contact_item): 1065 # type: (models.Contact) -> CertificateContact 1066 """Construct a CertificateContact from an autorest-generated ContactItem.""" 1067 return cls(email=contact_item.email_address, name=contact_item.name, phone=contact_item.phone) 1068 1069 @property 1070 def email(self): 1071 # type: () -> str 1072 """:rtype: str""" 1073 return self._email 1074 1075 @property 1076 def name(self): 1077 # type: () -> str 1078 """:rtype: str""" 1079 return self._name 1080 1081 @property 1082 def phone(self): 1083 # type: () -> str 1084 """:rtype: str""" 1085 return self._phone 1086 1087 1088class IssuerProperties(object): 1089 """The properties of an issuer containing the issuer metadata. 1090 1091 :param str provider: The issuer provider. 1092 """ 1093 1094 def __init__(self, provider=None, **kwargs): 1095 # type: (Optional[str], **Any) -> None 1096 self._id = kwargs.pop("issuer_id", None) 1097 self._vault_id = parse_key_vault_id(self._id) 1098 self._provider = provider 1099 1100 def __repr__(self): 1101 # type () -> str 1102 return "IssuerProperties(issuer_id={}, provider={})".format(self.id, self.provider)[:1024] 1103 1104 @classmethod 1105 def _from_issuer_item(cls, issuer_item): 1106 # type: (models.CertificateIssuerItem) -> IssuerProperties 1107 """Construct a IssuerProperties from an autorest-generated CertificateIssuerItem""" 1108 return cls(issuer_id=issuer_item.id, provider=issuer_item.provider) 1109 1110 @property 1111 def id(self): 1112 # type: () -> str 1113 """:rtype: str""" 1114 return self._id 1115 1116 @property 1117 def name(self): 1118 # type: () -> str 1119 # Issuer name is listed under version under vault_id 1120 """:rtype: str""" 1121 return self._vault_id.version 1122 1123 @property 1124 def provider(self): 1125 # type: () -> str 1126 """:rtype: str""" 1127 return self._provider 1128 1129 1130class CertificateIssuer(object): 1131 """The issuer for a Key Vault certificate. 1132 1133 :param str provider: The issuer provider 1134 :param str account_id: The username / account name / account id. 1135 :param str password: The password / secret / account key. 1136 :param str organization_id: The ID of the organization. 1137 :param admin_contacts: Details of the organization administrator. 1138 :type admin_contacts: list[~azure.keyvault.certificates.AdministratorContact] 1139 """ 1140 1141 def __init__( 1142 self, 1143 provider, # type: str 1144 attributes=None, # type: Optional[models.IssuerAttributes] 1145 account_id=None, # type: Optional[str] 1146 password=None, # type: Optional[str] 1147 organization_id=None, # type: Optional[str] 1148 admin_contacts=None, # type: Optional[List[AdministratorContact]] 1149 **kwargs # type: Any 1150 ): 1151 # type: (...) -> None 1152 self._provider = provider 1153 self._attributes = attributes 1154 self._account_id = account_id 1155 self._password = password 1156 self._organization_id = organization_id 1157 self._admin_contacts = admin_contacts 1158 self._id = kwargs.pop("issuer_id", None) 1159 self._vault_id = parse_key_vault_id(self._id) 1160 1161 def __repr__(self): 1162 # type () -> str 1163 return "<CertificateIssuer [{}]>".format(self.id)[:1024] 1164 1165 @classmethod 1166 def _from_issuer_bundle(cls, issuer_bundle): 1167 # type: (models.IssuerBundle) -> CertificateIssuer 1168 """Construct a CertificateIssuer from an autorest-generated IssuerBundle""" 1169 admin_contacts = [] 1170 admin_details = ( 1171 issuer_bundle.organization_details.admin_details if issuer_bundle.organization_details else None 1172 ) 1173 if admin_details: 1174 # pylint:disable=protected-access 1175 for admin_detail in admin_details: 1176 admin_contacts.append(AdministratorContact._from_admin_detail(admin_detail)) 1177 return cls( 1178 provider=IssuerProperties._from_issuer_item(issuer_bundle).provider, # pylint: disable=protected-access 1179 attributes=issuer_bundle.attributes, 1180 account_id=issuer_bundle.credentials.account_id if issuer_bundle.credentials else None, 1181 password=issuer_bundle.credentials.password if issuer_bundle.credentials else None, 1182 organization_id=issuer_bundle.organization_details.id if issuer_bundle.organization_details else None, 1183 admin_contacts=admin_contacts, 1184 issuer_id=issuer_bundle.id, 1185 ) 1186 1187 @property 1188 def id(self): 1189 # type: () -> str 1190 """:rtype: str""" 1191 return self._id 1192 1193 @property 1194 def name(self): 1195 # type: () -> str 1196 # Issuer name is listed under version under vault_id. 1197 # This is because the id we pass to parse_key_vault_id has an extra segment, so where most cases the version of 1198 # the general pattern is certificates/name/version, but here we have certificates/issuers/name/version. 1199 # Issuers are not versioned. 1200 """:rtype: str""" 1201 return self._vault_id.version 1202 1203 @property 1204 def provider(self): 1205 # type: () -> str 1206 """The issuer provider. 1207 1208 :rtype: str 1209 """ 1210 return self._provider 1211 1212 @property 1213 def enabled(self): 1214 # type: () -> bool 1215 """Whether the certificate is enabled or not. 1216 1217 :rtype: bool 1218 """ 1219 return self._attributes.enabled if self._attributes else None 1220 1221 @property 1222 def created_on(self): 1223 # type: () -> datetime 1224 """The datetime when the certificate is created. 1225 1226 :rtype: ~datetime.datetime 1227 """ 1228 return self._attributes.created if self._attributes else None 1229 1230 @property 1231 def updated_on(self): 1232 # type: () -> datetime 1233 """The datetime when the certificate was last updated. 1234 1235 :rtype: ~datetime.datetime 1236 """ 1237 return self._attributes.updated if self._attributes else None 1238 1239 @property 1240 def account_id(self): 1241 # type: () -> str 1242 """The username/ account name/ account id. 1243 1244 :rtype: str 1245 """ 1246 return self._account_id 1247 1248 @property 1249 def password(self): 1250 # type: () -> str 1251 """The password / secret / account key. 1252 1253 :rtype: str 1254 """ 1255 return self._password 1256 1257 @property 1258 def organization_id(self): 1259 # type: () -> str 1260 """:rtype: str""" 1261 return self._organization_id 1262 1263 @property 1264 def admin_contacts(self): 1265 # type: () -> List[AdministratorContact] 1266 """Contact details of the organization administrator of this issuer. 1267 1268 :rtype: list[~azure.keyvault.certificates.AdministratorContact] 1269 """ 1270 return self._admin_contacts 1271 1272 1273class LifetimeAction(object): 1274 """Action and its trigger that will be performed by certificate Vault over the 1275 lifetime of a certificate. 1276 1277 :param action: The type of the action. For valid values, see CertificatePolicyAction 1278 :type action: str or ~azure.keyvault.certificates.CertificatePolicyAction 1279 :param int lifetime_percentage: Percentage of lifetime at which to trigger. Value 1280 should be between 1 and 99. 1281 :param int days_before_expiry: Days before expiry to attempt renewal. Value should be between 1282 1 and validity_in_months multiplied by 27. I.e., if validity_in_months is 36, then value 1283 should be between 1 and 972 (36 * 27). 1284 """ 1285 1286 def __init__(self, action, lifetime_percentage=None, days_before_expiry=None): 1287 # type: (CertificatePolicyAction, Optional[int], Optional[int]) -> None 1288 self._lifetime_percentage = lifetime_percentage 1289 self._days_before_expiry = days_before_expiry 1290 self._action = action 1291 1292 def __repr__(self): 1293 # type () -> str 1294 return "LifetimeAction(action={}, lifetime_percentage={}, days_before_expiry={})".format( 1295 self.action, self.lifetime_percentage, self.days_before_expiry 1296 )[:1024] 1297 1298 @property 1299 def lifetime_percentage(self): 1300 # type: () -> int 1301 """Percentage of lifetime at which to trigger. 1302 1303 :rtype: int 1304 """ 1305 return self._lifetime_percentage 1306 1307 @property 1308 def days_before_expiry(self): 1309 # type: () -> int 1310 """Days before expiry to attempt renewal. 1311 1312 :rtype: int 1313 """ 1314 return self._days_before_expiry 1315 1316 @property 1317 def action(self): 1318 # type: () -> CertificatePolicyAction 1319 """The type of the action that will be executed. 1320 Valid values are "EmailContacts" and "AutoRenew" 1321 1322 :rtype: ~azure.keyvault.certificates.CertificatePolicyAction 1323 """ 1324 return self._action 1325 1326 1327class DeletedCertificate(KeyVaultCertificate): 1328 """A Deleted Certificate consisting of its previous id, attributes and its 1329 tags, as well as information on when it will be purged. 1330 1331 :param policy: The management policy of the deleted certificate. 1332 :type policy: ~azure.keyvault.certificates.CertificatePolicy 1333 :param bytearray cer: CER contents of the X509 certificate. 1334 :param datetime deleted_on: The time when the certificate was deleted, in UTC 1335 :param str recovery_id: The url of the recovery object, used to identify and 1336 recover the deleted certificate. 1337 :param datetime scheduled_purge_date: The time when the certificate is scheduled to 1338 be purged, in UTC 1339 """ 1340 1341 def __init__( 1342 self, 1343 properties=None, # type: Optional[CertificateProperties] 1344 policy=None, # type: Optional[CertificatePolicy] 1345 cer=None, # type: Optional[bytes] 1346 **kwargs # type: Any 1347 ): 1348 # type: (...) -> None 1349 super(DeletedCertificate, self).__init__(properties=properties, policy=policy, cer=cer, **kwargs) 1350 self._deleted_on = kwargs.get("deleted_on", None) 1351 self._recovery_id = kwargs.get("recovery_id", None) 1352 self._scheduled_purge_date = kwargs.get("scheduled_purge_date", None) 1353 1354 def __repr__(self): 1355 # type () -> str 1356 return "<DeletedCertificate [{}]>".format(self.id)[:1024] 1357 1358 @classmethod 1359 def _from_deleted_certificate_item(cls, deleted_certificate_item): 1360 # type: (models.DeletedCertificateItem) -> DeletedCertificate 1361 """Construct a DeletedCertificate from an autorest-generated DeletedCertificateItem""" 1362 return cls( 1363 properties=CertificateProperties._from_certificate_item( # pylint: disable=protected-access 1364 deleted_certificate_item 1365 ), 1366 key_id=None, 1367 secret_id=None, 1368 policy=None, 1369 cer=None, 1370 deleted_on=deleted_certificate_item.deleted_date, 1371 recovery_id=deleted_certificate_item.recovery_id, 1372 scheduled_purge_date=deleted_certificate_item.scheduled_purge_date, 1373 ) 1374 1375 @classmethod 1376 def _from_deleted_certificate_bundle(cls, deleted_certificate_bundle): 1377 # type: (models.DeletedCertificateBundle) -> DeletedCertificate 1378 """Construct a DeletedCertificate from an autorest-generated DeletedCertificateItem""" 1379 # pylint:disable=protected-access 1380 return cls( 1381 properties=CertificateProperties._from_certificate_item(deleted_certificate_bundle), 1382 key_id=deleted_certificate_bundle.kid, 1383 secret_id=deleted_certificate_bundle.sid, 1384 policy=CertificatePolicy._from_certificate_policy_bundle(deleted_certificate_bundle.policy), 1385 cer=deleted_certificate_bundle.cer, 1386 deleted_on=deleted_certificate_bundle.deleted_date, 1387 recovery_id=deleted_certificate_bundle.recovery_id, 1388 scheduled_purge_date=deleted_certificate_bundle.scheduled_purge_date, 1389 ) 1390 1391 @property 1392 def deleted_on(self): 1393 # type: () -> datetime 1394 """The datetime that the certificate was deleted. 1395 1396 :rtype: ~datetime.datetime 1397 """ 1398 return self._deleted_on 1399 1400 @property 1401 def recovery_id(self): 1402 # type: () -> str 1403 """The url of the recovery object, used to identify and recover the deleted certificate. 1404 1405 :rtype: str 1406 """ 1407 return self._recovery_id 1408 1409 @property 1410 def scheduled_purge_date(self): 1411 # type: () -> datetime 1412 """The datetime when the certificate is scheduled to be purged. 1413 1414 :rtype: str 1415 """ 1416 return self._scheduled_purge_date 1417