def Run(self, args): try: project_id = properties.VALUES.core.project.GetOrFail() memberships = feature_base.ListMemberships(project_id) name = 'projects/{0}/locations/global/features/{1}'.format( project_id, self.FEATURE_NAME) response = feature_base.GetFeature(name) except apitools_exceptions.HttpUnauthorizedError as e: raise exceptions.Error( 'You are not authorized to see the status of {} ' 'Feature from project [{}]. Underlying error: {}'.format( self.FEATURE_DISPLAY_NAME, project_id, e)) except apitools_exceptions.HttpNotFoundError as e: raise exceptions.Error( '{} Feature for project [{}] is not enabled'.format( self.FEATURE_DISPLAY_NAME, project_id)) if not memberships: return None acm_status = [] feature_state_memberships = parse_feature_state_memberships(response) for name in memberships: cluster = ConfigmanagementFeatureState(name) if name not in feature_state_memberships: acm_status.append(cluster) continue md = feature_state_memberships[name] fs = md.value.configmanagementFeatureState if fs and fs.membershipConfig and fs.membershipConfig.version: cluster.version = fs.membershipConfig.version acm_status.append(cluster) return acm_status
def Run(self, args): try: project_id = properties.VALUES.core.project.GetOrFail() memberships = feature_base.ListMemberships(project_id) name = 'projects/{0}/locations/global/features/{1}'.format( project_id, self.FEATURE_NAME) response = feature_base.GetFeature(name) except apitools_exceptions.HttpUnauthorizedError as e: raise exceptions.Error( 'You are not authorized to see the status of {} ' 'Feature from project [{}]. Underlying error: {}'.format( self.FEATURE_DISPLAY_NAME, project_id, e)) except apitools_exceptions.HttpNotFoundError as e: raise exceptions.Error( '{} Feature for project [{}] is not enabled'.format( self.FEATURE_DISPLAY_NAME, project_id)) if not memberships: return None if response.featureState is None or response.featureState.detailsByMembership is None: membership_details = [] else: membership_details = response.featureState.detailsByMembership.additionalProperties acm_status = [] acm_errors = [] fs_memberships = { os.path.basename(membership_detail.key): membership_detail for membership_detail in membership_details } for name in memberships: cluster = ConfigmanagementFeatureState(name) if name not in fs_memberships: acm_status.append(cluster) continue md = fs_memberships[name] fs = md.value.configmanagementFeatureState # (b/153587485) Show FeatureState.code if it's not OK # as it indicates an unreachable cluster or a dated syncState.code if md.value.code is None: cluster.config_sync = 'CODE_UNSPECIFIED' elif md.value.code.name != 'OK': cluster.config_sync = md.value.code.name else: # operator errors could occur regardless of the deployment_state if has_operator_error(fs): append_error(name, fs.operatorState.errors, acm_errors) # (b/154174276, b/156293028) # check operator_state to see if nomos has been installed if not has_operator_state(fs): cluster.config_sync = 'OPERATOR_STATE_UNSPECIFIED' else: cluster.config_sync = fs.operatorState.deploymentState.name if cluster.config_sync == 'INSTALLED': cluster.update_sync_state(fs) if has_config_sync_error(fs): append_error(name, fs.configSyncState.syncState.errors, acm_errors) cluster.update_policy_controller_state(fs) acm_status.append(cluster) return {'acm_errors': acm_errors, 'acm_status': acm_status}
def Run(self, args): try: project_id = properties.VALUES.core.project.GetOrFail() name = 'projects/{0}/locations/global/features/{1}'.format( project_id, self.FEATURE_NAME) response = feature_base.GetFeature(name) except apitools_exceptions.HttpUnauthorizedError as e: raise exceptions.Error( 'You are not authorized to see the status of {} ' 'Feature from project [{}]. Underlying error: {}'.format( self.FEATURE_DISPLAY_NAME, project_id, e)) except apitools_exceptions.HttpNotFoundError as e: raise exceptions.Error( '{} Feature for project [{}] is not enabled'.format( self.FEATURE_DISPLAY_NAME, project_id)) if response.featureState is None or response.featureState.detailsByMembership is None: return None membership_details = response.featureState.detailsByMembership nomos_status = [] nomos_errors = [] for md in membership_details.additionalProperties: name = os.path.basename(md.key) cluster = ConfigmanagementFeatureState(name) fs = md.value.configmanagementFeatureState # (b/153587485) Show FeatureState.code if it's not OK # as it indicates an unreachable cluster or a dated syncState.code if md.value.code is None: cluster.status = 'CODE_UNSPECIFIED' elif md.value.code.name != 'OK': cluster.status = md.value.code.name # (b/153566864) For cluster not being initialzed elif not (fs and fs.configSyncState and fs.configSyncState.syncState and fs.configSyncState.syncState.code): cluster.status = 'NOT_INSTALLED' else: cluster.status = fs.configSyncState.syncState.code if fs.configSyncState.syncState.syncToken: cluster.last_synced_token = fs.configSyncState.syncState.syncToken[: 7] cluster.last_synced = fs.configSyncState.syncState.lastSync if fs.configSyncState.syncState.errors is not None: for error in fs.configSyncState.syncState.errors: nomos_errors.append({ 'cluster': name, 'error': error.errorMessage }) if (fs.membershipConfig and fs.membershipConfig.configSync and fs.membershipConfig.configSync.git): cluster.sync_branch = fs.membershipConfig.configSync.git.syncBranch nomos_status.append(cluster) return {'nomos_errors': nomos_errors, 'nomos_status': nomos_status}
def _get_backfill_version(self, mem): """Get the value the version field in FeatureSpec should be set to. Args: mem: The membership name whose Spec will be backfilled. Returns: version: A string denoting the version field in MembershipConfig Raises: Error, if retrieving FeatureSpec of FeatureState fails """ try: project_id = properties.VALUES.core.project.GetOrFail() name = 'projects/{0}/locations/global/features/{1}'.format( project_id, self.FEATURE_NAME) response = base.GetFeature(name) except apitools_exceptions.HttpUnauthorizedError as e: raise exceptions.Error( 'You are not authorized to see the status of {} ' 'Feature from project [{}]. Underlying error: {}'.format( self.FEATURE_DISPLAY_NAME, project_id, e)) except apitools_exceptions.HttpNotFoundError as e: raise exceptions.Error( '{} Feature for project [{}] is not enabled'.format( self.FEATURE_DISPLAY_NAME, project_id)) # First check FeatureSpec to see if an existing version is set mem_config = _parse_membership(response, mem) if mem_config and mem_config.version: return mem_config.version # Next, check FeatureState if response.featureState and response.featureState.detailsByMembership: membership_details = response.featureState.detailsByMembership.additionalProperties for m in membership_details: if os.path.basename(m.key) == mem: fs = m.value.configmanagementFeatureState if fs and fs.membershipConfig and fs.membershipConfig.version: # If the version on the cluster is later than the latest supported # version in the Hub API, we do not want to write this version to # spec. If we did, this would result in an error updating spec, # rendering this gcloud command unusable. return fs.membershipConfig.version \ if fs.membershipConfig.version <= self.LATEST_VERSION else '' # If Spec/State did not contain version, return default (latest version) return self.LATEST_VERSION
def Run(self, args): # Get Hub memberships (cluster registered with Hub) from GCP Project. try: project = args.project or properties.VALUES.core.project.GetOrFail( ) memberships = base.ListMemberships(project) name = 'projects/{0}/locations/global/features/{1}'.format( project, self.FEATURE_NAME) response = base.GetFeature(name) except apitools_exceptions.HttpUnauthorizedError as e: raise exceptions.Error( 'Not authorized to see Feature {} status from project [{}]. ' 'Underlying error: {}'.format(self.FEATURE_DISPLAY_NAME, project, e)) except apitools_exceptions.HttpNotFoundError as e: raise exceptions.Error( '{} Feature for project [{}] is not enabled'.format( self.FEATURE_DISPLAY_NAME, project)) if not memberships: log.status.Print('No Memberships available in Hub.') return {} feature_spec_memberships = state_util.parse_feature_spec_memberships( response) feature_state_memberships = state_util.parse_feature_state_memberships( response) # Populate and print out status of memberships. ais_status = [] for name in memberships: cluster_in_spec = None cluster_in_state = None if name in feature_spec_memberships: cluster_in_spec = feature_spec_memberships[name] if name in feature_state_memberships: cluster_in_state = feature_state_memberships[name].value cluster_out = state_util.IdentityServiceMembershipState( name, cluster_in_spec=cluster_in_spec, cluster_in_state=cluster_in_state) ais_status.append(cluster_out) else: ais_status.append({name: 'config not applied'}) return {'Membership Status for Identity Service': ais_status}
def _get_feature(self, project): """Fetches the Config Management Feature. Args: project: project id Returns: configManagementFeature """ try: name = 'projects/{0}/locations/global/features/{1}'.format( project, self.FEATURE_NAME) response = base.GetFeature(name) except apitools_exceptions.HttpUnauthorizedError as e: raise exceptions.Error( 'You are not authorized to see the status of {} ' 'Feature from project [{}]. Underlying error: {}'.format( self.FEATURE_DISPLAY_NAME, project, e)) except apitools_exceptions.HttpNotFoundError as e: raise exceptions.Error( '{} Feature for project [{}] is not enabled'.format( self.FEATURE_DISPLAY_NAME, project)) return response
def _PollFunc(): return base.GetFeature(feature_name)